| /* |
| |
| Derby - Class DatabaseMetaData |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| */ |
| |
| package org.apache.derby.client.am; |
| |
| import java.sql.Connection; |
| import java.sql.DatabaseMetaData; |
| import java.sql.ResultSet; |
| import java.sql.RowIdLifetime; |
| import java.sql.SQLException; |
| import java.sql.Types; |
| import java.util.StringTokenizer; |
| |
| import org.apache.derby.iapi.services.info.JVMInfo; |
| import org.apache.derby.shared.common.reference.SQLState; |
| |
| // Note: |
| // Tag members using the strictest visibility. |
| // Note: |
| // Mark methods synchronized if and only if they update object state and are public. |
| // Not yet done: |
| // Application heap data should be copied for shiraz. |
| // Save for future pass to avoid clutter during development. |
| // Not yet done: |
| // Apply meaning-preserving program transformations for performance, |
| // including the replacement of slow ADTs with faster unsynchronized ADTs. |
| // Save for future pass to avoid clutter during development. |
| // Not yet done: |
| // Assign an ErrorKey, ResourceKey, and Resource for each throw statement. |
| // Save for future pass to avoid maintenance during development. |
| |
| public abstract class ClientDatabaseMetaData implements DatabaseMetaData { |
| //----------------------------- constants ----------------------------------- |
| |
| private final static short SQL_BEST_ROWID = 1; |
| private final static short SQL_ROWVER = 2; |
| |
| private final static short SQL_INDEX_UNIQUE = 0; |
| private final static short SQL_INDEX_ALL = 1; |
| |
| //---------------------navigational members----------------------------------- |
| |
| private Agent agent_; |
| protected ClientConnection connection_; |
| |
| //-----------------------------state------------------------------------------ |
| |
| private final static int numberOfMetaDataInfoMethods__ = 108; |
| private Object[] metaDataInfoCache_ = new Object[numberOfMetaDataInfoMethods__]; |
| private boolean metaDataInfoIsCached_ = false; |
| |
| ProductLevel productLevel_; |
| |
| /** The JDBC major version supported by the server. */ |
| private final int serverJdbcMajorVersion; |
| /** The JDBC minor version supported by the server. */ |
| private final int serverJdbcMinorVersion; |
| |
| /** True if the server supports QRYCLSIMP. */ |
| private boolean supportsQryclsimp_; |
| |
| private boolean supportsLayerBStreaming_; |
| |
| /** |
| * True if the server supports session data caching |
| */ |
| private boolean supportsSessionDataCaching_; |
| |
| /** True if the server supports UDTs */ |
| private boolean supportsUDTs_; |
| |
| /** |
| * True if the server supports aborting a statement whilst transferring |
| * EXTDTA objects. Note that there are two types of aborts, depending on |
| * whether an object is being transferred to the server using DDM layer B |
| * streaming or not. |
| */ |
| private boolean supportsEXTDTAAbort_; |
| |
| /** True if the server supports nanoseconds in timestamps */ |
| private boolean supportsTimestampNanoseconds_; |
| |
| /** True if the server supports boolean values */ |
| private boolean supportsBooleanValues_; |
| |
| /** |
| * DERBY-4805(Increase the length of the RDBNAM field in the DRDA |
| * implementation) |
| * True if the server supports RDBNAM longer than 255 character |
| */ |
| private boolean supportsLongRDBNAM_; |
| |
| /** |
| * True if the server supports transport of boolean parameter values as |
| * booleans. If false, boolean values used as parameters in prepared |
| * statements will be transported as smallints to preserve backwards |
| * compatibility. See DERBY-4965. |
| */ |
| private boolean supportsBooleanParameterTransport_; |
| |
| //---------------------constructors/finalizer--------------------------------- |
| |
| protected ClientDatabaseMetaData(Agent agent, |
| ClientConnection connection, |
| ProductLevel productLevel) { |
| agent_ = agent; |
| connection_ = connection; |
| productLevel_ = productLevel; |
| computeFeatureSet_(); |
| if (connection.isXAConnection()) { |
| connection.xaHostVersion_ = productLevel_.versionLevel_; |
| } |
| if (productLevel_.lessThan(10, 2, 0)) { |
| serverJdbcMajorVersion = 3; |
| serverJdbcMinorVersion = 0; |
| } else { |
| // this value is only used to check that we have at least 4.0; |
| // higher is irrelevant |
| serverJdbcMajorVersion = 4; |
| serverJdbcMinorVersion = 0; |
| } |
| } |
| |
| // ---------------------------jdbc 1------------------------------------------ |
| |
| //---------------------------------------------------------------------- |
| // First, a variety of minor information about the target database. |
| |
| private final static int allProceduresAreCallable__ = 0; |
| |
| public boolean allProceduresAreCallable() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(allProceduresAreCallable__); |
| } |
| |
| private final static int allTablesAreSelectable__ = 1; |
| |
| public boolean allTablesAreSelectable() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(allTablesAreSelectable__); |
| } |
| |
| private final static int nullsAreSortedHigh__ = 2; |
| |
| public boolean nullsAreSortedHigh() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(nullsAreSortedHigh__); |
| } |
| |
| private final static int nullsAreSortedLow__ = 3; |
| |
| public boolean nullsAreSortedLow() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(nullsAreSortedLow__); |
| } |
| |
| private final static int nullsAreSortedAtStart__ = 4; |
| |
| public boolean nullsAreSortedAtStart() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(nullsAreSortedAtStart__); |
| } |
| |
| private final static int nullsAreSortedAtEnd__ = 5; |
| |
| public boolean nullsAreSortedAtEnd() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(nullsAreSortedAtEnd__); |
| } |
| |
| private final static int usesLocalFiles__ = 6; |
| |
| public boolean usesLocalFiles() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(usesLocalFiles__); |
| } |
| |
| private final static int usesLocalFilePerTable__ = 7; |
| |
| public boolean usesLocalFilePerTable() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(usesLocalFilePerTable__); |
| } |
| |
| private final static int storesUpperCaseIdentifiers__ = 8; |
| |
| public boolean storesUpperCaseIdentifiers() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(storesUpperCaseIdentifiers__); |
| } |
| |
| |
| private final static int storesLowerCaseIdentifiers__ = 9; |
| |
| public boolean storesLowerCaseIdentifiers() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(storesLowerCaseIdentifiers__); |
| } |
| |
| private final static int storesMixedCaseIdentifiers__ = 10; |
| |
| public boolean storesMixedCaseIdentifiers() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(storesMixedCaseIdentifiers__); |
| } |
| |
| private final static int storesUpperCaseQuotedIdentifiers__ = 11; |
| |
| public boolean storesUpperCaseQuotedIdentifiers() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(storesUpperCaseQuotedIdentifiers__); |
| } |
| |
| private final static int storesLowerCaseQuotedIdentifiers__ = 12; |
| |
| public boolean storesLowerCaseQuotedIdentifiers() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(storesLowerCaseQuotedIdentifiers__); |
| } |
| |
| private final static int storesMixedCaseQuotedIdentifiers__ = 13; |
| |
| public boolean storesMixedCaseQuotedIdentifiers() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(storesMixedCaseQuotedIdentifiers__); |
| } |
| |
| private final static int getSQLKeywords__ = 14; |
| |
| public String getSQLKeywords() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoString(getSQLKeywords__); |
| } |
| |
| private final static int getNumericFunctions__ = 15; |
| |
| public String getNumericFunctions() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoString(getNumericFunctions__); |
| } |
| |
| private final static int getStringFunctions__ = 16; |
| |
| public String getStringFunctions() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoString(getStringFunctions__); |
| } |
| |
| private final static int getSystemFunctions__ = 17; |
| |
| public String getSystemFunctions() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoString(getSystemFunctions__); |
| } |
| |
| private final static int getTimeDateFunctions__ = 18; |
| |
| public String getTimeDateFunctions() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoString(getTimeDateFunctions__); |
| } |
| |
| private final static int getSearchStringEscape__ = 19; |
| |
| public String getSearchStringEscape() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoString(getSearchStringEscape__); |
| } |
| |
| private final static int getExtraNameCharacters__ = 20; |
| |
| public String getExtraNameCharacters() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoString(getExtraNameCharacters__); |
| } |
| |
| private final static int supportsAlterTableWithAddColumn__ = 21; |
| |
| public boolean supportsAlterTableWithAddColumn() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsAlterTableWithAddColumn__); |
| } |
| |
| private final static int supportsAlterTableWithDropColumn__ = 22; |
| |
| public boolean supportsAlterTableWithDropColumn() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsAlterTableWithDropColumn__); |
| } |
| |
| private final static int supportsConvert__ = 23; |
| |
| public boolean supportsConvert() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsConvert__); |
| } |
| |
| private final static int supportsConvertType__ = 24; |
| |
| public boolean supportsConvert(int fromType, int toType) throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean_supportsConvert(supportsConvertType__, fromType, toType); |
| } |
| |
| private final static int supportsDifferentTableCorrelationNames__ = 25; |
| |
| public boolean supportsDifferentTableCorrelationNames() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsDifferentTableCorrelationNames__); |
| } |
| |
| private final static int supportsExpressionsInOrderBy__ = 26; |
| |
| public boolean supportsExpressionsInOrderBy() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsExpressionsInOrderBy__); |
| } |
| |
| private final static int supportsOrderByUnrelated__ = 27; |
| |
| public boolean supportsOrderByUnrelated() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsOrderByUnrelated__); |
| } |
| |
| private final static int supportsGroupBy__ = 28; |
| |
| public boolean supportsGroupBy() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsGroupBy__); |
| } |
| |
| private final static int supportsGroupByUnrelated__ = 29; |
| |
| public boolean supportsGroupByUnrelated() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsGroupByUnrelated__); |
| } |
| |
| private final static int supportsGroupByBeyondSelect__ = 30; |
| |
| public boolean supportsGroupByBeyondSelect() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsGroupByBeyondSelect__); |
| } |
| |
| private final static int supportsMultipleResultSets__ = 31; |
| |
| public boolean supportsMultipleResultSets() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsMultipleResultSets__); |
| } |
| |
| private final static int supportsMultipleTransactions__ = 32; |
| |
| public boolean supportsMultipleTransactions() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsMultipleTransactions__); |
| } |
| |
| private final static int supportsCoreSQLGrammar__ = 33; |
| |
| public boolean supportsCoreSQLGrammar() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsCoreSQLGrammar__); |
| } |
| |
| private final static int supportsExtendedSQLGrammar__ = 34; |
| |
| public boolean supportsExtendedSQLGrammar() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsExtendedSQLGrammar__); |
| } |
| |
| private final static int supportsANSI92IntermediateSQL__ = 35; |
| |
| public boolean supportsANSI92IntermediateSQL() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsANSI92IntermediateSQL__); |
| } |
| |
| private final static int supportsANSI92FullSQL__ = 36; |
| |
| public boolean supportsANSI92FullSQL() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsANSI92FullSQL__); |
| } |
| |
| private final static int supportsIntegrityEnhancementFacility__ = 37; |
| |
| public boolean supportsIntegrityEnhancementFacility() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsIntegrityEnhancementFacility__); |
| } |
| |
| private final static int supportsOuterJoins__ = 38; |
| |
| public boolean supportsOuterJoins() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsOuterJoins__); |
| } |
| |
| private final static int supportsFullOuterJoins__ = 39; |
| |
| public boolean supportsFullOuterJoins() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsFullOuterJoins__); |
| } |
| |
| private final static int supportsLimitedOuterJoins__ = 40; |
| |
| public boolean supportsLimitedOuterJoins() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsLimitedOuterJoins__); |
| } |
| |
| private final static int getSchemaTerm__ = 41; |
| |
| public String getSchemaTerm() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoString(getSchemaTerm__); |
| } |
| |
| private final static int getProcedureTerm__ = 42; |
| |
| public String getProcedureTerm() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoString(getProcedureTerm__); |
| } |
| |
| private final static int getCatalogTerm__ = 43; |
| |
| public String getCatalogTerm() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoString(getCatalogTerm__); |
| } |
| |
| private final static int isCatalogAtStart__ = 44; |
| |
| public boolean isCatalogAtStart() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(isCatalogAtStart__); |
| } |
| |
| private final static int getCatalogSeparator__ = 45; |
| |
| public String getCatalogSeparator() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoString(getCatalogSeparator__); |
| } |
| |
| private final static int supportsSchemasInDataManipulation__ = 46; |
| |
| public boolean supportsSchemasInDataManipulation() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsSchemasInDataManipulation__); |
| } |
| |
| private final static int supportsSchemasInProcedureCalls__ = 47; |
| |
| public boolean supportsSchemasInProcedureCalls() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsSchemasInProcedureCalls__); |
| } |
| |
| private final static int supportsSchemasInTableDefinitions__ = 48; |
| |
| public boolean supportsSchemasInTableDefinitions() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsSchemasInTableDefinitions__); |
| } |
| |
| |
| private final static int supportsSchemasInIndexDefinitions__ = 49; |
| |
| public boolean supportsSchemasInIndexDefinitions() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsSchemasInIndexDefinitions__); |
| } |
| |
| private final static int supportsSchemasInPrivilegeDefinitions__ = 50; |
| |
| public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsSchemasInPrivilegeDefinitions__); |
| } |
| |
| private final static int supportsCatalogsInDataManipulation__ = 51; |
| |
| public boolean supportsCatalogsInDataManipulation() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsCatalogsInDataManipulation__); |
| } |
| |
| private final static int supportsCatalogsInProcedureCalls__ = 52; |
| |
| public boolean supportsCatalogsInProcedureCalls() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsCatalogsInProcedureCalls__); |
| } |
| |
| private final static int supportsCatalogsInTableDefinitions__ = 53; |
| |
| public boolean supportsCatalogsInTableDefinitions() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsCatalogsInTableDefinitions__); |
| } |
| |
| private final static int supportsCatalogsInIndexDefinitions__ = 54; |
| |
| public boolean supportsCatalogsInIndexDefinitions() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsCatalogsInIndexDefinitions__); |
| } |
| |
| private final static int supportsCatalogsInPrivilegeDefinitions__ = 55; |
| |
| public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsCatalogsInPrivilegeDefinitions__); |
| } |
| |
| private final static int supportsPositionedDelete__ = 56; |
| |
| public boolean supportsPositionedDelete() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsPositionedDelete__); |
| } |
| |
| |
| private final static int supportsPositionedUpdate__ = 57; |
| |
| public boolean supportsPositionedUpdate() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsPositionedUpdate__); |
| } |
| |
| private final static int supportsSelectForUpdate__ = 58; |
| |
| public boolean supportsSelectForUpdate() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsSelectForUpdate__); |
| } |
| |
| private final static int supportsStoredProcedures__ = 59; |
| |
| public boolean supportsStoredProcedures() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsStoredProcedures__); |
| } |
| |
| private final static int supportsSubqueriesInComparisons__ = 60; |
| |
| public boolean supportsSubqueriesInComparisons() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsSubqueriesInComparisons__); |
| } |
| |
| private final static int supportsUnion__ = 61; |
| |
| public boolean supportsUnion() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsUnion__); |
| } |
| |
| private final static int supportsUnionAll__ = 62; |
| |
| public boolean supportsUnionAll() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsUnionAll__); |
| |
| } |
| |
| private final static int supportsOpenCursorsAcrossCommit__ = 63; |
| |
| public boolean supportsOpenCursorsAcrossCommit() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsOpenCursorsAcrossCommit__); |
| } |
| |
| private final static int supportsOpenCursorsAcrossRollback__ = 64; |
| |
| public boolean supportsOpenCursorsAcrossRollback() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsOpenCursorsAcrossRollback__); |
| } |
| |
| private final static int supportsOpenStatementsAcrossCommit__ = 65; |
| |
| public boolean supportsOpenStatementsAcrossCommit() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsOpenStatementsAcrossCommit__); |
| } |
| |
| |
| private final static int supportsOpenStatementsAcrossRollback__ = 66; |
| |
| public boolean supportsOpenStatementsAcrossRollback() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsOpenStatementsAcrossRollback__); |
| } |
| |
| //---------------------------------------------------------------------- |
| // The following group of methods exposes various limitations |
| // based on the target database with the current driver. |
| // Unless otherwise specified, a result of zero means there is no |
| // limit, or the limit is not known. |
| private final static int getMaxBinaryLiteralLength__ = 67; |
| |
| public int getMaxBinaryLiteralLength() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxBinaryLiteralLength__); |
| } |
| |
| private final static int getMaxCharLiteralLength__ = 68; |
| |
| public int getMaxCharLiteralLength() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxCharLiteralLength__); |
| } |
| |
| private final static int getMaxColumnNameLength__ = 69; |
| |
| public int getMaxColumnNameLength() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxColumnNameLength__); |
| } |
| |
| private final static int getMaxColumnsInGroupBy__ = 70; |
| |
| public int getMaxColumnsInGroupBy() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxColumnsInGroupBy__); |
| } |
| |
| private final static int getMaxColumnsInIndex__ = 71; |
| |
| public int getMaxColumnsInIndex() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxColumnsInIndex__); |
| } |
| |
| private final static int getMaxColumnsInOrderBy__ = 72; |
| |
| public int getMaxColumnsInOrderBy() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxColumnsInOrderBy__); |
| } |
| |
| private final static int getMaxColumnsInSelect__ = 73; |
| |
| public int getMaxColumnsInSelect() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxColumnsInSelect__); |
| } |
| |
| private final static int getMaxColumnsInTable__ = 74; |
| |
| public int getMaxColumnsInTable() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxColumnsInTable__); |
| } |
| |
| private final static int getMaxConnections__ = 75; |
| |
| public int getMaxConnections() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxConnections__); |
| } |
| |
| private final static int getMaxCursorNameLength__ = 76; |
| |
| public int getMaxCursorNameLength() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxCursorNameLength__); |
| } |
| |
| private final static int getMaxIndexLength__ = 77; |
| |
| public int getMaxIndexLength() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxIndexLength__); |
| } |
| |
| private final static int getMaxSchemaNameLength__ = 78; |
| |
| public int getMaxSchemaNameLength() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxSchemaNameLength__); |
| } |
| |
| private final static int getMaxProcedureNameLength__ = 79; |
| |
| public int getMaxProcedureNameLength() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxProcedureNameLength__); |
| } |
| |
| private final static int getMaxCatalogNameLength__ = 80; |
| |
| public int getMaxCatalogNameLength() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxCatalogNameLength__); |
| } |
| |
| private final static int getMaxRowSize__ = 81; |
| |
| public int getMaxRowSize() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxRowSize__); |
| } |
| |
| private final static int doesMaxRowSizeIncludeBlobs__ = 82; |
| |
| public boolean doesMaxRowSizeIncludeBlobs() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(doesMaxRowSizeIncludeBlobs__); |
| } |
| |
| private final static int getMaxStatementLength__ = 83; |
| |
| public int getMaxStatementLength() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxStatementLength__); |
| } |
| |
| private final static int getMaxStatements__ = 84; |
| |
| public int getMaxStatements() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxStatements__); |
| } |
| |
| private final static int getMaxTableNameLength__ = 85; |
| |
| public int getMaxTableNameLength() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxTableNameLength__); |
| } |
| |
| private final static int getMaxTablesInSelect__ = 86; |
| |
| public int getMaxTablesInSelect() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxTablesInSelect__); |
| } |
| |
| private final static int getMaxUserNameLength__ = 87; |
| |
| public int getMaxUserNameLength() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getMaxUserNameLength__); |
| } |
| |
| private final static int getDefaultTransactionIsolation__ = 88; |
| |
| public int getDefaultTransactionIsolation() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt(getDefaultTransactionIsolation__); |
| } |
| |
| private final static int supportsTransactions__ = 89; |
| |
| public boolean supportsTransactions() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsTransactions__); |
| } |
| |
| // Stored Procedure will return a String containing a |
| // comma seperated list of all supported levels |
| private final static int supportsTransactionIsolationLevel__ = 90; |
| |
| public boolean supportsTransactionIsolationLevel(int level) throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBooleanWithType(supportsTransactionIsolationLevel__, level); |
| } |
| |
| |
| private final static int supportsDataDefinitionAndDataManipulationTransactions__ = 91; |
| |
| public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsDataDefinitionAndDataManipulationTransactions__); |
| } |
| |
| private final static int supportsDataManipulationTransactionsOnly__ = 92; |
| |
| public boolean supportsDataManipulationTransactionsOnly() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsDataManipulationTransactionsOnly__); |
| } |
| |
| private final static int dataDefinitionCausesTransactionCommit__ = 93; |
| |
| public boolean dataDefinitionCausesTransactionCommit() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(dataDefinitionCausesTransactionCommit__); |
| } |
| |
| private final static int dataDefinitionIgnoredInTransactions__ = 94; |
| |
| public boolean dataDefinitionIgnoredInTransactions() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(dataDefinitionIgnoredInTransactions__); |
| } |
| |
| // Stored Procedure will return a String containing a |
| // comma seperated list of all the supported resultSet types |
| private final static int supportsResultSetType__ = 95; |
| |
| public boolean supportsResultSetType(int type) throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBooleanWithType(supportsResultSetType__, type); |
| } |
| |
| private final static int supportsResultSetConcurrency__ = 96; |
| |
| public boolean supportsResultSetConcurrency(int type, int concurrency) throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoInt_SupportsResultSetConcurrency(supportsResultSetConcurrency__, type, concurrency); |
| } |
| |
| // Stored Procedure will return a String containing a |
| // comma seperated list of all the supported result Set types |
| private final static int ownUpdatesAreVisible__ = 97; |
| |
| public boolean ownUpdatesAreVisible(int type) throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBooleanWithType(ownUpdatesAreVisible__, type); |
| } |
| |
| // Stored Procedure will return a String containing a |
| // comma seperated list of all the supported result Set types |
| private final static int ownDeletesAreVisible__ = 98; |
| |
| public boolean ownDeletesAreVisible(int type) throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBooleanWithType(ownDeletesAreVisible__, type); |
| } |
| |
| // Stored Procedure will return a String containing a |
| // comma seperated list all the supported result Set types |
| private final static int ownInsertsAreVisible__ = 99; |
| |
| public boolean ownInsertsAreVisible(int type) throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBooleanWithType(ownInsertsAreVisible__, type); |
| } |
| |
| // Stored Procedure will return a String containing a |
| // comma seperated list of all the supported result Set types |
| private final static int othersUpdatesAreVisible__ = 100; |
| |
| public boolean othersUpdatesAreVisible(int type) throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBooleanWithType(othersUpdatesAreVisible__, type); |
| } |
| |
| // Stored Procedure will return a String containing a |
| // comma seperated list of all the supported result Set types |
| private final static int othersDeletesAreVisible__ = 101; |
| |
| public boolean othersDeletesAreVisible(int type) throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBooleanWithType(othersDeletesAreVisible__, type); |
| } |
| |
| // Stored Procedure will return a String containing a |
| // comma seperated list of all the supported result Set types |
| private final static int othersInsertsAreVisible__ = 102; |
| |
| public boolean othersInsertsAreVisible(int type) throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBooleanWithType(othersInsertsAreVisible__, type); |
| } |
| |
| // Stored Procedure will return a String containing a |
| // comma seperated list of all the supported result Set types |
| private final static int updatesAreDetected__ = 103; |
| |
| public boolean updatesAreDetected(int type) throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBooleanWithType(updatesAreDetected__, type); |
| } |
| |
| // Stored Procedure will return a String containing a |
| // comma seperated list of all the supported result Set types |
| private final static int deletesAreDetected__ = 104; |
| |
| public boolean deletesAreDetected(int type) throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBooleanWithType(deletesAreDetected__, type); |
| } |
| |
| // Stored Procedure will return a String containing a |
| // comma seperated list of all the supported result Set types |
| private final static int insertsAreDetected__ = 105; |
| |
| public boolean insertsAreDetected(int type) throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBooleanWithType(insertsAreDetected__, type); |
| } |
| |
| private final static int supportsBatchUpdates__ = 106; |
| |
| public boolean supportsBatchUpdates() throws SQLException { |
| checkForClosedConnection(); |
| return getMetaDataInfoBoolean(supportsBatchUpdates__); |
| } |
| |
| public boolean supportsSavepoints() throws SQLException { |
| checkForClosedConnection(); |
| if (productLevel_.greaterThanOrEqualTo(5, 2, 0)) { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| // start tagging all abstract methods with an underscore like this !! |
| abstract public String getURL_() throws SqlException; |
| |
| public String getURL() throws SQLException { |
| try |
| { |
| checkForClosedConnection(); |
| return getURL_(); |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| public String getUserName() throws SQLException { |
| checkForClosedConnection(); |
| return connection_.user_; |
| } |
| |
| public boolean isReadOnly() throws SQLException { |
| return false; |
| } |
| |
| public String getDatabaseProductName() throws SQLException { |
| checkForClosedConnection(); |
| return productLevel_.databaseProductName_; |
| } |
| |
| public String getDatabaseProductVersion() throws SQLException { |
| checkForClosedConnection(); |
| return productLevel_.databaseProductVersion_; |
| } |
| |
| public String getDriverName() throws SQLException { |
| checkForClosedConnection(); |
| return Configuration.dncDriverName; |
| } |
| |
| public String getDriverVersion() throws SQLException { |
| checkForClosedConnection(); |
| return Version.getDriverVersion(); |
| } |
| |
| // JDBC signature also does not throw SqlException, so we don't check for closed connection. |
| public int getDriverMajorVersion() { |
| return Version.getMajorVersion(); |
| } |
| |
| // JDBC signature also does not throw SqlException, so we don't check for closed connection. |
| public int getDriverMinorVersion() { |
| return Version.getMinorVersion(); |
| } |
| |
| //All JDBC Drivers must return false for this method. For this reason we choose |
| //to return FALSE |
| public boolean supportsMixedCaseIdentifiers() throws SQLException { |
| checkForClosedConnection(); |
| return false; |
| } |
| |
| public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| public String getIdentifierQuoteString() throws SQLException { |
| checkForClosedConnection(); |
| return "\""; |
| } |
| |
| public boolean supportsColumnAliasing() throws SQLException { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| public boolean nullPlusNonNullIsNull() throws SQLException { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| public boolean supportsTableCorrelationNames() throws SQLException { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| public boolean supportsLikeEscapeClause() throws SQLException { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| public boolean supportsNonNullableColumns() throws SQLException { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| public boolean supportsMinimumSQLGrammar() throws SQLException { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| public boolean supportsANSI92EntryLevelSQL() throws SQLException { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| public boolean supportsSubqueriesInExists() throws SQLException { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| public boolean supportsSubqueriesInIns() throws SQLException { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| public boolean supportsSubqueriesInQuantifieds() throws SQLException { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| public boolean supportsCorrelatedSubqueries() throws SQLException { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| |
| //------------------------catalog query methods follow-------------------------------------------- |
| |
| // call stored procedure SQLProcedures |
| // SYSIBM.SQLProcedures( |
| // CatalogName varchar(128), |
| // SchemaName varchar(128), |
| // ProcName varchar(128), |
| // Options varchar(4000)) |
| // |
| public ResultSet getProcedures(String catalog, |
| String schemaPattern, |
| String procedureNamePattern) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getProcedures", catalog, schemaPattern, procedureNamePattern); |
| } |
| return getProceduresX(catalog, schemaPattern, procedureNamePattern); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| |
| private ClientResultSet getProceduresX(String catalog, |
| String schemaPattern, |
| String procedureNamePattern) throws SqlException { |
| checkForClosedConnectionX(); |
| |
| ClientPreparedStatement cs = |
| prepareMetaDataQuery("SYSIBM.SQLPROCEDURES(?,?,?,?)"); |
| |
| cs.setStringX(1, catalog); |
| cs.setStringX(2, schemaPattern); |
| cs.setStringX(3, procedureNamePattern); |
| cs.setStringX(4, getOptions()); |
| return executeCatalogQuery(cs); |
| } |
| |
| |
| // call stored procedure SQLProcedureCols |
| // SYSIBM.SQLProcedureCols( |
| // CatalogName varchar(128), |
| // SchemaName varchar(128), |
| // ProcName varchar(128), |
| // ParamName varchar(128), |
| // Options varchar(4000)) |
| // |
| public ResultSet getProcedureColumns(String catalog, |
| String schemaPattern, |
| String procedureNamePattern, |
| String columnNamePattern) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getProcedureColumns", catalog, schemaPattern, procedureNamePattern, columnNamePattern); |
| } |
| return getProcedureColumnsX(catalog, schemaPattern, procedureNamePattern, columnNamePattern); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| |
| } |
| |
| private ClientResultSet getProcedureColumnsX(String catalog, |
| String schemaPattern, |
| String procedureNamePattern, |
| String columnNamePattern) throws SqlException { |
| checkForClosedConnectionX(); |
| |
| ClientPreparedStatement cs = |
| prepareMetaDataQuery("SYSIBM.SQLPROCEDURECOLS(?,?,?,?,?)"); |
| |
| cs.setStringX(1, catalog); |
| cs.setStringX(2, schemaPattern); |
| cs.setStringX(3, procedureNamePattern); |
| cs.setStringX(4, columnNamePattern); |
| cs.setStringX(5, getOptions()); |
| return executeCatalogQuery(cs); |
| } |
| |
| /** |
| * Get the function names available in the database. Calls stored |
| * procedure <code>SYSIBM.SQLFunctions(CatalogName |
| * varchar(128), SchemaName varchar(128), FuncName varchar(128), |
| * Options varchar(4000))</code> on the server. This procedure |
| * will in turn call |
| * <code>EmbedDatabaseMetaData.getFunctions(String,String,String)</code><p> |
| * Compatibility: Only available if both server and client version |
| * < 10.1, and JDK version >= 1.6. Older clients will not have |
| * this method available. Newer clients will be able to call this |
| * method when connected to an older server, but this will be |
| * trigger an exception in |
| * <code>checkServerJdbcVersionX()</code>. <p>Upgrade: |
| * <code>SYSIBM.SQLFunctions</code> is added in |
| * <code>DataDictionaryImpl.create_10_2_system_procedures |
| * (TransactionController,UUID)</code> so it will become available |
| * in newly created databases and after <b>hard</b> upgrade. |
| * |
| * @param catalog limit search to this catalog |
| * @param schemaPattern limit search to schemas matching this pattern |
| * @param functionNamePattern limit search to functions matching this |
| * pattern |
| * @return a <code>ResultSet</code> listing the fucntions |
| * @exception SQLException if a database error occurs |
| * @see #getFunctionsX(String, String, String) |
| * @see org.apache.derby.impl.sql.catalog.DataDictionaryImpl#create_10_2_system_procedures(TransactionController,java.util.HashSet,UUID) |
| * @see org.apache.derby.impl.jdbc.EmbedDatabaseMetaData#getFunctions(String,String,String) |
| */ |
| |
| public ResultSet getFunctions(String catalog, |
| String schemaPattern, |
| String functionNamePattern) |
| throws SQLException { |
| try { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getFunctions", |
| catalog, schemaPattern, |
| functionNamePattern); |
| } |
| return getFunctionsX(catalog, schemaPattern, |
| functionNamePattern); |
| } |
| } |
| catch (SqlException se) { |
| throw se.getSQLException(); |
| } |
| } |
| |
| /** |
| * Untraced version of <code>getFunctions(String, String, String)</code>. |
| * @param catalog limit search to this catalog |
| * @param schemaPattern limit search to schemas matching this pattern |
| * @param functionNamePattern limit search to functions matching this |
| * pattern |
| * @return a <code>ResultSet</code> listing the fucntions |
| * @exception SqlException if a database error occurs |
| * @see #getFunctions(String, String, String) |
| */ |
| private ClientResultSet getFunctionsX(String catalog, |
| String schemaPattern, |
| String functionNamePattern) |
| throws SqlException { |
| checkForClosedConnectionX(); |
| checkServerJdbcVersionX("getFunctions(String,String,String)", 4, 0); |
| |
| ClientPreparedStatement cs = |
| prepareMetaDataQuery("SYSIBM.SQLFUNCTIONS(?,?,?,?)"); |
| |
| cs.setStringX(1, catalog); |
| cs.setStringX(2, schemaPattern); |
| cs.setStringX(3, functionNamePattern); |
| cs.setStringX(4, getOptions()); |
| return executeCatalogQuery(cs); |
| } |
| |
| /** |
| * Get the function names available in the database. Calls stored |
| * procedure <code>SYSIBM.SQLFunctionParams(CatalogName |
| * varchar(128), SchemaName varchar(128), FuncName varchar(128), |
| * ParamName varchar(128), Options varchar(4000))</code> on the |
| * server. This procedure will in turn call |
| * <code>EmbedDatabaseMetaData.getFunctionColumns(String,String, |
| * String,String)</code><p> Compatibility: Only available if both |
| * server and client version > 10.1, and JDK version >= 1.6. Older |
| * clients will not have this method available. Newer clients will |
| * be able to call this method when connected to an older server, |
| * but this will be trigger an exception in |
| * <code>checkServerJdbcVersionX()</code>. <p>Upgrade: |
| * <code>SYSIBM.SQLFunctionParams</code> is added in |
| * <code>DataDictionaryImpl.create_10_2_system_procedures |
| * (TransactionController,UUID)</code> so it will become available |
| * in newly created databases and after <b>hard</b> upgrade. |
| * |
| * @param catalog limit search to this catalog |
| * @param schemaPattern limit search to schemas matching this pattern |
| * @param functionNamePattern limit search to functions matching this |
| * pattern |
| * @return a <code>ResultSet</code> listing the fucntions |
| * @exception SQLException if a database error occurs |
| * @see #getFunctionColumnsX(String, String, String,String) |
| * @see org.apache.derby.impl.sql.catalog.DataDictionaryImpl#create_10_2_system_procedures(TransactionController,java.util.HashSet,UUID) |
| * @see org.apache.derby.impl.jdbc.EmbedDatabaseMetaData#getFunctions(String,String,String) |
| */ |
| public ResultSet |
| getFunctionColumns(String catalog, |
| String schemaPattern, |
| String functionNamePattern, |
| String parameterNamePattern) |
| throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_. |
| traceEntry(this, |
| "getFunctionColumns", |
| catalog, schemaPattern, |
| functionNamePattern, parameterNamePattern); |
| } |
| return getFunctionColumnsX(catalog, schemaPattern, |
| functionNamePattern, |
| parameterNamePattern); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| /** |
| * Untraced version of <code>getFunctionColumns(String, String, |
| * String, String)</code>. |
| * @param catalog limit search to this catalog |
| * @param schemaPattern limit search to schemas matching this pattern |
| * @param functionNamePattern limit search to functions matching this |
| * pattern |
| * @param parameterNamePattern limit search to parameters mathing |
| * this pattern |
| * @return a <code>ResultSet</code> listing the fucntions |
| * @exception SqlException if a database error occurs |
| * @see #getFunctionColumns(String, String, String, String) |
| */ |
| private ClientResultSet getFunctionColumnsX(String catalog, |
| String schemaPattern, |
| String functionNamePattern, |
| String parameterNamePattern) |
| throws SqlException { |
| checkForClosedConnectionX(); |
| checkServerJdbcVersionX("getFunctionColumns"+ |
| "(String,String,String,String)", 4, 0); |
| |
| ClientPreparedStatement cs = |
| prepareMetaDataQuery("SYSIBM.SQLFUNCTIONPARAMS(?,?,?,?,?)"); |
| |
| cs.setStringX(1, catalog); |
| cs.setStringX(2, schemaPattern); |
| cs.setStringX(3, functionNamePattern); |
| cs.setStringX(4, parameterNamePattern); |
| cs.setStringX(5, getOptions()); |
| return executeCatalogQuery(cs); |
| } |
| |
| // call stored procedure SQLTables |
| // SYSIBM.SQLTables( |
| // CatalogName varchar(128), |
| // SchemaName varchar(128), |
| // TableName varchar(128), |
| // TaleType varchar(4000), |
| // Options varchar(4000)) |
| // |
| public ResultSet getTables(String catalog, |
| String schemaPattern, |
| String tableNamePattern, |
| String types[]) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getTables", catalog, schemaPattern, tableNamePattern, types); |
| } |
| return getTablesX(catalog, schemaPattern, tableNamePattern, types); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getTablesX(String catalog, |
| String schemaPattern, |
| String tableNamePattern, |
| String types[]) throws SqlException { |
| try { |
| checkForClosedConnection(); |
| } catch ( SQLException se ) { |
| throw new SqlException(se); |
| } |
| |
| ClientPreparedStatement cs = |
| prepareMetaDataQuery("SYSIBM.SQLTABLES(?,?,?,?,?)"); |
| |
| if (catalog == null) { |
| cs.setNullX(1, Types.VARCHAR); |
| } else { |
| cs.setStringX(1, catalog); |
| } |
| |
| if (schemaPattern == null) { |
| cs.setNullX(2, Types.VARCHAR); |
| } else { |
| cs.setStringX(2, schemaPattern); |
| } |
| |
| if (tableNamePattern == null) { |
| cs.setNullX(3, Types.VARCHAR); |
| } else { |
| cs.setStringX(3, tableNamePattern); |
| } |
| |
| String tableTypes = ""; |
| int i = 0; |
| if (types == null) { |
| cs.setNullX(4, Types.VARCHAR); |
| } else if (types.length == 1 && (types[0].trim()).equals("%")) { |
| cs.setStringX(4, types[0]); |
| } else { |
| while (i < types.length) { |
| if (i > 0) { |
| tableTypes = tableTypes.concat(","); |
| } |
| tableTypes = tableTypes.concat("'" + types[i] + "'"); |
| i++; |
| } |
| cs.setStringX(4, tableTypes); |
| } |
| cs.setStringX(5, getOptions()); |
| return executeCatalogQuery(cs); |
| } |
| |
| // call stored procedure SQLTables |
| // SYSIBM.SQLTables( |
| // CatalogName varchar(128), |
| // SchemaName varchar(128), |
| // TableName varchar(128), |
| // TaleType varchar(4000), |
| // Options varchar(4000)) |
| // |
| public ResultSet getSchemas() throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getSchemas"); |
| } |
| return getSchemasX(); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getSchemasX() throws SqlException { |
| try { |
| checkForClosedConnection(); |
| } catch ( SQLException se ) { |
| throw new SqlException(se); |
| } |
| |
| ClientPreparedStatement cs = prepareMetaDataQuery( |
| "SYSIBM.SQLTABLES('', '', '', '', 'GETSCHEMAS=1')"); |
| return (ClientResultSet) cs.executeQueryX(); |
| } |
| |
| |
| // DERBY does not have the notion of a catalog, so we return a result set with no rows. |
| public ResultSet getCatalogs() throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getCatalogs"); |
| } |
| return getCatalogsX(); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getCatalogsX() throws SqlException { |
| checkForClosedConnectionX(); |
| |
| ClientPreparedStatement cs = prepareMetaDataQuery( |
| "SYSIBM.SQLTABLES('', '', '', '', 'GETCATALOGS=1')"); |
| return (ClientResultSet) cs.executeQueryX(); |
| } |
| |
| // call stored procedure SQLTables |
| // SYSIBM.SQLTables( |
| // CatalogName varchar(128), |
| // SchemaName varchar(128), |
| // TableName varchar(128), |
| // TableType varchar(4000), |
| // Options varchar(4000)) |
| public ResultSet getTableTypes() throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getTableTypes"); |
| } |
| return getTableTypesX(); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getTableTypesX() throws SqlException { |
| checkForClosedConnectionX(); |
| |
| ClientPreparedStatement cs = null; |
| cs = prepareMetaDataQuery("SYSIBM.SQLTABLES(?,?,?,?,?)"); |
| |
| cs.setStringX(1, ""); |
| cs.setStringX(2, ""); |
| cs.setStringX(3, ""); |
| cs.setStringX(4, "%"); |
| int cursorHold; |
| if (connection_.holdability() == ResultSet.HOLD_CURSORS_OVER_COMMIT) { |
| cursorHold = 1; |
| } else { |
| cursorHold = 0; |
| } |
| cs.setStringX(5, "DATATYPE='JDBC';GETTABLETYPES=1; CURSORHOLD=" + cursorHold); |
| return executeCatalogQuery(cs); |
| } |
| |
| |
| // call stored procedure SQLColumns |
| // SYSIBM.SQLColumns( |
| // CatalogName varchar(128), |
| // SchemaName varchar(128), |
| // TableName varchar(128), |
| // ColumnName varchar(128), |
| // Options varchar(4000)) |
| // |
| public ResultSet getColumns(String catalog, |
| String schemaPattern, |
| String tableNamePattern, |
| String columnNamePattern) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getColumns", catalog, schemaPattern, tableNamePattern, columnNamePattern); |
| } |
| checkForClosedConnection(); |
| return getColumnsX(catalog, schemaPattern, tableNamePattern, columnNamePattern); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getColumnsX(String catalog, |
| String schemaPattern, |
| String tableNamePattern, |
| String columnNamePattern) throws SqlException { |
| checkForClosedConnectionX(); |
| |
| ClientPreparedStatement cs = prepareMetaDataQuery( |
| "SYSIBM.SQLCOLUMNS(?,?,?,?,?)"); |
| |
| cs.setStringX(1, catalog); |
| cs.setStringX(2, schemaPattern); |
| cs.setStringX(3, tableNamePattern); |
| cs.setStringX(4, columnNamePattern); //Always null for JDBC |
| cs.setStringX(5, getOptions()); |
| return executeCatalogQuery(cs); |
| } |
| |
| |
| // call stored procedure SQLColumnPrivileges |
| // SYSIBM.SQLColPrivileges( |
| // CatalogName varchar(128), |
| // SchemaName varchar(128), |
| // TableName varchar(128), |
| // ColumnName varchar(128), |
| // Options varchar(4000)) |
| // |
| public ResultSet getColumnPrivileges(String catalog, |
| String schema, |
| String table, |
| String columnNamePattern) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getColumnPrivileges", catalog, schema, table, columnNamePattern); |
| } |
| return getColumnPrivilegesX(catalog, schema, table, columnNamePattern); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getColumnPrivilegesX(String catalog, |
| String schema, |
| String table, |
| String columnNamePattern) throws SqlException { |
| checkForClosedConnectionX(); |
| // check input params, table and columnNamePattern cannot be null |
| if (table == null) { |
| throw new SqlException(agent_.logWriter_, |
| new ClientMessageId(SQLState.TABLE_NAME_CANNOT_BE_NULL)); |
| |
| } |
| |
| ClientPreparedStatement cs = prepareMetaDataQuery( |
| "SYSIBM.SQLCOLPRIVILEGES(?,?,?,?,?)"); |
| |
| cs.setStringX(1, catalog); |
| cs.setStringX(2, schema); |
| cs.setStringX(3, table); |
| cs.setStringX(4, columnNamePattern); |
| cs.setStringX(5, getOptions()); |
| return executeCatalogQuery(cs); |
| } |
| |
| |
| // call stored procedure SQLTablePrivileges |
| // SYSIBM.SQLTablePrivileges( |
| // CatalogName varchar(128), |
| // SchemaName varchar(128), |
| // TableName varchar(128), |
| // Options varchar(4000)) |
| // |
| public ResultSet getTablePrivileges(String catalog, |
| String schemaPattern, |
| String tableNamePattern) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getTablePrivileges", catalog, schemaPattern, tableNamePattern); |
| } |
| return getTablePrivilegesX(catalog, schemaPattern, tableNamePattern); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getTablePrivilegesX(String catalog, |
| String schemaPattern, |
| String tableNamePattern) throws SqlException { |
| checkForClosedConnectionX(); |
| |
| ClientPreparedStatement cs = prepareMetaDataQuery( |
| "SYSIBM.SQLTABLEPRIVILEGES(?,?,?,?)"); |
| |
| cs.setStringX(1, catalog); |
| cs.setStringX(2, schemaPattern); |
| cs.setStringX(3, tableNamePattern); |
| cs.setStringX(4, getOptions()); |
| return executeCatalogQuery(cs); |
| } |
| |
| |
| // call stored procedure |
| // SYSIBM.SQLSPECIALCOLUMNS ( IN COLTYPE SMALLINT, |
| // IN CATALOG_NAME VARCHAR(128), |
| // IN SCHEMA_NAME VARCHAR(128), |
| // IN TABLE_NAME VARCHAR(128), |
| // IN SCOPE SMALLINT, |
| // IN NULLABLE SMALLINT, |
| // IN OPTIONS VARCHAR(4000) ) |
| // |
| public ResultSet getBestRowIdentifier(String catalog, |
| String schema, |
| String table, |
| int scope, |
| boolean nullable) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getBestRowIdentifier", catalog, schema, table, scope, nullable); |
| } |
| return getBestRowIdentifierX(catalog, schema, table, scope, nullable); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getBestRowIdentifierX(String catalog, |
| String schema, |
| String table, |
| int scope, |
| boolean nullable) throws SqlException { |
| checkForClosedConnectionX(); |
| |
| // check input params |
| // |
| // validate input table, which can not be null |
| if (table == null) { |
| throw new SqlException(agent_.logWriter_, |
| new ClientMessageId(SQLState.TABLE_NAME_CANNOT_BE_NULL)); |
| |
| } |
| ClientPreparedStatement cs = prepareMetaDataQuery( |
| "SYSIBM.SQLSPECIALCOLUMNS(?,?,?,?,?,?,?)"); |
| |
| cs.setIntX(1, SQL_BEST_ROWID); |
| cs.setStringX(2, catalog); |
| cs.setStringX(3, schema); |
| cs.setStringX(4, table); |
| cs.setIntX(5, scope); |
| if (nullable) { |
| cs.setShortX(6, (short) 1); |
| } else { |
| cs.setShortX(6, (short) 0); |
| } |
| cs.setStringX(7, getOptions()); |
| return executeCatalogQuery(cs); |
| } |
| |
| |
| public ResultSet getVersionColumns(String catalog, |
| String schema, |
| String table) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getVersionColumns", catalog, schema, table); |
| } |
| return getVersionColumnsX(catalog, schema, table); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getVersionColumnsX(String catalog, |
| String schema, |
| String table) throws SqlException { |
| checkForClosedConnectionX(); |
| |
| // validate input table, which can not be null |
| if (table == null) { |
| throw new SqlException(agent_.logWriter_, |
| new ClientMessageId(SQLState.TABLE_NAME_CANNOT_BE_NULL)); |
| |
| } |
| ClientPreparedStatement cs = prepareMetaDataQuery( |
| "SYSIBM.SQLSPECIALCOLUMNS(?,?,?,?,?,?,?)"); |
| |
| cs.setIntX(1, SQL_ROWVER); |
| cs.setStringX(2, catalog); |
| cs.setStringX(3, schema); |
| cs.setStringX(4, table); |
| cs.setIntX(5, 0); |
| cs.setShortX(6, (short) 0); |
| cs.setStringX(7, getOptions()); |
| |
| return executeCatalogQuery(cs); |
| } |
| |
| // call stored procedure SQLPrimaryKeys |
| // SYSIBM.SQLPrimaryKeys( |
| // CatalogName varchar(128), |
| // SchemaName varchar(128), |
| // TableName varchar(128), |
| // Options varchar(4000)) |
| // |
| public ResultSet getPrimaryKeys(String catalog, |
| String schema, |
| String table) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getPrimaryKeys", catalog, schema, table); |
| } |
| return getPrimaryKeysX(catalog, schema, table); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getPrimaryKeysX(String catalog, |
| String schema, |
| String table) throws SqlException { |
| checkForClosedConnectionX(); |
| |
| // validate the input table name |
| if (table == null) { |
| throw new SqlException(agent_.logWriter_, |
| new ClientMessageId(SQLState.TABLE_NAME_CANNOT_BE_NULL)); |
| |
| } |
| ClientPreparedStatement cs = prepareMetaDataQuery( |
| "SYSIBM.SQLPRIMARYKEYS(?,?,?,?)"); |
| |
| cs.setStringX(1, catalog); |
| cs.setStringX(2, schema); |
| cs.setStringX(3, table); |
| cs.setStringX(4, getOptions()); |
| return executeCatalogQuery(cs); |
| } |
| |
| |
| // call storlastGetPrimaryKeysResultSet_ed procedure SQLForeignKeys |
| // SYSIBM.SQLForeignKeys( |
| // PKCatalogName varchar(128), |
| // PKSchemaName varchar(128), |
| // PKTableName varchar(128), |
| // FKCatalogName varchar(128), |
| // FKSchemaName varchar(128), |
| // FKTableName varchar(128), |
| // Options varchar(4000)) |
| // |
| public ResultSet getImportedKeys(String catalog, |
| String schema, |
| String table) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getImportedKeys", catalog, schema, table); |
| } |
| return getImportedKeysX(catalog, schema, table); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getImportedKeysX(String catalog, |
| String schema, |
| String table) throws SqlException { |
| checkForClosedConnectionX(); |
| |
| // validate the table name |
| if (table == null) { |
| throw new SqlException(agent_.logWriter_, |
| new ClientMessageId(SQLState.TABLE_NAME_CANNOT_BE_NULL)); |
| } |
| ClientPreparedStatement cs = prepareMetaDataQuery( |
| "SYSIBM.SQLFOREIGNKEYS(?,?,?,?,?,?,?)"); |
| |
| cs.setStringX(1, ""); |
| cs.setStringX(2, null); |
| cs.setStringX(3, ""); |
| cs.setStringX(4, catalog); |
| cs.setStringX(5, schema); |
| cs.setStringX(6, table); |
| // We're passing the keyword EXPORTEDKEY, but this support may not be in the GA version of SPs. |
| // As a workaround in getCrossReference(), we'll just "select * where 0=1" when primaryTable=="" |
| if (connection_.holdability() == ResultSet.HOLD_CURSORS_OVER_COMMIT) { |
| cs.setStringX(7, "DATATYPE='JDBC';IMPORTEDKEY=1; CURSORHOLD=1"); |
| } else { |
| cs.setStringX(7, "DATATYPE='JDBC';IMPORTEDKEY=1; CURSORHOLD=0"); |
| } |
| return executeCatalogQuery(cs); |
| } |
| |
| // call stored procedure SQLForeignKeys |
| // SYSIBM.SQLForeignKeys( |
| // PKCatalogName varchar(128), |
| // PKSchemaName varchar(128), |
| // PKTableName varchar(128), |
| // FKCatalogName varchar(128), |
| // FKSchemaName varchar(128), |
| // FKTableName varchar(128), |
| // Options varchar(4000)) |
| // |
| public ResultSet getExportedKeys(String catalog, |
| String schema, |
| String table) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getExportedKeys", catalog, schema, table); |
| } |
| return getExportedKeysX(catalog, schema, table); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getExportedKeysX(String catalog, |
| String schema, |
| String table) throws SqlException { |
| checkForClosedConnectionX(); |
| |
| // validate the table name |
| if (table == null) { |
| throw new SqlException(agent_.logWriter_, |
| new ClientMessageId(SQLState.TABLE_NAME_CANNOT_BE_NULL)); |
| } |
| ClientPreparedStatement cs = prepareMetaDataQuery( |
| "SYSIBM.SQLFOREIGNKEYS(?,?,?,?,?,?,?)"); |
| |
| cs.setStringX(1, catalog); |
| cs.setStringX(2, schema); |
| cs.setStringX(3, table); |
| cs.setStringX(4, ""); |
| cs.setStringX(5, null); |
| cs.setStringX(6, ""); |
| // We're passing the keyword EXPORTEDKEY, but this support may not be in the GA version of SPs. |
| // As a workaround in getCrossReference(), we'll just "select * where 0=1" when foreignTable=="" |
| if (connection_.holdability() == ResultSet.HOLD_CURSORS_OVER_COMMIT) { |
| cs.setStringX(7, "DATATYPE='JDBC';EXPORTEDKEY=1; CURSORHOLD=1"); |
| } else { |
| cs.setStringX(7, "DATATYPE='JDBC';EXPORTEDKEY=1; CURSORHOLD=0"); |
| } |
| return executeCatalogQuery(cs); |
| } |
| |
| // call stored procedure SQLForeignKeys |
| // SYSIBM.SQLForeignKeys( |
| // PKCatalogName varchar(128), |
| // PKSchemaName varchar(128), |
| // PKTableName varchar(128), |
| // FKCatalogName varchar(128), |
| // FKSchemaName varchar(128), |
| // FKTableName varchar(128), |
| // Options varchar(4000)) |
| // |
| public ResultSet getCrossReference(String primaryCatalog, |
| String primarySchema, |
| String primaryTable, |
| String foreignCatalog, |
| String foreignSchema, |
| String foreignTable) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getCrossReference", primaryCatalog, primarySchema, primaryTable, foreignCatalog, foreignSchema, foreignTable); |
| } |
| return getCrossReferenceX(primaryCatalog, primarySchema, primaryTable, |
| foreignCatalog, foreignSchema, foreignTable); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| |
| private ClientResultSet getCrossReferenceX(String primaryCatalog, |
| String primarySchema, |
| String primaryTable, |
| String foreignCatalog, |
| String foreignSchema, |
| String foreignTable) throws SqlException { |
| checkForClosedConnectionX(); |
| |
| // check input params, primaryTable and foreignTable cannot be null |
| if (primaryTable == null) { |
| throw new SqlException(agent_.logWriter_, |
| new ClientMessageId(SQLState.PRIMARY_TABLE_NAME_IS_NULL)); |
| |
| } |
| |
| if (foreignTable == null) { |
| throw new SqlException(agent_.logWriter_, |
| new ClientMessageId(SQLState.FOREIGN_TABLE_NAME_IS_NULL)); |
| |
| } |
| |
| ClientPreparedStatement cs = prepareMetaDataQuery( |
| "SYSIBM.SQLFOREIGNKEYS(?,?,?,?,?,?,?)"); |
| |
| cs.setStringX(1, primaryCatalog); |
| cs.setStringX(2, primarySchema); |
| cs.setStringX(3, primaryTable); |
| cs.setStringX(4, foreignCatalog); |
| cs.setStringX(5, foreignSchema); |
| cs.setStringX(6, foreignTable); |
| cs.setStringX(7, getOptions()); |
| return executeCatalogQuery(cs); |
| } |
| |
| // call stored procedure SQLGetTypeInfo |
| // SYSIBM.SQLGetTypeInfo (IN DATATYPE SMALLINT, |
| // IN Options VARCHAR(4000)) |
| // |
| // |
| public ResultSet getTypeInfo() throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getTypeInfo"); |
| } |
| return getTypeInfoX(); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getTypeInfoX() throws SqlException { |
| checkForClosedConnectionX(); |
| |
| // check if the last call's resultset is closed or not. |
| ClientPreparedStatement cs = prepareMetaDataQuery( |
| "SYSIBM.SQLGETTYPEINFO(?,?)"); |
| |
| cs.setShortX(1, (short) 0); |
| cs.setStringX(2, getOptions()); |
| return executeCatalogQuery(cs); |
| } |
| |
| |
| // call stored procedure SQLStatistics |
| // SYSIBM.SQLStatistics( |
| // CatalogName varchar(128), |
| // SchemaName varchar(128), |
| // TableName varchar(128), |
| // Unique Smallint, |
| // Reserved Smallint, |
| // Options varchar(4000)) |
| // |
| public ResultSet getIndexInfo(String catalog, |
| String schema, |
| String table, |
| boolean unique, |
| boolean approximate) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getIndexInfo", catalog, schema, table, unique, approximate); |
| } |
| return getIndexInfoX(catalog, schema, table, unique, approximate); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getIndexInfoX(String catalog, |
| String schema, |
| String table, |
| boolean unique, |
| boolean approximate) throws SqlException { |
| checkForClosedConnectionX(); |
| |
| // validate the input table name |
| if (table == null) { |
| throw new SqlException(agent_.logWriter_, |
| new ClientMessageId(SQLState.TABLE_NAME_CANNOT_BE_NULL)); |
| } |
| ClientPreparedStatement cs = prepareMetaDataQuery( |
| "SYSIBM.SQLSTATISTICS(?,?,?,?,?,?)"); |
| |
| cs.setStringX(1, catalog); |
| cs.setStringX(2, schema); |
| cs.setStringX(3, table); |
| |
| if (unique) { |
| cs.setShortX(4, SQL_INDEX_UNIQUE); |
| } else { |
| cs.setShortX(4, SQL_INDEX_ALL); |
| } |
| |
| if (approximate) { |
| cs.setShortX(5, (short) 1); |
| } else { |
| cs.setShortX(5, (short) 0); |
| } |
| |
| cs.setStringX(6, getOptions()); |
| return executeCatalogQuery(cs); |
| } |
| |
| |
| //--------------------------JDBC 2.0----------------------------- |
| |
| public ResultSet getUDTs(String catalog, |
| String schemaPattern, |
| String typeNamePattern, |
| int[] types) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getUDTs", catalog, schemaPattern, typeNamePattern, types); |
| } |
| return getUDTsX(catalog, schemaPattern, typeNamePattern, types); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getUDTsX(String catalog, |
| String schemaPattern, |
| String typeNamePattern, |
| int[] types) throws SqlException { |
| checkForClosedConnectionX(); |
| |
| ClientPreparedStatement cs = prepareMetaDataQuery( |
| "SYSIBM.SQLUDTS(?,?,?,?,?)"); |
| |
| cs.setStringX(1, catalog); |
| cs.setStringX(2, schemaPattern); |
| cs.setStringX(3, typeNamePattern); |
| int i = 0; |
| String udtTypes = ""; |
| while (types != null && i < types.length) { |
| if (i > 0) { |
| udtTypes = udtTypes.concat(","); |
| } |
| udtTypes = udtTypes.concat(String.valueOf(types[i])); |
| i++; |
| } |
| cs.setStringX(4, udtTypes); |
| cs.setStringX(5, getOptions()); |
| return executeCatalogQuery(cs); |
| } |
| |
| |
| // helper method for the catalog queries only |
| private String getOptions() { |
| int cursorHold; |
| if (connection_.holdability() == ResultSet.HOLD_CURSORS_OVER_COMMIT) { |
| cursorHold = 1; |
| } else { |
| cursorHold = 0; |
| } |
| return "DATATYPE='JDBC';DYNAMIC=0;REPORTPUBLICPRIVILEGES=1;CURSORHOLD=" + cursorHold; |
| |
| } |
| |
| // Derby uses a PreparedStatement argument rather than a callable statement |
| private ClientResultSet executeCatalogQuery(ClientPreparedStatement cs) |
| throws SqlException { |
| try { |
| return cs.executeQueryX(); |
| } catch (SqlException e) { |
| if (e.getErrorCode() == -440) { |
| SqlException newException = new SqlException(agent_.logWriter_, |
| new ClientMessageId(SQLState.STORED_PROC_NOT_INSTALLED)); |
| newException.setNextException(e); |
| throw newException; |
| } else if (e.getErrorCode() == -444) { |
| SqlException newException = new SqlException(agent_.logWriter_, |
| new ClientMessageId(SQLState.STORED_PROC_LOAD_MODULE_NOT_FOUND)); |
| newException.setNextException(e); |
| throw newException; |
| } else { |
| throw e; |
| } |
| } |
| } |
| |
| public Connection getConnection() throws SQLException { |
| checkForClosedConnection(); |
| return connection_; |
| } |
| |
| // ------------------- JDBC 3.0 ------------------------- |
| |
| public boolean supportsNamedParameters() throws SQLException { |
| checkForClosedConnection(); |
| return false; |
| } |
| |
| public boolean supportsMultipleOpenResults() throws SQLException { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| public boolean supportsGetGeneratedKeys() throws SQLException { |
| checkForClosedConnection(); |
| return false; |
| } |
| |
| public ResultSet getSuperTypes(String catalog, |
| String schemaPattern, |
| String typeNamePattern) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getSuperTypes", catalog, schemaPattern, typeNamePattern); |
| } |
| return getSuperTypesX(); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getSuperTypesX() throws SqlException { |
| checkForClosedConnectionX(); |
| String sql = "SELECT CAST(NULL AS VARCHAR(128)) AS TYPE_CAT," + |
| "CAST(NULL AS VARCHAR(128)) AS TYPE_SCHEM," + |
| "VARCHAR('', 128) AS TYPE_NAME," + |
| "CAST(NULL AS VARCHAR(128)) AS SUPERTYPE_CAT," + |
| "CAST(NULL AS VARCHAR(128)) AS SUPERTYPE_SCHEM," + |
| "VARCHAR('', 128) AS SUPERTYPE_NAME " + |
| "FROM SYSIBM.SYSDUMMY1 WHERE 1=0 WITH UR "; |
| ClientPreparedStatement ps = |
| connection_.prepareDynamicCatalogQuery(sql); |
| return ps.executeQueryX(); |
| } |
| |
| public ResultSet getSuperTables(String catalog, |
| String schemaPattern, |
| String tableNamePattern) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getSuperTables", catalog, schemaPattern, tableNamePattern); |
| } |
| return getSuperTablesX(); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getSuperTablesX() throws SqlException { |
| checkForClosedConnectionX(); |
| String sql = "SELECT CAST(NULL AS VARCHAR(128)) AS TABLE_CAT," + |
| "CAST(NULL AS VARCHAR(128)) AS TABLE_SCHEM," + |
| "VARCHAR('', 128) AS TABLE_NAME," + |
| "VARCHAR('', 128) AS SUPERTABLE_NAME FROM SYSIBM.SYSDUMMY1 " + |
| "WHERE 1=0 WITH UR"; |
| ClientPreparedStatement ps = |
| connection_.prepareDynamicCatalogQuery(sql); |
| return ps.executeQueryX(); |
| } |
| |
| |
| public ResultSet getAttributes(String catalog, |
| String schemaPattern, |
| String typeNamePattern, |
| String attributeNamePattern) throws SQLException { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getAttributes", catalog, schemaPattern, typeNamePattern, attributeNamePattern); |
| } |
| return getAttributesX(); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getAttributesX() throws SqlException { |
| checkForClosedConnectionX(); |
| String sql = "SELECT CAST(NULL AS VARCHAR(128)) AS TYPE_CAT," + |
| "CAST(NULL AS VARCHAR(128)) AS TYPE_SCHEM," + |
| "VARCHAR('', 128) AS TYPE_NAME," + |
| "VARCHAR('',128) AS ATTR_NAME," + |
| "0 AS DATA_TYPE," + |
| "VARCHAR('',129) AS ATTR_TYPE_NAME," + |
| "0 AS ATTR_SIZE," + |
| "0 AS DECIMAL_DIGITS," + |
| "0 AS NUM_PREC_RADIX," + |
| "2 AS NULLABLE," + |
| "CAST(NULL AS VARCHAR(254)) AS REMARKS," + |
| "CAST(NULL AS VARCHAR(128)) AS ATTR_DEF," + |
| "0 AS SQL_DATA_TYPE," + |
| "0 AS SQL_DATETIME_SUB," + |
| "0 AS CHAR_OCTET_LENGTH," + |
| "0 AS ORDINAL_POSITION," + |
| "VARCHAR('',128) AS IS_NULLABLE," + |
| "CAST(NULL AS VARCHAR(128)) AS SCOPE_CATALOG," + |
| "CAST(NULL AS VARCHAR(128)) AS SCOPE_SCHEMA," + |
| "CAST(NULL AS VARCHAR(128)) AS SCOPE_TABLE," + |
| "CAST(NULL AS SMALLINT) AS SOURCE_DATA_TYPE " + |
| "FROM SYSIBM.SYSDUMMY1 WHERE 1=0 WITH UR"; |
| ClientPreparedStatement ps = |
| connection_.prepareDynamicCatalogQuery(sql); |
| return ps.executeQueryX(); |
| } |
| |
| public boolean supportsResultSetHoldability(int holdability) throws SQLException { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| public int getResultSetHoldability() throws SQLException { |
| checkForClosedConnection(); |
| return ResultSet.HOLD_CURSORS_OVER_COMMIT; |
| } |
| |
| public int getDatabaseMajorVersion() throws SQLException { |
| checkForClosedConnection(); |
| return productLevel_.versionLevel_; |
| } |
| |
| public int getDatabaseMinorVersion() throws SQLException { |
| checkForClosedConnection(); |
| return productLevel_.releaseLevel_; |
| } |
| |
| public int getJDBCMajorVersion() throws SQLException { |
| checkForClosedConnection(); |
| return 4; |
| } |
| |
| public int getJDBCMinorVersion() throws SQLException { |
| checkForClosedConnection(); |
| return JVMInfo.jdbcMinorVersion(); |
| } |
| |
| public int getSQLStateType() throws SQLException { |
| checkForClosedConnection(); |
| return sqlStateSQL99; |
| } |
| |
| public boolean locatorsUpdateCopy() throws SQLException { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| public boolean supportsStatementPooling() throws SQLException { |
| checkForClosedConnection(); |
| return false; |
| } |
| |
| //-----------------------------helper methods--------------------------------- |
| |
| // Set flags describing the level of support for this connection. |
| // Flags will be set based on manager level and/or specific product identifiers. |
| // Support for a specific server version can be set as follows. For example |
| // if (productLevel_.greaterThanOrEqualTo(11,1,0)) |
| // supportsTheBestThingEver = true |
| // |
| // WARNING WARNING WARNING !!!! |
| // |
| // If you define an instance variable of NetDatabaseMetaData that |
| // you want computeFeatureSet_() to compute, DO NOT assign an |
| // initial value to the variable in the |
| // declaration. NetDatabaseMetaData's constructor will invoke |
| // DatabaseMetaData's constructor, which then invokes |
| // computeFeatureSet_(). Initialization of instance variables in |
| // NetDatabaseMetaData will happen *after* the invocation of |
| // computeFeatureSet_() and will therefore overwrite the computed |
| // values. So, LEAVE INSTANCE VARIABLES UNINITIALIZED! |
| // |
| // END OF WARNING |
| private void computeFeatureSet_() { |
| |
| // Support for QRYCLSIMP was added in 10.2.0 |
| if (productLevel_.greaterThanOrEqualTo(10, 2, 0)) { |
| supportsQryclsimp_ = true; |
| } else { |
| supportsQryclsimp_ = false; |
| } |
| |
| supportsLayerBStreaming_ = |
| productLevel_.greaterThanOrEqualTo(10, 3, 0); |
| |
| supportsSessionDataCaching_ = |
| productLevel_.greaterThanOrEqualTo(10, 4, 0); |
| |
| supportsUDTs_ = |
| productLevel_.greaterThanOrEqualTo(10, 6, 0); |
| |
| supportsTimestampNanoseconds_ = |
| productLevel_.greaterThanOrEqualTo(10, 6, 0); |
| |
| supportsEXTDTAAbort_ = |
| productLevel_.greaterThanOrEqualTo(10, 6, 0); |
| |
| supportsBooleanValues_ = |
| productLevel_.greaterThanOrEqualTo(10, 7, 0); |
| |
| supportsBooleanParameterTransport_ = |
| productLevel_.greaterThanOrEqualTo(10, 8, 0); |
| |
| supportsLongRDBNAM_ = |
| productLevel_.greaterThanOrEqualTo(10, 11, 0); |
| } |
| |
| /** |
| * Check whether the server has full support for the QRYCLSIMP |
| * parameter in OPNQRY. |
| * |
| * @return true if QRYCLSIMP is fully supported |
| */ |
| final public boolean serverSupportsQryclsimp() { |
| return supportsQryclsimp_; |
| } |
| |
| final public boolean serverSupportsLayerBStreaming() { |
| return supportsLayerBStreaming_; |
| } |
| |
| /** |
| * Check if server supports session data caching |
| * @return true if the server supports this |
| */ |
| final public boolean serverSupportsSessionDataCaching() { |
| return supportsSessionDataCaching_; |
| } |
| |
| /** |
| * Check if server supports UDTs |
| * @return true if the server supports this |
| */ |
| final public boolean serverSupportsUDTs() { |
| return supportsUDTs_; |
| } |
| |
| /** |
| * Check if server supports nanoseconds in timestamps |
| * @return true if the server supports this |
| */ |
| final public boolean serverSupportsTimestampNanoseconds() { |
| return supportsTimestampNanoseconds_; |
| } |
| |
| /** |
| * Check if server supports product specific EXTDTA abort protocol. |
| * @return {@code true} if the server supports this. |
| */ |
| final public boolean serverSupportsEXTDTAAbort() { |
| return supportsEXTDTAAbort_; |
| } |
| |
| /** |
| * Check if server supports boolean values |
| * @return true if the server supports this |
| */ |
| private boolean serverSupportsBooleanValues() { |
| return supportsBooleanValues_; |
| } |
| |
| /** |
| * Check if the server accepts receiving booleans as parameter values. |
| * @return true if the server supports this |
| */ |
| final public boolean serverSupportsBooleanParameterTransport() { |
| return supportsBooleanParameterTransport_; |
| } |
| |
| final public boolean serverSupportLongRDBNAM() { |
| return supportsLongRDBNAM_; |
| } |
| |
| //------------helper methods for meta data info call methods------------------ |
| |
| |
| private boolean getMetaDataInfoBoolean(int infoCallIndex) throws SQLException { |
| try |
| { |
| if ( !metaDataInfoIsCached_) { metaDataInfoCall(); } |
| |
| if ( serverSupportsBooleanValues() ) |
| { |
| return ((Boolean) metaDataInfoCache_[infoCallIndex]).booleanValue(); |
| } |
| else |
| { |
| return ((Integer) metaDataInfoCache_[infoCallIndex]).intValue() != 0; |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private int getMetaDataInfoInt(int infoCallIndex) throws SQLException { |
| try |
| { |
| if (metaDataInfoIsCached_) { |
| return ((Integer) metaDataInfoCache_[infoCallIndex]).intValue(); |
| } |
| metaDataInfoCall(); |
| return ((Integer) metaDataInfoCache_[infoCallIndex]).intValue(); |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| |
| } |
| |
| private String getMetaDataInfoString(int infoCallIndex) throws SQLException { |
| try |
| { |
| if (metaDataInfoIsCached_) { |
| return (String) metaDataInfoCache_[infoCallIndex]; |
| } |
| metaDataInfoCall(); |
| return (String) metaDataInfoCache_[infoCallIndex]; |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| |
| private boolean getMetaDataInfoBooleanWithType(int infoCallIndex, int type) |
| throws SQLException { |
| |
| boolean clientValue = |
| getMetaDataInfoBooleanWithTypeClient(infoCallIndex, type); |
| |
| // DERBY-1252. In Derby <= 10.x, clients (incl JCC) do not have |
| // logic to negotiate down these values with the server, so |
| // for features introduced with 10.x, x >= 2 (e.g. SUR |
| // DERBY-775, in 10.2), the server will return 10.0 values for |
| // any version 10.x so as not to break existing apps running |
| // an older 10 client (e.g. 10.1 client for DERBY-775). |
| // Reciprocally, this means clients at 10.x, where x => 2, |
| // must disregard the server's (too conservative) answers for |
| // these features, see logic in |
| // getMetaDataInfoBooleanWithTypeClient. |
| // |
| // For Derby >= 11, the down-negotiation code below which is |
| // presently commented out should be activated, and the values |
| // returned from the server should once more reflect reality. |
| |
| // Commented out till we hit Derby 11: |
| // |
| // boolean serverValue = |
| // getMetaDataInfoBooleanWithTypeServer(infoCallIndex, type); |
| // |
| // return clientValue && serverValue; |
| |
| return clientValue; |
| } |
| |
| |
| // Client's view of boolean metadata. |
| // |
| // For values which depend on (added) functionality in *both* the |
| // client and the server, the client should have its own view of |
| // all such values here. For other values, it can defer to the |
| // server. This is a prerequisite for negotiating down in a mixed |
| // client/Server context. Note that metadata negotiation should |
| // mirror the similar negotiation for use of the feature itself, |
| // for example, for scrollable updatable result sets of type |
| // insensitive, the server will downgrade to read-only if it is |
| // older than 10.2. |
| // |
| // See also comments in getMetaDataInfoBooleanWithType and |
| // engine/org/apache/derby/impl/sql/catalog/metadata_net.properties. |
| // |
| private boolean getMetaDataInfoBooleanWithTypeClient(int infoCallIndex, |
| int type) |
| throws SQLException { |
| |
| switch (infoCallIndex) { |
| case updatesAreDetected__: |
| case deletesAreDetected__: |
| case ownUpdatesAreVisible__: |
| case ownDeletesAreVisible__: |
| |
| if (productLevel_.greaterThanOrEqualTo(10,2,0) && |
| type == ResultSet.TYPE_SCROLL_INSENSITIVE) { |
| return true; |
| } else { |
| return getMetaDataInfoBooleanWithTypeServer(infoCallIndex, |
| type); |
| } |
| case insertsAreDetected__: |
| case ownInsertsAreVisible__: |
| if (productLevel_.greaterThanOrEqualTo(10,2,0) && |
| type == ResultSet.TYPE_SCROLL_INSENSITIVE) { |
| return false; |
| } else { |
| return getMetaDataInfoBooleanWithTypeServer(infoCallIndex, |
| type); |
| } |
| default: |
| return getMetaDataInfoBooleanWithTypeServer(infoCallIndex, |
| type); |
| } |
| } |
| |
| |
| private boolean getMetaDataInfoBooleanWithTypeServer(int infoCallIndex, |
| int type) |
| throws SQLException { |
| |
| // Stored Procedure will return a String containing a |
| // comma seperated list of all the supported result Set types |
| // not throwing any exception right now even if the the type is wrong as per the spec |
| try |
| { |
| String returnedFromSP = null; |
| if (metaDataInfoIsCached_) { |
| returnedFromSP = (String) metaDataInfoCache_[infoCallIndex]; |
| } else { |
| metaDataInfoCall(); |
| returnedFromSP = (String) metaDataInfoCache_[infoCallIndex]; |
| } |
| StringTokenizer st = new StringTokenizer(returnedFromSP, ","); |
| while (st.hasMoreTokens()) { |
| if ((Integer.parseInt(st.nextToken())) == type) { |
| return true; |
| } |
| } |
| return false; |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private boolean getMetaDataInfoInt_SupportsResultSetConcurrency(int infoCallIndex, int type, int concurrency) throws SQLException { |
| // The stored procured will return a String containing a list |
| // of lists: For each result set type in the outer list, an |
| // inner list gives the allowed concurrencies for that type: |
| // The encoding syntax is reproduced here from the server file |
| // 'metadata_net.properties (please keep in synch!): |
| // |
| // String syntax: |
| // <type> { "," <concurrency>}* { ";" <type> { "," <concurrency>}* }}* |
| // |
| // <type> ::= <the integer value for that type from interface java.sql.Resultset |
| // i.e. TYPE_FORWARD_ONLY is 1003> |
| // <concurrency> ::= <the integer value for that concurrency |
| // from interface java.sql.Resultset, i.e. |
| // CONCUR_UPDATABLE is 1008> |
| try |
| { |
| String returnedFromSP = null; |
| if (metaDataInfoIsCached_) { |
| returnedFromSP = (String) metaDataInfoCache_[infoCallIndex]; |
| } else { |
| metaDataInfoCall(); |
| returnedFromSP = (String) metaDataInfoCache_[infoCallIndex]; |
| } |
| StringTokenizer st = new StringTokenizer(returnedFromSP, ";"); |
| while (st.hasMoreTokens()) { |
| StringTokenizer stForConc = |
| new StringTokenizer(st.nextToken(), ","); |
| if ((Integer.parseInt(stForConc.nextToken())) == type) { |
| while (stForConc.hasMoreTokens()) { |
| if ((Integer.parseInt(stForConc.nextToken())) == concurrency) { |
| return true; |
| } |
| } |
| return false; |
| } |
| } |
| return false; |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private boolean getMetaDataInfoBoolean_supportsConvert(int infoCallIndex, int fromType, int toType) throws SQLException { |
| // The Stored procedure will return a String contain a list of all the valid conversions it support |
| // For eg. If the database conversion from char(1) to date(91), time(92) and |
| // Decimal(3) to char(1) ,double(8) |
| // then StoredProcedure string will return "1,91,92;3,1,8" |
| // see how fromTypes are seperated by ";" |
| try |
| { |
| String returnedFromSP = null; |
| if (metaDataInfoIsCached_) { |
| returnedFromSP = (String) metaDataInfoCache_[infoCallIndex]; |
| } else { |
| metaDataInfoCall(); |
| returnedFromSP = (String) metaDataInfoCache_[infoCallIndex]; |
| } |
| StringTokenizer st = new StringTokenizer(returnedFromSP, ";"); |
| while (st.hasMoreTokens()) { |
| StringTokenizer stForType = |
| new StringTokenizer(st.nextToken(), ","); |
| |
| if ((Integer.parseInt(stForType.nextToken())) == fromType) { |
| while (st.hasMoreTokens()) { |
| if ((Integer.parseInt(st.nextToken())) == toType) { |
| return true; |
| } |
| } |
| return false; |
| } |
| } |
| return false; |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| // We synchronize at this level so that we don't have to synchronize all |
| // the meta data info methods. If we just return hardwired answers we don't |
| // need to synchronize at the higher level. |
| private void metaDataInfoCall() throws SqlException { |
| synchronized (connection_) { |
| ClientResultSet rs; |
| |
| // These remote calls return a result set containing a single row. |
| // Each column in the row corresponds to a particular get meta data info |
| // method. |
| ClientPreparedStatement ps = prepareMetaDataQuery( |
| "SYSIBM.MetaData()"); |
| rs = (ClientResultSet) ps.executeQueryX(); |
| rs.nextX(); |
| int ColumnCount; |
| try { |
| ColumnCount = ((ColumnMetaData) rs.getMetaDataX()).getColumnCount(); |
| } catch ( SQLException se ) { |
| throw new SqlException(se); |
| } |
| for (int infoCallIndex = 0; |
| (infoCallIndex < ColumnCount && infoCallIndex < metaDataInfoCache_.length); |
| infoCallIndex++) { |
| metaDataInfoCache_[infoCallIndex] = rs.getObjectX(infoCallIndex + 1); |
| } |
| metaDataInfoIsCached_ = true; |
| rs.closeX(); |
| } |
| } |
| |
| // ------------------- JDBC 4.0 ------------------------- |
| |
| /** |
| * Retrieves whether this database supports invoking user-defined |
| * or vendor functions using the stored procedure escape syntax. |
| * |
| * @return <code>true</code>, since Derby supports the escape syntax |
| * @exception SQLException if a database access error occurs |
| */ |
| public final boolean supportsStoredFunctionsUsingCallSyntax() |
| throws SQLException |
| { |
| checkForClosedConnection(); |
| return true; |
| } |
| |
| /** |
| * Retrieves whether an <code>SQLException</code> will cause all |
| * open <code>ResultSet</code>s to be closed when auto-commit is |
| * <code>true</code>. |
| * |
| * @return <code>false</code>, since Derby does not close all open |
| * result sets when an error occurs |
| * @exception SQLException if a database access error occurs |
| */ |
| public final boolean autoCommitFailureClosesAllResultSets() |
| throws SQLException |
| { |
| checkForClosedConnection(); |
| return false; |
| } |
| |
| /** |
| * Get the schema names available in this database. The results |
| * are ordered by schema name. |
| * |
| * <p>The schema columns are: |
| * <ol> |
| * <li><strong>TABLE_SCHEM</strong> String => schema name</li> |
| * <li><strong>TABLE_CATALOG</strong> String => catalog name |
| * (may be <code>null</code>)</li> |
| * </ol> |
| * |
| * @param catalog catalog name used to narrow down the search; "" |
| * means no catalog, <code>null</code> means any catalog |
| * @param schemaPattern schema name used to narrow down the |
| * search, <code>null</code> means schema name should not be used |
| * to narrow down search |
| * @return a <code>ResultSet</code> object in which each row is a |
| * schema description |
| * @exception SQLException if a database error occurs |
| */ |
| public ResultSet getSchemas(String catalog, String schemaPattern) |
| throws SQLException |
| { |
| try { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, "getSchemas"); |
| } |
| return getSchemasX(catalog, schemaPattern); |
| } |
| } catch (SqlException se) { |
| throw se.getSQLException(); |
| } |
| } |
| |
| /** |
| * Untraced version of <code>getSchemas(String, String)</code>. |
| * |
| * @param catalog catalog name |
| * @param schemaPattern pattern for schema name |
| * @return a <code>ResultSet</code> value |
| * @exception SqlException if a database error occurs |
| * @see #getSchemas(String, String) |
| */ |
| private ClientResultSet getSchemasX(String catalog, String schemaPattern) |
| throws SqlException |
| { |
| checkForClosedConnectionX(); |
| |
| // If the server has not implemented support for JDBC 4.0, |
| // SYSIBM.SQLTABLES does not recognize the GETSCHEMAS=2 |
| // option, and it will call getTables() instead of |
| // getSchemas(). Therefore, check server version and throw an |
| // exception if the server does not support JDBC 4.0. |
| checkServerJdbcVersionX("getSchemas(String, String)", 4, 0); |
| |
| String call = "SYSIBM.SQLTABLES(?, ?, '', '', 'GETSCHEMAS=2')"; |
| ClientPreparedStatement cs = prepareMetaDataQuery(call); |
| if (catalog == null) { |
| cs.setNullX(1, Types.VARCHAR); |
| } else { |
| cs.setStringX(1, catalog); |
| } |
| if (schemaPattern == null) { |
| cs.setNullX(2, Types.VARCHAR); |
| } else { |
| cs.setStringX(2, schemaPattern); |
| } |
| return cs.executeQueryX(); |
| } |
| |
| /** |
| * Returns a list of the client info properties supported by the |
| * driver. The result set contains the following columns: |
| * |
| * <p> |
| * <ol> |
| * <li>NAME String=> The name of the client info property.</li> |
| * <li>MAX_LEN int=> The maximum length of the value for the |
| * property.</li> |
| * <li>DEFAULT_VALUE String=> The default value of the property.</li> |
| * <li>DESCRIPTION String=> A description of the property.</li> |
| * </ol> |
| * |
| * <p>The <code>ResultSet</code> is sorted by the NAME column. |
| * |
| * @return A <code>ResultSet</code> object; each row is a |
| * supported client info property |
| * @exception SQLException if an error occurs |
| */ |
| public ResultSet getClientInfoProperties() throws SQLException { |
| try { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry(this, |
| "getClientInfoProperties"); |
| } |
| return getClientInfoPropertiesX(); |
| } |
| } catch (SqlException se) { |
| throw se.getSQLException(); |
| } |
| } |
| |
| /** |
| * Untraced version of <code>getClientInfoProperties()</code>. |
| * Returns an empty <code>ResultSet</code> with the correct column |
| * names. |
| * |
| * @return a <code>ResultSet</code> value |
| * @exception SqlException if a database error occurs |
| * @see #getClientInfoProperties |
| */ |
| private ClientResultSet getClientInfoPropertiesX() throws SqlException { |
| checkForClosedConnectionX(); |
| final String sql = |
| "SELECT CAST(NULL AS VARCHAR(128)) AS NAME, " + |
| "CAST(NULL AS INT) AS MAX_LEN, " + |
| "CAST(NULL AS VARCHAR(128)) AS DEFAULT_VALUE, " + |
| "CAST(NULL AS VARCHAR(128)) AS DESCRIPTION " + |
| "FROM SYSIBM.SYSDUMMY1 WHERE 1=0 WITH UR"; |
| ClientPreparedStatement ps = |
| connection_.prepareDynamicCatalogQuery(sql); |
| return ps.executeQueryX(); |
| } |
| |
| /** |
| * Indicates whether or not this data source supports the SQL |
| * <code>ROWID</code> type. Since Derby does not support the |
| * <code>ROWID</code> type, return <code>ROWID_UNSUPPORTED</code>. |
| * |
| * @return <code>ROWID_UNSUPPORTED</code> |
| * @exception SQLException if a database access error occurs |
| */ |
| public RowIdLifetime getRowIdLifetime() throws SQLException { |
| checkForClosedConnection(); |
| return RowIdLifetime.ROWID_UNSUPPORTED; |
| } |
| |
| /** |
| * Returns false unless <code>interfaces</code> is implemented |
| * |
| * @param interfaces a Class defining an interface. |
| * @return true if this implements the interface or |
| * directly or indirectly wraps an object |
| * that does. |
| * @throws java.sql.SQLException if an error occurs while determining |
| * whether this is a wrapper for an object |
| * with the given interface. |
| */ |
| public boolean isWrapperFor(Class<?> interfaces) throws SQLException { |
| return interfaces.isInstance(this); |
| } |
| |
| /** |
| * Returns <code>this</code> if this class implements the interface |
| * |
| * @param interfaces a Class defining an interface |
| * @return an object that implements the interface |
| * @throws SQLException if no object if found that implements the |
| * interface |
| */ |
| public <T> T unwrap(Class<T> interfaces) |
| throws SQLException { |
| try { |
| return interfaces.cast(this); |
| } catch (ClassCastException cce) { |
| throw new SqlException(null, |
| new ClientMessageId(SQLState.UNABLE_TO_UNWRAP), |
| interfaces).getSQLException(); |
| } |
| } |
| |
| // ------------------- JDBC 4.1 ------------------------- |
| |
| /** See DatabaseMetaData javadoc */ |
| public boolean generatedKeyAlwaysReturned() { return true; } |
| |
| public ResultSet getPseudoColumns |
| ( String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern ) |
| throws SQLException |
| { |
| try |
| { |
| synchronized (connection_) { |
| if (agent_.loggingEnabled()) { |
| agent_.logWriter_.traceEntry |
| ( this, "getPseudoColumns", catalog, schemaPattern, tableNamePattern, columnNamePattern ); |
| } |
| return getPseudoColumnsX(); |
| } |
| } |
| catch ( SqlException se ) |
| { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private ClientResultSet getPseudoColumnsX() throws SqlException |
| { |
| checkForClosedConnectionX(); |
| String sql = |
| "SELECT \n" + |
| " CAST(NULL AS VARCHAR(128)) AS TABLE_CAT, \n" + |
| " CAST(NULL AS VARCHAR(128)) AS TABLE_SCHEM, \n" + |
| " VARCHAR('', 128) AS TABLE_NAME, \n" + |
| " VARCHAR('',128) AS COLUMN_NAME, \n" + |
| " CAST(1 AS INT) AS DATA_TYPE, \n" + |
| " CAST(1 AS INT) AS COLUMN_SIZE, \n" + |
| " CAST(NULL AS INT) AS DECIMAL_DIGITS, \n" + |
| " CAST(NULL AS INT) AS NUM_PREC_RADIX, \n" + |
| " VARCHAR('',128) AS COLUMN_USAGE, \n" + |
| " CAST(NULL AS VARCHAR(32672)) AS REMARKS, \n" + |
| " CAST(NULL AS INT) AS CHAR_OCTET_LENGTH, \n" + |
| " VARCHAR('NO',128) AS IS_NULLABLE \n" + |
| " FROM SYSIBM.SYSDUMMY1 WHERE 1=0 WITH UR" |
| ; |
| ClientPreparedStatement ps = |
| connection_.prepareDynamicCatalogQuery(sql); |
| return ps.executeQueryX(); |
| } |
| |
| // ------------------- JDBC 4.2 ------------------------- |
| |
| /** See DatabaseMetaData javadoc */ |
| public long getMaxLogicalLobSize() { return 0L; } |
| |
| /** Derby does not support the Types.REF_CURSOR type. */ |
| public boolean supportsRefCursors() { return false; } |
| |
| |
| //----------------------------helper methods---------------------------------- |
| |
| |
| private ClientPreparedStatement prepareMetaDataQuery(String cmd) |
| throws SqlException { |
| ClientPreparedStatement ps; |
| |
| ps = (ClientPreparedStatement) |
| connection_.prepareStatementX("CALL " + cmd, |
| ResultSet.TYPE_FORWARD_ONLY, |
| ResultSet.CONCUR_READ_ONLY, |
| connection_.holdability(), |
| ClientStatement.NO_GENERATED_KEYS, |
| null, null); |
| return ps; |
| } |
| |
| /** |
| * A "public" version of checkForClosedConnection() that throws |
| * SQLException instead of SqlException. In particular this is used |
| * by all the DatabaseMetadata methods |
| */ |
| protected void checkForClosedConnection() throws SQLException |
| { |
| try { |
| checkForClosedConnectionX(); |
| } catch ( SqlException se ) { |
| throw se.getSQLException(); |
| } |
| } |
| |
| private void checkForClosedConnectionX() throws SqlException { |
| if (connection_.isClosedX()) { |
| agent_.checkForDeferredExceptions(); |
| throw new SqlException(agent_.logWriter_, |
| new ClientMessageId(SQLState.NO_CURRENT_CONNECTION)); |
| |
| } else { |
| agent_.checkForDeferredExceptions(); |
| } |
| } |
| |
| /** |
| * Checks whether the server supports a JDBC version. If the |
| * server does not support the JDBC version, an exception is |
| * thrown. |
| * |
| * @param method name of the method for which support is needed on |
| * the server (used in exception message) |
| * @param major minimum JDBC major version |
| * @param minor minimum JDBC minor version if major version matches |
| * @exception SqlException if the server does not support the |
| * specified JDBC version |
| */ |
| private void checkServerJdbcVersionX(String method, int major, int minor) |
| throws SqlException |
| { |
| if (serverJdbcMajorVersion < major || |
| (serverJdbcMajorVersion == major && |
| serverJdbcMinorVersion < minor)) { |
| throw new SqlException(agent_.logWriter_, |
| new ClientMessageId(SQLState.JDBC_METHOD_NOT_SUPPORTED_BY_SERVER), method); |
| } |
| } |
| } |