KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > catalog > types > TypeDescriptorImpl


1 /*
2
3    Derby - Class org.apache.derby.catalog.types.TypeDescriptorImpl
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.catalog.types;
23
24 import org.apache.derby.iapi.services.io.StoredFormatIds;
25 import org.apache.derby.iapi.services.io.Formatable;
26
27 import org.apache.derby.catalog.TypeDescriptor;
28
29 import java.io.ObjectOutput JavaDoc;
30 import java.io.ObjectInput JavaDoc;
31 import java.io.IOException JavaDoc;
32 import java.sql.Types JavaDoc;
33                              
34 public class TypeDescriptorImpl implements TypeDescriptor, Formatable
35 {
36     /********************************************************
37     **
38     ** This class implements Formatable. That means that it
39     ** can write itself to and from a formatted stream. If
40     ** you add more fields to this class, make sure that you
41     ** also write/read them with the writeExternal()/readExternal()
42     ** methods.
43     **
44     ** If, inbetween releases, you add more fields to this class,
45     ** then you should bump the version number emitted by the getTypeFormatId()
46     ** method.
47     **
48     ********************************************************/

49
50     private BaseTypeIdImpl typeId;
51     private int precision;
52     private int scale;
53     private boolean isNullable;
54     private int maximumWidth;
55
56     /**
57      * Public niladic constructor. Needed for Formatable interface to work.
58      *
59      */

60     public TypeDescriptorImpl() {}
61
62     /**
63      * Constructor for use with numeric types
64      *
65      * @param typeId The typeId of the type being described
66      * @param precision The number of decimal digits.
67      * @param scale The number of digits after the decimal point.
68      * @param isNullable TRUE means it could contain NULL, FALSE means
69      * it definitely cannot contain NULL.
70      * @param maximumWidth The maximum number of bytes for this datatype
71      */

72     public TypeDescriptorImpl(
73         BaseTypeIdImpl typeId,
74         int precision,
75         int scale,
76         boolean isNullable,
77         int maximumWidth)
78     {
79         this.typeId = typeId;
80         this.precision = precision;
81         this.scale = scale;
82         this.isNullable = isNullable;
83         this.maximumWidth = maximumWidth;
84     }
85
86     /**
87      * Constructor for use with non-numeric types
88      *
89      * @param typeId The typeId of the type being described
90      * @param isNullable TRUE means it could contain NULL, FALSE means
91      * it definitely cannot contain NULL.
92      * @param maximumWidth The maximum number of bytes for this datatype
93      */

94     public TypeDescriptorImpl(
95         BaseTypeIdImpl typeId,
96         boolean isNullable,
97         int maximumWidth)
98     {
99         this.typeId = typeId;
100         this.isNullable = isNullable;
101         this.maximumWidth = maximumWidth;
102     }
103
104     /**
105      * Constructor for internal uses only.
106      * (This is useful when the precision and scale are potentially wider than
107      * those in the source, like when determining the dominant data type.)
108      *
109      * @param source The DTSI to copy
110      * @param precision The number of decimal digits.
111      * @param scale The number of digits after the decimal point.
112      * @param isNullable TRUE means it could contain NULL, FALSE means
113      * it definitely cannot contain NULL.
114      * @param maximumWidth The maximum number of bytes for this datatype
115      */

116     public TypeDescriptorImpl(
117         TypeDescriptorImpl source,
118         int precision,
119         int scale,
120         boolean isNullable,
121         int maximumWidth)
122     {
123         this.typeId = source.typeId;
124         this.precision = precision;
125         this.scale = scale;
126         this.isNullable = isNullable;
127         this.maximumWidth = maximumWidth;
128     }
129
130     /**
131      * Constructor for internal uses only
132      *
133      * @param source The DTSI to copy
134      * @param isNullable TRUE means it could contain NULL, FALSE means
135      * it definitely cannot contain NULL.
136      * @param maximumWidth The maximum number of bytes for this datatype
137      */

