KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hsqldb > jdbc > jdbcResultSetMetaData


1 /* Copyright (c) 2001-2005, The HSQL Development Group
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of the HSQL Development Group nor the names of its
15  * contributors may be used to endorse or promote products derived from this
16  * software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31
32 package org.hsqldb.jdbc;
33
34 import java.sql.ResultSetMetaData JavaDoc;
35 import java.sql.SQLException JavaDoc;
36
37 import org.hsqldb.Result;
38 import org.hsqldb.ResultConstants;
39 import org.hsqldb.Trace;
40 import org.hsqldb.Types;
41 import org.hsqldb.persist.HsqlProperties;
42
43 // fredt@users 20040412 - removed DITypeInfo dependencies
44
// boucherb@users - 200404xx - removed unused imports;refinement for better
45
// usability of getColumnDisplaySize;
46
// javadoc updates
47

48 /**
49  * <!-- start generic documentation -->
50  * An object that can be used to get information about the types
51  * and properties of the columns in a <code>ResultSet</code> object.
52  * The following code fragment creates the <code>ResultSet</code>
53  * object rs, creates the <code>ResultSetMetaData</code> object rsmd,
54  * and uses rsmd to find out how many columns rs has and whether the
55  * first column in rs can be used in a <code>WHERE</code> clause.
56  * <PRE>
57  *
58  * ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2");
59  * ResultSetMetaData rsmd = rs.getMetaData();
60  * int numberOfColumns = rsmd.getColumnCount();
61  * boolean b = rsmd.isSearchable(1);
62  *
63  * </PRE>
64  * <!-- end generic documentation -->
65  *
66  * <!-- start Release-specific documentation -->
67  * <div class="ReleaseSpecificDocumentation">
68  * <h3>HSQLDB-Specific Information:</h3> <p>
69  *
70  * HSQLDB supports a subset of the <code>ResultSetMetaData</code> interface.<p>
71  *
72  * The JDBC specification for <code>ResultSetMetaData</code> is in part very
73  * vague. This causes potential incompatibility between interpretations of the
74  * specification as realized in different JDBC driver implementations. As such,
75  * deciding to what degree reporting ResultSetMetaData is accurate has been
76  * considered very carefully. Hopefully, the design decisions made in light of
77  * these considerations have yeilded precisely the subset of full
78  * ResultSetMetaData support that is most commonly needed and that is most
79  * important, while also providing, under the most common use-cases, the
80  * fastest access with the least overhead and the best comprimise between
81  * speed, accuracy, jar-foootprint and retention of JDBC resources. <p>
82  *
83  * (fredt@users) <br>
84  * (boucherb@users)<p>
85  * </div>
86  * <!-- end release-specific documentation -->
87  *
88  * @author boucherb@users
89  * @version 1.7.2
90  * @see jdbcStatement#executeQuery
91  * @see jdbcStatement#getResultSet
92  * @see java.sql.ResultSetMetaData
93  */

