KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > client > am > ColumnMetaData


1 /*
2
3    Derby - Class org.apache.derby.client.am.ColumnMetaData
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.client.am;
23
24 import java.sql.SQLException JavaDoc;
25
26 import org.apache.derby.iapi.reference.DRDAConstants;
27 import org.apache.derby.iapi.reference.JDBC30Translation;
28 import org.apache.derby.shared.common.reference.SQLState;
29
30 // Under JDBC 2, we must new up our parameter meta data as column meta data instances
31
// Once we move to JDK 1.4 pre-req, create a ResultSetMetaData class and make this class abstract
32

33 public class ColumnMetaData implements java.sql.ResultSetMetaData JavaDoc {
34
35     public int columns_;
36
37     public boolean[] nullable_;
38
39     // Although this is describe information, it is tagged transient for now becuase it is not currently used.
40
transient public int[] singleMixedByteOrDouble_; // 1 means single, 2 means double, 3 means mixed-byte, 0 not applicable
41

42     // All of the following state data comes from the SQLDA reply.
43

44     //Data from SQLDHGRP
45
public short sqldHold_;
46     public short sqldReturn_;
47     public short sqldScroll_;
48     public short sqldSensitive_;
49     public short sqldFcode_;
50     public short sqldKeytype_;
51     public String JavaDoc sqldRdbnam_; // catalog name, not used by driver, placeholder only
52
public String JavaDoc sqldSchema_; // schema name, not used by driver, placeholder only
53

54     //data comes from SQLDAGRP
55
public int[] sqlPrecision_; // adjusted sqllen;
56
public int[] sqlScale_;
57     public long[] sqlLength_; // This is maximum length for varchar fields
58
// These are the derby sql types, for use only by ResultSetMetaData, other code should use jdbcTypes_.
59
// sqlTypes_ is currently not set for input column meta data.
60
public int[] sqlType_;
61     public int[] sqlCcsid_;
62
63     // With the exception of sqlNames_ and sqlxParmmode_, the following members are only allocated when needed
64

65     //Data from SQLDOPTGRP
66
public String JavaDoc[] sqlName_; // column name, pre-allocated
67
public String JavaDoc[] sqlLabel_; // column label
68
public short[] sqlUnnamed_;
69     public String JavaDoc[] sqlComment_;
70
71     //Data from SQLDXGRP
72
public short[] sqlxKeymem_;
73     public short[] sqlxGenerated_;
74     public short[] sqlxParmmode_; // pre-allocated
75
public String JavaDoc[] sqlxCorname_;
76     public String JavaDoc[] sqlxName_;
77     public String JavaDoc[] sqlxBasename_; // table name
78
public int[] sqlxUpdatable_;
79     public String JavaDoc[] sqlxSchema_; // schema name
80
public String JavaDoc[] sqlxRdbnam_; // catalog name
81

82     //-----------------------------transient state--------------------------------
83

84     // For performance only, not part of logical model.
85
public transient int[][] protocolTypesCache_ = null;
86     public transient java.util.Hashtable JavaDoc protocolTypeToOverrideLidMapping_ = null;
87     public transient java.util.ArrayList JavaDoc mddOverrideArray_ = null;
88
89     public transient int[] types_;
90     public transient int[] clientParamtertype_;
91
92     public transient LogWriter logWriter_;
93
94     // only set on execute replies, this is not describe information.
95
// only used for result set meta data.
96

97     public transient int resultSetConcurrency_;
98
99     transient private java.util.Hashtable JavaDoc columnNameToIndexCache_ = null;
100
101     transient private boolean statementClosed_ = false;
102
103     void markClosed() {
104         statementClosed_ = true;
105         nullDataForGC();
106     }
107
108     void checkForClosedStatement() throws SqlException {
109         // agent_.checkForDeferredExceptions();
110
if (statementClosed_) {
111             throw new SqlException(logWriter_,
112                     new ClientMessageId (SQLState.LANG_STATEMENT_CLOSED_NO_REASON));
113         }
114     }
115
116
117     //---------------------navigational members-----------------------------------
118

119     //---------------------constructors/finalizer---------------------------------
120

121     // Called by NETColumnMetaData constructor before #columns is parsed out yet.
122
public ColumnMetaData(LogWriter logWriter) {
123         logWriter_ = logWriter;
124     }
125
126     // For creating column meta data when describe input is not available.
127
// The upper bound that is passed in is determined by counting the number of parameter markers.
128
// Called by PreparedStatement.flowPrepareStatement() and flowDescribeInputOutput()
129
// only when describe input is not available.
130
public ColumnMetaData(LogWriter logWriter, int upperBound) {
131         logWriter_ = logWriter;
132         initializeCache(upperBound);
133     }
134
135
136     public void initializeCache(int upperBound) {
137         columns_ = upperBound;
138         nullable_ = new boolean[upperBound];
139         types_ = new int[upperBound];
140         clientParamtertype_ = new int[upperBound];
141         singleMixedByteOrDouble_ = new int[upperBound]; // 1 means single, 2 means double, 3 means mixed-byte, 0 not applicable
142

143         sqlPrecision_ = new int[upperBound];
144         sqlScale_ = new int[upperBound];
145         sqlLength_ = new long[upperBound];
146         sqlType_ = new int[upperBound];
147         sqlCcsid_ = new int[upperBound];
148
149         sqlName_ = new String JavaDoc[upperBound];
150         sqlxParmmode_ = new short[upperBound];
151     }
152
153     protected void finalize() throws java.lang.Throwable JavaDoc {
154         super.finalize();
155     }
156
157     //--------------------Abstract material layer call-down methods-----------------
158

159     //------------------material layer event callback methods-----------------------
160

161     // ---------------------------jdbc 1------------------------------------------
162

163     public int getColumnCount() throws SQLException JavaDoc {
164         try
165         {
166             checkForClosedStatement();
167             return columns_;
168         }
169         catch ( SqlException e )
170         {
171             throw e.getSQLException();
172         }
173     }
174
175     public boolean isAutoIncrement(int column) throws SQLException JavaDoc {
176         try
177         {
178             checkForClosedStatement();
179             checkForValidColumnIndex(column);
180             return false;
181         }
182         catch ( SqlException e )
183         {
184             throw e.getSQLException();
185         }
186     }
187
188     public boolean isCaseSensitive(int column) throws SQLException JavaDoc {
189         try
190         {
191             checkForClosedStatement();
192             checkForValidColumnIndex(column);
193             //return true if the SQLTYPE is CHAR, VARCHAR, LOGVARCHAR or CLOB
194
int type = types_[column - 1];
195             return
196                     type == Types.CHAR ||
197                     type == Types.VARCHAR ||
198                     type == Types.LONGVARCHAR ||
199                     type == Types.CLOB;
200         }
201         catch ( SqlException e )
202         {
203             throw e.getSQLException();
204         }
205     }
206
207     // all searchable except distinct
208
public boolean isSearchable(int column) throws SQLException JavaDoc {
209         try
210         {
211             checkForClosedStatement();
212             checkForValidColumnIndex(column);
213             return true;
214         }
215         catch ( SqlException e )
216         {
217             throw e.getSQLException();
218         }
219     }
220
221     public boolean isCurrency(int column) throws SQLException JavaDoc {
222         try
223         {
224             checkForClosedStatement();
225             checkForValidColumnIndex(column);
226             return false;
227         }
228         catch ( SqlException e )
229         {
230             throw e.getSQLException();
231         }
232     }
233
234     public int isNullable(int column) throws SQLException JavaDoc {
235         try
236         {
237             checkForClosedStatement();
238             checkForValidColumnIndex(column);
239             if (nullable_[column - 1]) {
240                 return java.sql.ResultSetMetaData.columnNullable;
241             } else {
242                 return java.sql.ResultSetMetaData.columnNoNulls;
243             }
244         }
245         catch ( SqlException e )
246         {
247             throw e.getSQLException();
248         }
249     }
250
251     public boolean isSigned(int column) throws SQLException JavaDoc {
252         try
253         {
254             checkForClosedStatement();
255             checkForValidColumnIndex(column);
256             //return true only if the SQLType is SMALLINT, INT, BIGINT, FLOAT, REAL, DOUBLE, NUMERIC OR DECIMAL
257
int type = types_[column - 1];
258             return
259                     type == Types.SMALLINT ||
260                     type == Types.INTEGER ||
261                     type == Types.BIGINT ||
262                     type == java.sql.Types.FLOAT ||
263                     type == Types.REAL ||
264                     type == Types.DOUBLE ||
265                     type == java.sql.Types.NUMERIC ||
266                     type == Types.DECIMAL;
267         }
268         catch ( SqlException e )
269         {
270             throw e.getSQLException();
271         }
272 }
273
274     public int getColumnDisplaySize(int column) throws SQLException JavaDoc {
275         try
276         {
277             checkForClosedStatement();
278             checkForValidColumnIndex(column);
279             int jdbcType = types_[column - 1];
280             switch (jdbcType) {
281             case Types.INTEGER:
282                 return 11;
283             case Types.SMALLINT:
284                 return 6;
285             case Types.BIGINT:
286                 return 20;
287             case Types.REAL:
288                 return 13;
289             case Types.DOUBLE:
290             case java.sql.Types.FLOAT:
291                 return 22;
292             case Types.DECIMAL:
293             case java.sql.Types.NUMERIC:
294         // There are 3 possible cases with respect to finding the correct max width for DECIMAL type.
295
// 1. If scale = 0, only sign should be added to precision.
296
// 2. scale = precision, 3 should be added to precision for sign, decimal and an additional char '0'.
297
// 3. precision > scale > 0, 2 should be added to precision for sign and decimal.
298
int scale = getScale(column);
299         int precision = getPrecision(column);
300         return (scale == 0) ? (precision + 1) : ((scale == precision) ? (precision + 3) : (precision + 2));
301             case Types.CHAR:
302             case Types.VARCHAR:
303             case Types.LONGVARCHAR:
304             case Types.CLOB:
305                 return (int) sqlLength_[column - 1];
306             case Types.DATE:
307                 return 10;
308             case Types.TIME:
309                 return 8;
310             case Types.TIMESTAMP:
311                 return 26;
312             case Types.BINARY:
313             case Types.VARBINARY:
314             case Types.LONGVARBINARY:
315             case Types.BLOB:
316                 return (int) (2 * sqlLength_[column - 1]); // eg. "FF" represents just one byte
317
default:
318                 throw new SqlException(logWriter_,
319                         new ClientMessageId (SQLState.UNSUPPORTED_TYPE));
320             }
321         }
322         catch ( SqlException e )
323         {
324             throw e.getSQLException();
325         }
326     }
327
328     public String JavaDoc getColumnLabel(int column) throws SQLException JavaDoc {
329         try
330         {
331             checkForClosedStatement();
332             checkForValidColumnIndex(column);
333             // return labels if label is turned on, otherwise, return column name
334
if (sqlLabel_ != null && sqlLabel_[column - 1] != null) {
335                 return sqlLabel_[column - 1];
336             }
337             if (sqlName_ == null || sqlName_[column - 1] == null) {
338                 assignColumnName(column);
339             }
340             return sqlName_[column - 1];
341         }
342         catch ( SqlException e )
343         {
344             throw e.getSQLException();
345         }
346     }
347
348     public String JavaDoc getColumnName(int column) throws SQLException JavaDoc {
349         try
350         {
351             checkForClosedStatement();
352             checkForValidColumnIndex(column);
353             // The Javadoc and Jdbc book explicitly state that the empty string ("") is returned if "not applicable"
354
// for the following methods:
355
// getSchemaName()
356
// getTableName()
357
// getCatalogName()
358
// Since the empty string is a valid string and is not really a proper table name, schema name, or catalog name,
359
// we're not sure why the empty string was chosen over null, except possibly to be friendly to lazy jdbc apps
360
// that may not be checking for nulls, thereby minimizing potential NPE's.
361
// By induction, it would make sense to return the empty string when column name is not available/applicable.
362
//
363
// The JDBC specification contains blanket statements about SQL compliance levels,
364
// so elaboration within the JDBC specification is often bypassed.
365
// Personally, I would prefer to return Java null for all the not-applicable cases,
366
// but it appears that we have precedent for the empty ("") string.
367
//
368
// We assume a straightforward induction from jdbc spec that the column name be "" (empty)
369
// in preference to null or NULL for the not applicable case.
370
//
371
if (sqlName_ == null || sqlName_[column - 1] == null) {
372                 assignColumnName(column);
373             }
374             return sqlName_[column - 1];
375         }
376         catch ( SqlException e )
377         {
378             throw e.getSQLException();
379         }
380     }
381
382     public String JavaDoc getSchemaName(int column) throws SQLException JavaDoc {
383         try
384         {
385             checkForClosedStatement();
386             checkForValidColumnIndex(column);
387             if (sqlxSchema_ == null || sqlxSchema_[column - 1] == null) {
388                 return ""; // Per jdbc spec
389
}
390             return sqlxSchema_[column - 1];
391         }
392         catch ( SqlException e )
393         {
394             throw e.getSQLException();
395         }
396     }
397
398     public int getPrecision(int column) throws SQLException JavaDoc {
399         try
400         {
401             checkForClosedStatement();
402             checkForValidColumnIndex(column);
403             int jdbcType = types_[column - 1];
404
405             switch (jdbcType) {
406             case java.sql.Types.NUMERIC:
407             case Types.DECIMAL:
408                 return sqlPrecision_[column - 1];
409             case Types.SMALLINT:
410                 return 5;
411             case Types.INTEGER:
412                 return 10;
413             case Types.BIGINT:
414                 return 19;
415             case java.sql.Types.FLOAT:
416                 return 15;
417             case Types.REAL:
418                 return 7; // This is the number of signed digits for IEEE float with mantissa 24, ie. 2^24
419
case Types.DOUBLE:
420                 return 15; // This is the number of signed digits for IEEE float with mantissa 24, ie. 2^24
421
case Types.CHAR:
422             case Types.VARCHAR:
423             case Types.LONGVARCHAR:
424             case Types.BINARY:
425             case Types.VARBINARY:
426             case Types.LONGVARBINARY:
427             case Types.CLOB:
428             case Types.BLOB:
429                 return (int) sqlLength_[column - 1];
430             case Types.DATE:
431                 return 10;
432             case Types.TIME:
433                 return 8;
434             case Types.TIMESTAMP:
435                 return 26;
436             default:
437                 throw new SqlException(logWriter_,
438                         new ClientMessageId (SQLState.UNSUPPORTED_TYPE));
439             }
440         }
441         catch ( SqlException e )
442         {
443             throw e.getSQLException();
444         }
445     }
446
447     public int getScale(int column) throws SQLException JavaDoc {
448         try
449         {
450             checkForClosedStatement();
451             checkForValidColumnIndex(column);
452
453             // We get the scale from the SQLDA as returned by DERBY, but DERBY does not return the ANSI-defined
454
// value of scale 6 for TIMESTAMP.
455
//
456
// The JDBC drivers should hardcode this info as a short/near term solution.
457
//
458
if (types_[column - 1] == Types.TIMESTAMP) {
459                 return 6;
460             }
461
462             return sqlScale_[column - 1];
463         }
464         catch ( SqlException e )
465         {
466             throw e.getSQLException();
467         }
468     }
469
470     public String JavaDoc getTableName(int column) throws SQLException JavaDoc {
471         try
472         {
473             checkForClosedStatement();
474             checkForValidColumnIndex(column);
475             if (sqlxBasename_ == null || sqlxBasename_[column - 1] == null) {
476                 return ""; // Per jdbc spec
477
}
478             return sqlxBasename_[column - 1];
479         }
480         catch ( SqlException e )
481         {
482             throw e.getSQLException();
483         }
484     }
485
486     /**
487      * What's a column's table's catalog name?
488      *
489      * @param column the first column is 1, the second is 2, ...
490      *
491      * @return column name or "" if not applicable.
492      *
493      * @throws SQLException thrown on failure
494      */

