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 org.slf4j.Logger;
25  import org.slf4j.LoggerFactory;
26  
27  import java.sql.PreparedStatement;
28  import java.sql.ResultSet;
29  import java.sql.SQLException;
30  import java.sql.Types;
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: 1194 $
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 BytesDataType(
95              "BINARY", Types.BINARY);
96      public static final DataType VARBINARY = new BytesDataType(
97              "VARBINARY", Types.VARBINARY);
98      public static final DataType LONGVARBINARY = new BytesDataType(
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 <code>true</code> if this <code>DataType</code> represents a
150      * number.
151      */
152     public abstract boolean isNumber();
153 
154     /**
155      * Returns <code>true</code> if this <code>DataType</code> represents a
156      * date and/or time.
157      */
158     public abstract boolean isDateTime();
159 
160     /**
161      * Returns the specified column value from the specified resultset object.
162      */
163     public abstract Object getSqlValue(int column, ResultSet resultSet)
164             throws SQLException, TypeCastException;
165 
166     /**
167      * Set the specified value to the specified prepared statement object.
168      */
169     public abstract void setSqlValue(Object value, int column,
170             PreparedStatement statement) throws SQLException, TypeCastException;
171 
172     /**
173      * Typecast the specified value to string.
174      */
175     public static String asString(Object value) throws TypeCastException
176     {
177         logger.debug("asString(value={}) - start", value);
178 
179         return (String)DataType.VARCHAR.typeCast(value);
180     }
181 
182     /**
183      * Returns the <code>DataType</code> corresponding to the specified Sql
184      * type. See {@link java.sql.Types}.
185      *
186      */
187     public static DataType forSqlType(int sqlType) throws DataTypeException
188     {
189     	if(logger.isDebugEnabled())
190     		logger.debug("forSqlType(sqlType={}) - start", new Integer(sqlType));
191 
192         for (int i = 0; i < TYPES.length; i++)
193         {
194             if (sqlType == TYPES[i].getSqlType())
195             {
196                 return TYPES[i];
197             }
198         }
199 
200         return UNKNOWN;
201     }
202 
203     /**
204      * Returns the <code>DataType</code> corresponding to the specified Sql
205      * type name.
206      *
207      * @deprecated Should not be used anymore
208      */
209     public static DataType forSqlTypeName(String sqlTypeName) throws DataTypeException
210     {
211     	if(logger.isDebugEnabled())
212     		logger.debug("forSqlTypeName(sqlTypeName=" + sqlTypeName + ") - start");
213 
214         for (int i = 0; i < TYPES.length; i++)
215         {
216             if (sqlTypeName.equals(TYPES[i].toString()))
217             {
218                 return TYPES[i];
219             }
220         }
221 
222         return UNKNOWN;
223     }
224 
225     /**
226      * Returns the <code>DataType</code> corresponding to the specified value
227      * runtime class. This method returns <code>DataType.UNKNOWN</code>
228      * if the value is <code>null</code> or runtime class not recognized.
229      */
230     public static DataType forObject(Object value)
231     {
232         logger.debug("forObject(value={}) - start", value);
233 
234         if (value == null)
235         {
236             return UNKNOWN;
237         }
238 
239         for (int i = 0; i < TYPES.length; i++)
240         {
241             Class typeClass = TYPES[i].getTypeClass();
242             if (typeClass.isInstance(value))
243             {
244                 return TYPES[i];
245             }
246         }
247 
248         return UNKNOWN;
249     }
250 }
251 
252 
253 
254 
255 
256 
257 
258 
259 
260