001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.jdbc;
007:
008: import java.sql.ResultSetMetaData;
009: import java.sql.SQLException;
010:
011: import org.h2.message.Message;
012: import org.h2.message.Trace;
013: import org.h2.message.TraceObject;
014: import org.h2.result.ResultInterface;
015: import org.h2.util.MathUtils;
016: import org.h2.value.DataType;
017:
018: /**
019: * Represents the meta data for a ResultSet.
020: */
021: public class JdbcResultSetMetaData extends TraceObject implements
022: ResultSetMetaData {
023:
024: private final String catalog;
025: private final JdbcResultSet rs;
026: private final JdbcPreparedStatement prep;
027: private final ResultInterface result;
028: private final int columnCount;
029:
030: JdbcResultSetMetaData(JdbcResultSet rs, JdbcPreparedStatement prep,
031: ResultInterface result, String catalog, Trace trace, int id) {
032: setTrace(trace, TraceObject.RESULT_SET_META_DATA, id);
033: this .catalog = catalog;
034: this .rs = rs;
035: this .prep = prep;
036: this .result = result;
037: this .columnCount = result.getVisibleColumnCount();
038: }
039:
040: /**
041: * Returns the number of columns.
042: *
043: * @return the number of columns
044: * @throws SQLException if the result set is closed or invalid
045: */
046: public int getColumnCount() throws SQLException {
047: try {
048: debugCodeCall("getColumnCount");
049: checkClosed();
050: return columnCount;
051: } catch (Throwable e) {
052: throw logAndConvert(e);
053: }
054: }
055:
056: /**
057: * Returns the column label.
058: *
059: * @param column the column index (1,2,...)
060: * @return the column label
061: * @throws SQLException if the result set is closed or invalid
062: */
063: public String getColumnLabel(int column) throws SQLException {
064: try {
065: debugCodeCall("getColumnLabel", column);
066: checkColumnIndex(column);
067: return result.getAlias(--column);
068: } catch (Throwable e) {
069: throw logAndConvert(e);
070: }
071: }
072:
073: /**
074: * Returns the column name.
075: *
076: * @param column the column index (1,2,...)
077: * @return the column name
078: * @throws SQLException if the result set is closed or invalid
079: */
080: public String getColumnName(int column) throws SQLException {
081: try {
082: debugCodeCall("getColumnName", column);
083: checkColumnIndex(column);
084: return result.getColumnName(--column);
085: } catch (Throwable e) {
086: throw logAndConvert(e);
087: }
088: }
089:
090: /**
091: * Returns the data type of a column.
092: *
093: * @param column the column index (1,2,...)
094: * @return the data type
095: * @throws SQLException if the result set is closed or invalid
096: */
097: public int getColumnType(int column) throws SQLException {
098: try {
099: debugCodeCall("getColumnType", column);
100: checkColumnIndex(column);
101: int type = result.getColumnType(--column);
102: return DataType.convertTypeToSQLType(type);
103: } catch (Throwable e) {
104: throw logAndConvert(e);
105: }
106: }
107:
108: /**
109: * Returns the data type name of a column.
110: *
111: * @param column the column index (1,2,...)
112: * @return the data type
113: * @throws SQLException if the result set is closed or invalid
114: */
115: public String getColumnTypeName(int column) throws SQLException {
116: try {
117: debugCodeCall("getColumnTypeName", column);
118: checkColumnIndex(column);
119: int type = result.getColumnType(--column);
120: return DataType.getDataType(type).name;
121: } catch (Throwable e) {
122: throw logAndConvert(e);
123: }
124: }
125:
126: /**
127: * Returns the schema name.
128: *
129: * @param column the column index (1,2,...)
130: * @return the schema name
131: * @throws SQLException if the result set is closed or invalid
132: */
133: public String getSchemaName(int column) throws SQLException {
134: try {
135: debugCodeCall("getSchemaName", column);
136: checkColumnIndex(column);
137: return result.getSchemaName(--column);
138: } catch (Throwable e) {
139: throw logAndConvert(e);
140: }
141: }
142:
143: /**
144: * Returns the table name.
145: *
146: * @param column the column index (1,2,...)
147: * @return the table name
148: * @throws SQLException if the result set is closed or invalid
149: */
150: public String getTableName(int column) throws SQLException {
151: try {
152: debugCodeCall("getTableName", column);
153: checkColumnIndex(column);
154: return result.getTableName(--column);
155: } catch (Throwable e) {
156: throw logAndConvert(e);
157: }
158: }
159:
160: /**
161: * Returns the catalog name.
162: *
163: * @param column the column index (1,2,...)
164: * @return the catalog name
165: * @throws SQLException if the result set is closed or invalid
166: */
167: public String getCatalogName(int column) throws SQLException {
168: try {
169: debugCodeCall("getCatalogName", column);
170: checkColumnIndex(column);
171: return catalog;
172: } catch (Throwable e) {
173: throw logAndConvert(e);
174: }
175: }
176:
177: /**
178: * Checks if this an autoincrement column.
179: * It always returns false.
180: *
181: * @param column the column index (1,2,...)
182: * @return false
183: * @throws SQLException if the result set is closed or invalid
184: */
185: public boolean isAutoIncrement(int column) throws SQLException {
186: try {
187: debugCodeCall("isAutoIncrement", column);
188: checkColumnIndex(column);
189: return result.isAutoIncrement(--column);
190: } catch (Throwable e) {
191: throw logAndConvert(e);
192: }
193: }
194:
195: /**
196: * Checks if this column is case sensitive.
197: * It always returns true.
198: *
199: * @param column the column index (1,2,...)
200: * @return true
201: * @throws SQLException if the result set is closed or invalid
202: */
203: public boolean isCaseSensitive(int column) throws SQLException {
204: try {
205: debugCodeCall("isCaseSensitive", column);
206: checkColumnIndex(column);
207: return true;
208: } catch (Throwable e) {
209: throw logAndConvert(e);
210: }
211: }
212:
213: /**
214: * Checks if this column is searchable.
215: * It always returns true.
216: *
217: * @param column the column index (1,2,...)
218: * @return true
219: * @throws SQLException if the result set is closed or invalid
220: */
221: public boolean isSearchable(int column) throws SQLException {
222: try {
223: debugCodeCall("isSearchable", column);
224: checkColumnIndex(column);
225: return true;
226: } catch (Throwable e) {
227: throw logAndConvert(e);
228: }
229: }
230:
231: /**
232: * Checks if this is a currency column.
233: * It always returns false.
234: *
235: * @param column the column index (1,2,...)
236: * @return false
237: * @throws SQLException if the result set is closed or invalid
238: */
239: public boolean isCurrency(int column) throws SQLException {
240: try {
241: debugCodeCall("isCurrency", column);
242: checkColumnIndex(column);
243: return false;
244: } catch (Throwable e) {
245: throw logAndConvert(e);
246: }
247: }
248:
249: /**
250: * Checks if this is nullable column. Returns
251: * ResultSetMetaData.columnNullableUnknown if this is not a column of a
252: * table. Otherwise, it returns ResultSetMetaData.columnNoNulls if the
253: * column is not nullable, and ResultSetMetaData.columnNullable if it is
254: * nullable.
255: *
256: * @param column the column index (1,2,...)
257: * @return ResultSetMetaData.column*
258: * @throws SQLException if the result set is closed or invalid
259: */
260: public int isNullable(int column) throws SQLException {
261: try {
262: debugCodeCall("isNullable", column);
263: checkColumnIndex(column);
264: return result.getNullable(--column);
265: } catch (Throwable e) {
266: throw logAndConvert(e);
267: }
268: }
269:
270: /**
271: * Checks if this column is signed.
272: * It always returns true.
273: *
274: * @param column the column index (1,2,...)
275: * @return true
276: * @throws SQLException if the result set is closed or invalid
277: */
278: public boolean isSigned(int column) throws SQLException {
279: try {
280: debugCodeCall("isSigned", column);
281: checkColumnIndex(column);
282: return true;
283: } catch (Throwable e) {
284: throw logAndConvert(e);
285: }
286: }
287:
288: /**
289: * Checks if this column is read only.
290: * It always returns false.
291: *
292: * @param column the column index (1,2,...)
293: * @return false
294: * @throws SQLException if the result set is closed or invalid
295: */
296: public boolean isReadOnly(int column) throws SQLException {
297: try {
298: debugCodeCall("isReadOnly", column);
299: checkColumnIndex(column);
300: return false;
301: } catch (Throwable e) {
302: throw logAndConvert(e);
303: }
304: }
305:
306: /**
307: * Checks whether it is possible for a write on this column to succeed.
308: * It always returns true.
309: *
310: * @param column the column index (1,2,...)
311: * @return true
312: * @throws SQLException if the result set is closed or invalid
313: */
314: public boolean isWritable(int column) throws SQLException {
315: try {
316: debugCodeCall("isWritable", column);
317: checkColumnIndex(column);
318: return true;
319: } catch (Throwable e) {
320: throw logAndConvert(e);
321: }
322: }
323:
324: /**
325: * Checks whether a write on this column will definitely succeed.
326: * It always returns false.
327: *
328: * @param column the column index (1,2,...)
329: * @return false
330: * @throws SQLException if the result set is closed or invalid
331: */
332: public boolean isDefinitelyWritable(int column) throws SQLException {
333: try {
334: debugCodeCall("isDefinitelyWritable", column);
335: checkColumnIndex(column);
336: return false;
337: } catch (Throwable e) {
338: throw logAndConvert(e);
339: }
340: }
341:
342: /**
343: * Gets the Java class name of the object that will be returned
344: * if ResultSet.getObject is called.
345: *
346: * @param column the column index (1,2,...)
347: * @return the Java class name
348: * @throws SQLException if the result set is closed or invalid
349: */
350: public String getColumnClassName(int column) throws SQLException {
351: try {
352: debugCodeCall("getColumnClassName", column);
353: checkColumnIndex(column);
354: int type = result.getColumnType(--column);
355: return DataType.getTypeClassName(type);
356: } catch (Throwable e) {
357: throw logAndConvert(e);
358: }
359: }
360:
361: /**
362: * Gets the precision for this column.
363: * This method always returns 0.
364: *
365: * @param column the column index (1,2,...)
366: * @return the precision
367: * @throws SQLException if the result set is closed or invalid
368: */
369: public int getPrecision(int column) throws SQLException {
370: try {
371: debugCodeCall("getPrecision", column);
372: checkColumnIndex(column);
373: long prec = result.getColumnPrecision(--column);
374: return MathUtils.convertLongToInt(prec);
375: } catch (Throwable e) {
376: throw logAndConvert(e);
377: }
378: }
379:
380: /**
381: * Gets the scale for this column.
382: * This method always returns 0.
383: *
384: * @param column the column index (1,2,...)
385: * @return the scale
386: * @throws SQLException if the result set is closed or invalid
387: */
388: public int getScale(int column) throws SQLException {
389: try {
390: debugCodeCall("getScale", column);
391: checkColumnIndex(column);
392: return result.getColumnScale(--column);
393: } catch (Throwable e) {
394: throw logAndConvert(e);
395: }
396: }
397:
398: /**
399: * Gets the maximum display size for this column.
400: *
401: * @param column the column index (1,2,...)
402: * @return the display size
403: * @throws SQLException if the result set is closed or invalid
404: */
405: public int getColumnDisplaySize(int column) throws SQLException {
406: try {
407: debugCodeCall("getColumnDisplaySize", column);
408: checkColumnIndex(column);
409: return result.getDisplaySize(--column);
410: } catch (Throwable e) {
411: throw logAndConvert(e);
412: }
413: }
414:
415: private void checkClosed() throws SQLException {
416: if (rs != null) {
417: rs.checkClosed();
418: }
419: if (prep != null) {
420: prep.checkClosed();
421: }
422: }
423:
424: private void checkColumnIndex(int columnIndex) throws SQLException {
425: checkClosed();
426: if (columnIndex < 1 || columnIndex > columnCount) {
427: throw Message.getInvalidValueException("" + columnIndex,
428: "columnIndex");
429: }
430: }
431:
432: /**
433: * [Not supported] Return an object of this class if possible.
434: */
435: //#ifdef JDK16
436: /*
437: public <T> T unwrap(Class<T> iface) throws SQLException {
438: debugCodeCall("unwrap");
439: throw Message.getUnsupportedException();
440: }
441: */
442: //#endif
443: /**
444: * [Not supported] Checks if unwrap can return an object of this class.
445: */
446: //#ifdef JDK16
447: /*
448: public boolean isWrapperFor(Class< ? > iface) throws SQLException {
449: debugCodeCall("isWrapperFor");
450: throw Message.getUnsupportedException();
451: }
452: */
453: //#endif
454: /**
455: * INTERNAL
456: */
457: public String toString() {
458: return getTraceObjectName() + ": columns=" + columnCount;
459: }
460:
461: }
|