138     public TypeDescriptorImpl(
139         TypeDescriptorImpl source,
140         boolean isNullable,
141         int maximumWidth)
142     {
143         this.typeId = source.typeId;
144         this.precision = source.precision;
145         this.scale = source.scale;
146         this.isNullable = isNullable;
147         this.maximumWidth = maximumWidth;
148     }
149
150     /**
151      * @see TypeDescriptor#getMaximumWidth
152      */

153     public int getMaximumWidth()
154     {
155         return maximumWidth;
156     }
157
158     /**
159      * Return the length of this type in bytes. Note that
160      * while the JDBC API _does_ define a need for
161      * returning length in bytes of a type, it doesn't
162      * state clearly what that means for the various
163      * types. We assume therefore that the values here
164      * are meant to match those specified by the ODBC
165      * specification (esp. since ODBC clients are more
166      * likely to need this value than a Java client).
167      * The ODBC spec that defines the values we use here
168      * can be found at the following link:
169      *
170      * http://msdn.microsoft.com/library/default.asp?url=/library/
171      * en-us/odbc/htm/odbctransfer_octet_length.asp
172      *
173      * @see TypeDescriptor#getMaximumWidthInBytes
174      */

175     public int getMaximumWidthInBytes()
176     {
177         switch (typeId.getJDBCTypeId()) {
178
179             case Types.BIT:
180             case Types.TINYINT:
181             case Types.SMALLINT:
182             case Types.INTEGER:
183             case Types.REAL:
184             case Types.DOUBLE:
185             case Types.FLOAT:
186             case Types.BINARY:
187             case Types.VARBINARY:
188             case Types.LONGVARBINARY:
189             case Types.BLOB:
190
191                 // For all of these, just take the maximumWidth,
192
// since that already holds the length in bytes.
193
return maximumWidth;
194
195             // For BIGINT values, ODBC spec says to return
196
// 40 because max length of a C/C++ BIGINT in
197
// string form is 20 and we assume the client
198
// character set is Unicode (spec says to
199
// multiply by 2 for unicode).
200
case Types.BIGINT:
201                 return 40;
202
203             // ODBC spec explicitly declares what the lengths
204
// should be for datetime values, based on the
205
// declared fields of SQL_DATE_STRUCT, SQL_TIME_STRUCT,
206
// and SQL_TIMESTAMP_STRUCT. So we just use those
207
// values.
208
case Types.DATE:
209             case Types.TIME:
210                 return 6;
211
212             case Types.TIMESTAMP:
213                 return 16;
214
215             // ODBC spec says that for numeric/decimal values,
216
// we should use max number of digits plus 2
217
// (for sign and decimal point), since that's
218
// the length of a decimal value in string form.
219
// And since we assume client character set
220
// is unicode, we have to multiply by 2 to
221
// get the number of bytes.
222
case Types.NUMERIC:
223             case Types.DECIMAL:
224                 return 2 * (precision + 2);
225
226             // ODBC spec says to use length in chars
227
// for character types, times two if we
228
// assume client character set is unicode.
229
// If 2 * character length is greater than
230
// variable type (in this case, integer),
231
// then we return the max value for an
232
// integer.
233
case Types.CHAR:
234             case Types.VARCHAR:
235             case Types.LONGVARCHAR:
236             case Types.CLOB:
237                 if ((maximumWidth > 0) && (2 * maximumWidth < 0))
238                 // integer overflow; return max integer possible.
239
return Integer.MAX_VALUE;
240                 else
241                     return 2 * maximumWidth;
242
243             case Types.ARRAY:
244             case Types.DISTINCT:
245             case Types.NULL:
246             case Types.OTHER:
247             case Types.REF:
248             case Types.STRUCT:
249             case Types.JAVA_OBJECT:
250             default:
251
252                 // For these we don't know, so return the "don't-know"
253
// indicator.
254
return -1;
255
256         }
257
258     }
259
260     /**
261      * Get the jdbc type id for this type. JDBC type can be
262      * found in java.sql.Types.
263      *
264      * @return a jdbc type, e.g. java.sql.Types.DECIMAL
265      *
266      * @see Types
267      */

268     public int getJDBCTypeId()
269     {
270         return typeId.getJDBCTypeId();
271     }
272
273     /**
274      * Gets the name of this datatype.
275      *
276      *
277      * @return the name of this datatype
278      */

