0001: /*
0002:
0003: Derby - Class org.apache.derby.client.am.DatabaseMetaData
0004:
0005: Licensed to the Apache Software Foundation (ASF) under one or more
0006: contributor license agreements. See the NOTICE file distributed with
0007: this work for additional information regarding copyright ownership.
0008: The ASF licenses this file to You under the Apache License, Version 2.0
0009: (the "License"); you may not use this file except in compliance with
0010: the License. You may obtain a copy of the License at
0011:
0012: http://www.apache.org/licenses/LICENSE-2.0
0013:
0014: Unless required by applicable law or agreed to in writing, software
0015: distributed under the License is distributed on an "AS IS" BASIS,
0016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: See the License for the specific language governing permissions and
0018: limitations under the License.
0019:
0020: */
0021:
0022: package org.apache.derby.client.am;
0023:
0024: import java.sql.SQLException;
0025:
0026: import org.apache.derby.jdbc.ClientDataSource;
0027: import org.apache.derby.shared.common.reference.SQLState;
0028: import org.apache.derby.shared.common.reference.JDBC30Translation;
0029:
0030: // Note:
0031: // Tag members using the strictest visibility.
0032: // Note:
0033: // Mark methods synchronized if and only if they update object state and are public.
0034: // Not yet done:
0035: // Application heap data should be copied for shiraz.
0036: // Save for future pass to avoid clutter during development.
0037: // Not yet done:
0038: // Apply meaning-preserving program transformations for performance,
0039: // including the replacement of slow ADTs with faster unsynchronized ADTs.
0040: // Save for future pass to avoid clutter during development.
0041: // Not yet done:
0042: // Assign an ErrorKey, ResourceKey, and Resource for each throw statement.
0043: // Save for future pass to avoid maintenance during development.
0044:
0045: public abstract class DatabaseMetaData implements
0046: java.sql.DatabaseMetaData {
0047: //----------------------------- constants -----------------------------------
0048:
0049: private final static short SQL_BEST_ROWID = 1;
0050: private final static short SQL_ROWVER = 2;
0051:
0052: private final static short SQL_INDEX_UNIQUE = 0;
0053: private final static short SQL_INDEX_ALL = 1;
0054:
0055: //---------------------navigational members-----------------------------------
0056:
0057: protected Agent agent_;
0058: protected Connection connection_;
0059:
0060: //-----------------------------state------------------------------------------
0061:
0062: private final static int numberOfMetaDataInfoMethods__ = 108;
0063: private Object[] metaDataInfoCache_ = new Object[numberOfMetaDataInfoMethods__];
0064: private boolean metaDataInfoIsCached_ = false;
0065:
0066: public ProductLevel productLevel_;
0067:
0068: /** The JDBC major version supported by the server. */
0069: private final int serverJdbcMajorVersion;
0070: /** The JDBC minor version supported by the server. */
0071: private final int serverJdbcMinorVersion;
0072:
0073: public boolean useServerXAState_ = true;
0074:
0075: //---------------------constructors/finalizer---------------------------------
0076:
0077: protected DatabaseMetaData(Agent agent, Connection connection,
0078: ProductLevel productLevel) {
0079: agent_ = agent;
0080: connection_ = connection;
0081: productLevel_ = productLevel;
0082: computeFeatureSet_();
0083: if (connection.isXAConnection()) {
0084: connection.xaHostVersion_ = productLevel_.versionLevel_;
0085: }
0086: if (productLevel_.lessThan(10, 2, 0)) {
0087: serverJdbcMajorVersion = 3;
0088: serverJdbcMinorVersion = 0;
0089: } else {
0090: serverJdbcMajorVersion = 4;
0091: serverJdbcMinorVersion = 0;
0092: }
0093: }
0094:
0095: // ---------------------------jdbc 1------------------------------------------
0096:
0097: //----------------------------------------------------------------------
0098: // First, a variety of minor information about the target database.
0099:
0100: private final static int allProceduresAreCallable__ = 0;
0101:
0102: public boolean allProceduresAreCallable() throws SQLException {
0103: checkForClosedConnection();
0104: return getMetaDataInfoBoolean(allProceduresAreCallable__);
0105: }
0106:
0107: private final static int allTablesAreSelectable__ = 1;
0108:
0109: public boolean allTablesAreSelectable() throws SQLException {
0110: checkForClosedConnection();
0111: return getMetaDataInfoBoolean(allTablesAreSelectable__);
0112: }
0113:
0114: private final static int nullsAreSortedHigh__ = 2;
0115:
0116: public boolean nullsAreSortedHigh() throws SQLException {
0117: checkForClosedConnection();
0118: return getMetaDataInfoBoolean(nullsAreSortedHigh__);
0119: }
0120:
0121: private final static int nullsAreSortedLow__ = 3;
0122:
0123: public boolean nullsAreSortedLow() throws SQLException {
0124: checkForClosedConnection();
0125: return getMetaDataInfoBoolean(nullsAreSortedLow__);
0126: }
0127:
0128: private final static int nullsAreSortedAtStart__ = 4;
0129:
0130: public boolean nullsAreSortedAtStart() throws SQLException {
0131: checkForClosedConnection();
0132: return getMetaDataInfoBoolean(nullsAreSortedAtStart__);
0133: }
0134:
0135: private final static int nullsAreSortedAtEnd__ = 5;
0136:
0137: public boolean nullsAreSortedAtEnd() throws SQLException {
0138: checkForClosedConnection();
0139: return getMetaDataInfoBoolean(nullsAreSortedAtEnd__);
0140: }
0141:
0142: private final static int usesLocalFiles__ = 6;
0143:
0144: public boolean usesLocalFiles() throws SQLException {
0145: checkForClosedConnection();
0146: return getMetaDataInfoBoolean(usesLocalFiles__);
0147: }
0148:
0149: private final static int usesLocalFilePerTable__ = 7;
0150:
0151: public boolean usesLocalFilePerTable() throws SQLException {
0152: checkForClosedConnection();
0153: return getMetaDataInfoBoolean(usesLocalFilePerTable__);
0154: }
0155:
0156: private final static int storesUpperCaseIdentifiers__ = 8;
0157:
0158: public boolean storesUpperCaseIdentifiers() throws SQLException {
0159: checkForClosedConnection();
0160: return getMetaDataInfoBoolean(storesUpperCaseIdentifiers__);
0161: }
0162:
0163: private final static int storesLowerCaseIdentifiers__ = 9;
0164:
0165: public boolean storesLowerCaseIdentifiers() throws SQLException {
0166: checkForClosedConnection();
0167: return getMetaDataInfoBoolean(storesLowerCaseIdentifiers__);
0168: }
0169:
0170: private final static int storesMixedCaseIdentifiers__ = 10;
0171:
0172: public boolean storesMixedCaseIdentifiers() throws SQLException {
0173: checkForClosedConnection();
0174: return getMetaDataInfoBoolean(storesMixedCaseIdentifiers__);
0175: }
0176:
0177: private final static int storesUpperCaseQuotedIdentifiers__ = 11;
0178:
0179: public boolean storesUpperCaseQuotedIdentifiers()
0180: throws SQLException {
0181: checkForClosedConnection();
0182: return getMetaDataInfoBoolean(storesUpperCaseQuotedIdentifiers__);
0183: }
0184:
0185: private final static int storesLowerCaseQuotedIdentifiers__ = 12;
0186:
0187: public boolean storesLowerCaseQuotedIdentifiers()
0188: throws SQLException {
0189: checkForClosedConnection();
0190: return getMetaDataInfoBoolean(storesLowerCaseQuotedIdentifiers__);
0191: }
0192:
0193: private final static int storesMixedCaseQuotedIdentifiers__ = 13;
0194:
0195: public boolean storesMixedCaseQuotedIdentifiers()
0196: throws SQLException {
0197: checkForClosedConnection();
0198: return getMetaDataInfoBoolean(storesMixedCaseQuotedIdentifiers__);
0199: }
0200:
0201: private final static int getSQLKeywords__ = 14;
0202:
0203: public String getSQLKeywords() throws SQLException {
0204: checkForClosedConnection();
0205: return getMetaDataInfoString(getSQLKeywords__);
0206: }
0207:
0208: private final static int getNumericFunctions__ = 15;
0209:
0210: public String getNumericFunctions() throws SQLException {
0211: checkForClosedConnection();
0212: return getMetaDataInfoString(getNumericFunctions__);
0213: }
0214:
0215: private final static int getStringFunctions__ = 16;
0216:
0217: public String getStringFunctions() throws SQLException {
0218: checkForClosedConnection();
0219: return getMetaDataInfoString(getStringFunctions__);
0220: }
0221:
0222: private final static int getSystemFunctions__ = 17;
0223:
0224: public String getSystemFunctions() throws SQLException {
0225: checkForClosedConnection();
0226: return getMetaDataInfoString(getSystemFunctions__);
0227: }
0228:
0229: private final static int getTimeDateFunctions__ = 18;
0230:
0231: public String getTimeDateFunctions() throws SQLException {
0232: checkForClosedConnection();
0233: return getMetaDataInfoString(getTimeDateFunctions__);
0234: }
0235:
0236: private final static int getSearchStringEscape__ = 19;
0237:
0238: public String getSearchStringEscape() throws SQLException {
0239: checkForClosedConnection();
0240: return getMetaDataInfoString(getSearchStringEscape__);
0241: }
0242:
0243: private final static int getExtraNameCharacters__ = 20;
0244:
0245: public String getExtraNameCharacters() throws SQLException {
0246: checkForClosedConnection();
0247: return getMetaDataInfoString(getExtraNameCharacters__);
0248: }
0249:
0250: private final static int supportsAlterTableWithAddColumn__ = 21;
0251:
0252: public boolean supportsAlterTableWithAddColumn()
0253: throws SQLException {
0254: checkForClosedConnection();
0255: return getMetaDataInfoBoolean(supportsAlterTableWithAddColumn__);
0256: }
0257:
0258: private final static int supportsAlterTableWithDropColumn__ = 22;
0259:
0260: public boolean supportsAlterTableWithDropColumn()
0261: throws SQLException {
0262: checkForClosedConnection();
0263: return getMetaDataInfoBoolean(supportsAlterTableWithDropColumn__);
0264: }
0265:
0266: private final static int supportsConvert__ = 23;
0267:
0268: public boolean supportsConvert() throws SQLException {
0269: checkForClosedConnection();
0270: return getMetaDataInfoBoolean(supportsConvert__);
0271: }
0272:
0273: private final static int supportsConvertType__ = 24;
0274:
0275: public boolean supportsConvert(int fromType, int toType)
0276: throws SQLException {
0277: checkForClosedConnection();
0278: return getMetaDataInfoBoolean_supportsConvert(
0279: supportsConvertType__, fromType, toType);
0280: }
0281:
0282: private final static int supportsDifferentTableCorrelationNames__ = 25;
0283:
0284: public boolean supportsDifferentTableCorrelationNames()
0285: throws SQLException {
0286: checkForClosedConnection();
0287: return getMetaDataInfoBoolean(supportsDifferentTableCorrelationNames__);
0288: }
0289:
0290: private final static int supportsExpressionsInOrderBy__ = 26;
0291:
0292: public boolean supportsExpressionsInOrderBy() throws SQLException {
0293: checkForClosedConnection();
0294: return getMetaDataInfoBoolean(supportsExpressionsInOrderBy__);
0295: }
0296:
0297: private final static int supportsOrderByUnrelated__ = 27;
0298:
0299: public boolean supportsOrderByUnrelated() throws SQLException {
0300: checkForClosedConnection();
0301: return getMetaDataInfoBoolean(supportsOrderByUnrelated__);
0302: }
0303:
0304: private final static int supportsGroupBy__ = 28;
0305:
0306: public boolean supportsGroupBy() throws SQLException {
0307: checkForClosedConnection();
0308: return getMetaDataInfoBoolean(supportsGroupBy__);
0309: }
0310:
0311: private final static int supportsGroupByUnrelated__ = 29;
0312:
0313: public boolean supportsGroupByUnrelated() throws SQLException {
0314: checkForClosedConnection();
0315: return getMetaDataInfoBoolean(supportsGroupByUnrelated__);
0316: }
0317:
0318: private final static int supportsGroupByBeyondSelect__ = 30;
0319:
0320: public boolean supportsGroupByBeyondSelect() throws SQLException {
0321: checkForClosedConnection();
0322: return getMetaDataInfoBoolean(supportsGroupByBeyondSelect__);
0323: }
0324:
0325: private final static int supportsMultipleResultSets__ = 31;
0326:
0327: public boolean supportsMultipleResultSets() throws SQLException {
0328: checkForClosedConnection();
0329: return getMetaDataInfoBoolean(supportsMultipleResultSets__);
0330: }
0331:
0332: private final static int supportsMultipleTransactions__ = 32;
0333:
0334: public boolean supportsMultipleTransactions() throws SQLException {
0335: checkForClosedConnection();
0336: return getMetaDataInfoBoolean(supportsMultipleTransactions__);
0337: }
0338:
0339: private final static int supportsCoreSQLGrammar__ = 33;
0340:
0341: public boolean supportsCoreSQLGrammar() throws SQLException {
0342: checkForClosedConnection();
0343: return getMetaDataInfoBoolean(supportsCoreSQLGrammar__);
0344: }
0345:
0346: private final static int supportsExtendedSQLGrammar__ = 34;
0347:
0348: public boolean supportsExtendedSQLGrammar() throws SQLException {
0349: checkForClosedConnection();
0350: return getMetaDataInfoBoolean(supportsExtendedSQLGrammar__);
0351: }
0352:
0353: private final static int supportsANSI92IntermediateSQL__ = 35;
0354:
0355: public boolean supportsANSI92IntermediateSQL() throws SQLException {
0356: checkForClosedConnection();
0357: return getMetaDataInfoBoolean(supportsANSI92IntermediateSQL__);
0358: }
0359:
0360: private final static int supportsANSI92FullSQL__ = 36;
0361:
0362: public boolean supportsANSI92FullSQL() throws SQLException {
0363: checkForClosedConnection();
0364: return getMetaDataInfoBoolean(supportsANSI92FullSQL__);
0365: }
0366:
0367: private final static int supportsIntegrityEnhancementFacility__ = 37;
0368:
0369: public boolean supportsIntegrityEnhancementFacility()
0370: throws SQLException {
0371: checkForClosedConnection();
0372: return getMetaDataInfoBoolean(supportsIntegrityEnhancementFacility__);
0373: }
0374:
0375: private final static int supportsOuterJoins__ = 38;
0376:
0377: public boolean supportsOuterJoins() throws SQLException {
0378: checkForClosedConnection();
0379: return getMetaDataInfoBoolean(supportsOuterJoins__);
0380: }
0381:
0382: private final static int supportsFullOuterJoins__ = 39;
0383:
0384: public boolean supportsFullOuterJoins() throws SQLException {
0385: checkForClosedConnection();
0386: return getMetaDataInfoBoolean(supportsFullOuterJoins__);
0387: }
0388:
0389: private final static int supportsLimitedOuterJoins__ = 40;
0390:
0391: public boolean supportsLimitedOuterJoins() throws SQLException {
0392: checkForClosedConnection();
0393: return getMetaDataInfoBoolean(supportsLimitedOuterJoins__);
0394: }
0395:
0396: private final static int getSchemaTerm__ = 41;
0397:
0398: public String getSchemaTerm() throws SQLException {
0399: checkForClosedConnection();
0400: return getMetaDataInfoString(getSchemaTerm__);
0401: }
0402:
0403: private final static int getProcedureTerm__ = 42;
0404:
0405: public String getProcedureTerm() throws SQLException {
0406: checkForClosedConnection();
0407: return getMetaDataInfoString(getProcedureTerm__);
0408: }
0409:
0410: private final static int getCatalogTerm__ = 43;
0411:
0412: public String getCatalogTerm() throws SQLException {
0413: checkForClosedConnection();
0414: return getMetaDataInfoString(getCatalogTerm__);
0415: }
0416:
0417: private final static int isCatalogAtStart__ = 44;
0418:
0419: public boolean isCatalogAtStart() throws SQLException {
0420: checkForClosedConnection();
0421: return getMetaDataInfoBoolean(isCatalogAtStart__);
0422: }
0423:
0424: private final static int getCatalogSeparator__ = 45;
0425:
0426: public String getCatalogSeparator() throws SQLException {
0427: checkForClosedConnection();
0428: return getMetaDataInfoString(getCatalogSeparator__);
0429: }
0430:
0431: private final static int supportsSchemasInDataManipulation__ = 46;
0432:
0433: public boolean supportsSchemasInDataManipulation()
0434: throws SQLException {
0435: checkForClosedConnection();
0436: return getMetaDataInfoBoolean(supportsSchemasInDataManipulation__);
0437: }
0438:
0439: private final static int supportsSchemasInProcedureCalls__ = 47;
0440:
0441: public boolean supportsSchemasInProcedureCalls()
0442: throws SQLException {
0443: checkForClosedConnection();
0444: return getMetaDataInfoBoolean(supportsSchemasInProcedureCalls__);
0445: }
0446:
0447: private final static int supportsSchemasInTableDefinitions__ = 48;
0448:
0449: public boolean supportsSchemasInTableDefinitions()
0450: throws SQLException {
0451: checkForClosedConnection();
0452: return getMetaDataInfoBoolean(supportsSchemasInTableDefinitions__);
0453: }
0454:
0455: private final static int supportsSchemasInIndexDefinitions__ = 49;
0456:
0457: public boolean supportsSchemasInIndexDefinitions()
0458: throws SQLException {
0459: checkForClosedConnection();
0460: return getMetaDataInfoBoolean(supportsSchemasInIndexDefinitions__);
0461: }
0462:
0463: private final static int supportsSchemasInPrivilegeDefinitions__ = 50;
0464:
0465: public boolean supportsSchemasInPrivilegeDefinitions()
0466: throws SQLException {
0467: checkForClosedConnection();
0468: return getMetaDataInfoBoolean(supportsSchemasInPrivilegeDefinitions__);
0469: }
0470:
0471: private final static int supportsCatalogsInDataManipulation__ = 51;
0472:
0473: public boolean supportsCatalogsInDataManipulation()
0474: throws SQLException {
0475: checkForClosedConnection();
0476: return getMetaDataInfoBoolean(supportsCatalogsInDataManipulation__);
0477: }
0478:
0479: private final static int supportsCatalogsInProcedureCalls__ = 52;
0480:
0481: public boolean supportsCatalogsInProcedureCalls()
0482: throws SQLException {
0483: checkForClosedConnection();
0484: return getMetaDataInfoBoolean(supportsCatalogsInProcedureCalls__);
0485: }
0486:
0487: private final static int supportsCatalogsInTableDefinitions__ = 53;
0488:
0489: public boolean supportsCatalogsInTableDefinitions()
0490: throws SQLException {
0491: checkForClosedConnection();
0492: return getMetaDataInfoBoolean(supportsCatalogsInTableDefinitions__);
0493: }
0494:
0495: private final static int supportsCatalogsInIndexDefinitions__ = 54;
0496:
0497: public boolean supportsCatalogsInIndexDefinitions()
0498: throws SQLException {
0499: checkForClosedConnection();
0500: return getMetaDataInfoBoolean(supportsCatalogsInIndexDefinitions__);
0501: }
0502:
0503: private final static int supportsCatalogsInPrivilegeDefinitions__ = 55;
0504:
0505: public boolean supportsCatalogsInPrivilegeDefinitions()
0506: throws SQLException {
0507: checkForClosedConnection();
0508: return getMetaDataInfoBoolean(supportsCatalogsInPrivilegeDefinitions__);
0509: }
0510:
0511: private final static int supportsPositionedDelete__ = 56;
0512:
0513: public boolean supportsPositionedDelete() throws SQLException {
0514: checkForClosedConnection();
0515: return getMetaDataInfoBoolean(supportsPositionedDelete__);
0516: }
0517:
0518: private final static int supportsPositionedUpdate__ = 57;
0519:
0520: public boolean supportsPositionedUpdate() throws SQLException {
0521: checkForClosedConnection();
0522: return getMetaDataInfoBoolean(supportsPositionedUpdate__);
0523: }
0524:
0525: private final static int supportsSelectForUpdate__ = 58;
0526:
0527: public boolean supportsSelectForUpdate() throws SQLException {
0528: checkForClosedConnection();
0529: return getMetaDataInfoBoolean(supportsSelectForUpdate__);
0530: }
0531:
0532: private final static int supportsStoredProcedures__ = 59;
0533:
0534: public boolean supportsStoredProcedures() throws SQLException {
0535: checkForClosedConnection();
0536: return getMetaDataInfoBoolean(supportsStoredProcedures__);
0537: }
0538:
0539: private final static int supportsSubqueriesInComparisons__ = 60;
0540:
0541: public boolean supportsSubqueriesInComparisons()
0542: throws SQLException {
0543: checkForClosedConnection();
0544: return getMetaDataInfoBoolean(supportsSubqueriesInComparisons__);
0545: }
0546:
0547: private final static int supportsUnion__ = 61;
0548:
0549: public boolean supportsUnion() throws SQLException {
0550: checkForClosedConnection();
0551: return getMetaDataInfoBoolean(supportsUnion__);
0552: }
0553:
0554: private final static int supportsUnionAll__ = 62;
0555:
0556: public boolean supportsUnionAll() throws SQLException {
0557: checkForClosedConnection();
0558: return getMetaDataInfoBoolean(supportsUnionAll__);
0559:
0560: }
0561:
0562: private final static int supportsOpenCursorsAcrossCommit__ = 63;
0563:
0564: public boolean supportsOpenCursorsAcrossCommit()
0565: throws SQLException {
0566: checkForClosedConnection();
0567: return getMetaDataInfoBoolean(supportsOpenCursorsAcrossCommit__);
0568: }
0569:
0570: private final static int supportsOpenCursorsAcrossRollback__ = 64;
0571:
0572: public boolean supportsOpenCursorsAcrossRollback()
0573: throws SQLException {
0574: checkForClosedConnection();
0575: return getMetaDataInfoBoolean(supportsOpenCursorsAcrossRollback__);
0576: }
0577:
0578: private final static int supportsOpenStatementsAcrossCommit__ = 65;
0579:
0580: public boolean supportsOpenStatementsAcrossCommit()
0581: throws SQLException {
0582: checkForClosedConnection();
0583: return getMetaDataInfoBoolean(supportsOpenStatementsAcrossCommit__);
0584: }
0585:
0586: private final static int supportsOpenStatementsAcrossRollback__ = 66;
0587:
0588: public boolean supportsOpenStatementsAcrossRollback()
0589: throws SQLException {
0590: checkForClosedConnection();
0591: return getMetaDataInfoBoolean(supportsOpenStatementsAcrossRollback__);
0592: }
0593:
0594: //----------------------------------------------------------------------
0595: // The following group of methods exposes various limitations
0596: // based on the target database with the current driver.
0597: // Unless otherwise specified, a result of zero means there is no
0598: // limit, or the limit is not known.
0599: private final static int getMaxBinaryLiteralLength__ = 67;
0600:
0601: public int getMaxBinaryLiteralLength() throws SQLException {
0602: checkForClosedConnection();
0603: return getMetaDataInfoInt(getMaxBinaryLiteralLength__);
0604: }
0605:
0606: private final static int getMaxCharLiteralLength__ = 68;
0607:
0608: public int getMaxCharLiteralLength() throws SQLException {
0609: checkForClosedConnection();
0610: return getMetaDataInfoInt(getMaxCharLiteralLength__);
0611: }
0612:
0613: private final static int getMaxColumnNameLength__ = 69;
0614:
0615: public int getMaxColumnNameLength() throws SQLException {
0616: checkForClosedConnection();
0617: return getMetaDataInfoInt(getMaxColumnNameLength__);
0618: }
0619:
0620: private final static int getMaxColumnsInGroupBy__ = 70;
0621:
0622: public int getMaxColumnsInGroupBy() throws SQLException {
0623: checkForClosedConnection();
0624: return getMetaDataInfoInt(getMaxColumnsInGroupBy__);
0625: }
0626:
0627: private final static int getMaxColumnsInIndex__ = 71;
0628:
0629: public int getMaxColumnsInIndex() throws SQLException {
0630: checkForClosedConnection();
0631: return getMetaDataInfoInt(getMaxColumnsInIndex__);
0632: }
0633:
0634: private final static int getMaxColumnsInOrderBy__ = 72;
0635:
0636: public int getMaxColumnsInOrderBy() throws SQLException {
0637: checkForClosedConnection();
0638: return getMetaDataInfoInt(getMaxColumnsInOrderBy__);
0639: }
0640:
0641: private final static int getMaxColumnsInSelect__ = 73;
0642:
0643: public int getMaxColumnsInSelect() throws SQLException {
0644: checkForClosedConnection();
0645: return getMetaDataInfoInt(getMaxColumnsInSelect__);
0646: }
0647:
0648: private final static int getMaxColumnsInTable__ = 74;
0649:
0650: public int getMaxColumnsInTable() throws SQLException {
0651: checkForClosedConnection();
0652: return getMetaDataInfoInt(getMaxColumnsInTable__);
0653: }
0654:
0655: private final static int getMaxConnections__ = 75;
0656:
0657: public int getMaxConnections() throws SQLException {
0658: checkForClosedConnection();
0659: return getMetaDataInfoInt(getMaxConnections__);
0660: }
0661:
0662: private final static int getMaxCursorNameLength__ = 76;
0663:
0664: public int getMaxCursorNameLength() throws SQLException {
0665: checkForClosedConnection();
0666: return getMetaDataInfoInt(getMaxCursorNameLength__);
0667: }
0668:
0669: private final static int getMaxIndexLength__ = 77;
0670:
0671: public int getMaxIndexLength() throws SQLException {
0672: checkForClosedConnection();
0673: return getMetaDataInfoInt(getMaxIndexLength__);
0674: }
0675:
0676: private final static int getMaxSchemaNameLength__ = 78;
0677:
0678: public int getMaxSchemaNameLength() throws SQLException {
0679: checkForClosedConnection();
0680: return getMetaDataInfoInt(getMaxSchemaNameLength__);
0681: }
0682:
0683: private final static int getMaxProcedureNameLength__ = 79;
0684:
0685: public int getMaxProcedureNameLength() throws SQLException {
0686: checkForClosedConnection();
0687: return getMetaDataInfoInt(getMaxProcedureNameLength__);
0688: }
0689:
0690: private final static int getMaxCatalogNameLength__ = 80;
0691:
0692: public int getMaxCatalogNameLength() throws SQLException {
0693: checkForClosedConnection();
0694: return getMetaDataInfoInt(getMaxCatalogNameLength__);
0695: }
0696:
0697: private final static int getMaxRowSize__ = 81;
0698:
0699: public int getMaxRowSize() throws SQLException {
0700: checkForClosedConnection();
0701: return getMetaDataInfoInt(getMaxRowSize__);
0702: }
0703:
0704: private final static int doesMaxRowSizeIncludeBlobs__ = 82;
0705:
0706: public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
0707: checkForClosedConnection();
0708: return getMetaDataInfoBoolean(doesMaxRowSizeIncludeBlobs__);
0709: }
0710:
0711: private final static int getMaxStatementLength__ = 83;
0712:
0713: public int getMaxStatementLength() throws SQLException {
0714: checkForClosedConnection();
0715: return getMetaDataInfoInt(getMaxStatementLength__);
0716: }
0717:
0718: private final static int getMaxStatements__ = 84;
0719:
0720: public int getMaxStatements() throws SQLException {
0721: checkForClosedConnection();
0722: return getMetaDataInfoInt(getMaxStatements__);
0723: }
0724:
0725: private final static int getMaxTableNameLength__ = 85;
0726:
0727: public int getMaxTableNameLength() throws SQLException {
0728: checkForClosedConnection();
0729: return getMetaDataInfoInt(getMaxTableNameLength__);
0730: }
0731:
0732: private final static int getMaxTablesInSelect__ = 86;
0733:
0734: public int getMaxTablesInSelect() throws SQLException {
0735: checkForClosedConnection();
0736: return getMetaDataInfoInt(getMaxTablesInSelect__);
0737: }
0738:
0739: private final static int getMaxUserNameLength__ = 87;
0740:
0741: public int getMaxUserNameLength() throws SQLException {
0742: checkForClosedConnection();
0743: return getMetaDataInfoInt(getMaxUserNameLength__);
0744: }
0745:
0746: private final static int getDefaultTransactionIsolation__ = 88;
0747:
0748: public int getDefaultTransactionIsolation() throws SQLException {
0749: checkForClosedConnection();
0750: return getMetaDataInfoInt(getDefaultTransactionIsolation__);
0751: }
0752:
0753: private final static int supportsTransactions__ = 89;
0754:
0755: public boolean supportsTransactions() throws SQLException {
0756: checkForClosedConnection();
0757: return getMetaDataInfoBoolean(supportsTransactions__);
0758: }
0759:
0760: // Stored Procedure will return a String containing a
0761: // comma seperated list of all supported levels
0762: private final static int supportsTransactionIsolationLevel__ = 90;
0763:
0764: public boolean supportsTransactionIsolationLevel(int level)
0765: throws SQLException {
0766: checkForClosedConnection();
0767: return getMetaDataInfoBooleanWithType(
0768: supportsTransactionIsolationLevel__, level);
0769: }
0770:
0771: private final static int supportsDataDefinitionAndDataManipulationTransactions__ = 91;
0772:
0773: public boolean supportsDataDefinitionAndDataManipulationTransactions()
0774: throws SQLException {
0775: checkForClosedConnection();
0776: return getMetaDataInfoBoolean(supportsDataDefinitionAndDataManipulationTransactions__);
0777: }
0778:
0779: private final static int supportsDataManipulationTransactionsOnly__ = 92;
0780:
0781: public boolean supportsDataManipulationTransactionsOnly()
0782: throws SQLException {
0783: checkForClosedConnection();
0784: return getMetaDataInfoBoolean(supportsDataManipulationTransactionsOnly__);
0785: }
0786:
0787: private final static int dataDefinitionCausesTransactionCommit__ = 93;
0788:
0789: public boolean dataDefinitionCausesTransactionCommit()
0790: throws SQLException {
0791: checkForClosedConnection();
0792: return getMetaDataInfoBoolean(dataDefinitionCausesTransactionCommit__);
0793: }
0794:
0795: private final static int dataDefinitionIgnoredInTransactions__ = 94;
0796:
0797: public boolean dataDefinitionIgnoredInTransactions()
0798: throws SQLException {
0799: checkForClosedConnection();
0800: return getMetaDataInfoBoolean(dataDefinitionIgnoredInTransactions__);
0801: }
0802:
0803: // Stored Procedure will return a String containing a
0804: // comma seperated list of all the supported resultSet types
0805: private final static int supportsResultSetType__ = 95;
0806:
0807: public boolean supportsResultSetType(int type) throws SQLException {
0808: checkForClosedConnection();
0809: return getMetaDataInfoBooleanWithType(supportsResultSetType__,
0810: type);
0811: }
0812:
0813: private final static int supportsResultSetConcurrency__ = 96;
0814:
0815: public boolean supportsResultSetConcurrency(int type,
0816: int concurrency) throws SQLException {
0817: checkForClosedConnection();
0818: return getMetaDataInfoInt_SupportsResultSetConcurrency(
0819: supportsResultSetConcurrency__, type, concurrency);
0820: }
0821:
0822: // Stored Procedure will return a String containing a
0823: // comma seperated list of all the supported result Set types
0824: private final static int ownUpdatesAreVisible__ = 97;
0825:
0826: public boolean ownUpdatesAreVisible(int type) throws SQLException {
0827: checkForClosedConnection();
0828: return getMetaDataInfoBooleanWithType(ownUpdatesAreVisible__,
0829: type);
0830: }
0831:
0832: // Stored Procedure will return a String containing a
0833: // comma seperated list of all the supported result Set types
0834: private final static int ownDeletesAreVisible__ = 98;
0835:
0836: public boolean ownDeletesAreVisible(int type) throws SQLException {
0837: checkForClosedConnection();
0838: return getMetaDataInfoBooleanWithType(ownDeletesAreVisible__,
0839: type);
0840: }
0841:
0842: // Stored Procedure will return a String containing a
0843: // comma seperated list all the supported result Set types
0844: private final static int ownInsertsAreVisible__ = 99;
0845:
0846: public boolean ownInsertsAreVisible(int type) throws SQLException {
0847: checkForClosedConnection();
0848: return getMetaDataInfoBooleanWithType(ownInsertsAreVisible__,
0849: type);
0850: }
0851:
0852: // Stored Procedure will return a String containing a
0853: // comma seperated list of all the supported result Set types
0854: private final static int othersUpdatesAreVisible__ = 100;
0855:
0856: public boolean othersUpdatesAreVisible(int type)
0857: throws SQLException {
0858: checkForClosedConnection();
0859: return getMetaDataInfoBooleanWithType(
0860: othersUpdatesAreVisible__, type);
0861: }
0862:
0863: // Stored Procedure will return a String containing a
0864: // comma seperated list of all the supported result Set types
0865: private final static int othersDeletesAreVisible__ = 101;
0866:
0867: public boolean othersDeletesAreVisible(int type)
0868: throws SQLException {
0869: checkForClosedConnection();
0870: return getMetaDataInfoBooleanWithType(
0871: othersDeletesAreVisible__, type);
0872: }
0873:
0874: // Stored Procedure will return a String containing a
0875: // comma seperated list of all the supported result Set types
0876: private final static int othersInsertsAreVisible__ = 102;
0877:
0878: public boolean othersInsertsAreVisible(int type)
0879: throws SQLException {
0880: checkForClosedConnection();
0881: return getMetaDataInfoBooleanWithType(
0882: othersInsertsAreVisible__, type);
0883: }
0884:
0885: // Stored Procedure will return a String containing a
0886: // comma seperated list of all the supported result Set types
0887: private final static int updatesAreDetected__ = 103;
0888:
0889: public boolean updatesAreDetected(int type) throws SQLException {
0890: checkForClosedConnection();
0891: return getMetaDataInfoBooleanWithType(updatesAreDetected__,
0892: type);
0893: }
0894:
0895: // Stored Procedure will return a String containing a
0896: // comma seperated list of all the supported result Set types
0897: private final static int deletesAreDetected__ = 104;
0898:
0899: public boolean deletesAreDetected(int type) throws SQLException {
0900: checkForClosedConnection();
0901: return getMetaDataInfoBooleanWithType(deletesAreDetected__,
0902: type);
0903: }
0904:
0905: // Stored Procedure will return a String containing a
0906: // comma seperated list of all the supported result Set types
0907: private final static int insertsAreDetected__ = 105;
0908:
0909: public boolean insertsAreDetected(int type) throws SQLException {
0910: checkForClosedConnection();
0911: return getMetaDataInfoBooleanWithType(insertsAreDetected__,
0912: type);
0913: }
0914:
0915: private final static int supportsBatchUpdates__ = 106;
0916:
0917: public boolean supportsBatchUpdates() throws SQLException {
0918: checkForClosedConnection();
0919: return getMetaDataInfoBoolean(supportsBatchUpdates__);
0920: }
0921:
0922: public boolean supportsSavepoints() throws SQLException {
0923: checkForClosedConnection();
0924: if (productLevel_.greaterThanOrEqualTo(5, 2, 0)) {
0925: return true;
0926: }
0927:
0928: return false;
0929: }
0930:
0931: // start tagging all abstract methods with an underscore like this !!
0932: abstract public String getURL_() throws SqlException;
0933:
0934: public String getURL() throws SQLException {
0935: try {
0936: checkForClosedConnection();
0937: return getURL_();
0938: } catch (SqlException se) {
0939: throw se.getSQLException();
0940: }
0941: }
0942:
0943: public String getUserName() throws SQLException {
0944: checkForClosedConnection();
0945: return connection_.user_;
0946: }
0947:
0948: public boolean isReadOnly() throws SQLException {
0949: return false;
0950: }
0951:
0952: public String getDatabaseProductName() throws SQLException {
0953: checkForClosedConnection();
0954: return productLevel_.databaseProductName_;
0955: }
0956:
0957: public String getDatabaseProductVersion() throws SQLException {
0958: checkForClosedConnection();
0959: return productLevel_.databaseProductVersion_;
0960: }
0961:
0962: public String getDriverName() throws SQLException {
0963: checkForClosedConnection();
0964: return Configuration.dncDriverName;
0965: }
0966:
0967: public String getDriverVersion() throws SQLException {
0968: checkForClosedConnection();
0969: return Version.getDriverVersion();
0970: }
0971:
0972: // JDBC signature also does not throw SqlException, so we don't check for closed connection.
0973: public int getDriverMajorVersion() {
0974: return Version.getMajorVersion();
0975: }
0976:
0977: // JDBC signature also does not throw SqlException, so we don't check for closed connection.
0978: public int getDriverMinorVersion() {
0979: return Version.getMinorVersion();
0980: }
0981:
0982: //All JDBC Drivers must return false for this method. For this reason we choose
0983: //to return FALSE
0984: public boolean supportsMixedCaseIdentifiers() throws SQLException {
0985: checkForClosedConnection();
0986: return false;
0987: }
0988:
0989: public boolean supportsMixedCaseQuotedIdentifiers()
0990: throws SQLException {
0991: checkForClosedConnection();
0992: return true;
0993: }
0994:
0995: public String getIdentifierQuoteString() throws SQLException {
0996: checkForClosedConnection();
0997: return "\"";
0998: }
0999:
1000: public boolean supportsColumnAliasing() throws SQLException {
1001: checkForClosedConnection();
1002: return true;
1003: }
1004:
1005: public boolean nullPlusNonNullIsNull() throws SQLException {
1006: checkForClosedConnection();
1007: return true;
1008: }
1009:
1010: public boolean supportsTableCorrelationNames() throws SQLException {
1011: checkForClosedConnection();
1012: return true;
1013: }
1014:
1015: public boolean supportsLikeEscapeClause() throws SQLException {
1016: checkForClosedConnection();
1017: return true;
1018: }
1019:
1020: public boolean supportsNonNullableColumns() throws SQLException {
1021: checkForClosedConnection();
1022: return true;
1023: }
1024:
1025: public boolean supportsMinimumSQLGrammar() throws SQLException {
1026: checkForClosedConnection();
1027: return true;
1028: }
1029:
1030: public boolean supportsANSI92EntryLevelSQL() throws SQLException {
1031: checkForClosedConnection();
1032: return true;
1033: }
1034:
1035: public boolean supportsSubqueriesInExists() throws SQLException {
1036: checkForClosedConnection();
1037: return true;
1038: }
1039:
1040: public boolean supportsSubqueriesInIns() throws SQLException {
1041: checkForClosedConnection();
1042: return true;
1043: }
1044:
1045: public boolean supportsSubqueriesInQuantifieds()
1046: throws SQLException {
1047: checkForClosedConnection();
1048: return true;
1049: }
1050:
1051: public boolean supportsCorrelatedSubqueries() throws SQLException {
1052: checkForClosedConnection();
1053: return true;
1054: }
1055:
1056: //------------------------catalog query methods follow--------------------------------------------
1057:
1058: // call stored procedure SQLProcedures
1059: // SYSIBM.SQLProcedures(
1060: // CatalogName varchar(128),
1061: // SchemaName varchar(128),
1062: // ProcName varchar(128),
1063: // Options varchar(4000))
1064: //
1065: public java.sql.ResultSet getProcedures(String catalog,
1066: String schemaPattern, String procedureNamePattern)
1067: throws SQLException {
1068: try {
1069: synchronized (connection_) {
1070: if (agent_.loggingEnabled()) {
1071: agent_.logWriter_.traceEntry(this , "getProcedures",
1072: catalog, schemaPattern,
1073: procedureNamePattern);
1074: }
1075: return getProceduresX(catalog, schemaPattern,
1076: procedureNamePattern);
1077: }
1078: } catch (SqlException se) {
1079: throw se.getSQLException();
1080: }
1081: }
1082:
1083: private ResultSet getProceduresX(String catalog,
1084: String schemaPattern, String procedureNamePattern)
1085: throws SqlException {
1086: checkForClosedConnectionX();
1087:
1088: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLPROCEDURES(?,?,?,?)");
1089:
1090: cs.setStringX(1, catalog);
1091: cs.setStringX(2, schemaPattern);
1092: cs.setStringX(3, procedureNamePattern);
1093: cs.setStringX(4, getOptions());
1094: return executeCatalogQuery(cs);
1095: }
1096:
1097: // call stored procedure SQLProcedureCols
1098: // SYSIBM.SQLProcedureCols(
1099: // CatalogName varchar(128),
1100: // SchemaName varchar(128),
1101: // ProcName varchar(128),
1102: // ParamName varchar(128),
1103: // Options varchar(4000))
1104: //
1105: public java.sql.ResultSet getProcedureColumns(String catalog,
1106: String schemaPattern, String procedureNamePattern,
1107: String columnNamePattern) throws SQLException {
1108: try {
1109: synchronized (connection_) {
1110: if (agent_.loggingEnabled()) {
1111: agent_.logWriter_.traceEntry(this ,
1112: "getProcedureColumns", catalog,
1113: schemaPattern, procedureNamePattern,
1114: columnNamePattern);
1115: }
1116: return getProcedureColumnsX(catalog, schemaPattern,
1117: procedureNamePattern, columnNamePattern);
1118: }
1119: } catch (SqlException se) {
1120: throw se.getSQLException();
1121: }
1122:
1123: }
1124:
1125: private ResultSet getProcedureColumnsX(String catalog,
1126: String schemaPattern, String procedureNamePattern,
1127: String columnNamePattern) throws SqlException {
1128: checkForClosedConnectionX();
1129: ;
1130:
1131: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLPROCEDURECOLS(?,?,?,?,?)");
1132:
1133: cs.setStringX(1, catalog);
1134: cs.setStringX(2, schemaPattern);
1135: cs.setStringX(3, procedureNamePattern);
1136: cs.setStringX(4, columnNamePattern);
1137: cs.setStringX(5, getOptions());
1138: return executeCatalogQuery(cs);
1139: }
1140:
1141: /**
1142: * Get the function names available in the database. Calls stored
1143: * procedure <code>SYSIBM.SQLFunctions(CatalogName
1144: * varchar(128), SchemaName varchar(128), FuncName varchar(128),
1145: * Options varchar(4000))</code> on the server. This procedure
1146: * will in turn call
1147: * <code>EmbedDatabaseMetaData.getFunctions(String,String,String)</code><p>
1148: * Compatibility: Only available if both server and client version
1149: * > 10.1, and JDK version >= 1.6. Older clients will not have
1150: * this method available. Newer clients will be able to call this
1151: * method when connected to an older server, but this will be
1152: * trigger an exception in
1153: * <code>checkServerJdbcVersionX()</code>. <p>Upgrade:
1154: * <code>SYSIBM.SQLFunctions</code> is added in
1155: * <code>DataDictionaryImpl.create_10_2_system_procedures
1156: * (TransactionController,UUID)</code> so it will become available
1157: * in newly created databases and after <b>hard</b> upgrade.
1158: *
1159: * @param catalog limit search to this catalog
1160: * @param schemaPattern limit search to schemas matching this pattern
1161: * @param functionNamePattern limit search to functions matching this
1162: * pattern
1163: * @return a <code>ResultSet</code> listing the fucntions
1164: * @exception SqlException if a database error occurs
1165: * @see #getFunctionsX(String, String, String)
1166: * @see org.apache.derby.impl.sql.catalog.DataDictionaryImpl#create_10_2_system_procedures(TransactionController,UUID)
1167: * @see org.apache.derby.impl.jdbc.EmbedDatabaseMetaData#getFunctions(String,String,String)
1168: */
1169:
1170: public java.sql.ResultSet getFunctions(String catalog,
1171: String schemaPattern, String functionNamePattern)
1172: throws SQLException {
1173: try {
1174: synchronized (connection_) {
1175: if (agent_.loggingEnabled()) {
1176: agent_.logWriter_
1177: .traceEntry(this , "getFunctions", catalog,
1178: schemaPattern, functionNamePattern);
1179: }
1180: return getFunctionsX(catalog, schemaPattern,
1181: functionNamePattern);
1182: }
1183: } catch (SqlException se) {
1184: throw se.getSQLException();
1185: }
1186: }
1187:
1188: /**
1189: * Untraced version of <code>getFunctions(String, String, String)</code>.
1190: * @param catalog limit search to this catalog
1191: * @param schemaPattern limit search to schemas matching this pattern
1192: * @param functionNamePattern limit search to functions matching this
1193: * pattern
1194: * @return a <code>ResultSet</code> listing the fucntions
1195: * @exception SqlException if a database error occurs
1196: * @see #getFunctions(String, String, String)
1197: */
1198: private ResultSet getFunctionsX(String catalog,
1199: String schemaPattern, String functionNamePattern)
1200: throws SqlException {
1201: checkForClosedConnectionX();
1202: checkServerJdbcVersionX("getFunctions(String,String,String)",
1203: 4, 0);
1204:
1205: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLFUNCTIONS(?,?,?,?)");
1206:
1207: cs.setStringX(1, catalog);
1208: cs.setStringX(2, schemaPattern);
1209: cs.setStringX(3, functionNamePattern);
1210: cs.setStringX(4, getOptions());
1211: return executeCatalogQuery(cs);
1212: }
1213:
1214: /**
1215: * Get the function names available in the database. Calls stored
1216: * procedure <code>SYSIBM.SQLFunctionParams(CatalogName
1217: * varchar(128), SchemaName varchar(128), FuncName varchar(128),
1218: * ParamName varchar(128), Options varchar(4000))</code> on the
1219: * server. This procedure will in turn call
1220: * <code>EmbedDatabaseMetaData.getFunctionColumns(String,String,
1221: * String,String)</code><p> Compatibility: Only available if both
1222: * server and client version > 10.1, and JDK version >= 1.6. Older
1223: * clients will not have this method available. Newer clients will
1224: * be able to call this method when connected to an older server,
1225: * but this will be trigger an exception in
1226: * <code>checkServerJdbcVersionX()</code>. <p>Upgrade:
1227: * <code>SYSIBM.SQLFunctionParams</code> is added in
1228: * <code>DataDictionaryImpl.create_10_2_system_procedures
1229: * (TransactionController,UUID)</code> so it will become available
1230: * in newly created databases and after <b>hard</b> upgrade.
1231: *
1232: * @param catalog limit search to this catalog
1233: * @param schemaPattern limit search to schemas matching this pattern
1234: * @param functionNamePattern limit search to functions matching this
1235: * pattern
1236: * @return a <code>ResultSet</code> listing the fucntions
1237: * @exception SqlException if a database error occurs
1238: * @see #getFunctionColumnsX(String, String, String,String)
1239: * @see org.apache.derby.impl.sql.catalog.DataDictionaryImpl#create_10_2_system_procedures(TransactionController,UUID)
1240: * @see org.apache.derby.impl.jdbc.EmbedDatabaseMetaData#getFunctions(String,String,String)
1241: */
1242: public java.sql.ResultSet getFunctionColumns(String catalog,
1243: String schemaPattern, String functionNamePattern,
1244: String parameterNamePattern) throws SQLException {
1245: try {
1246: synchronized (connection_) {
1247: if (agent_.loggingEnabled()) {
1248: agent_.logWriter_.traceEntry(this ,
1249: "getFunctionColumns", catalog,
1250: schemaPattern, functionNamePattern,
1251: parameterNamePattern);
1252: }
1253: return getFunctionColumnsX(catalog, schemaPattern,
1254: functionNamePattern, parameterNamePattern);
1255: }
1256: } catch (SqlException se) {
1257: throw se.getSQLException();
1258: }
1259: }
1260:
1261: /**
1262: * Untraced version of <code>getFunctionColumns(String, String,
1263: * String, String)</code>.
1264: * @param catalog limit search to this catalog
1265: * @param schemaPattern limit search to schemas matching this pattern
1266: * @param functionNamePattern limit search to functions matching this
1267: * pattern
1268: * @param parameterNamePattern limit search to parameters mathing
1269: * this pattern
1270: * @return a <code>ResultSet</code> listing the fucntions
1271: * @exception SqlException if a database error occurs
1272: * @see #getFunctionColumns(String, String, String, String)
1273: */
1274: private ResultSet getFunctionColumnsX(String catalog,
1275: String schemaPattern, String functionNamePattern,
1276: String parameterNamePattern) throws SqlException {
1277: checkForClosedConnectionX();
1278: checkServerJdbcVersionX("getFunctionColumns"
1279: + "(String,String,String,String)", 4, 0);
1280:
1281: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLFUNCTIONPARAMS(?,?,?,?,?)");
1282:
1283: cs.setStringX(1, catalog);
1284: cs.setStringX(2, schemaPattern);
1285: cs.setStringX(3, functionNamePattern);
1286: cs.setStringX(4, parameterNamePattern);
1287: cs.setStringX(5, getOptions());
1288: return executeCatalogQuery(cs);
1289: }
1290:
1291: // call stored procedure SQLTables
1292: // SYSIBM.SQLTables(
1293: // CatalogName varchar(128),
1294: // SchemaName varchar(128),
1295: // TableName varchar(128),
1296: // TaleType varchar(4000),
1297: // Options varchar(4000))
1298: //
1299: public java.sql.ResultSet getTables(String catalog,
1300: String schemaPattern, String tableNamePattern,
1301: String types[]) throws SQLException {
1302: try {
1303: synchronized (connection_) {
1304: if (agent_.loggingEnabled()) {
1305: agent_.logWriter_.traceEntry(this , "getTables",
1306: catalog, schemaPattern, tableNamePattern,
1307: types);
1308: }
1309: return getTablesX(catalog, schemaPattern,
1310: tableNamePattern, types);
1311: }
1312: } catch (SqlException se) {
1313: throw se.getSQLException();
1314: }
1315: }
1316:
1317: private ResultSet getTablesX(String catalog, String schemaPattern,
1318: String tableNamePattern, String types[])
1319: throws SqlException {
1320: try {
1321: checkForClosedConnection();
1322: } catch (SQLException se) {
1323: throw new SqlException(se);
1324: }
1325:
1326: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLTABLES(?,?,?,?,?)");
1327:
1328: if (catalog == null) {
1329: cs.setNullX(1, java.sql.Types.VARCHAR);
1330: } else {
1331: cs.setStringX(1, catalog);
1332: }
1333:
1334: if (schemaPattern == null) {
1335: cs.setNullX(2, java.sql.Types.VARCHAR);
1336: } else {
1337: cs.setStringX(2, schemaPattern);
1338: }
1339:
1340: if (tableNamePattern == null) {
1341: cs.setNullX(3, java.sql.Types.VARCHAR);
1342: } else {
1343: cs.setStringX(3, tableNamePattern);
1344: }
1345:
1346: String tableTypes = new String();
1347: int i = 0;
1348: if (types == null) {
1349: cs.setNullX(4, java.sql.Types.VARCHAR);
1350: } else if (types.length == 1 && (types[0].trim()).equals("%")) {
1351: cs.setStringX(4, types[0]);
1352: } else {
1353: while (i < types.length) {
1354: if (i > 0) {
1355: tableTypes = tableTypes.concat(",");
1356: }
1357: tableTypes = tableTypes.concat("'" + types[i] + "'");
1358: i++;
1359: }
1360: cs.setStringX(4, tableTypes);
1361: }
1362: cs.setStringX(5, getOptions());
1363: return executeCatalogQuery(cs);
1364: }
1365:
1366: // call stored procedure SQLTables
1367: // SYSIBM.SQLTables(
1368: // CatalogName varchar(128),
1369: // SchemaName varchar(128),
1370: // TableName varchar(128),
1371: // TaleType varchar(4000),
1372: // Options varchar(4000))
1373: //
1374: public java.sql.ResultSet getSchemas() throws SQLException {
1375: try {
1376: synchronized (connection_) {
1377: if (agent_.loggingEnabled()) {
1378: agent_.logWriter_.traceEntry(this , "getSchemas");
1379: }
1380: return getSchemasX();
1381: }
1382: } catch (SqlException se) {
1383: throw se.getSQLException();
1384: }
1385: }
1386:
1387: private ResultSet getSchemasX() throws SqlException {
1388: try {
1389: checkForClosedConnection();
1390: } catch (SQLException se) {
1391: throw new SqlException(se);
1392: }
1393:
1394: ;
1395:
1396: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLTABLES('', '', '', '', 'GETSCHEMAS=1')");
1397: return (ResultSet) cs.executeQueryX();
1398: }
1399:
1400: // DERBY does not have the notion of a catalog, so we return a result set with no rows.
1401: public java.sql.ResultSet getCatalogs() throws SQLException {
1402: try {
1403: synchronized (connection_) {
1404: if (agent_.loggingEnabled()) {
1405: agent_.logWriter_.traceEntry(this , "getCatalogs");
1406: }
1407: return getCatalogsX();
1408: }
1409: } catch (SqlException se) {
1410: throw se.getSQLException();
1411: }
1412: }
1413:
1414: private ResultSet getCatalogsX() throws SqlException {
1415: checkForClosedConnectionX();
1416:
1417: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLTABLES('', '', '', '', 'GETCATALOGS=1')");
1418: return (ResultSet) cs.executeQueryX();
1419: }
1420:
1421: // call stored procedure SQLTables
1422: // SYSIBM.SQLTables(
1423: // CatalogName varchar(128),
1424: // SchemaName varchar(128),
1425: // TableName varchar(128),
1426: // TableType varchar(4000),
1427: // Options varchar(4000))
1428: public java.sql.ResultSet getTableTypes() throws SQLException {
1429: try {
1430: synchronized (connection_) {
1431: if (agent_.loggingEnabled()) {
1432: agent_.logWriter_.traceEntry(this , "getTableTypes");
1433: }
1434: return getTableTypesX();
1435: }
1436: } catch (SqlException se) {
1437: throw se.getSQLException();
1438: }
1439: }
1440:
1441: private ResultSet getTableTypesX() throws SqlException {
1442: checkForClosedConnectionX();
1443: ;
1444:
1445: PreparedStatement cs = null;
1446: cs = prepareMetaDataQuery("SYSIBM.SQLTABLES(?,?,?,?,?)");
1447:
1448: cs.setStringX(1, "");
1449: cs.setStringX(2, "");
1450: cs.setStringX(3, "");
1451: cs.setStringX(4, "%");
1452: int cursorHold;
1453: if (connection_.holdability() == JDBC30Translation.HOLD_CURSORS_OVER_COMMIT) {
1454: cursorHold = 1;
1455: } else {
1456: cursorHold = 0;
1457: }
1458: cs.setStringX(5, "DATATYPE='JDBC';GETTABLETYPES=1; CURSORHOLD="
1459: + cursorHold);
1460: return executeCatalogQuery(cs);
1461: }
1462:
1463: // call stored procedure SQLColumns
1464: // SYSIBM.SQLColumns(
1465: // CatalogName varchar(128),
1466: // SchemaName varchar(128),
1467: // TableName varchar(128),
1468: // ColumnName varchar(128),
1469: // Options varchar(4000))
1470: //
1471: public java.sql.ResultSet getColumns(String catalog,
1472: String schemaPattern, String tableNamePattern,
1473: String columnNamePattern) throws SQLException {
1474: try {
1475: synchronized (connection_) {
1476: if (agent_.loggingEnabled()) {
1477: agent_.logWriter_.traceEntry(this , "getColumns",
1478: catalog, schemaPattern, tableNamePattern,
1479: columnNamePattern);
1480: }
1481: checkForClosedConnection();
1482: return getColumnsX(catalog, schemaPattern,
1483: tableNamePattern, columnNamePattern);
1484: }
1485: } catch (SqlException se) {
1486: throw se.getSQLException();
1487: }
1488: }
1489:
1490: private ResultSet getColumnsX(String catalog, String schemaPattern,
1491: String tableNamePattern, String columnNamePattern)
1492: throws SqlException {
1493: checkForClosedConnectionX();
1494:
1495: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLCOLUMNS(?,?,?,?,?)");
1496:
1497: cs.setStringX(1, catalog);
1498: cs.setStringX(2, schemaPattern);
1499: cs.setStringX(3, tableNamePattern);
1500: cs.setStringX(4, columnNamePattern); //Always null for JDBC
1501: cs.setStringX(5, getOptions());
1502: return executeCatalogQuery(cs);
1503: }
1504:
1505: // call stored procedure SQLColumnPrivileges
1506: // SYSIBM.SQLColPrivileges(
1507: // CatalogName varchar(128),
1508: // SchemaName varchar(128),
1509: // TableName varchar(128),
1510: // ColumnName varchar(128),
1511: // Options varchar(4000))
1512: //
1513: public java.sql.ResultSet getColumnPrivileges(String catalog,
1514: String schema, String table, String columnNamePattern)
1515: throws SQLException {
1516: try {
1517: synchronized (connection_) {
1518: if (agent_.loggingEnabled()) {
1519: agent_.logWriter_.traceEntry(this ,
1520: "getColumnPrivileges", catalog, schema,
1521: table, columnNamePattern);
1522: }
1523: return getColumnPrivilegesX(catalog, schema, table,
1524: columnNamePattern);
1525: }
1526: } catch (SqlException se) {
1527: throw se.getSQLException();
1528: }
1529: }
1530:
1531: private ResultSet getColumnPrivilegesX(String catalog,
1532: String schema, String table, String columnNamePattern)
1533: throws SqlException {
1534: checkForClosedConnectionX();
1535: // check input params, table and columnNamePattern cannot be null
1536: if (table == null) {
1537: throw new SqlException(agent_.logWriter_,
1538: new ClientMessageId(
1539: SQLState.TABLE_NAME_CANNOT_BE_NULL));
1540:
1541: }
1542:
1543: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLCOLPRIVILEGES(?,?,?,?,?)");
1544:
1545: cs.setStringX(1, catalog);
1546: cs.setStringX(2, schema);
1547: cs.setStringX(3, table);
1548: cs.setStringX(4, columnNamePattern);
1549: cs.setStringX(5, getOptions());
1550: return executeCatalogQuery(cs);
1551: }
1552:
1553: // call stored procedure SQLTablePrivileges
1554: // SYSIBM.SQLTablePrivileges(
1555: // CatalogName varchar(128),
1556: // SchemaName varchar(128),
1557: // TableName varchar(128),
1558: // Options varchar(4000))
1559: //
1560: public java.sql.ResultSet getTablePrivileges(String catalog,
1561: String schemaPattern, String tableNamePattern)
1562: throws SQLException {
1563: try {
1564: synchronized (connection_) {
1565: if (agent_.loggingEnabled()) {
1566: agent_.logWriter_.traceEntry(this ,
1567: "getTablePrivileges", catalog,
1568: schemaPattern, tableNamePattern);
1569: }
1570: return getTablePrivilegesX(catalog, schemaPattern,
1571: tableNamePattern);
1572: }
1573: } catch (SqlException se) {
1574: throw se.getSQLException();
1575: }
1576: }
1577:
1578: private ResultSet getTablePrivilegesX(String catalog,
1579: String schemaPattern, String tableNamePattern)
1580: throws SqlException {
1581: checkForClosedConnectionX();
1582: ;
1583:
1584: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLTABLEPRIVILEGES(?,?,?,?)");
1585:
1586: cs.setStringX(1, catalog);
1587: cs.setStringX(2, schemaPattern);
1588: cs.setStringX(3, tableNamePattern);
1589: cs.setStringX(4, getOptions());
1590: return executeCatalogQuery(cs);
1591: }
1592:
1593: // call stored procedure
1594: // SYSIBM.SQLSPECIALCOLUMNS ( IN COLTYPE SMALLINT,
1595: // IN CATALOG_NAME VARCHAR(128),
1596: // IN SCHEMA_NAME VARCHAR(128),
1597: // IN TABLE_NAME VARCHAR(128),
1598: // IN SCOPE SMALLINT,
1599: // IN NULLABLE SMALLINT,
1600: // IN OPTIONS VARCHAR(4000) )
1601: //
1602: public java.sql.ResultSet getBestRowIdentifier(String catalog,
1603: String schema, String table, int scope, boolean nullable)
1604: throws SQLException {
1605: try {
1606: synchronized (connection_) {
1607: if (agent_.loggingEnabled()) {
1608: agent_.logWriter_.traceEntry(this ,
1609: "getBestRowIdentifier", catalog, schema,
1610: table, scope, nullable);
1611: }
1612: return getBestRowIdentifierX(catalog, schema, table,
1613: scope, nullable);
1614: }
1615: } catch (SqlException se) {
1616: throw se.getSQLException();
1617: }
1618: }
1619:
1620: private ResultSet getBestRowIdentifierX(String catalog,
1621: String schema, String table, int scope, boolean nullable)
1622: throws SqlException {
1623: checkForClosedConnectionX();
1624: ;
1625:
1626: // check input params
1627: //
1628: // validate input table, which can not be null
1629: if (table == null) {
1630: throw new SqlException(agent_.logWriter_,
1631: new ClientMessageId(
1632: SQLState.TABLE_NAME_CANNOT_BE_NULL));
1633:
1634: }
1635: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLSPECIALCOLUMNS(?,?,?,?,?,?,?)");
1636:
1637: cs.setIntX(1, SQL_BEST_ROWID);
1638: cs.setStringX(2, catalog);
1639: cs.setStringX(3, schema);
1640: cs.setStringX(4, table);
1641: cs.setIntX(5, scope);
1642: if (nullable) {
1643: cs.setShortX(6, (short) 1);
1644: } else {
1645: cs.setShortX(6, (short) 0);
1646: }
1647: cs.setStringX(7, getOptions());
1648: return executeCatalogQuery(cs);
1649: }
1650:
1651: public java.sql.ResultSet getVersionColumns(String catalog,
1652: String schema, String table) throws SQLException {
1653: try {
1654: synchronized (connection_) {
1655: if (agent_.loggingEnabled()) {
1656: agent_.logWriter_
1657: .traceEntry(this , "getVersionColumns",
1658: catalog, schema, table);
1659: }
1660: return getVersionColumnsX(catalog, schema, table);
1661: }
1662: } catch (SqlException se) {
1663: throw se.getSQLException();
1664: }
1665: }
1666:
1667: private ResultSet getVersionColumnsX(String catalog, String schema,
1668: String table) throws SqlException {
1669: checkForClosedConnectionX();
1670:
1671: // validate input table, which can not be null
1672: if (table == null) {
1673: throw new SqlException(agent_.logWriter_,
1674: new ClientMessageId(
1675: SQLState.TABLE_NAME_CANNOT_BE_NULL));
1676:
1677: }
1678: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLSPECIALCOLUMNS(?,?,?,?,?,?,?)");
1679:
1680: cs.setIntX(1, SQL_ROWVER);
1681: cs.setStringX(2, catalog);
1682: cs.setStringX(3, schema);
1683: cs.setStringX(4, table);
1684: cs.setIntX(5, 0);
1685: cs.setShortX(6, (short) 0);
1686: cs.setStringX(7, getOptions());
1687:
1688: return executeCatalogQuery(cs);
1689: }
1690:
1691: // call stored procedure SQLPrimaryKeys
1692: // SYSIBM.SQLPrimaryKeys(
1693: // CatalogName varchar(128),
1694: // SchemaName varchar(128),
1695: // TableName varchar(128),
1696: // Options varchar(4000))
1697: //
1698: public java.sql.ResultSet getPrimaryKeys(String catalog,
1699: String schema, String table) throws SQLException {
1700: try {
1701: synchronized (connection_) {
1702: if (agent_.loggingEnabled()) {
1703: agent_.logWriter_.traceEntry(this ,
1704: "getPrimaryKeys", catalog, schema, table);
1705: }
1706: return getPrimaryKeysX(catalog, schema, table);
1707: }
1708: } catch (SqlException se) {
1709: throw se.getSQLException();
1710: }
1711: }
1712:
1713: private ResultSet getPrimaryKeysX(String catalog, String schema,
1714: String table) throws SqlException {
1715: checkForClosedConnectionX();
1716: ;
1717:
1718: // validate the input table name
1719: if (table == null) {
1720: throw new SqlException(agent_.logWriter_,
1721: new ClientMessageId(
1722: SQLState.TABLE_NAME_CANNOT_BE_NULL));
1723:
1724: }
1725: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLPRIMARYKEYS(?,?,?,?)");
1726:
1727: cs.setStringX(1, catalog);
1728: cs.setStringX(2, schema);
1729: cs.setStringX(3, table);
1730: cs.setStringX(4, getOptions());
1731: return executeCatalogQuery(cs);
1732: }
1733:
1734: // call storlastGetPrimaryKeysResultSet_ed procedure SQLForeignKeys
1735: // SYSIBM.SQLForeignKeys(
1736: // PKCatalogName varchar(128),
1737: // PKSchemaName varchar(128),
1738: // PKTableName varchar(128),
1739: // FKCatalogName varchar(128),
1740: // FKSchemaName varchar(128),
1741: // FKTableName varchar(128),
1742: // Options varchar(4000))
1743: //
1744: public java.sql.ResultSet getImportedKeys(String catalog,
1745: String schema, String table) throws SQLException {
1746: try {
1747: synchronized (connection_) {
1748: if (agent_.loggingEnabled()) {
1749: agent_.logWriter_.traceEntry(this ,
1750: "getImportedKeys", catalog, schema, table);
1751: }
1752: return getImportedKeysX(catalog, schema, table);
1753: }
1754: } catch (SqlException se) {
1755: throw se.getSQLException();
1756: }
1757: }
1758:
1759: private ResultSet getImportedKeysX(String catalog, String schema,
1760: String table) throws SqlException {
1761: checkForClosedConnectionX();
1762:
1763: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLFOREIGNKEYS(?,?,?,?,?,?,?)");
1764:
1765: cs.setStringX(1, "");
1766: cs.setStringX(2, null);
1767: cs.setStringX(3, "");
1768: cs.setStringX(4, catalog);
1769: cs.setStringX(5, schema);
1770: cs.setStringX(6, table);
1771: // We're passing the keyword EXPORTEDKEY, but this support may not be in the GA version of SPs.
1772: // As a workaround in getCrossReference(), we'll just "select * where 0=1" when primaryTable==""
1773: if (connection_.holdability() == JDBC30Translation.HOLD_CURSORS_OVER_COMMIT) {
1774: cs.setStringX(7,
1775: "DATATYPE='JDBC';IMPORTEDKEY=1; CURSORHOLD=1");
1776: } else {
1777: cs.setStringX(7,
1778: "DATATYPE='JDBC';IMPORTEDKEY=1; CURSORHOLD=0");
1779: }
1780: return executeCatalogQuery(cs);
1781: }
1782:
1783: // call stored procedure SQLForeignKeys
1784: // SYSIBM.SQLForeignKeys(
1785: // PKCatalogName varchar(128),
1786: // PKSchemaName varchar(128),
1787: // PKTableName varchar(128),
1788: // FKCatalogName varchar(128),
1789: // FKSchemaName varchar(128),
1790: // FKTableName varchar(128),
1791: // Options varchar(4000))
1792: //
1793: public java.sql.ResultSet getExportedKeys(String catalog,
1794: String schema, String table) throws SQLException {
1795: try {
1796: synchronized (connection_) {
1797: if (agent_.loggingEnabled()) {
1798: agent_.logWriter_.traceEntry(this ,
1799: "getExportedKeys", catalog, schema, table);
1800: }
1801: return getExportedKeysX(catalog, schema, table);
1802: }
1803: } catch (SqlException se) {
1804: throw se.getSQLException();
1805: }
1806: }
1807:
1808: private ResultSet getExportedKeysX(String catalog, String schema,
1809: String table) throws SqlException {
1810: checkForClosedConnectionX();
1811: ;
1812:
1813: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLFOREIGNKEYS(?,?,?,?,?,?,?)");
1814:
1815: cs.setStringX(1, catalog);
1816: cs.setStringX(2, schema);
1817: cs.setStringX(3, table);
1818: cs.setStringX(4, "");
1819: cs.setStringX(5, null);
1820: cs.setStringX(6, "");
1821: // We're passing the keyword EXPORTEDKEY, but this support may not be in the GA version of SPs.
1822: // As a workaround in getCrossReference(), we'll just "select * where 0=1" when foreignTable==""
1823: if (connection_.holdability() == JDBC30Translation.HOLD_CURSORS_OVER_COMMIT) {
1824: cs.setStringX(7,
1825: "DATATYPE='JDBC';EXPORTEDKEY=1; CURSORHOLD=1");
1826: } else {
1827: cs.setStringX(7,
1828: "DATATYPE='JDBC';EXPORTEDKEY=1; CURSORHOLD=0");
1829: }
1830: return executeCatalogQuery(cs);
1831: }
1832:
1833: // call stored procedure SQLForeignKeys
1834: // SYSIBM.SQLForeignKeys(
1835: // PKCatalogName varchar(128),
1836: // PKSchemaName varchar(128),
1837: // PKTableName varchar(128),
1838: // FKCatalogName varchar(128),
1839: // FKSchemaName varchar(128),
1840: // FKTableName varchar(128),
1841: // Options varchar(4000))
1842: //
1843: public java.sql.ResultSet getCrossReference(String primaryCatalog,
1844: String primarySchema, String primaryTable,
1845: String foreignCatalog, String foreignSchema,
1846: String foreignTable) throws SQLException {
1847: try {
1848: synchronized (connection_) {
1849: if (agent_.loggingEnabled()) {
1850: agent_.logWriter_
1851: .traceEntry(this , "getCrossReference",
1852: primaryCatalog, primarySchema,
1853: primaryTable, foreignCatalog,
1854: foreignSchema, foreignTable);
1855: }
1856: return getCrossReferenceX(primaryCatalog,
1857: primarySchema, primaryTable, foreignCatalog,
1858: foreignSchema, foreignTable);
1859: }
1860: } catch (SqlException se) {
1861: throw se.getSQLException();
1862: }
1863: }
1864:
1865: private ResultSet getCrossReferenceX(String primaryCatalog,
1866: String primarySchema, String primaryTable,
1867: String foreignCatalog, String foreignSchema,
1868: String foreignTable) throws SqlException {
1869: checkForClosedConnectionX();
1870: ;
1871:
1872: // check input params, primaryTable and foreignTable cannot be null
1873: if (primaryTable == null) {
1874: throw new SqlException(agent_.logWriter_,
1875: new ClientMessageId(
1876: SQLState.PRIMARY_TABLE_NAME_IS_NULL));
1877:
1878: }
1879:
1880: if (foreignTable == null) {
1881: throw new SqlException(agent_.logWriter_,
1882: new ClientMessageId(
1883: SQLState.FOREIGN_TABLE_NAME_IS_NULL));
1884:
1885: }
1886:
1887: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLFOREIGNKEYS(?,?,?,?,?,?,?)");
1888:
1889: cs.setStringX(1, primaryCatalog);
1890: cs.setStringX(2, primarySchema);
1891: cs.setStringX(3, primaryTable);
1892: cs.setStringX(4, foreignCatalog);
1893: cs.setStringX(5, foreignSchema);
1894: cs.setStringX(6, foreignTable);
1895: cs.setStringX(7, getOptions());
1896: return executeCatalogQuery(cs);
1897: }
1898:
1899: // call stored procedure SQLGetTypeInfo
1900: // SYSIBM.SQLGetTypeInfo (IN DATATYPE SMALLINT,
1901: // IN Options VARCHAR(4000))
1902: //
1903: //
1904: public java.sql.ResultSet getTypeInfo() throws SQLException {
1905: try {
1906: synchronized (connection_) {
1907: if (agent_.loggingEnabled()) {
1908: agent_.logWriter_.traceEntry(this , "getTypeInfo");
1909: }
1910: return getTypeInfoX();
1911: }
1912: } catch (SqlException se) {
1913: throw se.getSQLException();
1914: }
1915: }
1916:
1917: private ResultSet getTypeInfoX() throws SqlException {
1918: checkForClosedConnectionX();
1919: ;
1920:
1921: // check if the last call's resultset is closed or not.
1922: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLGETTYPEINFO(?,?)");
1923:
1924: cs.setShortX(1, (short) 0);
1925: cs.setStringX(2, getOptions());
1926: return executeCatalogQuery(cs);
1927: }
1928:
1929: // call stored procedure SQLStatistics
1930: // SYSIBM.SQLStatistics(
1931: // CatalogName varchar(128),
1932: // SchemaName varchar(128),
1933: // TableName varchar(128),
1934: // Unique Smallint,
1935: // Reserved Smallint,
1936: // Options varchar(4000))
1937: //
1938: public java.sql.ResultSet getIndexInfo(String catalog,
1939: String schema, String table, boolean unique,
1940: boolean approximate) throws SQLException {
1941: try {
1942: synchronized (connection_) {
1943: if (agent_.loggingEnabled()) {
1944: agent_.logWriter_
1945: .traceEntry(this , "getIndexInfo", catalog,
1946: schema, table, unique, approximate);
1947: }
1948: return getIndexInfoX(catalog, schema, table, unique,
1949: approximate);
1950: }
1951: } catch (SqlException se) {
1952: throw se.getSQLException();
1953: }
1954: }
1955:
1956: private ResultSet getIndexInfoX(String catalog, String schema,
1957: String table, boolean unique, boolean approximate)
1958: throws SqlException {
1959: checkForClosedConnectionX();
1960:
1961: // validate the input table name
1962: if (table == null) {
1963: throw new SqlException(agent_.logWriter_,
1964: new ClientMessageId(
1965: SQLState.TABLE_NAME_CANNOT_BE_NULL));
1966: }
1967: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLSTATISTICS(?,?,?,?,?,?)");
1968:
1969: cs.setStringX(1, catalog);
1970: cs.setStringX(2, schema);
1971: cs.setStringX(3, table);
1972:
1973: if (unique) {
1974: cs.setShortX(4, SQL_INDEX_UNIQUE);
1975: } else {
1976: cs.setShortX(4, SQL_INDEX_ALL);
1977: }
1978:
1979: if (approximate) {
1980: cs.setShortX(5, (short) 1);
1981: } else {
1982: cs.setShortX(5, (short) 0);
1983: }
1984:
1985: cs.setStringX(6, getOptions());
1986: return executeCatalogQuery(cs);
1987: }
1988:
1989: //--------------------------JDBC 2.0-----------------------------
1990:
1991: public java.sql.ResultSet getUDTs(String catalog,
1992: String schemaPattern, String typeNamePattern, int[] types)
1993: throws SQLException {
1994: try {
1995: synchronized (connection_) {
1996: if (agent_.loggingEnabled()) {
1997: agent_.logWriter_.traceEntry(this , "getUDTs",
1998: catalog, schemaPattern, typeNamePattern,
1999: types);
2000: }
2001: return getUDTsX(catalog, schemaPattern,
2002: typeNamePattern, types);
2003: }
2004: } catch (SqlException se) {
2005: throw se.getSQLException();
2006: }
2007: }
2008:
2009: private ResultSet getUDTsX(String catalog, String schemaPattern,
2010: String typeNamePattern, int[] types) throws SqlException {
2011: checkForClosedConnectionX();
2012: ;
2013:
2014: PreparedStatement cs = prepareMetaDataQuery("SYSIBM.SQLUDTS(?,?,?,?,?)");
2015:
2016: cs.setStringX(1, catalog);
2017: cs.setStringX(2, schemaPattern);
2018: cs.setStringX(3, typeNamePattern);
2019: int i = 0;
2020: String udtTypes = new String();
2021: while (types != null && i < types.length) {
2022: if (i > 0) {
2023: udtTypes = udtTypes.concat(",");
2024: }
2025: udtTypes = udtTypes.concat(String.valueOf(types[i]));
2026: i++;
2027: }
2028: cs.setStringX(4, udtTypes);
2029: cs.setStringX(5, getOptions());
2030: return executeCatalogQuery(cs);
2031: }
2032:
2033: // helper method for the catalog queries only
2034: private String getOptions() {
2035: int cursorHold;
2036: if (connection_.holdability() == JDBC30Translation.HOLD_CURSORS_OVER_COMMIT) {
2037: cursorHold = 1;
2038: } else {
2039: cursorHold = 0;
2040: }
2041: return "DATATYPE='JDBC';DYNAMIC=0;REPORTPUBLICPRIVILEGES=1;CURSORHOLD="
2042: + cursorHold;
2043:
2044: }
2045:
2046: // Derby uses a PreparedStatement argument rather than a callable statement
2047: private ResultSet executeCatalogQuery(PreparedStatement cs)
2048: throws SqlException {
2049: try {
2050: return cs.executeQueryX();
2051: } catch (SqlException e) {
2052: if (e.getErrorCode() == -440) {
2053: SqlException newException = new SqlException(
2054: agent_.logWriter_, new ClientMessageId(
2055: SQLState.STORED_PROC_NOT_INSTALLED));
2056: newException.setNextException(e);
2057: throw newException;
2058: } else if (e.getErrorCode() == -444) {
2059: SqlException newException = new SqlException(
2060: agent_.logWriter_,
2061: new ClientMessageId(
2062: SQLState.STORED_PROC_LOAD_MODULE_NOT_FOUND));
2063: newException.setNextException(e);
2064: throw newException;
2065: } else {
2066: throw e;
2067: }
2068: }
2069: }
2070:
2071: public java.sql.Connection getConnection() throws SQLException {
2072: checkForClosedConnection();
2073: return connection_;
2074: }
2075:
2076: // ------------------- JDBC 3.0 -------------------------
2077:
2078: public boolean supportsNamedParameters() throws SQLException {
2079: checkForClosedConnection();
2080: return false;
2081: }
2082:
2083: public boolean supportsMultipleOpenResults() throws SQLException {
2084: checkForClosedConnection();
2085: return true;
2086: }
2087:
2088: public boolean supportsGetGeneratedKeys() throws SQLException {
2089: checkForClosedConnection();
2090: return false;
2091: }
2092:
2093: public java.sql.ResultSet getSuperTypes(String catalog,
2094: String schemaPattern, String typeNamePattern)
2095: throws SQLException {
2096: try {
2097: synchronized (connection_) {
2098: if (agent_.loggingEnabled()) {
2099: agent_.logWriter_.traceEntry(this , "getSuperTypes",
2100: catalog, schemaPattern, typeNamePattern);
2101: }
2102: return getSuperTypesX();
2103: }
2104: } catch (SqlException se) {
2105: throw se.getSQLException();
2106: }
2107: }
2108:
2109: private ResultSet getSuperTypesX() throws SqlException {
2110: checkForClosedConnectionX();
2111: String sql = "SELECT CAST(NULL AS VARCHAR(128)) AS TYPE_CAT,"
2112: + "CAST(NULL AS VARCHAR(128)) AS TYPE_SCHEM,"
2113: + "VARCHAR('', 128) AS TYPE_NAME,"
2114: + "CAST(NULL AS VARCHAR(128)) AS SUPERTYPE_CAT,"
2115: + "CAST(NULL AS VARCHAR(128)) AS SUPERTYPE_SCHEM,"
2116: + "VARCHAR('', 128) AS SUPERTYPE_NAME "
2117: + "FROM SYSIBM.SYSDUMMY1 WHERE 1=0 WITH UR ";
2118: PreparedStatement ps = connection_
2119: .prepareDynamicCatalogQuery(sql);
2120: return ps.executeQueryX();
2121: }
2122:
2123: public java.sql.ResultSet getSuperTables(String catalog,
2124: String schemaPattern, String tableNamePattern)
2125: throws SQLException {
2126: try {
2127: synchronized (connection_) {
2128: if (agent_.loggingEnabled()) {
2129: agent_.logWriter_.traceEntry(this ,
2130: "getSuperTables", catalog, schemaPattern,
2131: tableNamePattern);
2132: }
2133: return getSuperTablesX();
2134: }
2135: } catch (SqlException se) {
2136: throw se.getSQLException();
2137: }
2138: }
2139:
2140: private ResultSet getSuperTablesX() throws SqlException {
2141: checkForClosedConnectionX();
2142: java.lang.String sql = "SELECT CAST(NULL AS VARCHAR(128)) AS TABLE_CAT,"
2143: + "CAST(NULL AS VARCHAR(128)) AS TABLE_SCHEM,"
2144: + "VARCHAR('', 128) AS TABLE_NAME,"
2145: + "VARCHAR('', 128) AS SUPERTABLE_NAME FROM SYSIBM.SYSDUMMY1 "
2146: + "WHERE 1=0 WITH UR";
2147: PreparedStatement ps = connection_
2148: .prepareDynamicCatalogQuery(sql);
2149: return ps.executeQueryX();
2150: }
2151:
2152: public java.sql.ResultSet getAttributes(String catalog,
2153: String schemaPattern, String typeNamePattern,
2154: String attributeNamePattern) throws SQLException {
2155: try {
2156: synchronized (connection_) {
2157: if (agent_.loggingEnabled()) {
2158: agent_.logWriter_.traceEntry(this , "getAttributes",
2159: catalog, schemaPattern, typeNamePattern,
2160: attributeNamePattern);
2161: }
2162: return getAttributesX();
2163: }
2164: } catch (SqlException se) {
2165: throw se.getSQLException();
2166: }
2167: }
2168:
2169: private ResultSet getAttributesX() throws SqlException {
2170: checkForClosedConnectionX();
2171: java.lang.String sql = "SELECT CAST(NULL AS VARCHAR(128)) AS TYPE_CAT,"
2172: + "CAST(NULL AS VARCHAR(128)) AS TYPE_SCHEM,"
2173: + "VARCHAR('', 128) AS TYPE_NAME,"
2174: + "VARCHAR('',128) AS ATTR_NAME,"
2175: + "0 AS DATA_TYPE,"
2176: + "VARCHAR('',129) AS ATTR_TYPE_NAME,"
2177: + "0 AS ATTR_SIZE,"
2178: + "0 AS DECIMAL_DIGITS,"
2179: + "0 AS NUM_PREC_RADIX,"
2180: + "2 AS NULLABLE,"
2181: + "CAST(NULL AS VARCHAR(254)) AS REMARKS,"
2182: + "CAST(NULL AS VARCHAR(128)) AS ATTR_DEF,"
2183: + "0 AS SQL_DATA_TYPE,"
2184: + "0 AS SQL_DATETIME_SUB,"
2185: + "0 AS CHAR_OCTET_LENGTH,"
2186: + "0 AS ORDINAL_POSITION,"
2187: + "VARCHAR('',128) AS IS_NULLABLE,"
2188: + "CAST(NULL AS VARCHAR(128)) AS SCOPE_CATALOG,"
2189: + "CAST(NULL AS VARCHAR(128)) AS SCOPE_SCHEMA,"
2190: + "CAST(NULL AS VARCHAR(128)) AS SCOPE_TABLE,"
2191: + "CAST(NULL AS SMALLINT) AS SOURCE_DATA_TYPE "
2192: + "FROM SYSIBM.SYSDUMMY1 WHERE 1=0 WITH UR";
2193: PreparedStatement ps = connection_
2194: .prepareDynamicCatalogQuery(sql);
2195: return ps.executeQueryX();
2196: }
2197:
2198: public boolean supportsResultSetHoldability(int holdability)
2199: throws SQLException {
2200: checkForClosedConnection();
2201: return true;
2202: }
2203:
2204: public int getResultSetHoldability() throws SQLException {
2205: checkForClosedConnection();
2206: return java.sql.ResultSet.HOLD_CURSORS_OVER_COMMIT;
2207: }
2208:
2209: public int getDatabaseMajorVersion() throws SQLException {
2210: checkForClosedConnection();
2211: return productLevel_.versionLevel_;
2212: }
2213:
2214: public int getDatabaseMinorVersion() throws SQLException {
2215: checkForClosedConnection();
2216: return productLevel_.releaseLevel_;
2217: }
2218:
2219: public int getJDBCMajorVersion() throws SQLException {
2220: checkForClosedConnection();
2221: return 3;
2222: }
2223:
2224: public int getJDBCMinorVersion() throws SQLException {
2225: checkForClosedConnection();
2226: return 0;
2227: }
2228:
2229: public int getSQLStateType() throws SQLException {
2230: checkForClosedConnection();
2231: return sqlStateSQL99;
2232: }
2233:
2234: public boolean locatorsUpdateCopy() throws SQLException {
2235: checkForClosedConnection();
2236: return false;
2237: }
2238:
2239: public boolean supportsStatementPooling() throws SQLException {
2240: checkForClosedConnection();
2241: return false;
2242: }
2243:
2244: //--------------------Abstract material layer call-down methods-----------------
2245:
2246: // Compute feature set based on release
2247: abstract protected void computeFeatureSet_();
2248:
2249: //------------helper methods for meta data info call methods------------------
2250:
2251: private boolean getMetaDataInfoBoolean(int infoCallIndex)
2252: throws SQLException {
2253: try {
2254: if (metaDataInfoIsCached_) {
2255: return ((Integer) metaDataInfoCache_[infoCallIndex])
2256: .intValue() != 0;
2257: }
2258: metaDataInfoCall();
2259: return ((Integer) metaDataInfoCache_[infoCallIndex])
2260: .intValue() != 0;
2261: } catch (SqlException se) {
2262: throw se.getSQLException();
2263: }
2264: }
2265:
2266: private int getMetaDataInfoInt(int infoCallIndex)
2267: throws SQLException {
2268: try {
2269: if (metaDataInfoIsCached_) {
2270: return ((Integer) metaDataInfoCache_[infoCallIndex])
2271: .intValue();
2272: }
2273: metaDataInfoCall();
2274: return ((Integer) metaDataInfoCache_[infoCallIndex])
2275: .intValue();
2276: } catch (SqlException se) {
2277: throw se.getSQLException();
2278: }
2279:
2280: }
2281:
2282: private String getMetaDataInfoString(int infoCallIndex)
2283: throws SQLException {
2284: try {
2285: if (metaDataInfoIsCached_) {
2286: return (String) metaDataInfoCache_[infoCallIndex];
2287: }
2288: metaDataInfoCall();
2289: return (String) metaDataInfoCache_[infoCallIndex];
2290: } catch (SqlException se) {
2291: throw se.getSQLException();
2292: }
2293: }
2294:
2295: private boolean getMetaDataInfoBooleanWithType(int infoCallIndex,
2296: int type) throws SQLException {
2297:
2298: boolean clientValue = getMetaDataInfoBooleanWithTypeClient(
2299: infoCallIndex, type);
2300:
2301: // DERBY-1252. In Derby <= 10.x, clients (incl JCC) do not have
2302: // logic to negotiate down these values with the server, so
2303: // for features introduced with 10.x, x >= 2 (e.g. SUR
2304: // DERBY-775, in 10.2), the server will return 10.0 values for
2305: // any version 10.x so as not to break existing apps running
2306: // an older 10 client (e.g. 10.1 client for DERBY-775).
2307: // Reciprocally, this means clients at 10.x, where x => 2,
2308: // must disregard the server's (too conservative) answers for
2309: // these features, see logic in
2310: // getMetaDataInfoBooleanWithTypeClient.
2311: //
2312: // For Derby >= 11, the down-negotiation code below which is
2313: // presently commented out should be activated, and the values
2314: // returned from the server should once more reflect reality.
2315:
2316: // Commented out till we hit Derby 11:
2317: //
2318: // boolean serverValue =
2319: // getMetaDataInfoBooleanWithTypeServer(infoCallIndex, type);
2320: //
2321: // return clientValue && serverValue;
2322:
2323: return clientValue;
2324: }
2325:
2326: // Client's view of boolean metadata.
2327: //
2328: // For values which depend on (added) functionality in *both* the
2329: // client and the server, the client should have its own view of
2330: // all such values here. For other values, it can defer to the
2331: // server. This is a prerequisite for negotiating down in a mixed
2332: // client/Server context. Note that metadata negotiation should
2333: // mirror the similar negotiation for use of the feature itself,
2334: // for example, for scrollable updatable result sets of type
2335: // insensitive, the server will downgrade to read-only if it is
2336: // older than 10.2.
2337: //
2338: // See also comments in getMetaDataInfoBooleanWithType and
2339: // engine/org/apache/derby/impl/sql/catalog/metadata_net.properties.
2340: //
2341: private boolean getMetaDataInfoBooleanWithTypeClient(
2342: int infoCallIndex, int type) throws SQLException {
2343:
2344: switch (infoCallIndex) {
2345: case updatesAreDetected__:
2346: case deletesAreDetected__:
2347: case ownUpdatesAreVisible__:
2348: case ownDeletesAreVisible__:
2349:
2350: if (productLevel_.greaterThanOrEqualTo(10, 2, 0)
2351: && type == ResultSet.TYPE_SCROLL_INSENSITIVE) {
2352: return true;
2353: } else {
2354: return getMetaDataInfoBooleanWithTypeServer(
2355: infoCallIndex, type);
2356: }
2357: case insertsAreDetected__:
2358: case ownInsertsAreVisible__:
2359: if (productLevel_.greaterThanOrEqualTo(10, 2, 0)
2360: && type == ResultSet.TYPE_SCROLL_INSENSITIVE) {
2361: return false;
2362: } else {
2363: return getMetaDataInfoBooleanWithTypeServer(
2364: infoCallIndex, type);
2365: }
2366: default:
2367: return getMetaDataInfoBooleanWithTypeServer(infoCallIndex,
2368: type);
2369: }
2370: }
2371:
2372: private boolean getMetaDataInfoBooleanWithTypeServer(
2373: int infoCallIndex, int type) throws SQLException {
2374:
2375: // Stored Procedure will return a String containing a
2376: // comma seperated list of all the supported result Set types
2377: // not throwing any exception right now even if the the type is wrong as per the spec
2378: try {
2379: String returnedFromSP = null;
2380: if (metaDataInfoIsCached_) {
2381: returnedFromSP = (String) metaDataInfoCache_[infoCallIndex];
2382: } else {
2383: metaDataInfoCall();
2384: returnedFromSP = (String) metaDataInfoCache_[infoCallIndex];
2385: }
2386: java.util.StringTokenizer st = new java.util.StringTokenizer(
2387: returnedFromSP, ",");
2388: while (st.hasMoreTokens()) {
2389: if ((new Integer(st.nextToken())).intValue() == type) {
2390: return true;
2391: }
2392: }
2393: return false;
2394: } catch (SqlException se) {
2395: throw se.getSQLException();
2396: }
2397: }
2398:
2399: private boolean getMetaDataInfoInt_SupportsResultSetConcurrency(
2400: int infoCallIndex, int type, int concurrency)
2401: throws SQLException {
2402: // The stored procured will return a String containing a list
2403: // of lists: For each result set type in the outer list, an
2404: // inner list gives the allowed concurrencies for that type:
2405: // The encoding syntax is reproduced here from the server file
2406: // 'metadata_net.properties (please keep in synch!):
2407: //
2408: // String syntax:
2409: // <type> { "," <concurrency>}* { ";" <type> { "," <concurrency>}* }}*
2410: //
2411: // <type> ::= <the integer value for that type from interface java.sql.Resultset
2412: // i.e. TYPE_FORWARD_ONLY is 1003>
2413: // <concurrency> ::= <the integer value for that concurrency
2414: // from interface java.sql.Resultset, i.e.
2415: // CONCUR_UPDATABLE is 1008>
2416: try {
2417: String returnedFromSP = null;
2418: if (metaDataInfoIsCached_) {
2419: returnedFromSP = (String) metaDataInfoCache_[infoCallIndex];
2420: } else {
2421: metaDataInfoCall();
2422: returnedFromSP = (String) metaDataInfoCache_[infoCallIndex];
2423: }
2424: java.util.StringTokenizer st = new java.util.StringTokenizer(
2425: returnedFromSP, ";");
2426: while (st.hasMoreTokens()) {
2427: java.util.StringTokenizer stForConc = new java.util.StringTokenizer(
2428: st.nextToken(), ",");
2429: if ((new Integer(stForConc.nextToken())).intValue() == type) {
2430: while (stForConc.hasMoreTokens()) {
2431: if ((new Integer(stForConc.nextToken()))
2432: .intValue() == concurrency) {
2433: return true;
2434: }
2435: }
2436: return false;
2437: }
2438: }
2439: return false;
2440: } catch (SqlException se) {
2441: throw se.getSQLException();
2442: }
2443: }
2444:
2445: private boolean getMetaDataInfoBoolean_supportsConvert(
2446: int infoCallIndex, int fromType, int toType)
2447: throws SQLException {
2448: // The Stored procedure will return a String contain a list of all the valid conversions it support
2449: // For eg. If the database conversion from char(1) to date(91), time(92) and
2450: // Decimal(3) to char(1) ,double(8)
2451: // then StoredProcedure string will return "1,91,92;3,1,8"
2452: // see how fromTypes are seperated by ";"
2453: try {
2454: String returnedFromSP = null;
2455: if (metaDataInfoIsCached_) {
2456: returnedFromSP = (String) metaDataInfoCache_[infoCallIndex];
2457: } else {
2458: metaDataInfoCall();
2459: returnedFromSP = (String) metaDataInfoCache_[infoCallIndex];
2460: }
2461: java.util.StringTokenizer st = new java.util.StringTokenizer(
2462: returnedFromSP, ";");
2463: while (st.hasMoreTokens()) {
2464: java.util.StringTokenizer stForType = new java.util.StringTokenizer(
2465: st.nextToken(), ",");
2466: if ((new Integer(stForType.nextToken())).intValue() == fromType) {
2467: while (st.hasMoreTokens()) {
2468: if ((new Integer(st.nextToken())).intValue() == toType) {
2469: return true;
2470: }
2471: }
2472: return false;
2473: }
2474: }
2475: return false;
2476: } catch (SqlException se) {
2477: throw se.getSQLException();
2478: }
2479: }
2480:
2481: // We synchronize at this level so that we don't have to synchronize all
2482: // the meta data info methods. If we just return hardwired answers we don't
2483: // need to synchronize at the higher level.
2484: private void metaDataInfoCall() throws SqlException {
2485: synchronized (connection_) {
2486: ResultSet rs;
2487:
2488: // These remote calls return a result set containing a single row.
2489: // Each column in the row corresponds to a particular get meta data info
2490: // method.
2491: PreparedStatement ps = prepareMetaDataQuery("SYSIBM.MetaData()");
2492: rs = (ResultSet) ps.executeQueryX();
2493: rs.nextX();
2494: int ColumnCount;
2495: try {
2496: ColumnCount = ((ColumnMetaData) rs.getMetaDataX())
2497: .getColumnCount();
2498: } catch (SQLException se) {
2499: throw new SqlException(se);
2500: }
2501: for (int infoCallIndex = 0; (infoCallIndex < ColumnCount && infoCallIndex < metaDataInfoCache_.length); infoCallIndex++) {
2502: metaDataInfoCache_[infoCallIndex] = rs
2503: .getObjectX(infoCallIndex + 1);
2504: }
2505: metaDataInfoIsCached_ = true;
2506: rs.closeX();
2507: }
2508: }
2509:
2510: // ------------------- JDBC 4.0 -------------------------
2511:
2512: /**
2513: * Retrieves whether this database supports invoking user-defined
2514: * or vendor functions using the stored procedure escape syntax.
2515: *
2516: * @return <code>true</code>, since Derby supports the escape syntax
2517: * @exception SQLException if a database access error occurs
2518: */
2519: public final boolean supportsStoredFunctionsUsingCallSyntax()
2520: throws SQLException {
2521: checkForClosedConnection();
2522: return true;
2523: }
2524:
2525: /**
2526: * Retrieves whether an <code>SQLException</code> will cause all
2527: * open <code>ResultSet</code>s to be closed when auto-commit is
2528: * <code>true</code>.
2529: *
2530: * @return <code>false</code>, since Derby does not close all open
2531: * result sets when an error occurs
2532: * @exception SQLException if a database access error occurs
2533: */
2534: public final boolean autoCommitFailureClosesAllResultSets()
2535: throws SQLException {
2536: checkForClosedConnection();
2537: return false;
2538: }
2539:
2540: /**
2541: * Retrieves whether this JDBC driver provides its own
2542: * <code>QueryObjectGenerator</code>.
2543: *
2544: * @return <code>false</code>, since Derby does not provide its
2545: * own generator
2546: * @exception SQLException if a database access error occurs
2547: */
2548: public final boolean providesQueryObjectGenerator()
2549: throws SQLException {
2550: checkForClosedConnection();
2551: return false;
2552: }
2553:
2554: /**
2555: * Get the schema names available in this database. The results
2556: * are ordered by schema name.
2557: *
2558: * <p>The schema columns are:
2559: * <ol>
2560: * <li><strong>TABLE_SCHEM</strong> String => schema name</li>
2561: * <li><strong>TABLE_CATALOG</strong> String => catalog name
2562: * (may be <code>null</code>)</li>
2563: * </ol>
2564: *
2565: * @param catalog catalog name used to narrow down the search; ""
2566: * means no catalog, <code>null</code> means any catalog
2567: * @param schemaPattern schema name used to narrow down the
2568: * search, <code>null</code> means schema name should not be used
2569: * to narrow down search
2570: * @return a <code>ResultSet</code> object in which each row is a
2571: * schema description
2572: * @exception SQLException if a database error occurs
2573: */
2574: public ResultSet getSchemas(String catalog, String schemaPattern)
2575: throws SQLException {
2576: try {
2577: synchronized (connection_) {
2578: if (agent_.loggingEnabled()) {
2579: agent_.logWriter_.traceEntry(this , "getSchemas");
2580: }
2581: return getSchemasX(catalog, schemaPattern);
2582: }
2583: } catch (SqlException se) {
2584: throw se.getSQLException();
2585: }
2586: }
2587:
2588: /**
2589: * Untraced version of <code>getSchemas(String, String)</code>.
2590: *
2591: * @param catalog catalog name
2592: * @param schemaPattern pattern for schema name
2593: * @return a <code>ResultSet</code> value
2594: * @exception SqlException if a database error occurs
2595: * @see #getSchemas(String, String)
2596: */
2597: private ResultSet getSchemasX(String catalog, String schemaPattern)
2598: throws SqlException {
2599: checkForClosedConnectionX();
2600:
2601: // If the server has not implemented support for JDBC 4.0,
2602: // SYSIBM.SQLTABLES does not recognize the GETSCHEMAS=2
2603: // option, and it will call getTables() instead of
2604: // getSchemas(). Therefore, check server version and throw an
2605: // exception if the server does not support JDBC 4.0.
2606: checkServerJdbcVersionX("getSchemas(String, String)", 4, 0);
2607:
2608: String call = "SYSIBM.SQLTABLES(?, ?, '', '', 'GETSCHEMAS=2')";
2609: PreparedStatement cs = prepareMetaDataQuery(call);
2610: if (catalog == null) {
2611: cs.setNullX(1, java.sql.Types.VARCHAR);
2612: } else {
2613: cs.setStringX(1, catalog);
2614: }
2615: if (schemaPattern == null) {
2616: cs.setNullX(2, java.sql.Types.VARCHAR);
2617: } else {
2618: cs.setStringX(2, schemaPattern);
2619: }
2620: return cs.executeQueryX();
2621: }
2622:
2623: /**
2624: * Returns a list of the client info properties supported by the
2625: * driver. The result set contains the following columns:
2626: *
2627: * <p>
2628: * <ol>
2629: * <li>NAME String=> The name of the client info property.</li>
2630: * <li>MAX_LEN int=> The maximum length of the value for the
2631: * property.</li>
2632: * <li>DEFAULT_VALUE String=> The default value of the property.</li>
2633: * <li>DESCRIPTION String=> A description of the property.</li>
2634: * </ol>
2635: *
2636: * <p>The <code>ResultSet</code> is sorted by the NAME column.
2637: *
2638: * @return A <code>ResultSet</code> object; each row is a
2639: * supported client info property
2640: * @exception SQLException if an error occurs
2641: */
2642: public ResultSet getClientInfoProperties() throws SQLException {
2643: try {
2644: synchronized (connection_) {
2645: if (agent_.loggingEnabled()) {
2646: agent_.logWriter_.traceEntry(this ,
2647: "getClientInfoProperties");
2648: }
2649: return getClientInfoPropertiesX();
2650: }
2651: } catch (SqlException se) {
2652: throw se.getSQLException();
2653: }
2654: }
2655:
2656: /**
2657: * Untraced version of <code>getClientInfoProperties()</code>.
2658: * Returns an empty <code>ResultSet</code> with the correct column
2659: * names.
2660: *
2661: * @return a <code>ResultSet</code> value
2662: * @exception SqlException if a database error occurs
2663: * @see #getClientInfoProperties
2664: */
2665: private ResultSet getClientInfoPropertiesX() throws SqlException {
2666: checkForClosedConnectionX();
2667: final String sql = "SELECT CAST(NULL AS VARCHAR(128)) AS NAME, "
2668: + "CAST(NULL AS INT) AS MAX_LEN, "
2669: + "CAST(NULL AS VARCHAR(128)) AS DEFAULT_VALUE, "
2670: + "CAST(NULL AS VARCHAR(128)) AS DESCRIPTION "
2671: + "FROM SYSIBM.SYSDUMMY1 WHERE 1=0 WITH UR";
2672: PreparedStatement ps = connection_
2673: .prepareDynamicCatalogQuery(sql);
2674: return ps.executeQueryX();
2675: }
2676:
2677: //----------------------------helper methods----------------------------------
2678:
2679: private PreparedStatement prepareMetaDataQuery(String cmd)
2680: throws SqlException {
2681: PreparedStatement ps;
2682:
2683: ps = (org.apache.derby.client.am.PreparedStatement) connection_
2684: .prepareStatementX("CALL " + cmd,
2685: java.sql.ResultSet.TYPE_FORWARD_ONLY,
2686: java.sql.ResultSet.CONCUR_READ_ONLY,
2687: connection_.holdability(),
2688: java.sql.Statement.NO_GENERATED_KEYS, null);
2689: return ps;
2690: }
2691:
2692: /**
2693: * A "public" version of checkForClosedConnection() that throws
2694: * SQLException instead of SqlException. In particular this is used
2695: * by all the DatabaseMetadata methods
2696: */
2697: protected void checkForClosedConnection() throws SQLException {
2698: try {
2699: checkForClosedConnectionX();
2700: } catch (SqlException se) {
2701: throw se.getSQLException();
2702: }
2703: }
2704:
2705: private void checkForClosedConnectionX() throws SqlException {
2706: if (connection_.isClosedX()) {
2707: agent_.checkForDeferredExceptions();
2708: throw new SqlException(agent_.logWriter_,
2709: new ClientMessageId(SQLState.NO_CURRENT_CONNECTION));
2710:
2711: } else {
2712: agent_.checkForDeferredExceptions();
2713: }
2714: }
2715:
2716: /**
2717: * Checks whether the server supports a JDBC version. If the
2718: * server does not support the JDBC version, an exception is
2719: * thrown.
2720: *
2721: * @param method name of the method for which support is needed on
2722: * the server (used in exception message)
2723: * @param major minimum JDBC major version
2724: * @param minor minimum JDBC minor version if major version matches
2725: * @exception SqlException if the server does not support the
2726: * specified JDBC version
2727: */
2728: protected void checkServerJdbcVersionX(String method, int major,
2729: int minor) throws SqlException {
2730: if (serverJdbcMajorVersion < major
2731: || (serverJdbcMajorVersion == major && serverJdbcMinorVersion < minor)) {
2732: throw new SqlException(
2733: agent_.logWriter_,
2734: new ClientMessageId(
2735: SQLState.JDBC_METHOD_NOT_SUPPORTED_BY_SERVER),
2736: method);
2737: }
2738: }
2739: }
|