495     public String JavaDoc getCatalogName(int column) throws SQLException JavaDoc {
496         try
497         {
498             checkForClosedStatement();
499             checkForValidColumnIndex(column);
500             return "";
501         }
502         catch ( SqlException e )
503         {
504             throw e.getSQLException();
505         }
506     }
507
508     public int getColumnType(int column) throws SQLException JavaDoc {
509         try
510         {
511             checkForClosedStatement();
512             checkForValidColumnIndex(column);
513
514             return types_[column - 1];
515         }
516         catch ( SqlException e )
517         {
518             throw e.getSQLException();
519         }
520     }
521
522     public String JavaDoc getColumnTypeName(int column) throws SQLException JavaDoc {
523         try
524         {
525             checkForClosedStatement();
526             checkForValidColumnIndex(column);
527
528             int jdbcType = types_[column - 1];
529             // So these all come back zero for downlevel servers in PROTOCOL.
530
// John is going to write some code to construct the sqlType_ array
531
// based on the protocol types from the query descriptor.
532
int sqlType = sqlType_[column - 1];
533
534             switch (sqlType) {
535             case DRDAConstants.DB2_SQLTYPE_DATE:
536             case DRDAConstants.DB2_SQLTYPE_NDATE:
537                 return "DATE";
538             case DRDAConstants.DB2_SQLTYPE_TIME:
539             case DRDAConstants.DB2_SQLTYPE_NTIME:
540                 return "TIME";
541             case DRDAConstants.DB2_SQLTYPE_TIMESTAMP:
542             case DRDAConstants.DB2_SQLTYPE_NTIMESTAMP:
543                 return "TIMESTAMP";
544             case DRDAConstants.DB2_SQLTYPE_BLOB:
545             case DRDAConstants.DB2_SQLTYPE_NBLOB:
546                 return "BLOB";
547             case DRDAConstants.DB2_SQLTYPE_CLOB:
548             case DRDAConstants.DB2_SQLTYPE_NCLOB:
549                 return "CLOB";
550             case DRDAConstants.DB2_SQLTYPE_VARCHAR:
551             case DRDAConstants.DB2_SQLTYPE_NVARCHAR:
552                 if (jdbcType == Types.VARBINARY) {
553                     return "VARCHAR FOR BIT DATA";
554                 } else {
555                     return "VARCHAR";
556                 }
557             case DRDAConstants.DB2_SQLTYPE_CHAR:
558             case DRDAConstants.DB2_SQLTYPE_NCHAR:
559                 if (jdbcType == Types.BINARY) {
560                     return "CHAR FOR BIT DATA";
561                 } else {
562                     return "CHAR";
563                 }
564             case DRDAConstants.DB2_SQLTYPE_LONG:
565             case DRDAConstants.DB2_SQLTYPE_NLONG:
566                 if (jdbcType == Types.LONGVARBINARY) {
567                     return "LONG VARCHAR FOR BIT DATA";
568                 } else {
569                     return "LONG VARCHAR";
570                 }
571             case DRDAConstants.DB2_SQLTYPE_CSTR:
572             case DRDAConstants.DB2_SQLTYPE_NCSTR:
573                 return "SBCS";
574             case DRDAConstants.DB2_SQLTYPE_FLOAT:
575             case DRDAConstants.DB2_SQLTYPE_NFLOAT:
576                 if (jdbcType == Types.DOUBLE) {
577                     return "DOUBLE";
578                 }
579                 if (jdbcType == Types.REAL) {
580                     return "REAL";
581                 }
582             case DRDAConstants.DB2_SQLTYPE_DECIMAL:
583             case DRDAConstants.DB2_SQLTYPE_NDECIMAL:
584                 return "DECIMAL";
585             case DRDAConstants.DB2_SQLTYPE_BIGINT:
586             case DRDAConstants.DB2_SQLTYPE_NBIGINT:
587                 return "BIGINT";
588             case DRDAConstants.DB2_SQLTYPE_INTEGER:
589             case DRDAConstants.DB2_SQLTYPE_NINTEGER:
590                 return "INTEGER";
591             case DRDAConstants.DB2_SQLTYPE_SMALL:
592             case DRDAConstants.DB2_SQLTYPE_NSMALL:
593                 return "SMALLINT";
594             case DRDAConstants.DB2_SQLTYPE_NUMERIC:
595             case DRDAConstants.DB2_SQLTYPE_NNUMERIC:
596                 return "NUMERIC";
597             default:
598                 throw new SqlException(logWriter_,
599                         new ClientMessageId (SQLState.UNSUPPORTED_TYPE));
600             }
601         }
602         catch ( SqlException e )
603         {
604             throw e.getSQLException();
605         }
606     }
607
608     public boolean isReadOnly(int column) throws SQLException JavaDoc {
609         try
610         {
611             checkForClosedStatement();
612             checkForValidColumnIndex(column);
613             if (sqlxUpdatable_ == null) {
614                 return (resultSetConcurrency_ == java.sql.ResultSet.CONCUR_READ_ONLY); // If no extended describe, return resultSet's concurrecnty
615
}
616             return sqlxUpdatable_[column - 1] == 0; // PROTOCOL 0 means not updatable, 1 means updatable
617
}
618         catch ( SqlException e )
619         {
620             throw e.getSQLException();
621         }
622     }
623
624     public boolean isWritable(int column) throws SQLException JavaDoc {
625         try
626         {
627             checkForClosedStatement();
628             checkForValidColumnIndex(column);
629             if (sqlxUpdatable_ == null) {
630                 return (resultSetConcurrency_ == java.sql.ResultSet.CONCUR_UPDATABLE); // If no extended describe, return resultSet's concurrency
631
}
632             return sqlxUpdatable_[column - 1] == 1; // PROTOCOL 0 means not updatable, 1 means updatable
633
}
634         catch ( SqlException e )
635         {
636             throw e.getSQLException();
637         }
638     }
639
640     public boolean isDefinitelyWritable(int column) throws SQLException JavaDoc {
641         try
642         {
643             checkForClosedStatement();
644             checkForValidColumnIndex(column);
645             if (sqlxUpdatable_ == null) {
646                 return false;
647             }
648             return sqlxUpdatable_[column - 1] == 1; // PROTOCOL 0 means not updatable, 1 means updatable
649
}
650         catch ( SqlException e )
651         {
652             throw e.getSQLException();
653         }
654     }
655
656     //--------------------------jdbc 2.0-----------------------------------
657

