KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > triactive > jdo > store > TypeInfo


1 /*
2  * Copyright 2002 (C) TJDO.
3  * All rights reserved.
4  *
5  * This software is distributed under the terms of the TJDO License version 1.0.
6  * See the terms of the TJDO License in the documentation provided with this software.
7  *
8  * $Id: TypeInfo.java,v 1.8 2003/11/26 20:02:41 jackknifebarber Exp $
9  */

10
11 package com.triactive.jdo.store;
12
13 import java.io.PrintWriter JavaDoc;
14 import java.io.StringWriter JavaDoc;
15 import java.sql.DatabaseMetaData JavaDoc;
16 import java.sql.ResultSet JavaDoc;
17 import java.sql.SQLException JavaDoc;
18 import java.sql.Types JavaDoc;
19 import javax.jdo.JDOFatalDataStoreException;
20
21
22 /**
23  * Represents the metadata of a specific JDBC data type. This class is
24  * basically a data structure that makes accessing the JDBC type metadata
25  * easier. Each of the columns of information returned by
26  * {@link DatabaseMetaData#getTypeInfo()} is represented by a public field
27  * in this class.
28  *
29  * Subclasses of TypeInfo can be created on a per-DBMS basis to supply missing
30  * metadata or correct faulty metadata obtained from that DBMS's JDBC driver(s).
31  *
32  * @author <a HREF="mailto:mmartin5@austin.rr.com">Mike Martin</a>
33  * @version $Revision: 1.8 $
34  *
35  * @see DatabaseAdapter#getTypeInfo
36  * @see DatabaseAdapter#newTypeInfo
37  * @see DatabaseMetaData#getTypeInfo
38  */

