001: /*
002:
003: Derby - Class org.apache.derby.impl.jdbc.EmbedResultSetMetaData
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.jdbc;
023:
024: import org.apache.derby.iapi.sql.ResultDescription;
025: import org.apache.derby.iapi.sql.ResultColumnDescriptor;
026: import org.apache.derby.iapi.types.DataTypeDescriptor;
027: import org.apache.derby.iapi.types.DataTypeUtilities;
028: import org.apache.derby.iapi.types.TypeId;
029:
030: import org.apache.derby.iapi.services.sanity.SanityManager;
031:
032: import org.apache.derby.iapi.reference.SQLState;
033:
034: import java.sql.ResultSetMetaData;
035: import java.sql.SQLException;
036: import java.sql.Types;
037: import java.sql.ResultSet;
038:
039: /**
040: * A ResultSetMetaData object can be used to find out about the types
041: * and properties of the columns in a ResultSet.
042: *
043: * <p>
044: * We take the (cloudscape) ResultDescription and examine it, to return
045: * the appropriate information.
046:
047: <P>
048: This class can be used outside of this package to convert a
049: ResultDescription into a ResultSetMetaData object.
050: *
051: * @author ames
052: */
053: public class EmbedResultSetMetaData implements ResultSetMetaData {
054:
055: private final ResultColumnDescriptor[] columnInfo;
056:
057: //
058: // constructor
059: //
060: public EmbedResultSetMetaData(ResultColumnDescriptor[] columnInfo) {
061: this .columnInfo = columnInfo;
062: }
063:
064: //
065: // ResultSetMetaData interface
066: //
067:
068: /**
069: * What's the number of columns in the ResultSet?
070: *
071: * @return the number
072: */
073: public int getColumnCount() {
074: return columnInfo == null ? 0 : columnInfo.length;
075: }
076:
077: /**
078: * Is the column automatically numbered, thus read-only?
079: *
080: * @param column the first column is 1, the second is 2, ...
081: * @return true if so
082: * @exception SQLException thrown on failure
083: *
084: */
085: public boolean isAutoIncrement(int column) throws SQLException {
086:
087: ResultColumnDescriptor rcd = columnInfo[column - 1];
088: return rcd.isAutoincrement();
089: }
090:
091: /**
092: * Does a column's case matter?
093: *
094: * @param column the first column is 1, the second is 2, ...
095: * @return true if so
096: * @exception SQLException thrown on failure
097: */
098: public boolean isCaseSensitive(int column) throws SQLException {
099: return DataTypeUtilities
100: .isCaseSensitive(getColumnTypeDescriptor(column));
101: }
102:
103: /**
104: * Can the column be used in a where clause?
105: *
106: * @param column the first column is 1, the second is 2, ...
107: * @return true if so
108: * @exception SQLException thrown on failure
109: */
110: public boolean isSearchable(int column) throws SQLException {
111: validColumnNumber(column);
112:
113: // we have no restrictions yet, so this is always true
114: // might eventually be false for e.g. extra-long columns?
115: return true;
116: }
117:
118: /**
119: * Is the column a cash value?
120: *
121: * @param column the first column is 1, the second is 2, ...
122: * @return true if so
123: * @exception SQLException thrown on failure
124: */
125: public boolean isCurrency(int column) throws SQLException {
126:
127: return DataTypeUtilities
128: .isCurrency(getColumnTypeDescriptor(column));
129: }
130:
131: /**
132: * Can you put a NULL in this column?
133: *
134: * @param column the first column is 1, the second is 2, ...
135: * @return columnNoNulls, columnNullable or columnNullableUnknown
136: * @exception SQLException thrown on failure
137: */
138: public int isNullable(int column) throws SQLException {
139: return DataTypeUtilities
140: .isNullable(getColumnTypeDescriptor(column));
141: }
142:
143: /**
144: * Is the column a signed number?
145: *
146: * @param column the first column is 1, the second is 2, ...
147: * @return true if so
148: * @exception SQLException thrown on failure
149: */
150: public boolean isSigned(int column) throws SQLException {
151: return DataTypeUtilities
152: .isSigned(getColumnTypeDescriptor(column));
153: }
154:
155: /**
156: * What's the column's normal max width in chars?
157: *
158: * @param column the first column is 1, the second is 2, ...
159: * @return max width
160: * @exception SQLException thrown on failure
161: */
162: public int getColumnDisplaySize(int column) throws SQLException {
163: return DataTypeUtilities
164: .getColumnDisplaySize(getColumnTypeDescriptor(column));
165: }
166:
167: /**
168: * What's the suggested column title for use in printouts and
169: * displays?
170: *
171: * @param column the first column is 1, the second is 2, ...
172: * @return true if so
173: * @exception SQLException thrown on failure
174: */
175: public String getColumnLabel(int column) throws SQLException {
176: ResultColumnDescriptor cd = columnInfo[column - 1];
177: String s = cd.getName();
178:
179: // we could get fancier than this, but it's simple
180: return (s == null ? "Column" + Integer.toString(column) : s);
181: }
182:
183: /**
184: * What's a column's name?
185: *
186: * @param column the first column is 1, the second is 2, ...
187: * @return column name
188: * @exception SQLException thrown on failure
189: */
190: public String getColumnName(int column) throws SQLException {
191: ResultColumnDescriptor cd = columnInfo[column - 1];
192: String s = cd.getName();
193: // database returns null when no column name to differentiate from empty name
194: return (s == null ? "" : s);
195:
196: }
197:
198: /**
199: * What's a column's table's schema?
200: *
201: * @param column the first column is 1, the second is 2, ...
202: * @return schema name or "" if not applicable
203: * @exception SQLException thrown on failure
204: */
205: public String getSchemaName(int column) throws SQLException {
206: ResultColumnDescriptor cd = columnInfo[column - 1];
207:
208: String s = cd.getSourceSchemaName();
209: // database returns null when no schema name to differentiate from empty name
210: return (s == null ? "" : s);
211: }
212:
213: /**
214: * What's a column's number of decimal digits?
215: *
216: * @param column the first column is 1, the second is 2, ...
217: * @return precision
218: * @exception SQLException thrown on failure
219: */
220: public int getPrecision(int column) throws SQLException {
221: return DataTypeUtilities
222: .getDigitPrecision(getColumnTypeDescriptor(column));
223: }
224:
225: /**
226: * What's a column's number of digits to right of the decimal point?
227: *
228: * @param column the first column is 1, the second is 2, ...
229: * @return scale
230: * @exception SQLException thrown on failure
231: */
232: public int getScale(int column) throws SQLException {
233: DataTypeDescriptor dtd = getColumnTypeDescriptor(column);
234: // REMIND -- check it is valid to ask for scale
235: return dtd.getScale();
236: }
237:
238: /**
239: * What's a column's table name?
240: *
241: * @return table name or "" if not applicable
242: * @exception SQLException thrown on failure
243: */
244: public String getTableName(int column) throws SQLException {
245: ResultColumnDescriptor cd = columnInfo[column - 1];
246: String s = cd.getSourceTableName();
247:
248: // database returns null when no table name to differentiate from empty name
249: return (s == null ? "" : s);
250: }
251:
252: /**
253: * What's a column's table's catalog name?
254: *
255: * @param column the first column is 1, the second is 2, ...
256: * @return column name or "" if not applicable.
257: * @exception SQLException thrown on failure
258: */
259: public String getCatalogName(int column) throws SQLException {
260: validColumnNumber(column);
261: return "";
262: }
263:
264: /**
265: * What's a column's SQL type?
266: *
267: * @param column the first column is 1, the second is 2, ...
268: * @return SQL type
269: * @see Types
270: * @exception SQLException thrown on failure
271: */
272: public int getColumnType(int column) throws SQLException {
273: DataTypeDescriptor dtd = getColumnTypeDescriptor(column);
274: return dtd.getTypeId().getJDBCTypeId();
275: }
276:
277: /**
278: * What's a column's data source specific type name?
279: *
280: * @param column the first column is 1, the second is 2, ...
281: * @return type name
282: * @exception SQLException thrown on failure
283: */
284: public String getColumnTypeName(int column) throws SQLException {
285: DataTypeDescriptor dtd = getColumnTypeDescriptor(column);
286: return dtd.getTypeId().getSQLTypeName();
287: }
288:
289: /**
290: * Is a column definitely not writable?
291: *
292: * @param column the first column is 1, the second is 2, ...
293: * @return true if so
294: * @exception SQLException thrown on failure
295: */
296: public boolean isReadOnly(int column) throws SQLException {
297: validColumnNumber(column);
298:
299: // we just don't know if it is a base table column or not
300: return false;
301: }
302:
303: /**
304: * Is it possible for a write on the column to succeed?
305: *
306: * @param column the first column is 1, the second is 2, ...
307: * @return true if so
308: * @exception SQLException thrown on failure
309: */
310: public boolean isWritable(int column) throws SQLException {
311: validColumnNumber(column);
312: return columnInfo[column - 1].updatableByCursor();
313: }
314:
315: /**
316: * Will a write on the column definitely succeed?
317: *
318: * @param column the first column is 1, the second is 2, ...
319: * @return true if so
320: * @exception SQLException thrown on failure
321: */
322: public boolean isDefinitelyWritable(int column) throws SQLException {
323: validColumnNumber(column);
324:
325: // we just don't know if it is a base table column or not
326: return false;
327: }
328:
329: /*
330: * class interface
331: */
332:
333: private void validColumnNumber(int column) throws SQLException {
334: if (column < 1 || column > getColumnCount())
335: throw Util.generateCsSQLException(
336: SQLState.COLUMN_NOT_FOUND, new Integer(column));
337: }
338:
339: public DataTypeDescriptor getColumnTypeDescriptor(int column)
340: throws SQLException {
341: validColumnNumber(column);
342:
343: ResultColumnDescriptor cd = columnInfo[column - 1];
344:
345: return cd.getType();
346: }
347:
348: /////////////////////////////////////////////////////////////////////////
349: //
350: // JDBC 2.0 - New public methods
351: //
352: /////////////////////////////////////////////////////////////////////////
353:
354: /**
355: * JDBC 2.0
356: *
357: * <p>Return the fully qualified name of the Java class whose instances
358: * are manufactured if ResultSet.getObject() is called to retrieve a value
359: * from the column. ResultSet.getObject() may return a subClass of the
360: * class returned by this method.
361: *
362: * @exception SQLException Feature not inplemented for now.
363: */
364: public String getColumnClassName(int column) throws SQLException {
365:
366: return getColumnTypeDescriptor(column).getTypeId()
367: .getResultSetMetaDataTypeName();
368: }
369:
370: public static ResultColumnDescriptor getResultColumnDescriptor(
371: String name, int jdcbTypeId, boolean nullable) {
372:
373: return new org.apache.derby.impl.sql.GenericColumnDescriptor(
374: name, DataTypeDescriptor.getBuiltInDataTypeDescriptor(
375: jdcbTypeId, nullable));
376: }
377:
378: public static ResultColumnDescriptor getResultColumnDescriptor(
379: String name, int jdcbTypeId, boolean nullable, int length) {
380:
381: return new org.apache.derby.impl.sql.GenericColumnDescriptor(
382: name, DataTypeDescriptor.getBuiltInDataTypeDescriptor(
383: jdcbTypeId, nullable, length));
384: }
385:
386: public static ResultColumnDescriptor getResultColumnDescriptor(
387: String name, DataTypeDescriptor dtd) {
388: return new org.apache.derby.impl.sql.GenericColumnDescriptor(
389: name, dtd);
390: }
391: }
|