658     public String JavaDoc getColumnClassName(int column) throws SQLException JavaDoc {
659         try
660         {
661             checkForClosedStatement();
662             checkForValidColumnIndex(column);
663
664             int jdbcType = types_[column - 1];
665             switch (jdbcType) {
666             case java.sql.Types.BIT:
667                 return "java.lang.Boolean";
668             case java.sql.Types.TINYINT:
669                 return "java.lang.Integer";
670             case Types.SMALLINT:
671                 return "java.lang.Integer";
672             case Types.INTEGER:
673                 return "java.lang.Integer";
674             case Types.BIGINT:
675                 return "java.lang.Long";
676             case java.sql.Types.FLOAT:
677                 return "java.lang.Double";
678             case Types.REAL:
679                 return "java.lang.Float";
680             case Types.DOUBLE:
681                 return "java.lang.Double";
682             case java.sql.Types.NUMERIC:
683             case Types.DECIMAL:
684                 return "java.math.BigDecimal";
685             case Types.CHAR:
686             case Types.VARCHAR:
687             case Types.LONGVARCHAR:
688                 return "java.lang.String";
689             case Types.DATE:
690                 return "java.sql.Date";
691             case Types.TIME:
692                 return "java.sql.Time";
693             case Types.TIMESTAMP:
694                 return "java.sql.Timestamp";
695             case Types.BINARY:
696             case Types.VARBINARY:
697             case Types.LONGVARBINARY:
698                 return "byte[]";
699             case java.sql.Types.STRUCT:
700                 return "java.sql.Struct";
701             case java.sql.Types.ARRAY:
702                 return "java.sql.Array";
703             case Types.BLOB:
704                 return "java.sql.Blob";
705             case Types.CLOB:
706                 return "java.sql.Clob";
707             case java.sql.Types.REF:
708                 return "java.sql.Ref";
709             default:
710                 throw new SqlException(logWriter_,
711                         new ClientMessageId (SQLState.UNSUPPORTED_TYPE));
712             }
713         }
714         catch ( SqlException e )
715         {
716             throw e.getSQLException();
717         }
718     }
719
720     //----------------------------helper methods----------------------------------
721

