View Javadoc
1   /*
2    *
3    * The DbUnit Database Testing Framework
4    * Copyright (C)2002-2004, DbUnit.org
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 2.1 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   *
20   */
21  
22  package org.dbunit.dataset;
23  
24  import org.slf4j.Logger;
25  import org.slf4j.LoggerFactory;
26  
27  import org.dbunit.dataset.datatype.DataType;
28  
29  import java.sql.DatabaseMetaData;
30  
31  /**
32   * Represents a table column.
33   *
34   * @author Manuel Laflamme
35   * @author Last changed by: $Author$
36   * @version $Revision$ $Date$
37   * @since 1.0 (Feb 17, 2002)
38   */
39  public class Column
40  {
41  
42      /**
43       * Logger for this class
44       */
45      private static final Logger logger = LoggerFactory.getLogger(Column.class);
46  
47      /**
48       * Indicates that the column might not allow <code>NULL</code> values.
49       */
50      public static final Nullable NO_NULLS = new Nullable("noNulls");
51      /**
52       * Indicates that the column definitely allows <code>NULL</code> values.
53       */
54      public static final Nullable NULLABLE = new Nullable("nullable");
55      /**
56       * Indicates that the nullability of columns is unknown.
57       */
58      public static final Nullable NULLABLE_UNKNOWN = new Nullable("nullableUnknown");
59  
60      private final String _columnName;
61      private final DataType _dataType;
62      private final String _sqlTypeName;
63      private final Nullable _nullable;
64      private final String _defaultValue;
65      private final String _remarks;
66      private final AutoIncrement _autoIncrement;
67      private final Boolean _generatedColumn;
68  
69      /**
70       * Creates a Column object. This constructor set nullable to true.
71       *
72       * @param columnName the column name
73       * @param dataType the data type
74       */
75      public Column(String columnName, DataType dataType)
76      {
77          this(columnName, dataType, NULLABLE_UNKNOWN);
78      }
79  
80      /**
81       * Creates a Column object.
82       */
83      public Column(String columnName, DataType dataType, Nullable nullable)
84      {
85          this(columnName, dataType, dataType.toString(), nullable, null);
86      }
87  
88      /**
89       * Creates a Column object.
90       */
91      public Column(String columnName, DataType dataType, String sqlTypeName,
92              Nullable nullable)
93      {
94          this(columnName, dataType, sqlTypeName, nullable, null);
95      }
96  
97      /**
98       * Creates a Column object.
99       * @param columnName The name of the column
100      * @param dataType The DbUnit {@link DataType} of the column
101      * @param sqlTypeName The SQL name of the column which comes from the JDBC driver.
102      * See value 'TYPE_NAME' in {@link DatabaseMetaData#getColumns(String, String, String, String)}
103      * @param nullable whether or not the column is nullable
104      * @param defaultValue The default value on the DB for this column. Can be <code>null</code>.
105      */
106     public Column(String columnName, DataType dataType, String sqlTypeName,
107             Nullable nullable, String defaultValue)
108     {
109         this(columnName, dataType, sqlTypeName, nullable, defaultValue, null, null);
110     }
111 
112     /**
113      * Creates a Column object.
114      * @param columnName The name of the column
115      * @param dataType The DbUnit {@link DataType} of the column
116      * @param sqlTypeName The SQL name of the column which comes from the JDBC driver.
117      * See value 'TYPE_NAME' in {@link DatabaseMetaData#getColumns(String, String, String, String)}
118      * @param nullable whether or not the column is nullable
119      * @param defaultValue The default value on the DB for this column. Can be <code>null</code>.
120      * @param remarks The remarks on the DB for this column. Can be <code>null</code>.
121      * @param autoIncrement The auto increment setting for this column. Can be <code>null</code>.
122      */
123     public Column(String columnName, DataType dataType, String sqlTypeName,
124             Nullable nullable, String defaultValue, String remarks, AutoIncrement autoIncrement)
125     {
126         this(columnName, dataType, sqlTypeName, nullable, defaultValue, remarks, autoIncrement, null);
127     }
128 
129     /**
130      * Creates a Column object.
131      * @param columnName The name of the column
132      * @param dataType The DbUnit {@link DataType} of the column
133      * @param sqlTypeName The SQL name of the column which comes from the JDBC driver.
134      * See value 'TYPE_NAME' in {@link DatabaseMetaData#getColumns(String, String, String, String)}
135      * @param nullable whether or not the column is nullable
136      * @param defaultValue The default value on the DB for this column. Can be <code>null</code>.
137      * @param remarks The remarks on the DB for this column. Can be <code>null</code>.
138      * @param autoIncrement The auto increment setting for this column. Can be <code>null</code>.
139      * @param generatedColumn Whether this column is a generated column. Can be <code>null</code>.
140      */
141     public Column(String columnName, DataType dataType, String sqlTypeName,
142             Nullable nullable, String defaultValue, String remarks, AutoIncrement autoIncrement,
143             Boolean generatedColumn)
144     {
145         _columnName = columnName;
146         _dataType = dataType;
147         _sqlTypeName = sqlTypeName;
148         _nullable = nullable;
149         _defaultValue = defaultValue;
150         _remarks = remarks;
151         _autoIncrement = autoIncrement;
152         _generatedColumn = generatedColumn;
153     }
154 
155     public boolean hasDefaultValue()
156     {
157         return _defaultValue != null;
158     }
159     
160     public boolean isNotNullable()
161     {
162         return _nullable== Column.NO_NULLS;
163     }
164     
165     /**
166      * Returns this column name.
167      */
168     public String getColumnName()
169     {
170         return _columnName;
171     }
172 
173     /**
174      * Returns this column data type.
175      */
176     public DataType getDataType()
177     {
178         return _dataType;
179     }
180 
181     /**
182      * Returns this column sql data type name.
183      */
184     public String getSqlTypeName()
185     {
186         return _sqlTypeName;
187     }
188 
189     /**
190      * Returns <code>true</code> if this column is nullable.
191      */
192     public Nullable getNullable()
193     {
194         return _nullable;
195     }
196 
197     /**
198      * @return The default value the database uses for this column 
199      * if not specified in the insert column list
200      */
201     public String getDefaultValue()
202     {
203         return _defaultValue;
204     }
205     
206     /**
207      * @return The remarks set on the database for this column
208      * @since 2.4.3
209      */
210     public String getRemarks()
211     {
212         return _remarks;
213     }
214     
215     /**
216      * @return The auto-increment property for this column
217      * @since 2.4.3
218      */
219     public AutoIncrement getAutoIncrement()
220     {
221         return _autoIncrement;
222     }
223     
224     /**
225      * @return Whether the column is a generated column
226      * @since 3.0.0
227      */
228     public Boolean getGeneratedColumn()
229     {
230         return _generatedColumn;
231     }
232     
233     /**
234      * Returns the appropriate Nullable constant according specified JDBC
235      * DatabaseMetaData constant.
236      *
237      * @param nullable one of the following constants
238      * {@link java.sql.DatabaseMetaData#columnNoNulls},
239      * {@link java.sql.DatabaseMetaData#columnNullable},
240      * {@link java.sql.DatabaseMetaData#columnNullableUnknown}
241      */
242     public static Nullable nullableValue(int nullable)
243     {
244         if(logger.isDebugEnabled())
245             logger.debug("nullableValue(nullable={}) - start", String.valueOf(nullable));
246 
247         switch (nullable)
248         {
249             case DatabaseMetaData.columnNoNulls:
250                 return NO_NULLS;
251 
252             case DatabaseMetaData.columnNullable:
253                 return NULLABLE;
254 
255             case DatabaseMetaData.columnNullableUnknown:
256                 return NULLABLE_UNKNOWN;
257 
258             default:
259                 throw new IllegalArgumentException("Unknown constant value "
260                         + nullable);
261         }
262     }
263 
264     /**
265      * Returns the appropriate Nullable constant.
266      *
267      * @param nullable <code>true</code> if null is allowed
268      */
269     public static Nullable nullableValue(boolean nullable)
270     {
271         if(logger.isDebugEnabled())
272             logger.debug("nullableValue(nullable={}) - start", String.valueOf(nullable));
273         
274         return nullable ? NULLABLE : NO_NULLS;
275     }
276     
277     /**
278      * Converts a DatabaseMetaData boolean string to a Boolean object.
279      * @param value The string to convert
280      * @return True if string is "YES", false if string is "NO", null otherwise
281      */
282     public static Boolean convertMetaDataBoolean(String value)
283     {
284         if ("YES".equalsIgnoreCase(value)) {
285             return true;
286         } else if ("NO".equalsIgnoreCase(value)) {
287             return false;
288         } else {
289             return null;
290         }
291     }
292 
293     ////////////////////////////////////////////////////////////////////////////
294     // Object class
295 
296     public String toString()
297     {
298         return "(" + _columnName + ", " + _dataType + ", " + _nullable + ")";
299     }
300 
301     public boolean equals(Object o)
302     {
303         logger.debug("equals(o={}) - start", o);
304 
305         if (this == o) return true;
306         if (!(o instanceof Column)) return false;
307 
308         final Column column = (Column)o;
309 
310         if (!_columnName.equals(column._columnName)) return false;
311         if (!_dataType.equals(column._dataType)) return false;
312         if (!_nullable.equals(column._nullable)) return false;
313         if (!_sqlTypeName.equals(column._sqlTypeName)) return false;
314         
315         // Default value is nullable
316         if (_defaultValue==null){
317             if(column._defaultValue!=null)
318                 return false;
319         }
320         else{
321             if(!_defaultValue.equals(column._defaultValue))
322                 return false;
323         }
324 
325         return true;
326     }
327 
328     public int hashCode()
329     {
330         int result;
331         result = _columnName.hashCode();
332         result = 29 * result + _dataType.hashCode();
333         result = 29 * result + _sqlTypeName.hashCode();
334         result = 29 * result + _nullable.hashCode();
335         result = 29 * result + (_defaultValue==null? 0 : _defaultValue.hashCode());
336         return result;
337     }
338 
339     /**
340      * Specifies nullable usage.
341      * 
342 	 * @author Manuel Laflamme
343 	 * @author Last changed by: $Author$
344 	 * @version $Revision$ $Date$
345 	 * @since Feb 17, 2002
346 	 * @see Column
347      */
348     public static class Nullable
349     {
350 
351         private final String _name;
352 
353         private Nullable(String name)
354         {
355             _name = name;
356         }
357 
358         ////////////////////////////////////////////////////////////////////////////
359         // Object class
360 
361         public String toString()
362         {
363             return _name;
364         }
365     }
366     
367     
368     /**
369      * Enumeration for valid auto-increment values provided by JDBC driver implementations.
370      * 
371      * @author gommma
372      * @author Last changed by: $Author$
373      * @version $Revision$ $Date$
374      * @since 2.4.3
375      * @see Column
376      */
377     public static class AutoIncrement
378     {
379         public static final AutoIncrement YES = new AutoIncrement("YES");
380         public static final AutoIncrement NO = new AutoIncrement("NO");
381         public static final AutoIncrement UNKNOWN = new AutoIncrement("UNKNOWN");
382         
383         /**
384          * Logger for this class
385          */
386         private static final Logger LOGGER = LoggerFactory.getLogger(AutoIncrement.class);
387 
388         private final String key;
389         private AutoIncrement(String key)
390         {
391             this.key = key;
392         }
393         
394         public String getKey() 
395         {
396             return key;
397         }
398 
399         /**
400          * Searches the enumeration type for the given String provided by the JDBC driver.
401          * <p>
402          * If the parameter <code>autoIncrementValue</code>
403          * <ul>
404          * <li>equalsIgnoreCase &quot;YES&quot; or equals &quot;1&quot; then {@link AutoIncrement#YES} is returned</li>
405          * <li></li>
406          * </ul>
407          * </p>
408          * @param isAutoIncrement The String from the JDBC driver.
409          * @return The enumeration
410          */
411         public static AutoIncrement autoIncrementValue(String isAutoIncrement) 
412         {
413             if(LOGGER.isDebugEnabled())
414                 logger.debug("autoIncrementValue(isAutoIncrement={}) - start", isAutoIncrement);
415             
416             AutoIncrement result = AutoIncrement.UNKNOWN;
417             
418             if(isAutoIncrement != null)
419             {
420                 if(isAutoIncrement.equalsIgnoreCase("YES") || isAutoIncrement.equals("1"))
421                 {
422                     result = AutoIncrement.YES;
423                 }
424                 else if(isAutoIncrement.equalsIgnoreCase("NO") || isAutoIncrement.equals("0"))
425                 {
426                     result = AutoIncrement.NO;
427                 }
428             }
429             return result;
430         }
431 
432 
433         public String toString()
434         {
435             return "autoIncrement=" + key;
436         }
437     }
438 
439 }