/* * Copyright (c) 2004, 2005, 2006 TADA AB - Taby Sweden * Distributed under the terms shown in the file COPYRIGHT * found in the root folder of this project or at * http://eng.tada.se/osprojects/COPYRIGHT.html */ package org.postgresql.pljava.jdbc; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Connection; import java.sql.DriverManager; import org.postgresql.pljava.internal.Oid; /** * Implementation of ResultSetMetaData for SyntheticResultSet * * @author Filip Hrbek */ public abstract class AbstractResultSetMetaData implements ResultSetMetaData { private Connection m_conn; /** * Constructor. */ public AbstractResultSetMetaData() { m_conn = null; } /** * Returns the number of columns in this <code>ResultSet</code> object. * * @return the number of columns * @exception SQLException if a database access error occurs */ public abstract int getColumnCount() throws SQLException; /** * Indicates whether the designated column is automatically numbered, thus read-only. * * @param column the first column is 1, the second is 2, ... * @return <code>true</code> if so; <code>false</code> otherwise * @exception SQLException if a database access error occurs */ public abstract boolean isAutoIncrement(int column) throws SQLException; /** * Indicates whether a column's case matters. * * @param column the first column is 1, the second is 2, ... * @return <code>true</code> if so; <code>false</code> otherwise * @exception SQLException if a database access error occurs */ public final boolean isCaseSensitive(int column) throws SQLException { checkColumnIndex(column); Oid oid = this.getOid(column); return ( oid.equals(TypeOid.TEXT) || oid.equals(TypeOid.BYTEA) || oid.equals(TypeOid.VARCHAR) || oid.equals(TypeOid.BPCHAR)); } /** * Indicates whether the designated column can be used in a where clause. * * @param column the first column is 1, the second is 2, ... * @return <code>true</code> if so; <code>false</code> otherwise * @exception SQLException if a database access error occurs */ public final boolean isSearchable(int column) throws SQLException { checkColumnIndex(column); return true; } /** * Indicates whether the designated column is a cash value. * * @param column the first column is 1, the second is 2, ... * @return <code>true</code> if so; <code>false</code> otherwise * @exception SQLException if a database access error occurs */ public final boolean isCurrency(int column) throws SQLException { checkColumnIndex(column); //For now it is false; it can be changed when TypeOid.java //contains currency data types. return false; } /** * Indicates the nullability of values in the designated column. * * @param column the first column is 1, the second is 2, ... * @return the nullability status of the given column; one of <code>columnNoNulls</code>, * <code>columnNullable</code> or <code>columnNullableUnknown</code> * @exception SQLException if a database access error occurs */ public final int isNullable(int column) throws SQLException { checkColumnIndex(column); return columnNullableUnknown; } /** * Indicates whether values in the designated column are signed numbers. * * @param column the first column is 1, the second is 2, ... * @return <code>true</code> if so; <code>false</code> otherwise * @exception SQLException if a database access error occurs */ public final boolean isSigned(int column) throws SQLException { checkColumnIndex(column); Oid oid = this.getOid(column); return ( oid.equals(TypeOid.INT2) || oid.equals(TypeOid.INT4) || oid.equals(TypeOid.INT8) || oid.equals(TypeOid.FLOAT4) || oid.equals(TypeOid.FLOAT8)); } /** * Indicates the designated column's normal maximum width in characters. * * @param column the first column is 1, the second is 2, ... * @return the normal maximum number of characters allowed as the width * of the designated column * @exception SQLException if a database access error occurs */ public final int getColumnDisplaySize(int column) throws SQLException { checkColumnIndex(column); Oid oid = this.getOid(column); if(oid.equals(TypeOid.INT2)) return 6; if(oid.equals(TypeOid.INT4) || oid.equals(TypeOid.FLOAT4)) return 11; if(oid.equals(TypeOid.INT8) || oid.equals(TypeOid.NUMERIC) || oid.equals(TypeOid.FLOAT8) || oid.equals(TypeOid.OID)) return 20; if(oid.equals(TypeOid.BOOL)) return 3; if(oid.equals(TypeOid.DATE)) return 13; if(oid.equals(TypeOid.TIME)) return 10; if(oid.equals(TypeOid.TIMESTAMP) || oid.equals(TypeOid.TIMESTAMPTZ)) return 25; return getFieldLength(column); } /** * Gets the designated column's suggested title for use in printouts and * displays. * * @param column the first column is 1, the second is 2, ... * @return the suggested column title * @exception SQLException if a database access error occurs */ public abstract String getColumnLabel(int column) throws SQLException; /** * Get the designated column's name. * * @param column the first column is 1, the second is 2, ... * @return column name * @exception SQLException if a database access error occurs */ public String getColumnName(int column) throws SQLException { checkColumnIndex(column); return getColumnLabel(column); } /** * Get the designated column's table's schema. * * @param column the first column is 1, the second is 2, ... * @return schema name or "" if not applicable * @exception SQLException if a database access error occurs */ public final String getSchemaName(int column) throws SQLException { checkColumnIndex(column); return ""; } /** * Get the designated column's number of decimal digits. * * @param column the first column is 1, the second is 2, ... * @return precision * @exception SQLException if a database access error occurs */ public final int getPrecision(int column) throws SQLException { checkColumnIndex(column); Oid oid = this.getOid(column); if(oid.equals(TypeOid.INT2)) return 5; if(oid.equals(TypeOid.INT4)) return 10; if(oid.equals(TypeOid.INT8) || oid.equals(TypeOid.OID)) return 20; if(oid.equals(TypeOid.FLOAT4)) return 8; if(oid.equals(TypeOid.FLOAT8)) return 16; if(oid.equals(TypeOid.BOOL)) return 1; if(oid.equals(TypeOid.NUMERIC)) return -1; return 0; } /** * Gets the designated column's number of digits to right of the decimal point. * * @param column the first column is 1, the second is 2, ... * @return scale * @exception SQLException if a database access error occurs */ public final int getScale(int column) throws SQLException { checkColumnIndex(column); Oid oid = this.getOid(column); if(oid.equals(TypeOid.FLOAT4)) return 8; if(oid.equals(TypeOid.FLOAT8)) return 16; if(oid.equals(TypeOid.NUMERIC)) return -1; return 0; } /** * Gets the designated column's table name. * * @param column the first column is 1, the second is 2, ... * @return table name or "" if not applicable * @exception SQLException if a database access error occurs */ public final String getTableName(int column) throws SQLException { checkColumnIndex(column); return ""; } /** * Gets the designated column's table's catalog name. * * @param column the first column is 1, the second is 2, ... * @return the name of the catalog for the table in which the given column * appears or "" if not applicable * @exception SQLException if a database access error occurs */ public final String getCatalogName(int column) throws SQLException { checkColumnIndex(column); return ""; } /** * Retrieves the designated column's SQL type. * * @param column the first column is 1, the second is 2, ... * @return SQL type from {@link java.sql.Types} * @exception SQLException if a database access error occurs * @see java.sql.Types */ public final int getColumnType(int column) throws SQLException { checkColumnIndex(column); return ((SPIConnection)getDefaultConnection()).getSQLType(getOid(column)); } /** * Retrieves the designated column's database-specific type name. * * @param column the first column is 1, the second is 2, ... * @return type name used by the database. If the column type is * a user-defined type, then a fully-qualified type name is returned. * @exception SQLException if a database access error occurs */ public final String getColumnTypeName(int column) throws SQLException { checkColumnIndex(column); return ((SPIConnection)getDefaultConnection()).getPGType(getOid(column)); } /** * Indicates whether the designated column is definitely not writable. * * @param column the first column is 1, the second is 2, ... * @return <code>true</code> if so; <code>false</code> otherwise * @exception SQLException if a database access error occurs */ public final boolean isReadOnly(int column) throws SQLException { checkColumnIndex(column); return true; } /** * Indicates whether it is possible for a write on the designated column to succeed. * * @param column the first column is 1, the second is 2, ... * @return <code>true</code> if so; <code>false</code> otherwise * @exception SQLException if a database access error occurs */ public final boolean isWritable(int column) throws SQLException { checkColumnIndex(column); return false; } /** * Indicates whether a write on the designated column will definitely succeed. * * @param column the first column is 1, the second is 2, ... * @return <code>true</code> if so; <code>false</code> otherwise * @exception SQLException if a database access error occurs */ public final boolean isDefinitelyWritable(int column) throws SQLException { checkColumnIndex(column); return false; } //--------------------------JDBC 2.0----------------------------------- /** * <p>Returns the fully-qualified name of the Java class whose instances * are manufactured if the method <code>ResultSet.getObject</code> * is called to retrieve a value * from the column. <code>ResultSet.getObject</code> may return a subclass of the * class returned by this method. * * @param column the first column is 1, the second is 2, ... * @return the fully-qualified name of the class in the Java programming * language that would be used by the method * <code>ResultSet.getObject</code> to retrieve the value in the specified * column. This is the class name used for custom mapping. * @exception SQLException if a database access error occurs * @since 1.2 */ public abstract String getColumnClassName(int column) throws SQLException; /** * Checks if the column index is valid. * * @param column the first column is 1, the second is 2, ... * @exception SQLException if the column is out of index bounds */ protected abstract void checkColumnIndex(int column) throws SQLException; /** * Gets column OID * @param column Column index * @return column OID * @throws SQLException if an error occurs */ protected abstract Oid getOid(int column) throws SQLException; /** * Gets column length * @param column Column index * @return column length * @throws SQLException if an error occurs */ protected abstract int getFieldLength(int column) throws SQLException; /** * Obtains connection to the database if needed. * Once called, it stores the connection reference to a private variable. */ private Connection getDefaultConnection() throws SQLException { if (m_conn == null) { m_conn = DriverManager.getConnection("jdbc:default:connection"); } return m_conn; } }