39
40 class TypeInfo
41 {
42     /**
43      * A JDBC 3.0 data type definition.
44      * Can be removed when TJDO drops support for buildability using JDK's older
45      * than 1.4.
46      */

47     public static final short Types_BOOLEAN = 16;
48
49     /**
50      * The DBMS-specific name for this data type.
51      */

52     public String JavaDoc typeName;
53
54     /**
55      * The JDBC (SQL) data type number of this data type.
56      */

57     public short dataType;
58
59     /**
60      * The maximum precision/length allowed for this data type.
61      */

62     public int precision;
63
64     /**
65      * The prefix used to quote a literal of this data type; may be
66      * <tt>null</tt>.
67      */

68     public String JavaDoc literalPrefix;
69
70     /**
71      * The suffix used to quote a literal of this data type; may be
72      * <tt>null</tt>.
73      */

74     public String JavaDoc literalSuffix;
75
76     /**
77      * Indicates the parameters used in defining columns of this type.
78      */

79     public String JavaDoc createParams;
80
81     /**
82      * Indicates whether null values are allowed for this data type.
83      *
84      * @see DatabaseMetaData#typeNoNulls
85      * @see DatabaseMetaData#typeNullable
86      * @see DatabaseMetaData#typeNullableUnknown
87      */

88     public int nullable;
89
90     /**
91      * <tt>true</tt> indicates this data type is case-sensitive in comparisons,
92      * <tt>false</tt> otherwise.
93      */

94     public boolean caseSensitive;
95
96     /**
97      * Indicates searchability of this data type in terms of the kinds of SQL
98      * WHERE clauses that are allowed.
99      *
100      * @see DatabaseMetaData#typePredNone
101      * @see DatabaseMetaData#typePredChar
102      * @see DatabaseMetaData#typePredBasic
103      * @see DatabaseMetaData#typeSearchable
104      */

105     public short searchable;
106
107     /**
108      * <tt>true</tt> indicates the type is unsigned, <tt>false</tt> otherwise.
109      */

110     public boolean unsignedAttribute;
111
112     /**
113      * <tt>true</tt> indicates the type can be assigned a fixed scale value,
114      * such as for decimal or currency types, <tt>false</tt> otherwise.
115      */

116     public boolean fixedPrecScale;
117
118     /**
119      * <tt>true</tt> indicates the type automatically increments for each new
120      * row inserted, <tt>false</tt> otherwise.
121      */

122     public boolean autoIncrement;
123
124     /**
125      * Localized version of the DBMS-specific type name of this data type.
126      */

127     public String JavaDoc localTypeName;
128
129     /**
130      * The minimum supported scale value for this data type.
131      */

132     public short minimumScale;
133
134     /**
135      * The maximum supported scale value for this data type.
136      */

137     public short maximumScale;
138
139     /**
140      * Indicates the numeric radix of this data type, which is usually 2 or 10.
141      */

142     public int numPrecRadix;
143
144     private int hash = 0;
145
146
147     /**
148      * Constructs a type information objectd from the current row of the given
149      * result set. The {@link ResultSet} object passed must have been obtained
150      * from a call to DatabaseMetaData.getTypeInfo().
151      *
152      * <p>This method only retrieves the values from the current row; the caller
153      * is required to advance to the next row with {@link ResultSet#next}.
154      *
155      * @param rs The result set returned from DatabaseMetaData.getTypeInfo().
156      *
157      * @exception JDOFatalDataStoreException
158      * if a column of type information could not be retrieved from the
159      * result set.
160      */

161
162     public TypeInfo(ResultSet JavaDoc rs) throws JDOFatalDataStoreException
163     {
164         try
165         {
166             typeName = rs.getString(1);
167             dataType = rs.getShort(2);
168             precision = (int)rs.getLong(3);
169             literalPrefix = rs.getString(4);
170             literalSuffix = rs.getString(5);
171             createParams = rs.getString(6);
172             nullable = rs.getInt(7);
173             caseSensitive = rs.getBoolean(8);
174             searchable = rs.getShort(9);
175             unsignedAttribute = rs.getBoolean(10);
176             fixedPrecScale = rs.getBoolean(11);
177             autoIncrement = rs.getBoolean(12);
178             localTypeName = rs.getString(13);
179             minimumScale = rs.getShort(14);
180             maximumScale = rs.getShort(15);
181             numPrecRadix = rs.getInt(18);
182         }
183         catch (SQLException JavaDoc e)
184         {
185             throw new JDOFatalDataStoreException("Can't read JDBC metadata from result set", e);
186         }
187     }
188
189
190     /**
191      * Constructs a type information object from its individual attributes.
192      *
193      * <p>This can be useful to subclasses and/or custom DatabaseAdapters that
194      * need to modify and/or correct the metadata returned by the JDBC driver.
195      */

196
197     public TypeInfo(String JavaDoc typeName,
198                     short dataType,
199                     int precision,
200                     String JavaDoc literalPrefix,
201                     String JavaDoc literalSuffix,
202                     String JavaDoc createParams,
203                     int nullable,
204                     boolean caseSensitive,
205                     short searchable,
206                     boolean unsignedAttribute,
207                     boolean fixedPrecScale,
208                     boolean autoIncrement,
209                     String JavaDoc localTypeName,
210                     short minimumScale,
211                     short maximumScale,
212                     int numPrecRadix)
213     {
214         this.typeName = typeName;
215         this.dataType = dataType;
216         this.precision = precision;
217         this.literalPrefix = literalPrefix;
218         this.literalSuffix = literalSuffix;
219         this.createParams = createParams;
220         this.nullable = nullable;
221         this.caseSensitive = caseSensitive;
222         this.searchable = searchable;
223         this.unsignedAttribute = unsignedAttribute;
224         this.fixedPrecScale = fixedPrecScale;
225         this.autoIncrement = autoIncrement;
226         this.localTypeName = localTypeName;
227         this.minimumScale = minimumScale;
228         this.maximumScale = maximumScale;
229         this.numPrecRadix = numPrecRadix;
230     }
231
232
233     /**
234      * Indicates whether the type of a given database column is "compatible"
235      * with this type.
236      */

237
238     public boolean isCompatibleWith(ColumnInfo ci)
239     {
240         return areCompatibleTypes(dataType, ci.dataType);
241     }
242
243
244     /**
245      * Indicates whether some object is "equal to" this one. Two <tt>TypeInfo
246      * </tt> objects are considered equal if their <tt>typeName</tt> and
247      * <tt>dataType</tt> fields are equal.
248      *
249      * @param obj the reference object with which to compare
250      *
251      * @return <tt>true</tt> if this object is equal to the obj argument;
252      * <tt>false</tt> otherwise.
253      */

254
255     public boolean equals(Object JavaDoc obj)
256     {
257         if (obj == this)
258             return true;
259
260         if (!(obj instanceof TypeInfo))
261             return false;
262
263         TypeInfo ti = (TypeInfo)obj;
264
265         return typeName.equals(ti.typeName) && dataType == ti.dataType;
266     }
267
268
269     /**
270      * Returns a hash code value for this object.
271      *
272      * @return a hash code value for this object.
273      */

274
275     public int hashCode()
276     {
277         if (hash == 0)
278             hash = typeName.hashCode() ^ dataType;
279
280         return hash;
281     }
282
283
284     /**
285      * Returns the string representation of this object.
286      *
287      * @return string representation of this object.
288      */

289
290     public String JavaDoc toString()
291     {
292         StringWriter JavaDoc sw = new StringWriter JavaDoc();
293         PrintWriter JavaDoc pw = new PrintWriter JavaDoc(sw);
294
295         pw.println(this.getClass().getName());
296         pw.print(" typeName = "); pw.println(typeName);
297         pw.print(" dataType = "); pw.println(getJDBCTypeName(dataType));
298         pw.print(" precision = "); pw.println(precision);
299         pw.print(" literalPrefix = "); pw.println(literalPrefix);
300         pw.print(" literalSuffix = "); pw.println(literalSuffix);
301         pw.print(" createParams = "); pw.println(createParams);
302         pw.print(" nullable = "); pw.println(nullable);
303         pw.print(" caseSensitive = "); pw.println(caseSensitive);
304         pw.print(" searchable = "); pw.println(searchable);
305         pw.print(" searchable = "); pw.println(searchable);
306         pw.print(" unsignedAttribute = "); pw.println(unsignedAttribute);
307         pw.print(" fixedPrecScale = "); pw.println(fixedPrecScale);
308         pw.print(" autoIncrement = "); pw.println(autoIncrement);
309         pw.print(" localTypeName = "); pw.println(localTypeName);
310         pw.print(" minimumScale = "); pw.println(minimumScale);
311         pw.print(" maximumScale = "); pw.println(maximumScale);
312         pw.print(" numPrecRadix = "); pw.println(numPrecRadix);
313         pw.close();
314
315         return sw.toString();
316     }
317
318
319     /**
320      * Returns the string name of the Java constant that equals the given JDBC
321      * type number <tt>type</tt>. JDBC type numbers are defined in
322      * {@link Types}.
323      *
324      * <p>If <tt>type</tt> is not equal to one of the known type numbers,
325      * the string "Unrecognized type (<i>type</i>)" is returned.
326      *
327      * @param type the JDBC type number.
328      *
329      * @return the string name of the corresponding constant from
330      * {@link Types}.
331      */

332
333     public static String JavaDoc getJDBCTypeName(int type)
334     {
335         switch (type)
336         {
337             case Types.BIT:
338                 return "Types.BIT";
339             case Types_BOOLEAN:
340                 return "Types.BOOLEAN";
341             case Types.TINYINT:
342                 return "Types.TINYINT";
343             case Types.SMALLINT:
344                 return "Types.SMALLINT";
345             case Types.INTEGER:
346                 return "Types.INTEGER";
347             case Types.BIGINT:
348                 return "Types.BIGINT";
349             case Types.FLOAT:
350                 return "Types.FLOAT";
351             case Types.REAL:
352                 return "Types.REAL";
353             case Types.DOUBLE:
354                 return "Types.DOUBLE";
355             case Types.NUMERIC:
356                 return "Types.NUMERIC";
357             case Types.DECIMAL:
358                 return "Types.DECIMAL";
359             case Types.CHAR:
360                 return "Types.CHAR";
361             case Types.VARCHAR:
362                 return "Types.VARCHAR";
363             case Types.LONGVARCHAR:
364                 return "Types.LONGVARCHAR";
365             case Types.DATE:
366                 return "Types.DATE";
367             case Types.TIME:
368                 return "Types.TIME";
369             case Types.TIMESTAMP:
370                 return "Types.TIMESTAMP";
371             case Types.BINARY:
372                 return "Types.BINARY";
373             case Types.VARBINARY:
374                 return "Types.VARBINARY";
375             case Types.LONGVARBINARY:
376                 return "Types.LONGVARBINARY";
377             case Types.NULL:
378                 return "Types.NULL";
379             case Types.OTHER:
380                 return "Types.OTHER";
381             case Types.JAVA_OBJECT:
382                 return "Types.JAVA_OBJECT";
383             case Types.DISTINCT:
384                 return "Types.DISTINCT";
385             case Types.STRUCT:
386                 return "Types.STRUCT";
387             case Types.ARRAY:
388                 return "Types.ARRAY";
389             case Types.BLOB:
390                 return "Types.BLOB";
391             case Types.CLOB:
392                 return "Types.CLOB";
393             case Types.REF:
394                 return "Types.REF";
395             default:
396                 return "Unrecognized type (" + type + ")";
397         }
398     }
399
400
401     public static boolean areCompatibleTypes(int expected, int actual)
402     {
403         switch (expected)
404         {
405             case Types.BIT:
406             case Types_BOOLEAN:
407                 return isBooleanType(actual);
408
409             case Types.TINYINT:
410             case Types.SMALLINT:
411             case Types.INTEGER:
412             case Types.BIGINT:
413                 return isIntegerType(actual);
414
415             case Types.FLOAT:
416             case Types.REAL:
417             case Types.DOUBLE:
418                 return isFloatingType(actual);
419
420             case Types.NUMERIC:
421             case Types.DECIMAL:
422                 return isNumericType(actual);
423
424             case Types.CHAR:
425             case Types.VARCHAR:
426             case Types.LONGVARCHAR:
427             case Types.DATE:
428             case Types.TIME:
429             case Types.TIMESTAMP:
430             case Types.BINARY:
431             case Types.VARBINARY:
432             case Types.LONGVARBINARY:
433             case Types.NULL:
434             case Types.OTHER:
435             case Types.JAVA_OBJECT:
436             case Types.DISTINCT:
437             case Types.STRUCT:
438             case Types.ARRAY:
439             case Types.BLOB:
440             case Types.CLOB:
441             case Types.REF:
442             default:
443                 return expected == actual;
444         }
445     }
446
447     private static boolean isBooleanType(int type)
448     {
449         switch (type)
450         {
451             case Types.BIT:
452             case Types_BOOLEAN:
453                 return true;
454
455             default:
456                 return false;
457         }
458     }
459
460     private static boolean isIntegerType(int type)
461     {
462         switch (type)
463         {
464             case Types.TINYINT:
465             case Types.SMALLINT:
466             case Types.INTEGER:
467             case Types.BIGINT:
468                 return true;
469
470             default:
471                 return isNumericType(type);
472         }
473     }
474
475     private static boolean isFloatingType(int type)
476     {
477         switch (type)
478         {
479             case Types.FLOAT:
480             case Types.REAL:
481             case Types.DOUBLE:
482                 return true;
483
484             default:
485                 return isNumericType(type);
486         }
487     }
488
489     private static boolean isNumericType(int type)
490     {
491         switch (type)
492         {
493             case Types.NUMERIC:
494             case Types.DECIMAL:
495                 return true;
496
497             default:
498                 return false;
499         }
500     }
501 }
502
Popular Tags