279     public String JavaDoc getTypeName()
280     {
281         return typeId.getSQLTypeName();
282     }
283
284     /**
285      * Returns the number of decimal digits for the datatype, if applicable.
286      *
287      * @return The number of decimal digits for the datatype. Returns
288      * zero for non-numeric datatypes.
289      */

290     public int getPrecision()
291     {
292         return precision;
293     }
294
295     /**
296      * Returns the number of digits to the right of the decimal for
297      * the datatype, if applicable.
298      *
299      * @return The number of digits to the right of the decimal for
300      * the datatype. Returns zero for non-numeric datatypes.
301      */

302     public int getScale()
303     {
304         return scale;
305     }
306
307     /**
308      * Returns TRUE if the datatype can contain NULL, FALSE if not.
309      * JDBC supports a return value meaning "nullability unknown" -
310      * I assume we will never have columns where the nullability is unknown.
311      *
312      * @return TRUE if the datatype can contain NULL, FALSE if not.
313      */

314     public boolean isNullable()
315     {
316         return isNullable;
317     }
318
319     /**
320      * Set the nullability of the datatype described by this descriptor
321      *
322      * @param nullable TRUE means set nullability to TRUE, FALSE
323      * means set it to FALSE
324      */

325     public void setNullability(boolean nullable)
326     {
327         isNullable = nullable;
328     }
329
330     /**
331      * Converts this data type descriptor (including length/precision)
332      * to a string. E.g.
333
334
335      *
336      * VARCHAR(30)
337      *
338      * or
339      *
340      * java.util.Hashtable
341      *
342      * @return String version of datatype, suitable for running through
343      * the Parser.
344      */

345     public String JavaDoc getSQLstring()
346     {
347         return typeId.toParsableString( this );
348     }
349
350     public String JavaDoc toString()
351     {
352         String JavaDoc s = getSQLstring();
353         if (!isNullable())
354             return s + " NOT NULL";
355         return s;
356     }
357
358     /**
359      * Get the type Id stored within this type descriptor.
360      */

361     public BaseTypeIdImpl getTypeId()
362     {
363         return typeId;
364     }
365
366     /**
367       Compare if two TypeDescriptors are exactly the same
368       @param object the dataTypeDescriptor to compare to.
369       */

370     public boolean equals(Object JavaDoc object)
371     {
372         TypeDescriptor typeDescriptor = (TypeDescriptor)object;
373
374         if(!this.getTypeName().equals(typeDescriptor.getTypeName()) ||
375            this.precision != typeDescriptor.getPrecision() ||
376            this.scale != typeDescriptor.getScale() ||
377            this.isNullable != typeDescriptor.isNullable() ||
378            this.maximumWidth != typeDescriptor.getMaximumWidth())
379            return false;
380         else
381             return true;
382     }
383
384     // Formatable methods
385

386     /**
387      * Read this object from a stream of stored objects.
388      *
389      * @param in read this.
390      *
391      * @exception IOException thrown on error
392      * @exception ClassNotFoundException thrown on error
393      */

394     public void readExternal( ObjectInput JavaDoc in )
395          throws IOException JavaDoc, ClassNotFoundException JavaDoc
396     {
397         typeId = (BaseTypeIdImpl) in.readObject();
398         precision = in.readInt();
399         scale = in.readInt();
400         isNullable = in.readBoolean();
401         maximumWidth = in.readInt();
402     }
403
404     /**
405      * Write this object to a stream of stored objects.
406      *
407      * @param out write bytes here.
408      *
409      * @exception IOException thrown on error
410      */

411     public void writeExternal( ObjectOutput JavaDoc out )
412          throws IOException JavaDoc
413     {
414         out.writeObject( typeId );
415         out.writeInt( precision );
416         out.writeInt( scale );
417         out.writeBoolean( isNullable );
418         out.writeInt( maximumWidth );
419     }
420  
421     /**
422      * Get the formatID which corresponds to this class.
423      *
424      * @return the formatID of this class
425      */

426     public int getTypeFormatId() { return StoredFormatIds.DATA_TYPE_IMPL_DESCRIPTOR_V01_ID; }
427 }
428
Popular Tags