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.datatype;
23  
24  import java.sql.PreparedStatement;
25  import java.sql.ResultSet;
26  import java.sql.SQLException;
27  import java.sql.Types;
28  
29  import org.slf4j.Logger;
30  import org.slf4j.LoggerFactory;
31  
32  
33  /**
34   * Data type that maps {@link java.sql.Types} objects to their
35   * java counterparts. It also provides immutable constants for the most common data types.
36   * 
37   * @see <a href="http://java.sun.com/j2se/1.3/docs/guide/jdbc/getstart/mapping.html#table1">sun JDBC object mapping</a>
38   * 
39   * @author Manuel Laflamme
40   * @version $Revision$
41   */
42  public abstract class DataType
43  {
44  
45      /**
46       * Logger for this class
47       */
48      private static final Logger logger = LoggerFactory.getLogger(DataType.class);
49  
50      public static final DataType UNKNOWN = new UnknownDataType();
51  
52      public static final DataType CHAR = new StringDataType(
53              "CHAR", Types.CHAR);
54      public static final DataType VARCHAR = new StringDataType(
55              "VARCHAR", Types.VARCHAR);
56      public static final DataType LONGVARCHAR = new StringDataType(
57              "LONGVARCHAR", Types.LONGVARCHAR);
58      public static final DataType CLOB = new ClobDataType();
59  
60      public static final DataType NUMERIC = new NumberDataType(
61              "NUMERIC", Types.NUMERIC);
62      public static final DataType DECIMAL = new NumberDataType(
63              "DECIMAL", Types.DECIMAL);
64  
65      public static final DataType BOOLEAN = new BooleanDataType();
66      public static final DataType BIT = new BitDataType();
67  
68      public static final DataType TINYINT = new IntegerDataType(
69              "TINYINT", Types.TINYINT);
70      public static final DataType SMALLINT = new IntegerDataType(
71              "SMALLINT", Types.SMALLINT);
72      public static final DataType INTEGER = new IntegerDataType(
73              "INTEGER", Types.INTEGER);
74  
75  //    public static final DataType BIGINT = new LongDataType();
76      public static final DataType BIGINT = new BigIntegerDataType();
77      /**
78       * Auxiliary for the BIGINT type using a long. Is currently only
79       * needed for method {@link DataType#forObject(Object)}.
80       */
81      public static final DataType BIGINT_AUX_LONG = new LongDataType();
82  
83      public static final DataType REAL = new FloatDataType();
84  
85      public static final DataType FLOAT = new DoubleDataType(
86              "FLOAT", Types.FLOAT);
87      public static final DataType DOUBLE = new DoubleDataType(
88              "DOUBLE", Types.DOUBLE);
89  
90      public static final DataType DATE = new DateDataType();
91      public static final DataType TIME = new TimeDataType();
92      public static final DataType TIMESTAMP = new TimestampDataType();
93  
94      public static final DataType BINARY = new UuidAwareBytesDataType(
95              "BINARY", Types.BINARY);
96      public static final DataType VARBINARY = new UuidAwareBytesDataType(
97              "VARBINARY", Types.VARBINARY);
98      public static final DataType LONGVARBINARY = new UuidAwareBytesDataType(
99              "LONGVARBINARY", Types.LONGVARBINARY);
100     public static final DataType BLOB = new BlobDataType();
101 
102     //New JDBC 4.0 types:
103     //todo: ROWID = -8, NCLOB = 2011, SQLXML = 2009.
104 
105     public static final DataType NCHAR = new StringDataType(
106             "NCHAR", -15);
107 
108     public static final DataType NVARCHAR = new StringDataType(
109             "NVARCHAR", -9);
110 
111     public static final DataType LONGNVARCHAR = new StringDataType(
112             "LONGNVARCHAR", -16);
113 
114     private static final DataType[] TYPES = {
115         VARCHAR, CHAR, LONGVARCHAR, NCHAR, NVARCHAR, LONGNVARCHAR, CLOB, NUMERIC, DECIMAL, BOOLEAN, BIT, INTEGER,
116         TINYINT, SMALLINT, BIGINT, REAL, DOUBLE, FLOAT, DATE, TIME, TIMESTAMP,
117         VARBINARY, BINARY, LONGVARBINARY, BLOB,
118         //auxiliary types at the very end
119         BIGINT_AUX_LONG
120     };
121 
122     /**
123      * Returns the specified value typecasted to this <code>DataType</code>
124      */
125     public abstract Object typeCast(Object value) throws TypeCastException;
126 
127     /**
128      * Returns a negative integer, zero, or a positive integer as the first
129      * argument is less than, equal to, or greater than the second.
130      * <p>
131      * The two values are typecast to this DataType before being compared.
132      *
133      * @throws TypeCastException  if the arguments' types prevent them from
134      * being compared by this Comparator.
135      */
136     public abstract int compare(Object o1, Object o2) throws TypeCastException;
137 
138     /**
139      * Returns the corresponding {@link java.sql.Types}.
140      */
141     public abstract int getSqlType();
142 
143     /**
144      * Returns the runtime class of the typecast result.
145      */
146     public abstract Class getTypeClass();
147 
148     /**
149      * Returns the SQL type name for user types (null for basic SQL types)
150      */
151     public String getSqlTypeName()
152     {
153         return null;
154     }
155 
156     /**
157      * Returns <code>true</code> if this <code>DataType</code> represents a
158      * number.
159      */
160     public abstract boolean isNumber();
161 
162     /**
163      * Returns <code>true</code> if this <code>DataType</code> represents a
164      * date and/or time.
165      */
166     public abstract boolean isDateTime();
167 
168     /**
169      * Returns the specified column value from the specified resultset object.
170      */
171     public abstract Object getSqlValue(int column, ResultSet resultSet)
172             throws SQLException, TypeCastException;
173 
174     /**
175      * Set the specified value to the specified prepared statement object.
176      */
177     public abstract void setSqlValue(Object value, int column,
178             PreparedStatement statement) throws SQLException, TypeCastException;
179 
180     /**
181      * Typecast the specified value to string.
182      */
183     public static String asString(Object value) throws TypeCastException
184     {
185         logger.debug("asString(value={}) - start", value);
186 
187         return (String)DataType.VARCHAR.typeCast(value);
188     }
189 
190     /**
191      * Returns the <code>DataType</code> corresponding to the specified Sql
192      * type. See {@link java.sql.Types}.
193      *
194      */
195     public static DataType forSqlType(int sqlType) throws DataTypeException
196     {
197     	if(logger.isDebugEnabled())
198     		logger.debug("forSqlType(sqlType={}) - start", new Integer(sqlType));
199 
200         for (int i = 0; i < TYPES.length; i++)
201         {
202             if (sqlType == TYPES[i].getSqlType())
203             {
204                 return TYPES[i];
205             }
206         }
207 
208         return UNKNOWN;
209     }
210 
211     /**
212      * Returns the <code>DataType</code> corresponding to the specified Sql
213      * type name.
214      *
215      * @deprecated Should not be used anymore
216      */
217     public static DataType forSqlTypeName(String sqlTypeName) throws DataTypeException
218     {
219     	if(logger.isDebugEnabled())
220     		logger.debug("forSqlTypeName(sqlTypeName=" + sqlTypeName + ") - start");
221 
222         for (int i = 0; i < TYPES.length; i++)
223         {
224             if (sqlTypeName.equals(TYPES[i].toString()))
225             {
226                 return TYPES[i];
227             }
228         }
229 
230         return UNKNOWN;
231     }
232 
233     /**
234      * Returns the <code>DataType</code> corresponding to the specified value
235      * runtime class. This method returns <code>DataType.UNKNOWN</code>
236      * if the value is <code>null</code> or runtime class not recognized.
237      */
238     public static DataType forObject(Object value)
239     {
240         logger.debug("forObject(value={}) - start", value);
241 
242         if (value == null)
243         {
244             return UNKNOWN;
245         }
246 
247         for (int i = 0; i < TYPES.length; i++)
248         {
249             Class typeClass = TYPES[i].getTypeClass();
250             if (typeClass.isInstance(value))
251             {
252                 return TYPES[i];
253             }
254         }
255 
256         return UNKNOWN;
257     }
258     
259     public boolean equals(Object other) {
260     	if (!(other instanceof DataType)) return false;
261     	DataType otherDataType = (DataType) other;
262     	return otherDataType.getSqlType() == this.getSqlType()
263     			&& otherDataType.getSqlTypeName() == this.getSqlTypeName();
264     }
265 }
266 
267 
268 
269 
270 
271 
272 
273 
274 
275