--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.jdbc.EmbedResultSetMetaData\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.jdbc;\r
+\r
+import org.apache.derby.iapi.sql.ResultDescription;\r
+import org.apache.derby.iapi.sql.ResultColumnDescriptor;\r
+import org.apache.derby.iapi.types.DataTypeDescriptor;\r
+import org.apache.derby.iapi.types.DataTypeUtilities;\r
+import org.apache.derby.iapi.types.TypeId;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+import java.sql.ResultSetMetaData;\r
+import java.sql.SQLException;\r
+import java.sql.Types;\r
+import java.sql.ResultSet;\r
+\r
+/**\r
+ * A ResultSetMetaData object can be used to find out about the types\r
+ * and properties of the columns in a ResultSet.\r
+ *\r
+ * <p>\r
+ * We take the (Derby) ResultDescription and examine it, to return\r
+ * the appropriate information.\r
+\r
+ <P>\r
+ This class can be used outside of this package to convert a\r
+ ResultDescription into a ResultSetMetaData object.\r
+ <P>\r
+ EmbedResultSetMetaData objects are shared across multiple threads\r
+ by being stored in the ResultDescription for a compiled plan.\r
+ If the required api for ResultSetMetaData ever changes so\r
+ that it has a close() method, a getConnection() method or\r
+ any other Connection or ResultSet specific method then\r
+ this sharing must be removed.\r
+ *\r
+ */\r
+public class EmbedResultSetMetaData\r
+ implements ResultSetMetaData {\r
+\r
+ private final ResultColumnDescriptor[] columnInfo;\r
+\r
+ //\r
+ // constructor\r
+ //\r
+ public EmbedResultSetMetaData(ResultColumnDescriptor[] columnInfo) {\r
+ this.columnInfo = columnInfo;\r
+ }\r
+\r
+ //\r
+ // ResultSetMetaData interface\r
+ //\r
+\r
+ /**\r
+ * What's the number of columns in the ResultSet?\r
+ *\r
+ * @return the number\r
+ */\r
+ public final int getColumnCount() {\r
+ return columnInfo.length;\r
+ }\r
+\r
+ /**\r
+ * Is the column automatically numbered, thus read-only?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return true if so\r
+ * @exception SQLException thrown on failure\r
+ *\r
+ */\r
+ public final boolean isAutoIncrement(int column) throws SQLException {\r
+ validColumnNumber(column);\r
+ ResultColumnDescriptor rcd = columnInfo[column - 1];\r
+ return rcd.isAutoincrement();\r
+ }\r
+\r
+ /**\r
+ * Does a column's case matter?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return true if so\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final boolean isCaseSensitive(int column) throws SQLException {\r
+ return DataTypeUtilities.isCaseSensitive(getColumnTypeDescriptor(column));\r
+ }\r
+\r
+\r
+ /**\r
+ * Can the column be used in a where clause?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return true if so\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final boolean isSearchable(int column) throws SQLException {\r
+ validColumnNumber(column);\r
+\r
+ // we have no restrictions yet, so this is always true\r
+ // might eventually be false for e.g. extra-long columns?\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Is the column a cash value?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return true if so\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final boolean isCurrency(int column) throws SQLException {\r
+\r
+ return DataTypeUtilities.isCurrency(getColumnTypeDescriptor(column));\r
+ }\r
+\r
+ /**\r
+ * Can you put a NULL in this column?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return columnNoNulls, columnNullable or columnNullableUnknown\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final int isNullable(int column) throws SQLException {\r
+ return DataTypeUtilities.isNullable(getColumnTypeDescriptor(column));\r
+ }\r
+\r
+ /**\r
+ * Is the column a signed number?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return true if so\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final boolean isSigned(int column) throws SQLException {\r
+ return DataTypeUtilities.isSigned(getColumnTypeDescriptor(column));\r
+ }\r
+\r
+\r
+ /**\r
+ * What's the column's normal max width in chars?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return max width\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final int getColumnDisplaySize(int column) throws SQLException {\r
+ return DataTypeUtilities.getColumnDisplaySize(getColumnTypeDescriptor(column));\r
+ }\r
+\r
+ /**\r
+ * What's the suggested column title for use in printouts and\r
+ * displays?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return true if so\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final String getColumnLabel(int column) throws SQLException {\r
+ ResultColumnDescriptor cd = columnInfo[column - 1];\r
+ String s = cd.getName();\r
+\r
+ // we could get fancier than this, but it's simple\r
+ return (s==null? "Column"+Integer.toString(column) : s);\r
+ }\r
+\r
+\r
+ /**\r
+ * What's a column's name?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return column name\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final String getColumnName(int column) throws SQLException {\r
+ ResultColumnDescriptor cd = columnInfo[column - 1];\r
+ String s = cd.getName();\r
+ // database returns null when no column name to differentiate from empty name\r
+ return (s==null? "" : s);\r
+\r
+ }\r
+\r
+\r
+ /**\r
+ * What's a column's table's schema?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return schema name or "" if not applicable\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final String getSchemaName(int column) throws SQLException {\r
+ ResultColumnDescriptor cd = columnInfo[column - 1];\r
+\r
+ String s = cd.getSourceSchemaName();\r
+ // database returns null when no schema name to differentiate from empty name\r
+ return (s==null? "" : s);\r
+ }\r
+\r
+ /**\r
+ * What's a column's number of decimal digits?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return precision\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final int getPrecision(int column) throws SQLException {\r
+ return DataTypeUtilities.getDigitPrecision(getColumnTypeDescriptor(column));\r
+ }\r
+\r
+\r
+ /**\r
+ * What's a column's number of digits to right of the decimal point?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return scale\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final int getScale(int column) throws SQLException {\r
+ DataTypeDescriptor dtd = getColumnTypeDescriptor(column);\r
+ // REMIND -- check it is valid to ask for scale\r
+ return dtd.getScale();\r
+ }\r
+\r
+ /**\r
+ * What's a column's table name?\r
+ *\r
+ * @return table name or "" if not applicable\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final String getTableName(int column) throws SQLException {\r
+ ResultColumnDescriptor cd = columnInfo[column - 1];\r
+ String s = cd.getSourceTableName();\r
+\r
+ // database returns null when no table name to differentiate from empty name\r
+ return (s==null? "" : s);\r
+ }\r
+\r
+ /**\r
+ * What's a column's table's catalog name?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return column name or "" if not applicable.\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final String getCatalogName(int column) throws SQLException {\r
+ validColumnNumber(column);\r
+ return "";\r
+ }\r
+\r
+ /**\r
+ * What's a column's SQL type?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return SQL type\r
+ * @see Types\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final int getColumnType(int column) throws SQLException {\r
+ DataTypeDescriptor dtd = getColumnTypeDescriptor(column);\r
+ return dtd.getTypeId().getJDBCTypeId();\r
+ }\r
+\r
+ /**\r
+ * What's a column's data source specific type name?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return type name\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final String getColumnTypeName(int column) throws SQLException {\r
+ DataTypeDescriptor dtd = getColumnTypeDescriptor(column);\r
+ return dtd.getTypeId().getSQLTypeName();\r
+ }\r
+\r
+ /**\r
+ * Is a column definitely not writable?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return true if so\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final boolean isReadOnly(int column) throws SQLException {\r
+ validColumnNumber(column);\r
+\r
+ // we just don't know if it is a base table column or not\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Is it possible for a write on the column to succeed?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return true if so\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final boolean isWritable(int column) throws SQLException {\r
+ validColumnNumber(column);\r
+ return columnInfo[column - 1].updatableByCursor();\r
+ }\r
+\r
+ /**\r
+ * Will a write on the column definitely succeed?\r
+ *\r
+ * @param column the first column is 1, the second is 2, ...\r
+ * @return true if so\r
+ * @exception SQLException thrown on failure\r
+ */\r
+ public final boolean isDefinitelyWritable(int column) throws SQLException {\r
+ validColumnNumber(column);\r
+\r
+ // we just don't know if it is a base table column or not\r
+ return false;\r
+ }\r
+\r
+ /*\r
+ * class interface\r
+ */\r
+\r
+ private void validColumnNumber(int column) throws SQLException {\r
+ if (column < 1 ||\r
+ column > getColumnCount() )\r
+ throw Util.generateCsSQLException(\r
+ SQLState.COLUMN_NOT_FOUND, new Integer(column));\r
+ }\r
+\r
+ private DataTypeDescriptor getColumnTypeDescriptor(int column) throws SQLException \r
+ {\r
+ validColumnNumber(column);\r
+\r
+ ResultColumnDescriptor cd = columnInfo[column - 1];\r
+\r
+ return cd.getType();\r
+ }\r
+\r
+ /////////////////////////////////////////////////////////////////////////\r
+ //\r
+ // JDBC 2.0 - New public methods\r
+ //\r
+ /////////////////////////////////////////////////////////////////////////\r
+\r
+ /**\r
+ * JDBC 2.0\r
+ *\r
+ * <p>Return the fully qualified name of the Java class whose instances \r
+ * are manufactured if ResultSet.getObject() is called to retrieve a value \r
+ * from the column. ResultSet.getObject() may return a subClass of the\r
+ * class returned by this method.\r
+ *\r
+ * @exception SQLException Feature not inplemented for now.\r
+ */\r
+ public final String getColumnClassName(int column) throws SQLException {\r
+ \r
+ return getColumnTypeDescriptor(column).getTypeId().getResultSetMetaDataTypeName();\r
+ }\r
+\r
+\r
+ public static ResultColumnDescriptor getResultColumnDescriptor(String name, int jdcbTypeId, boolean nullable) {\r
+\r
+ return new org.apache.derby.impl.sql.GenericColumnDescriptor(\r
+ name, DataTypeDescriptor.getBuiltInDataTypeDescriptor(jdcbTypeId, nullable));\r
+ }\r
+ public static ResultColumnDescriptor getResultColumnDescriptor(String name, int jdcbTypeId, boolean nullable, int length) {\r
+\r
+ return new org.apache.derby.impl.sql.GenericColumnDescriptor(\r
+ name, DataTypeDescriptor.getBuiltInDataTypeDescriptor(jdcbTypeId, nullable, length));\r
+ }\r
+ public static ResultColumnDescriptor getResultColumnDescriptor(String name, DataTypeDescriptor dtd) {\r
+ return new org.apache.derby.impl.sql.GenericColumnDescriptor(name, dtd);\r
+ }\r
+\r
+ public boolean isWrapperFor(Class<?> iface) throws SQLException {\r
+ // TODO Auto-generated method stub\r
+ return false;\r
+ }\r
+\r
+ public <T> T unwrap(Class<T> iface) throws SQLException {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+}\r