722
723     void checkForValidColumnIndex(int column) throws SqlException {
724         if (column < 1 || column > columns_) {
725             throw new SqlException(logWriter_,
726                     new ClientMessageId (SQLState.LANG_INVALID_COLUMN_POSITION),
727                     new Integer JavaDoc (column), new Integer JavaDoc(columns_));
728         }
729     }
730
731     // If the input parameter has been set, return true, else return false.
732
private boolean isParameterModeGuessedAsAnInput(int parameterIndex) {
733         if (sqlxParmmode_[parameterIndex - 1] == java.sql.ParameterMetaData.parameterModeIn ||
734                 sqlxParmmode_[parameterIndex - 1] == java.sql.ParameterMetaData.parameterModeInOut) {
735             return true;
736         }
737         return false;
738     }
739
740     // Does OUT parm registration rely on extended describe?
741
// If the output parameter has been registered, return true, else return false.
742
public boolean isParameterModeGuessedAsOutput(int parameterIndex) {
743         return sqlxParmmode_[parameterIndex - 1] >= java.sql.ParameterMetaData.parameterModeInOut;
744     }
745
746     /** This method does not appear to be in use -- davidvc@apache.org
747     // Only called when column meta data is not described. Called by setXXX methods.
748     public void guessInputParameterMetaData(int parameterIndex,
749                                             int jdbcType) throws SqlException {
750         guessInputParameterMetaData(parameterIndex, jdbcType, 0);
751     }
752      */