94 public class jdbcResultSetMetaData implements ResultSetMetaData JavaDoc {
95
96     /**
97      * An array of objects, each of which represents the reported attributes
98      * for a single column of this object's parent ResultSet.
99      */

100     private jdbcColumnMetaData[] columnMetaData;
101
102     /** The number of columns in this object's parent ResultSet. */
103     private int columnCount;
104
105     /**
106      * Whether to use the underlying column name or label when reporting
107      * getColumnName().
108      */

109     private boolean useColumnName;
110
111     /**
112      * If true, then timings for init() are printed
113      * to the console.
114      */

115     private static final boolean TRACE = false;
116
117     /**
118      * Constructs a new jdbcResultSetMetaData object from the specified
119      * jdbcResultSet and HsqlProprties objects.
120      *
121      * @param rs the jdbcResultSet object from which to construct a new
122      * jdbcResultSetMetaData object
123      * @param props the HsqlProperties object from which to construct a
124      * new jdbcResultSetMetaData object
125      * @throws SQLException if a database access error occurs
126      */

127     jdbcResultSetMetaData(jdbcResultSet rs,
128                           HsqlProperties props) throws SQLException JavaDoc {
129         init(rs, props);
130     }
131
132     /**
133      * Constructs a new jdbcResultSetMetaData object from the specified
134      * Result and HsqlProprties objects.
135      *
136      * @param r the Result object from which to construct a new
137      * jdbcResultSetMetaData object
138      * @param props the HsqlProperties object from which to construct a
139      * new jdbcResultSetMetaData object
140      * @throws SQLException if a database access error occurs
141      */

142     jdbcResultSetMetaData(Result r,
143                           HsqlProperties props) throws SQLException JavaDoc {
144         init(r, props);
145     }
146
147     /**
148      * Initializes this jdbcResultSetMetaData object from the specified
149      * jdbcResultSet and HsqlProperties objects.
150      *
151      * @param rs the jdbcResultSet object from which to initialize this
152      * jdbcResultSetMetaData object
153      * @param props the HsqlProperties object from which to initialize this
154      * jdbcResultSetMetaData object
155      * @throws SQLException if a database access error occurs
156      */

157     void init(jdbcResultSet rs, HsqlProperties props) throws SQLException JavaDoc {
158
159         if (rs == null) {
160             throw Util.sqlException(Trace.GENERAL_ERROR,
161                                     Trace.JDBC_NO_RESULT_SET_METADATA, null);
162         }
163
164         init(rs.rResult, props);
165     }
166
167     /**
168      * Initializes this jdbcResultSetMetaData object from the specified
169      * Result and HsqlProperties objects.
170      *
171      * @param r the Result object from which to initialize this
172      * jdbcResultSetMetaData object
173      * @param props the HsqlProperties object from which to initialize this
174      * jdbcResultSetMetaData object
175      * @throws SQLException if a database access error occurs
176      */

177     void init(Result r, HsqlProperties props) throws SQLException JavaDoc {
178
179         jdbcColumnMetaData cmd;
180         int type;
181         Result.ResultMetaData rmd;
182
183         if (r == null) {
184             throw Util.sqlException(Trace.GENERAL_ERROR,
185                                     Trace.JDBC_NO_RESULT_SET, null);
186         }
187
188         if (!r.isData()) {
189
190             // implied: columnCount = 0;
191
return;
192         }
193
194         columnCount = r.getColumnCount();
195
196         // fredt - props is null for internal connections, so always use the default behaviour in this case
197
useColumnName = props == null ? true
198                                       : props.isPropertyTrue(
199                                           "get_column_name");
200         columnMetaData = new jdbcColumnMetaData[columnCount];
201         rmd = r.metaData;
202
203         for (int i = 0; i < columnCount; i++) {
204             cmd = new jdbcColumnMetaData();
205             columnMetaData[i] = cmd;
206
207             // Typically, these null checks are not needed, but as
208
// above, it is not _guaranteed_ that these values
209
// will be non-null. So, it is better to do the work
210
// here than have to perform checks and conversions later.
211
cmd.catalogName = rmd.catalogNames[i] == null ? ""
212                                                           : rmd
213                                                           .catalogNames[i];
214             cmd.schemaName = rmd.schemaNames[i] == null ? ""
215                                                             : rmd
216                                                             .schemaNames[i];
217             cmd.tableName = rmd.tableNames[i] == null ? ""
218                                                            : rmd
219                                                            .tableNames[i];
220             cmd.columnName = rmd.colNames[i] == null ? ""
221                                                          : rmd.colNames[i];
222             cmd.columnLabel = rmd.colLabels[i] == null ? ""
223                                                           : rmd.colLabels[i];
224             cmd.columnType = rmd.colTypes[i];
225             cmd.columnTypeName = Types.getTypeString(cmd.columnType);
226             cmd.isWritable = rmd.isWritable[i];
227             cmd.isReadOnly = !cmd.isWritable;
228
229             // default: cmd.isDefinitelyWritable = false;
230
cmd.isAutoIncrement = rmd.isIdentity[i];
231             cmd.isNullable = rmd.colNullable[i];
232             type = cmd.columnType;
233             cmd.columnClassName = rmd.classNames[i];
234
235             if (cmd.columnClassName == null
236                     || cmd.columnClassName.length() == 0) {
237                 cmd.columnClassName = Types.getColStClsName(type);
238             }
239
240             // Some tools, such as PowerBuilder, require that (for char and
241
// varchar types, at any rate) getMaxDisplaySize returns a value
242
// _at least_ as large as the length of the longest value in this
243
// column of the result set, or else an internal error will occur
244
// at retrieve time the instant a longer value is fetched.
245
//
246
// org.hsqldb.Types has been patched to retrieve, by default, either
247
// a large-but-reasonable value or a value defined through system
248
// properties that is expected to be unlikely to cause problems in
249
// the majority of cases.
250
if (Types.acceptsPrecisionCreateParam(type)) {
251                 if (rmd.colSizes[i] == 0) {
252                     cmd.columnDisplaySize = Types.getMaxDisplaySize(type);
253                 } else {
254                     cmd.columnDisplaySize = rmd.colSizes[i];
255
256                     if (Types.acceptsScaleCreateParam(type)) {
257                         if (rmd.colScales[i] != 0) {
258                             cmd.columnDisplaySize += (1 + rmd.colScales[i]);
259                         }
260                     }
261                 }
262             } else {
263                 cmd.columnDisplaySize = Types.getMaxDisplaySize(type);
264             }
265
266             if (Types.isNumberType(type)
267                     && Types.acceptsPrecisionCreateParam(type)) {
268                 cmd.precision = rmd.colSizes[i];
269
270                 if (cmd.precision == 0) {
271                     cmd.precision = Types.getPrecision(type);
272                 }
273             } else {
274                 cmd.precision = Types.getPrecision(type);
275             }
276
277             // Without a non-zero scale value, some (legacy only?) tools will
278
// simply truncate digits to the right of the decimal point when
279
// retrieving values from the result set. The measure below can
280
// help, but currently only as long as one is connected to an
281
// embedded instance at design time, not via a network connection.
282
if (Types.acceptsScaleCreateParam(type)) {
283                 cmd.scale = rmd.colScales[i];
284             }
285
286             Boolean JavaDoc iua = Types.isUnsignedAttribute(type);
287
288             cmd.isSigned = iua != null &&!iua.booleanValue();
289
290             Boolean JavaDoc ics = Types.isCaseSensitive(type);
291
292             cmd.isCaseSensitive = ics != null && ics.booleanValue();
293             cmd.isSearchable = Types.isSearchable(type);
294         }
295     }
296
297     /**
298      * <!-- start generic documentation -->
299      * Returns the number of columns in this <code>ResultSet</code>
300      * object. <p>
301      * <!-- end generic documentation -->
302      * @return the number of columns
303      * @exception SQLException if a database access error occurs
304      */

305     public int getColumnCount() throws SQLException JavaDoc {
306         return columnCount;
307     }
308
309     /**
310      * <!-- start generic documentation -->
311      * Indicates whether the designated column is automatically numbered,
312      * thus read-only. <p>
313      * <!-- end generic documentation -->
314      *
315      * <!-- start Release-specific documentation -->
316      * <div class="ReleaseSpecificDocumentation">
317      * <h3>HSQLDB-Specific Information:</h3> <p>
318      *
319      * HSQLDB 1.7.1 did not report this value accurately,
320      * either always throwing or always returning false, depending
321      * upon client property values.<p>
322      *
323      * Starting with HSQLDB 1.7.2, this feature is better supported. <p>
324      *
325      * <hr>
326      *
327      * However, it must be stated here that, contrary to the generic
328      * documentation above, HSQLDB automatically numbered columns
329      * (IDENTITY columns, in HSQLDB parlance) are not read-only. <p>
330      *
331      * In fact, the generic documentation above seems to contradict the general
332      * definition of what, at minimum, an auto-increment column is: <p>
333      *
334      * Simply, an auto-increment column is one that guarantees it has a
335      * unique value after a successful insert or update operation, even if
336      * no value is supplied or NULL is explicitly specified by the application
337      * or a default value expression. <p>
338      *
339      * Further, without SQL Feature T176, Sequence generator support, the
340      * attributes of the internal source consulted for unique values are not
341      * defined. That is, unlike for a standard SQL SEQUENCE object or a system
342      * with full SQL 9x or 200n support for SQL Feature T174, Identity columns,
343      * an application must not assume and cannot determine in a standard way
344      * that auto-increment values start at any particular point, increment by
345      * any particular value or have any of the other attributes generally
346      * associated with SQL SEQUENCE generators. Further still, without full
347      * support for both feature T174 and T176, if a unique value is supplied
348      * by an application or provided by a declared or implicit default value
349      * expression, then whether that value is used or substituted with one
350      * from the automatic unique value source is implementation-defined
351      * and cannot be known in a standard way. Finally, without full support
352      * for features T174 and T176, it is also implementation-defined and
353      * cannot be know in a standard way whether an exception is thrown or
354      * a unique value is automatically substituted when an application or
355      * default value expression supplies a non-NULL,
356      * non-unique value. <p>
357      *
358      * Up to and including HSQLDB 1.7.2, values supplied by an application or
359      * default value expression are used if they are indeed non-NULL unique
360      * values, while an exception is thrown if either possible value source
361      * for the site attempts to supply a non-NULL, non-unique value. This is
362      * very likely to remain the behaviour of HSQLDB for its foreseable
363      * lifetime and at the very least for the duration of the 1.7.x release
364      * series.<p>
365      *
366      * <hr>
367      *
368      * Regardless of the new and better support for reporting
369      * isAutoIncrement(), it is still possible under certain conditions that
370      * accurate reporting may be impossible. For example, if this object's
371      * parent Connection is closed before the first call to this method or to
372      * any other method of this class that initializes the connection-dependent
373      * ResultSetMetaData values, then it is impossible to report accurately for
374      * result set columns that directly represent table column values.<p>
375      *
376      * Under such special circumstances, the driver rethrows the exception that
377      * occured during the initialization, or a SQLException wrapping it. <p>
378      *
379      * Those wishing to determine the auto-increment status of a table column
380      * in isolation from ResultSetMetaData can do so by inspecting the
381      * corresponding value of the SYSTEM_COLUMNS.IS_IDENTITY BOOLEAN column which
382      * is also currently included (in a fashion proprietary to HSQLDB) as the
383      * last column of the jdbcDatabaseMetaData.getColumns() result.
384      *
385      * </div>
386      * <!-- end release-specific documentation -->
387      *
388      * @param column the first column is 1, the second is 2, ...
389      * @return <code>true</code> if so; <code>false</code> otherwise
390      * @exception SQLException if a database access error occurs
391      */

392     public boolean isAutoIncrement(int column) throws SQLException JavaDoc {
393
394         checkColumn(column);
395
396         return columnMetaData[--column].isAutoIncrement;
397     }
398
399     /**
400      * <!-- start generic documentation -->
401      * Indicates whether a column's case matters. <p>
402      * <!-- end generic documentation -->
403      *
404      * <!-- start Release-specific documentation -->
405      * <div class="ReleaseSpecificDocumentation">
406      * <h3>HSQLDB-Specific Information:</h3> <p>
407      *
408      * HSQLDB 1.7.1 did not report this value accurately. <p>
409      *
410      * Starting with 1.7.2, this feature is better supported. <p>
411      *
412      * This method returns true for any column whose data type is a character
413      * type, with the exception of VARCHAR_IGNORECASE for which it returns
414      * false. It also returns false for any column whose data type is a
415      * not a character data type. <p>
416      *
417      * </div>
418      * <!-- end release-specific documentation -->
419      *
420      * @param column the first column is 1, the second is 2, ...
421      * @return <code>true</code> if so; <code>false</code> otherwise
422      * @exception SQLException if a database access error occurs
423      */

424     public boolean isCaseSensitive(int column) throws SQLException JavaDoc {
425
426         checkColumn(column);
427
428         return columnMetaData[--column].isCaseSensitive;
429     }
430
431     /**
432      * <!-- start generic documentation -->
433      * Indicates whether the designated column can be used in a where
434      * clause. <p>
435      * <!-- end generic documentation -->
436      *
437      * <!-- start Release-specific documentation -->
438      * <div class="ReleaseSpecificDocumentation">
439      * <h3>HSQLDB-Specific Information:</h3> <p>
440      *
441      * HSQLDB 1.7.1 did not report this value accurately. <p>
442      *
443      * Starting with 1.7.2, this feature is better supported. <p>
444      *
445      * If the data type of the column is definitely known to be searchable
446      * in any way under HSQLDB, then true is returned, else false. That is,
447      * if the type is reported in DatabaseMetaData.getTypeInfo() as having
448      * DatabaseMetaData.typePredNone or is not reported, then false is
449      * returned, else true.
450      *
451      * </div>
452      * <!-- end release-specific documentation -->
453      *
454      * @param column the first column is 1, the second is 2, ...
455      * @return <code>true</code> if so; <code>false</code> otherwise
456      * @exception SQLException if a database access error occurs
457      */

458     public boolean isSearchable(int column) throws SQLException JavaDoc {
459
460         checkColumn(column);
461
462         return columnMetaData[--column].isSearchable;
463     }
464
465     /**
466      * <!-- start generic documentation -->
467      * Indicates whether the designated column is a cash value. <p>
468      * <!-- end generic documentation -->
469      *
470      * <!-- start Release-specific documentation -->
471      * <div class="ReleaseSpecificDocumentation">
472      * <h3>HSQLDB-Specific Information:</h3> <p>
473      *
474      * Up to and including HSQLDB 1.7.2, this method always returns
475      * false. <p>
476      *
477      * This is because true fixed (precision,scale) data types are not yet
478      * supported. That is, DECIMAL and NUMERIC types are implemented
479      * as a thin wrap of java.math.BigDecimal, which cannot, without
480      * additional, as yet unimplemented constraint enforcement code, be
481      * said to be a fixed (precision,scale) types. <p>
482      *
483      * </div>
484      * <!-- end release-specific documentation -->
485      *
486      * @param column the first column is 1, the second is 2, ...
487      * @return <code>true</code> if so; <code>false</code> otherwise
488      * @exception SQLException if a database access error occurs
489      */

490     public boolean isCurrency(int column) throws SQLException JavaDoc {
491
492         checkColumn(column);
493
494         return columnMetaData[--column].isCurrency;
495     }
496
497     /**
498      * <!-- start generic documentation -->
499      * Indicates the nullability of values in the designated column. <p>
500      * <!-- end generic documentation -->
501      *
502      * <!-- start Release-specific documentation -->
503      * <div class="ReleaseSpecificDocumentation">
504      * <h3>HSQLDB-Specific Information:</h3> <p>
505      *
506      * Up to 1.7.1, HSQLDB did not report this value accurately. <p>
507      *
508      * Starting with 1.7.2, this feature is better supported. <p>
509      *
510      * columnNullableUnknown is always returned for result set columns that
511      * do not directly represent table column values (i.e. are calculated),
512      * while the corresponding value in SYSTEM_COLUMNS.NULLABLE is returned
513      * for result set columns that do directly represent table column values. <p>
514      *
515      * Those wishing to determine the nullable status of a table column in
516      * isolation from ResultSetMetaData and in a DBMS-independent fashion
517      * can do so by calling DatabaseMetaData.getColumns() with the appropriate
518      * filter values and inspecting the result at the position described in
519      * the API documentation. <p>
520      *
521      * </div>
522      * <!-- end release-specific documentation -->
523      *
524      * @param column the first column is 1, the second is 2, ...
525      * @return the nullability status of the given column; one of
526      * <code>columnNoNulls</code>,
527      * <code>columnNullable</code> or <code>columnNullableUnknown</code>
528      * @exception SQLException if a database access error occurs
529      */

530     public int isNullable(int column) throws SQLException JavaDoc {
531
532         checkColumn(column);
533
534         return columnMetaData[--column].isNullable;
535     }
536
537     /**
538      * <!-- start generic documentation -->
539      * Indicates whether values in the designated column are signed
540      * numbers. <p>
541      * <!-- end generic documentation -->
542      *
543      * <!-- start Release-specific documentation -->
544      * <div class="ReleaseSpecificDocumentation">
545      * <h3>HSQLDB-Specific Information:</h3> <p>
546      *
547      * HSQLDB 1.7.1 introduced support for this feature and 1.7.2
548      * reports identical values (although using a slightly different
549      * implementation).<p>
550      *
551      * </div>
552      * <!-- end release-specific documentation -->
553      *
554      * @param column the first column is 1, the second is 2, ...
555      * @return <code>true</code> if so; <code>false</code> otherwise
556      * @exception SQLException if a database access error occurs
557      */

558     public boolean isSigned(int column) throws SQLException JavaDoc {
559
560         checkColumn(column);
561
562         return columnMetaData[--column].isSigned;
563     }
564
565     /**
566      * <!-- start generic documentation -->
567      * Indicates the designated column's normal maximum width in
568      * characters. <p>
569      * <!-- end generic documentation -->
570      *
571      * <!-- start Release-specific documentation -->
572      * <div class="ReleaseSpecificDocumentation">
573      * <h3>HSQLDB-Specific Information:</h3> <p>
574      *
575      * Up to and including HSQLDB 1.7.1, this method always returned
576      * 0, which was intended to convey unknown display size.
577      * Unfortunately, this value is not universally handled by all
578      * clients and in the worst case can cause some applications to
579      * crash. <p>
580      *
581      * Starting with 1.7.2, this feature is better supported. <p>
582      *
583      * The current calculation follows these rules: <p>
584      *
585      * <ol>
586      * <li>Long character types and datetime types:<p>
587      *
588      * The maximum length/precision, repectively.<p>
589      *
590      * <li>CHAR and VARCHAR types: <p>
591      *
592      * <ul>
593      * <li> If the result set column is a direct pass through of a table
594      * column value, column size was declared and the connection is
595      * to an embedded database instance, then the declared value is
596      * returned.<p>
597      *
598      * <li> Otherwise, the value of the system property
599      * hsqldb.max_xxxchar_display_size or the magic value
600      * 32766 (0x7FFE) (tested usable/accepted by most tools and
601      * compatible with assumptions made by java.io read/write
602      * UTF) when the system property is not defined or is not
603      * accessible, due to security constraints. <p>
604      *
605      * </ul>
606      *
607      * It must be noted that the latter value in no way affects the
608      * ability of the HSQLDB JDBC driver to retrieve longer values
609      * and serves only as the current best effort at providing a
610      * value that maximizes usability across a wide range of tools,
611      * given that the HSQLDB database engine does not require the
612      * length to be declared and does not necessarily enforce it,
613      * even if declared. <p>
614      *
615      * <li>Number types: <p>
616      *
617      * The max precision, plus the length of the negation character (1),
618      * plus (if applicable) the maximum number of characters that may
619      * occupy the exponent character sequence. Note that some legacy tools
620      * do not correctly handle BIGINT values of greater than 18 digits. <p>
621      *
622      * <li>BOOLEAN (BIT) type: <p>
623      *
624      * The length of the character sequence "false" (5), the longer of the
625      * two boolean value String representations. <p>
626      *
627      * <li>Remaining types: <p>
628      *
629      * The maximum length/precision, respectively, as reported by
630      * DatabaseMetaData.getTypeInfo(), when applicable. If the maximum
631      * display size is unknown, unknowable or inapplicable, then zero is
632      * returned. <p>
633      *
634      * </ol>
635      *
636      * </div>
637      * <!-- end release-specific documentation -->
638      *
639      * @param column the first column is 1, the second is 2, ...
640      * @return the normal maximum number of characters allowed as the width
641      * of the designated column
642      * @exception SQLException if a database access error occurs
643      */

644     public int getColumnDisplaySize(int column) throws SQLException JavaDoc {
645
646         checkColumn(column);
647
648         return columnMetaData[--column].columnDisplaySize;
649     }
650
651     /**
652      * <!-- start generic documentation -->
653      * Gets the designated column's suggested title for use in printouts and
654      * displays. <p>
655      * <!-- end generic documentation -->
656      *
657      * <!-- start Release-specific documentation -->
658      * <div class="ReleaseSpecificDocumentation">
659      * <h3>HSQLDB-Specific Information:</h3> <p>
660      *
661      * In HSQLDB a <code>ResultSet</code> column label is determined in the
662      * following order of precedence:<p>
663      *
664      * <OL>
665      * <LI>The label (alias) specified in the generating query.</LI>
666      * <LI>The name of the underlying column, if no label is specified.<br>
667      * This also applies to aggregate functions.</LI>
668      * <LI>An empty <code>String</code>.</LI>
669      * </OL> <p>
670      *
671      * </div>
672      * <!-- end release-specific documentation -->
673      *
674      * @param column the first column is 1, the second is 2, ...
675      * @return the suggested column title
676      * @exception SQLException if a database access error occurs
677      */

678     public String JavaDoc getColumnLabel(int column) throws SQLException JavaDoc {
679
680         checkColumn(column);
681
682         return columnMetaData[--column].columnLabel;
683     }
684
685     /**
686      * <!-- start generic documentation -->
687      * Get the designated column's name. <p>
688      * <!-- end generic documentation -->
689      *
690      * <!-- start Release-specific documentation -->
691      * <div class="ReleaseSpecificDocumentation">
692      * <h3>HSQLDB-Specific Information:</h3> <p>
693      *
694      * In HSQLDB a ResultSet column name is determined in the following
695      * order of prcedence:<p>
696      *
697      * <OL>
698      * <LI>The name of the underlying columnm, if the ResultSet column
699      * represents a column in a table.</LI>
700      * <LI>The label or alias specified in the generating query.</LI>
701      * <LI>An empty <code>String</code>.</LI>
702      * </OL> <p>
703      *
704      * If the <code>jdbc.get_column_name</code> property of the database
705      * has been set to false, this method returns the same value as
706      * {@link #getColumnLabel(int)}.<p>
707      *
708      * </div>
709      * <!-- end release-specific documentation -->
710      *
711      * @param column the first column is 1, the second is 2, ...
712      * @return column name
713      * @exception SQLException if a database access error occurs
714      */

715     public String JavaDoc getColumnName(int column) throws SQLException JavaDoc {
716
717         checkColumn(column);
718
719         column--;
720
721         return useColumnName ? columnMetaData[column].columnName
722                              : columnMetaData[column].columnLabel;
723     }
724
725     /**
726      * <!-- start generic documentation -->
727      * Get the designated column's table's schema. <p>
728      * <!-- end generic documentation -->
729      *
730      * <!-- start Release-specific documentation -->
731      * <div class="ReleaseSpecificDocumentation">
732      * <h3>HSQLDB-Specific Information:</h3> <p>
733      *
734      * Up to 1.7.1, HSQLDB did not support the notion of schemas at all,
735      * including schema names in result set metadata; this method always
736      * returned "". <p>
737      *
738      * Staring with 1.7.2, schema name reporting is supported only as an
739      * optional, experimental feature that is disabled by default.
740      * Enabling this feature requires setting the database property
741      * "hsqldb.schemas=true". <p>
742      *
743      * Specifically, when this feature is enabled under 1.7.2, only very
744      * limited support is provided by the engine for executing SQL containing
745      * schema-qualified database object identifiers. That is, when this
746      * feature is enabled under 1.7.2, it is not yet possible in most cases
747      * to use what would otherwise be the correct, canonical SQL calculated
748      * from ResultSetMetaData. <p>
749      *
750      * Regardless, reporting is done only in system table content and is
751      * not yet carried over to ResultSetMetaData. <p>
752      *
753      * For greater detail, see discussion at:
754      * {@link jdbcDatabaseMetaData}. <p>
755      *
756      * </div>
757      * <!-- end release-specific documentation -->
758      *
759      * @param column the first column is 1, the second is 2, ...
760      * @return schema name or "" if not applicable
761      * @exception SQLException if a database access error occurs
762      */

763     public String JavaDoc getSchemaName(int column) throws SQLException JavaDoc {
764
765         checkColumn(column);
766
767         return columnMetaData[--column].schemaName;
768     }
769
770     /**
771      * <!-- start generic documentation -->
772      * Get the designated column's number of decimal digits. <p>
773      * <!-- end generic documentation -->
774      *
775      * <!-- start Release-specific documentation -->
776      * <div class="ReleaseSpecificDocumentation">
777      * <h3>HSQLDB-Specific Information:</h3> <p>
778      *
779      * Starting with 1.8.0, HSQLDB reports the the declared
780      * length or precision specifiers for table columns (if they are defined,
781      * which up to 1.7.2 is not a requirement in DDL), as these values may or
782      * may not be enforced, depending on the value of the database
783      * property: <p>
784      *
785      * <pre>
786      * sql.enforce_strict_size
787      * </pre>
788      *
789      * Because the property may change from one instantiation of a Database
790      * to the next and because, when set true, is not applied to existing
791      * values in table columns (only to new values introduced by following
792      * inserts and updates), the length and/or precision specifiers for table
793      * columns still do not neccessarily accurately reflect true constraints
794      * upon the contents of the columns. This situation may or may not change
795      * in a future release. <p>
796      *
797      * </div>
798      * <!-- end release-specific documentation -->
799      *
800      * @param column the first column is 1, the second is 2, ...
801      * @return precision
802      * @exception SQLException if a database access error occurs
803      */

804     public int getPrecision(int column) throws SQLException JavaDoc {
805
806         checkColumn(column);
807
808         return columnMetaData[--column].precision;
809     }
810
811     /**
812      * <!-- start generic documentation -->
813      * Gets the designated column's number of digits to right of the
814      * decimal point. <p>
815      * <!-- end generic documentation -->
816      *
817      * <!-- start Release-specific documentation -->
818      * <div class="ReleaseSpecificDocumentation">
819      * <h3>HSQLDB-Specific Information:</h3> <p>
820      *
821      * Starting with 1.8.0, HSQLDB reports the declared
822      * scale for table columns depending on the value of the database
823      * property: <p>
824      *
825      * <pre>
826      * sql.enforce_strict_size
827      * </pre>
828      *
829      * </div>
830      * <!-- end release-specific documentation -->
831      *
832      * @param column the first column is 1, the second is 2, ...
833      * @return scale
834      * @exception SQLException if a database access error occurs
835      */

836     public int getScale(int column) throws SQLException JavaDoc {
837
838         checkColumn(column);
839
840         return columnMetaData[--column].scale;
841     }
842
843     /**
844      * <!-- start generic documentation -->
845      * Gets the designated column's table name. <p>
846      * <!-- end generic documentation -->
847      * @param column the first column is 1, the second is 2, ...
848      * @return table name or "" if not applicable
849      * @exception SQLException if a database access error occurs
850      */

851     public String JavaDoc getTableName(int column) throws SQLException JavaDoc {
852
853         checkColumn(column);
854
855         return columnMetaData[--column].tableName;
856     }
857
858     /**
859      * <!-- start generic documentation -->
860      * Gets the designated column's table's catalog name. <p>
861      * <!-- end generic documentation -->
862      *
863      * <!-- start Release-specific documentation -->
864      * <div class="ReleaseSpecificDocumentation">
865      * <h3>HSQLDB-Specific Information:</h3> <p>
866      *
867      * Up to and including 1.7.1, HSQLDB did not support the notion of
868      * catalog and this method always returned "". <p>
869      *
870      * Starting with 1.7.2, HSQLDB supports catalog reporting only as an
871      * optional, experimental feature that is disabled by default. Enabling
872      * this feature requires setting the database property
873      * "hsqldb.catalogs=true". When enabled, the catalog name for table columns
874      * is reported as the name by which the hosting Database knows itself. <p>
875      *
876      * HSQLDB does not yet support any use of catalog qualification in
877      * DLL or DML. This fact is accurately indicated in the corresponding
878      * DatabaseMetaData.supportsXXX() method return values. <p>
879      *
880      * Regardless, reporting is done only in system table content and is
881      * not yet carried over to ResultSetMetaData. <p>
882      *
883      * For greater detail, see discussion at:
884      * {@link jdbcDatabaseMetaData}. <p>
885      *
886      * </div>
887      * <!-- end release-specific documentation -->
888      *
889      * @param column the first column is 1, the second is 2, ...
890      * @return the name of the catalog for the table in which the given column
891      * appears or "" if not applicable
892      * @exception SQLException if a database access error occurs
893      */

894     public String JavaDoc getCatalogName(int column) throws SQLException JavaDoc {
895
896         checkColumn(column);
897
898         return columnMetaData[--column].catalogName;
899     }
900
901     /**
902      * <!-- start generic documentation -->
903      * Retrieves the designated column's SQL type. <p>
904      * <!-- end generic documentation -->
905      *
906      * <!-- start Release-specific documentation -->
907      * <div class="ReleaseSpecificDocumentation">
908      * <h3>HSQLDB-Specific Information:</h3> <p>
909      *
910      * This reports the SQL type of the column. HSQLDB can return Objects in
911      * any Java integral type wider than <code>Integer</code> for an SQL
912      * integral type.<p>
913      *
914      * </div>
915      * <!-- end release-specific documentation -->
916      *
917      *
918      * @param column the first column is 1, the second is 2, ...
919      * @return SQL type from java.sql.Types
920      * @exception SQLException if a database access error occurs
921      * @see java.sql.Types
922      */

923     public int getColumnType(int column) throws SQLException JavaDoc {
924
925         checkColumn(column);
926
927         int type = columnMetaData[--column].columnType;
928
929         return type == Types.VARCHAR_IGNORECASE ? Types.VARCHAR
930                                                 : type;
931     }
932
933     /**
934      * <!-- start generic documentation -->
935      * Retrieves the designated column's database-specific type name. <p>
936      * <!-- end generic documentation -->
937      *
938      * @param column the first column is 1, the second is 2, ...
939      * @return type name used by the database. If the column type is
940      * a user-defined type, then a fully-qualified type name is returned.
941      * @exception SQLException if a database access error occurs
942      */

943     public String JavaDoc getColumnTypeName(int column) throws SQLException JavaDoc {
944
945         checkColumn(column);
946
947         return columnMetaData[--column].columnTypeName;
948     }
949
950     /**
951      * <!-- start generic documentation -->
952      * Indicates whether the designated column is definitely not writable.<p>
953      * <!-- end generic documentation -->
954      *
955      * <!-- start Release-specific documentation -->
956      * <div class="ReleaseSpecificDocumentation">
957      * <h3>HSQLDB-Specific Information:</h3> <p>
958      *
959      * Up to and including 1.7.1, HSQLDB did not report this value accurately.
960      * <p>
961      *
962      * Starting with HSQLDB 1.7.2, this feature is better supported. <p>
963      *
964      * For result set columns that do not directly
965      * represent table column values (i.e. are calculated), true is reported.
966      * Otherwise, the read only status of the table and the database are used
967      * in the calculation, but not the read-only status of the session. <p>
968      *
969      * </div>
970      * <!-- end release-specific documentation -->
971      *
972      * @param column the first column is 1, the second is 2, ...
973      * @return <code>true</code> if so; <code>false</code> otherwise
974      * @exception SQLException if a database access error occurs
975      */

976     public boolean isReadOnly(int column) throws SQLException JavaDoc {
977
978         checkColumn(column);
979
980         return columnMetaData[--column].isReadOnly;
981     }
982
983     /**
984      * <!-- start generic documentation -->
985      * Indicates whether it is possible for a write on the designated
986      * column to succeed. <p>
987      * <!-- end generic documentation -->
988      *
989      * <!-- start Release-specific documentation -->
990      * <div class="ReleaseSpecificDocumentation">
991      * <h3>HSQLDB-Specific Information:</h3> <p>
992      *
993      * Up to and including 1.7.1, HSQLDB did not report this value accurately.
994      * <p>
995      *
996      * Starting with HSQLDB 1.7.2, this feature is better supported. <p>
997      *
998      * In essense, the negation of isReadOnly() is reported. <p>
999      *
1000     * </div>
1001     * <!-- end release-specific documentation -->
1002     *
1003     * @param column the first column is 1, the second is 2, ...
1004     * @return <code>true</code> if so; <code>false</code> otherwise
1005     * @exception SQLException if a database access error occurs
1006     */

1007    public boolean isWritable(int column) throws SQLException JavaDoc {
1008
1009        checkColumn(column);
1010
1011        return columnMetaData[--column].isWritable;
1012    }
1013
1014    /**
1015     * <!-- start generic documentation -->
1016     * Indicates whether a write on the designated column will definitely
1017     * succeed. <p>
1018     * <!-- end generic documentation -->
1019     *
1020     * <!-- start Release-specific documentation -->
1021     * <div class="ReleaseSpecificDocumentation">
1022     * <h3>HSQLDB-Specific Information:</h3> <p>
1023     *
1024     * HSQLDB 1.7.1 did not report this value accurately. <p>
1025     *
1026     * Starting with HSQLDB 1.7.2, this method always returns false. The
1027     * reason for this is that it is generally either very complex or
1028     * simply impossible to calculate deterministically true for table columns
1029     * under all concievable conditions. The value is of dubious usefulness, except
1030     * perhaps if there were support for updateable result sets using
1031     * "SELECT ... FOR UPDATE" style locking. However, this is not anticipated to
1032     * occur any time in the 1.7.x release series. <p>
1033     *
1034     * </div>
1035     * <!-- end release-specific documentation -->
1036     *
1037     * @param column the first column is 1, the second is 2, ...
1038     * @return <code>true</code> if so; <code>false</code> otherwise
1039     * @exception SQLException if a database access error occurs
1040     */

1041    public boolean isDefinitelyWritable(int column) throws SQLException JavaDoc {
1042
1043        checkColumn(column);
1044
1045// NOTE:
1046
// boucherb@users - 20020329
1047
// currently, we can't tell _for sure_ that this is true without a
1048
// great deal more work (and even then, not necessarily deterministically),
1049
// plus it is of dubious usefulness to know this is true _for sure_ anyway.
1050
// It's not like one can do an insert or update without a try-catch block
1051
// using JDBC, even if one knows that a column is definitely writable. And
1052
// the catch will always let us know if there is a failure and why. Also,
1053
// it is typically completely useless to know that, although it is _possible_
1054
// that a write may succeed (as indicated by a true value of isWritable()),
1055
// it also might fail (as indicated by a false returned here).
1056
// as of 1.7.2, always false
1057
return columnMetaData[--column].isDefinitelyWritable;
1058    }
1059
1060    //--------------------------JDBC 2.0-----------------------------------
1061

1062    /**
1063     * <!-- start generic documentation -->
1064     * Returns the fully-qualified name of the Java class whose instances
1065     * are manufactured if the method <code>ResultSet.getObject</code>
1066     * is called to retrieve a value from the column.
1067     * <code>ResultSet.getObject</code> may return a subclass of the class
1068     * returned by this method. <p>
1069     * <!-- end generic documentation -->
1070     *
1071     * <!-- start Release-specific documentation -->
1072     * <div class="ReleaseSpecificDocumentation">
1073     * <h3>HSQLDB-Specific Information:</h3> <p>
1074     *
1075     * HSQLDB 1.7.1 did not support this feature; calling this method
1076     * always caused an <code>SQLException</code> to be thrown,
1077     * stating that the function was not supported. <p>
1078     *
1079     * </div>
1080     * <!-- end release-specific documentation -->
1081     *
1082     * @param column the first column is 1, the second is 2, ...
1083     * @return the fully-qualified name of the class in the Java programming
1084     * language that would be used by the method
1085     * <code>ResultSet.getObject</code> to retrieve the value in the
1086     * specified column. This is the class name used for custom mapping.
1087     * @exception SQLException if a database access error occurs
1088     * @since JDK 1.2 (JDK 1.1.x developers: read the new overview for
1089     * jdbcResultSet)
1090     */

1091    public String JavaDoc getColumnClassName(int column) throws SQLException JavaDoc {
1092
1093        checkColumn(column);
1094
1095        return columnMetaData[--column].columnClassName;
1096    }
1097
1098    public String JavaDoc toString() {
1099
1100        StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1101
1102        sb.append(super.toString());
1103
1104        if (columnCount == 0) {
1105            sb.append("[columnCount=0]");
1106
1107            return sb.toString();
1108        }
1109
1110        sb.append('[');
1111
1112        for (int i = 0; i < columnCount; i++) {
1113            sb.append('\n');
1114            sb.append(" column_");
1115            sb.append(i + 1);
1116            sb.append('=');
1117            sb.append(columnMetaData[i]);
1118
1119            if (i + 1 < columnCount) {
1120                sb.append(',');
1121                sb.append(' ');
1122            }
1123        }
1124
1125        sb.append('\n');
1126        sb.append(']');
1127
1128        return sb.toString();
1129    }
1130
1131// ------------------------- Internal Implementation ---------------------------
1132

1133    /**
1134     * Performs an internal check for column index validity. <p>
1135     *
1136     * @param column index of column to check
1137     * @throws SQLException when this object's parent ResultSet has
1138     * no such column
1139     */

1140    private void checkColumn(int column) throws SQLException JavaDoc {
1141
1142        if (column < 1 || column > columnCount) {
1143            throw Util.sqlException(Trace.COLUMN_NOT_FOUND,
1144                                    String.valueOf(column));
1145        }
1146    }
1147}
1148
Popular Tags