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 "YES" or equals "1" 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 }