753
754     private void setParmModeForInputParameter(int parameterIndex) {
755         if (sqlxParmmode_[parameterIndex - 1] == java.sql.ParameterMetaData.parameterModeOut) {
756             sqlxParmmode_[parameterIndex - 1] = java.sql.ParameterMetaData.parameterModeInOut;
757         } else if (sqlxParmmode_[parameterIndex - 1] == java.sql.ParameterMetaData.parameterModeUnknown) {
758             sqlxParmmode_[parameterIndex - 1] = java.sql.ParameterMetaData.parameterModeIn;
759         }
760     }
761
762
763     private void setParmModeForOutputParameter(int parameterIndex) {
764         if (sqlxParmmode_[parameterIndex - 1] == java.sql.ParameterMetaData.parameterModeIn) {
765             sqlxParmmode_[parameterIndex - 1] = java.sql.ParameterMetaData.parameterModeInOut;
766         } else if (sqlxParmmode_[parameterIndex - 1] == java.sql.ParameterMetaData.parameterModeUnknown) {
767             sqlxParmmode_[parameterIndex - 1] = java.sql.ParameterMetaData.parameterModeOut;
768         }
769     }
770
771     private boolean isCompatibleDriverTypes(int registeredType, int guessedInputType) {
772         switch (registeredType) {
773         case Types.CHAR:
774         case Types.VARCHAR:
775         case Types.LONGVARCHAR:
776             return guessedInputType == Types.CHAR || guessedInputType == Types.VARCHAR || guessedInputType == Types.LONGVARCHAR;
777         case Types.BINARY:
778         case Types.VARBINARY:
779         case Types.LONGVARBINARY:
780             return guessedInputType == Types.BINARY || guessedInputType == Types.VARBINARY || guessedInputType == Types.LONGVARBINARY;
781         default:
782             return registeredType == guessedInputType;
783         }
784     }
785
786     // Only used when describe information is not available.
787
private int getInternalTypeForGuessedOrRegisteredJdbcType(int guessedOrRegisteredJdbcType) throws SqlException {
788         switch (guessedOrRegisteredJdbcType) {
789         case java.sql.Types.BIT:
790         case java.sql.Types.TINYINT:
791         case java.sql.Types.SMALLINT:
792             return Types.SMALLINT;
793         case java.sql.Types.INTEGER:
794             return Types.INTEGER;
795         case java.sql.Types.BIGINT:
796             return Types.BIGINT;
797         case java.sql.Types.REAL:
798             return Types.REAL;
799         case java.sql.Types.DOUBLE:
800         case java.sql.Types.FLOAT:
801             return Types.DOUBLE;
802         case java.sql.Types.DECIMAL:
803         case java.sql.Types.NUMERIC:
804             return Types.DECIMAL;
805         case java.sql.Types.DATE:
806             return Types.DATE;
807         case java.sql.Types.TIME:
808             return Types.TIME;
809         case java.sql.Types.TIMESTAMP:
810             return Types.TIMESTAMP;
811         case java.sql.Types.CHAR:
812             return Types.CHAR;
813         case java.sql.Types.VARCHAR:
814             return Types.VARCHAR;
815         case java.sql.Types.LONGVARCHAR:
816             return Types.LONGVARCHAR;
817         case java.sql.Types.BINARY:
818             return Types.BINARY;
819         case java.sql.Types.VARBINARY:
820             return Types.VARBINARY;
821         case java.sql.Types.LONGVARBINARY:
822             return Types.LONGVARBINARY;
823         case java.sql.Types.BLOB:
824             return Types.BLOB;
825         case java.sql.Types.CLOB:
826             return Types.CLOB;
827         case java.sql.Types.NULL:
828         case java.sql.Types.OTHER:
829             throw new SqlException(logWriter_,
830                     new ClientMessageId (SQLState.UNSUPPORTED_TYPE));
831         default:
832             throw new SqlException(logWriter_,
833                     new ClientMessageId (SQLState.UNSUPPORTED_TYPE));
834         }
835     }
836
837     public void setLogWriter(LogWriter logWriter) {
838         logWriter_ = logWriter;
839     }
840
841     private void nullDataForGC() {
842         columns_ = 0;
843         nullable_ = null;
844         types_ = null;
845         singleMixedByteOrDouble_ = null;
846         sqldRdbnam_ = null;
847         sqldSchema_ = null;
848         sqlPrecision_ = null;
849         sqlScale_ = null;
850         sqlLength_ = null;
851         sqlType_ = null;
852         sqlCcsid_ = null;
853         sqlName_ = null;
854         sqlLabel_ = null;
855         sqlUnnamed_ = null;
856         sqlComment_ = null;
857         sqlxKeymem_ = null;
858         sqlxGenerated_ = null;
859         sqlxParmmode_ = null;
860         sqlxCorname_ = null;
861         sqlxName_ = null;
862         sqlxBasename_ = null;
863         sqlxUpdatable_ = null;
864         sqlxSchema_ = null;
865         sqlxRdbnam_ = null;
866         clientParamtertype_ = null;
867         types_ = null;
868     }
869
870     public boolean hasLobColumns() {
871         for (int i = 0; i < columns_; i++) {
872             switch (org.apache.derby.client.am.Utils.getNonNullableSqlType(sqlType_[i])) {
873             case DRDAConstants.DB2_SQLTYPE_BLOB:
874             case DRDAConstants.DB2_SQLTYPE_CLOB:
875                 return true;
876             default:
877                 break;
878             }
879         }
880         return false;
881     }
882
883     // Cache the hashtable in ColumnMetaData.
884
int findColumnX(String JavaDoc columnName) throws SqlException {
885         // Create cache if it doesn't exist
886
if (columnNameToIndexCache_ == null) {
887             columnNameToIndexCache_ = new java.util.Hashtable JavaDoc();
888         } else { // Check cache for mapping
889
Integer JavaDoc index = (Integer JavaDoc) columnNameToIndexCache_.get(columnName);
890             if (index != null) {
891                 return index.intValue();
892             }
893         }
894
895         // Ok, we'll have to search the metadata
896
for (int col = 0; col < this.columns_; col++) {
897             if (this.sqlName_ != null && // sqlName comes from an optional group
898
this.sqlName_[col] != null &&
899                     this.sqlName_[col].equalsIgnoreCase(columnName)) {
900                 // Found it, add it to the cache
901
columnNameToIndexCache_.put(columnName, new Integer JavaDoc(col + 1));
902                 return col + 1;
903             }
904         }
905         throw new SqlException(logWriter_,
906                 new ClientMessageId (SQLState.INVALID_COLUMN_NAME), columnName);
907     }
908
909     // assign ordinal position as the column name if null.
910
void assignColumnName(int column) {
911         if (columnNameToIndexCache_ == null) {
912             columnNameToIndexCache_ = new java.util.Hashtable JavaDoc();
913         }
914         String JavaDoc columnName = (new Integer JavaDoc(column)).toString();
915         columnNameToIndexCache_.put(columnName, new Integer JavaDoc(column));
916         sqlName_[column - 1] = columnName;
917     }
918
919     public boolean columnIsNotInUnicode(int index) {
920         return (sqlCcsid_[index] != 1208);
921     }
922
923 }
924
Popular Tags