/projects/jtopen-7.8/src/com/ibm/as400/access/AS400JDBCDatabaseMetaData.java
Java | 1100 lines | 533 code | 155 blank | 412 comment | 69 complexity | d6606f4050bb8a3a7d309f2d9ff853a0 MD5 | raw file
- ///////////////////////////////////////////////////////////////////////////////
- //
- // JTOpen (IBM Toolbox for Java - OSS version)
- //
- // Filename: AS400JDBCDatabaseMetaData.java
- //
- // The source code contained herein is licensed under the IBM Public License
- // Version 1.0, which has been approved by the Open Source Initiative.
- // Copyright (C) 1997-2010 International Business Machines Corporation and
- // others. All rights reserved.
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- package com.ibm.as400.access;
-
- import java.sql.CallableStatement;
- import java.sql.Connection;
- import java.sql.DatabaseMetaData;
- import java.sql.ResultSet;
- /* ifdef JDBC40 */
- import java.sql.RowIdLifetime;
- /* endif */
- import java.sql.SQLException;
- import java.sql.Statement;
- import java.sql.Types;
- import java.util.Vector; // @D0A
-
-
-
-
- // @E4C
- /**
- The AS400JDBCDatabaseMetaData class provides information
- about the database as a whole.
-
- <p>Some of the methods in this class take arguments that are
- pattern strings. Such arguments are suffixed with "Pattern".
- Within a pattern string, "%" means match any substring of zero
- or more characters, and "_" means match exactly one character.
- Only entries matching the pattern string are returned.
-
- <p>For example, if the schemaPattern argument for getTables()
- is "H%WO_LD", then the following schemas might match
- the pattern, provided they exist on the system:
- <pre>
- HELLOWORLD
- HIWORLD
- HWORLD
- HELLOWOULD
- HIWOULD
- </pre>
-
- <p>Many of the methods here return lists of information in
- result sets. You can use the normal ResultSet methods to
- retrieve data from these result sets. The format of the
- result sets are described in the JDBC interface specification.
-
- <p>Schema and table names that are passed as input to methods
- in this class are implicitly uppercased unless enclosed in
- double-quotes.
- **/
-
- //-----------------------------------------------------------
- // Using nulls and empty strings for catalog functions
- //
- // When the parameter is NOT search pattern capable and:
- // null is specified for:
- // catalog (system) - parameter is ignored
- // schema (library) - use default SQL schema
- // The default SQL schema can be
- // set in the URL. If not
- // specified in URL, the first
- // library specified in the library
- // properties is used as the
- // default SQL schema.
- // If no default SQL schema exists,
- // QGPL is used.
- // table (file) - empty result set is returned
- // column (field) - empty result set is returned
- // empty string is specified for:
- // catalog (system) - empty result set is returned
- // schema (library) - empty result set is returned
- // table (file) - empty result set is returned
- // column (field) - empty result set is returned
- //
- //
- // When the parameter is search pattern capable and:
- // null is specified for:
- // schemaPattern (library) - no value sent to system.
- // System default of
- // *USRLIBL is used.
- // tablePattern (file) - no value sent to system
- // system default of *ALL used
- // empty string is specified for:
- // schemaPattern (library) - empty result set is returned
- // tablePattern (file) - empty result set is returned
- //
- //
- //----------------------------------------------------------
-
- public class AS400JDBCDatabaseMetaData
- /* ifdef JDBC40 */
- extends ToolboxWrapper
- /* endif */
-
- implements DatabaseMetaData
- {
- static final String copyright = "Copyright (C) 1997-2010 International Business Machines Corporation and others.";
-
-
- //New constants for JDBC 3.0.
- public static final int sqlStateXOpen = 1;
- public static final int sqlStateSQL99 = 2;
-
-
- // Private data.
- private AS400JDBCConnection connection_;
- private int id_;
- private SQLConversionSettings settings_;
-
- //@mdsp misc constants for sysibm stored procedures
- final static int SQL_NO_NULLS = 0; //@mdsp
- final static int SQL_NULLABLE = 1; //@mdsp
- final static int SQL_NULLABLE_UNKNOWN = 2; //@mdsp
- final static int SQL_BEST_ROWID = 1; //@mdsp
- final static int SQL_ROWVER = 2; //@mdsp
- static final String EMPTY_STRING = ""; //@mdsp
- static final String MATCH_ALL = "%"; //@mdsp
-
-
- private static final String VIEW = "VIEW"; //@mdsp
- private static final String TABLE = "TABLE"; //@mdsp
- private static final String SYSTEM_TABLE = "SYSTEM TABLE"; //@mdsp
- private static final String ALIAS = "ALIAS"; //@mdsp
- private static final String MQT = "MATERIALIZED QUERY TABLE"; //@mdsp
- private static final String SYNONYM = "SYNONYM"; //@mdsp
- private static final String FAKE_VALUE = "QCUJOFAKE"; //@mdsp
- private static final int SQL_ALL_TYPES = 0; //@mdsp
-
- // the DB2 SQL reference says this should be 2147483647 but we return 1 less to allow for NOT NULL columns
- static final int MAX_LOB_LENGTH = 2147483646; //@xml3
-
-
- static int javaVersion = 0;
- static {
- String javaVersionString = System.getProperty("java.version");
- if (javaVersionString != null) {
- int dotIndex = javaVersionString.indexOf('.');
- if (dotIndex > 0) {
- int secondDotIndex = javaVersionString.indexOf('.', dotIndex+1);
- if (secondDotIndex > 0) {
- String firstDigit = javaVersionString.substring(0,dotIndex);
- String secondDigit = javaVersionString.substring(dotIndex+1, secondDotIndex);
- javaVersion = Integer.parseInt(firstDigit)*10 + Integer.parseInt(secondDigit);
- }
- } else {
- // Android return 0. Set as version 4. @G3A
- if ("0".equals(javaVersionString)) {
- javaVersion = 4;
- }
- }
- }
- }
-
- /**
- Constructs an AS400JDBCDatabaseMetaData object.
-
- @param connection The connection to the system.
- @param id The ID the caller has assigned to this
- AS400JDBCDatabaseMetaData.
- **/
- AS400JDBCDatabaseMetaData (AS400JDBCConnection connection, int id)
- throws SQLException
- {
- connection_ = connection;
- settings_ = new SQLConversionSettings (connection);
- id_ = id;
- }
-
-
-
- /**
- Indicates if all of the procedures returned by getProcedures() can be
- called by the current user.
-
- @return Always false. This driver cannot determine if all of the procedures
- can be called by the current user.
- @exception SQLException This exception is never thrown.
- **/
- public boolean allProceduresAreCallable ()
- throws SQLException
- {
- return false;
- }
-
-
-
- /**
- Indicates if all of the tables returned by getTables() can be
- SELECTed by the current user.
-
- @return Always false. This driver cannot determine if all of the tables
- returned by getTables() can be selected by the current user.
- @exception SQLException This exception is never thrown.
- **/
- public boolean allTablesAreSelectable ()
- throws SQLException
- {
- return false;
- }
-
-
-
- /**
- Indicates if a data definition statement within a transaction
- can force the transaction to commit.
-
- @return Always false. A data definition statement within a transaction
- does not force the transaction to commit.
- @exception SQLException This exception is never thrown.
- **/
- public boolean dataDefinitionCausesTransactionCommit ()
- throws SQLException
- {
- return false;
- }
-
-
-
- /**
- Indicates if a data definition statement within a transaction is
- ignored.
-
- @return Always false. A data definition statement within a
- transaction is not ignored.
- @exception SQLException This exception is never thrown.
- **/
- public boolean dataDefinitionIgnoredInTransactions ()
- throws SQLException
- {
- return false;
- }
-
-
-
- // JDBC 2.0
- /**
- Indicates if visible deletes to a result set of the specified type
- can be detected by calling ResultSet.rowDeleted(). If visible
- deletes cannot be detected, then rows are removed from the
- result set as they are deleted.
-
- @param resultSetType The result set type. Value values are:
- <ul>
- <li>ResultSet.TYPE_FORWARD_ONLY
- <li>ResultSet.TYPE_SCROLL_INSENSITIVE
- <li>ResultSet.TYPE_SCROLL_SENSITIVE
- </ul>
- @return Always false. Deletes can not be detected
- by calling ResultSet.rowDeleted().
-
- @exception SQLException If the result set type is not valid.
- **/
- public boolean deletesAreDetected (int resultSetType)
- throws SQLException
- {
- // Validate the result set type.
- supportsResultSetType (resultSetType);
-
- return false;
- }
-
-
-
- /**
- Indicates if getMaxRowSize() includes blobs when computing the
- maximum length of a single row.
-
- @return Always true. getMaxRowSize() does include blobs when
- computing the maximum length of a single row.
- @exception SQLException This exception is never thrown.
- **/
- public boolean doesMaxRowSizeIncludeBlobs ()
- throws SQLException
- {
- return true;
- }
-
-
-
- //@G4A
- /**
- Returns a ResultSet containing a description of type attributes available in a
- specified catalog.
-
- This method only applies to the attributes of a
- structured type. Distinct types are stored in the datatypes
- catalog, not the attributes catalog. Since DB2 for IBM i does not support
- structured types at this time, an empty ResultSet will always be returned
- for calls to this method.
-
- @param catalog The catalog name.
- @param schemaPattern The schema name pattern.
- @param typeNamePattern The type name pattern.
- @param attributeNamePattern The attribute name pattern.
-
- @return The empty ResultSet
-
- @exception SQLException This exception is never thrown.
- @since Modification 5
- **/
- public ResultSet getAttributes (String catalog, String schemaPattern,
- String typeNamePattern, String attributeNamePattern)
- throws SQLException
- {
- // We return an empty result set because this is not supported by our driver
- Statement statement = connection_.createStatement();
-
- // TODO: Add this to all methods
- if (statement instanceof AS400JDBCStatement) {
- AS400JDBCStatement stmt= (AS400JDBCStatement) statement;
- stmt.closeOnCompletion();
- }
-
- ResultSet rs = statement.executeQuery("SELECT VARCHAR('1', 128) AS TYPE_CAT, " +
- "VARCHAR('2', 128) AS TYPE_SCHEM, " +
- "VARCHAR('3', 128) AS TYPE_NAME, " +
- "VARCHAR('4', 128) AS ATTR_NAME, " +
- "SMALLINT(5) AS DATA_TYPE, " +
- "VARCHAR('6', 128) AS ATTR_TYPE_NAME, " +
- "INT(7) AS ATTR_SIZE, " +
- "INT(8) AS DECIMAL_DIGITS, " +
- "INT(9) AS NUM_PREC_RADIX, " +
- "INT(10) AS NULLABLE, " +
- "VARCHAR('11', 128) AS REMARKS, " +
- "VARCHAR('12', 128) AS ATTR_DEF, " +
- "INT(13) AS SQL_DATA_TYPE, " +
- "INT(14) AS SQL_DATETIME_SUB, " +
- "INT(15) AS CHAR_OCTET_LENGTH, " +
- "INT(16) AS ORDINAL_POSITION, " +
- "VARCHAR('17', 128) AS IS_NULLABLE, " +
- "VARCHAR('18', 128) AS SCOPE_CATALOG, " +
- "VARCHAR('19', 128) AS SCOPE_SCHEMA, " +
- "VARCHAR('20', 128) AS SCOPE_TABLE, " +
- "SMALLINT(21) AS SOURCE_DATA_TYPE " +
- "FROM QSYS2" + getCatalogSeparator() +
- "SYSTYPES WHERE 1 = 2 FOR FETCH ONLY ");
-
- return rs;
- }
-
-
-
- /**
- Returns a description of a table's optimal set of columns
- that uniquely identifies a row.
-
-
- @param catalog The catalog name. If null is specified, this parameter
- is ignored. If empty string is specified,
- an empty result set is returned.
- @param schema The schema name. If null is specified, the
- default SQL schema specified in the URL is used.
- If null is specified and a default SQL schema was not
- specified in the URL, the first library specified
- in the libraries properties file is used.
- If null is specified and a default SQL schema was
- not specified in the URL and a library was not
- specified in the libraries properties file,
- QGPL is used.
- If empty string is specified, an empty result set will
- be returned.
- @param table The table name. If null or empty string is specified,
- an empty result set is returned.
- @param scope The scope of interest. Valid values are:
- bestRowTemporary and bestRowTransaction.
- bestRowSession is not allowed because
- it cannot be guaranteed that
- the row will remain valid for the session.
- If bestRowSession is specified, an empty result
- set is returned.
- If bestRowTransaction is specified,
- autocommit is false, and transaction is set to repeatable read,
- then results is returned; otherwise, an empty result set
- is returned.
- @param nullable The value indicating if columns that are nullable should be included.
- @return The ResultSet containing a table's optimal
- set of columns that uniquely identify a row.
-
- @exception SQLException If the connection is not open
- or an error occurs.
- **/
- public ResultSet getBestRowIdentifier (String catalog,
- String schema,
- String table,
- int scope,
- boolean nullable)
- throws SQLException
- {
- connection_.checkOpen ();
- int vrm = connection_.getVRM(); //@trunc3
- DBReplyRequestedDS getBestRowIdentifierReply = null;
-
- //@mdsp SYSIBM SP Call
- if (connection_.getProperties().getString(JDProperties.METADATA_SOURCE).equals( JDProperties.METADATA_SOURCE_STORED_PROCEDURE))
- {
- CallableStatement cstmt = connection_.prepareCall("call SYSIBM" + getCatalogSeparator () + "SQLSPECIALCOLUMNS(?,?,?,?,?,?,?)");
-
- cstmt.setShort(1, (short)SQL_BEST_ROWID);
- cstmt.setString(2, normalize(catalog));
- cstmt.setString(3, normalize(schema));
- cstmt.setString(4, normalize(table));
- cstmt.setShort(5, (short) scope);
- if (nullable) {
- cstmt.setShort(6, (short) SQL_NULLABLE);
- } else {
- cstmt.setShort(6, (short) SQL_NO_NULLS);
- }
- cstmt.setString(7,
- "DATATYPE='JDBC';DYNAMIC=0;REPORTPUBLICPRIVILEGES=1;CURSORHOLD=1");
- cstmt.execute();
-
- ResultSet rs = cstmt.getResultSet(); //@mdrs
- if(rs != null) //@mdrs
- ((AS400JDBCResultSet)rs).isMetadataResultSet = true;//@mdrs
- else
- cstmt.close(); //@mdrs2
-
- return rs; //@mdrs
- }
-
- // Initialize the format of the result set.
- String[] fieldNames = { "SCOPE",
- "COLUMN_NAME",
- "DATA_TYPE",
- "TYPE_NAME",
- "COLUMN_SIZE",
- "BUFFER_LENGTH",
- "DECIMAL_DIGITS",
- "PSEUDO_COLUMN",
- };
-
- SQLData[] sqlData = { new SQLSmallint (vrm, settings_), // scope //@trunc3
- new SQLVarchar (128, settings_), // column name
- new SQLSmallint (vrm, settings_), // data type //@trunc3
- new SQLVarchar (128, settings_), // type name
- new SQLInteger (vrm, settings_), // column size //@trunc3
- new SQLInteger (vrm, settings_), // buffer length //@trunc3
- new SQLSmallint (vrm, settings_), // decimal digits //@trunc3
- new SQLSmallint (vrm, settings_), // pseudo column //@trunc3
- };
-
- int[] fieldNullables = { columnNoNulls, // scope
- columnNoNulls, // column name
- columnNoNulls, // data type
- columnNoNulls, // type name
- columnNoNulls, // column size
- columnNoNulls, // buffer length
- columnNoNulls, // decimal digits
- columnNoNulls, // pseudo column
- };
-
- JDSimpleRow formatRow = new JDSimpleRow (fieldNames, sqlData, fieldNullables);
-
- JDRowCache rowCache = null;
- try
- {
- // Check for conditions that would result in an empty result set
- // Must check for null first to avoid NullPointerException
-
- if (!isCatalogValid(catalog) || // catalog is empty string
-
- // schema is not null and is empty string
- ((schema != null) && (schema.length()==0)) ||
-
- // Table is null
- (table==null) ||
-
- // Table is empty string
- (table.length()==0 ) ||
-
- // Scope.
- // If bestRowSession is specified, return empty set
- // since it can not be guaranteed that the row will
- // remain valid for the session.
- // If bestRowTemporary is specified, return results.
- // If bestRowTransaction is specified and autocommit
- // is true or transaction is not repeatableRead, return
- // empty result set
-
- ((scope == bestRowSession) ||
-
- ( (scope == bestRowTransaction) &&
- ( (connection_.getAutoCommit()==true) ||
- (connection_.getTransactionIsolation() != Connection.TRANSACTION_REPEATABLE_READ)))))
- { // Return empty result set
- rowCache = new JDSimpleRowCache(formatRow);
- }
-
-
- else
- { // parameter values are valid, build request & send
- // Create a request
- //@P0C
- DBReturnObjectInformationRequestDS request = null;
- try
- {
-
- request = DBDSPool.getDBReturnObjectInformationRequestDS (
- DBReturnObjectInformationRequestDS.FUNCTIONID_SPECIAL_COLUMN_INFO ,
- id_, DBBaseRequestDS.ORS_BITMAP_RETURN_DATA +
- DBBaseRequestDS.ORS_BITMAP_DATA_FORMAT +
- DBBaseRequestDS.ORS_BITMAP_RESULT_DATA, 0);
-
-
-
- // Set the library name
- if (schema == null)
- { // use default SQL schema or qgpl
- request.setLibraryName(connection_.getDefaultSchema(), connection_.converter_); //@P0C
- }
- else request.setLibraryName(normalize(schema), connection_.converter_); // @E4C @P0C
-
- // Set the table name
- request.setFileName(normalize(table), connection_.converter_); // @E4C @P0C
-
-
- // Set the Field Information to Return Bitmap
- // Return library, table, and column
-
- request.setSpecialColumnsReturnInfoBitmap(0x1F000000);
-
-
- // Set the short / long file and field name indicator
- request.setFileShortOrLongNameIndicator(0xF0); // Long
-
- // Set if columns are nullable
- request.setSpecialColumnsNullableIndicator(nullable ?
- 0xF1 : 0xF0);
-
- //--------------------------------------------------------
- // Send the request and cache all results from the system
- //--------------------------------------------------------
- if (getBestRowIdentifierReply != null) { getBestRowIdentifierReply.returnToPool(); getBestRowIdentifierReply=null; }
- getBestRowIdentifierReply = connection_.sendAndReceive(request);
-
-
- // Check for errors - throw exception if errors were
- // returned
- int errorClass = getBestRowIdentifierReply.getErrorClass();
- if (errorClass !=0)
- {
- int returnCode = getBestRowIdentifierReply.getReturnCode();
- JDError.throwSQLException (this, connection_, id_,
- errorClass, returnCode);
- }
-
- // Get the data format and result data
- DBDataFormat dataFormat = getBestRowIdentifierReply.getDataFormat();
- DBData resultData = getBestRowIdentifierReply.getResultData();
- if (resultData != null)
- {
- JDServerRow row = new JDServerRow (connection_, id_, dataFormat, settings_);
- JDRowCache serverRowCache = new JDSimpleRowCache(new JDServerRowCache(row, connection_, id_, 1, resultData, true, ResultSet.TYPE_SCROLL_INSENSITIVE));
- JDFieldMap[] maps = new JDFieldMap[8];
- maps[0] = new JDHardcodedFieldMap(new Short ((short) scope)); // scope
- maps[1] = new JDSimpleFieldMap (1); // column name
- maps[2] = new JDDataTypeFieldMap (2, 4, 3, 5, 0, connection_.getVRM(), connection_.getProperties()); // @M0C // data type - converted to short //@KKB pass 0 for ccsid since cannot get ccsid from host server
- maps[3] = new JDSimpleFieldMap (2); // type name
- maps[4] = new JDSimpleFieldMap (4); // column size (length)
- maps[5] = new JDHardcodedFieldMap(new Integer (0)); // buffer length
- maps[6] = new JDSimpleFieldMap (5); // decimal digits (scale)
- maps[7] = new JDHardcodedFieldMap(new Short ((short) versionColumnNotPseudo));
- JDMappedRow mappedRow = new JDMappedRow (formatRow, maps);
- rowCache = new JDMappedRowCache (mappedRow, serverRowCache);
- }
- else
- rowCache = new JDSimpleRowCache(formatRow);
- }
- finally
- {
- if (request != null) { request.returnToPool(); request = null; }
- // Cannot return to pool yet because array in use by resultData. Pased to result set to be closed there
- // if (getBestRowIdentifierReply != null) getBestRowIdentifierReply.returnToPool();
- }
- }
- }
- catch (DBDataStreamException e)
- {
- JDError.throwSQLException (this, JDError.EXC_INTERNAL, e);
- }
-
- return new AS400JDBCResultSet (rowCache, connection_.getCatalog(), "BestRowIdentifier", connection_, getBestRowIdentifierReply); //@in2
- }
-
-
-
-
-
- /**
- Returns the catalog name available in this database. This
- will return a ResultSet with a single row, whose value is
- the IBM i system name.
-
- @return The ResultSet containing the IBM i system name.
-
- @exception SQLException If the connection is not open
- or an error occurs.
- **/
- public ResultSet getCatalogs ()
- throws SQLException
- {
- connection_.checkOpen ();
-
- //@mdsp SYSIBM SP Call
- if (connection_.getProperties().getString(JDProperties.METADATA_SOURCE).equals( JDProperties.METADATA_SOURCE_STORED_PROCEDURE))
- {
- CallableStatement cstmt = connection_.prepareCall("CALL SYSIBM" + getCatalogSeparator() + "SQLTABLES(?,?,?,?,?)");
-
- cstmt.setString(1, "%");
- cstmt.setString(2, "%");
- cstmt.setString(3, "%");
- cstmt.setString(4, "%");
- cstmt.setString(5, "DATATYPE='JDBC';GETCATALOGS=1;CURSORHOLD=1");
- cstmt.execute();
- ResultSet rs = cstmt.getResultSet(); //@mdrs
- if(rs != null) //@mdrs
- ((AS400JDBCResultSet)rs).isMetadataResultSet = true;//@mdrs
- else
- cstmt.close(); //@mdrs2
-
- return rs; //@mdrs
- }
-
- String[] fieldNames = {"TABLE_CAT"};
- SQLData[] sqlData = { new SQLVarchar (128, settings_)};
- int[] fieldNullables = {columnNoNulls}; // Catalog Name
- JDSimpleRow formatRow = new JDSimpleRow (fieldNames, sqlData, fieldNullables);
- Object[][] data = { { connection_.getCatalog()}};
- boolean[][] nulls = {{false}};
- boolean[][] dataMappingErrors = {{false}};
-
- // If running to a system running OS/400 v5r2 or IBM i the list can contain more than just the system
- // name (when IASPs are on the system). Try to retrieve that list. Note
- // if getting the list fails we will still return a result set containing
- // one item -- the name of the system. We just built that result set
- // (the previous six lines of code) and that is what we will return. That
- // result set will be consistent with the result set returned when connecting
- // to OS/400 v5r1 or earlier versions. If getting the list works we will
- // build and return a new result set containing data retrieved from the system.
- if (connection_.getVRM() >= JDUtilities.vrm520) // @F1a
- { // @F1a
- try
- { // @F1a // @F1a
- Vector RDBEntries = new Vector(); // @F1a
-
- Statement statement = null; //@scan1
- ResultSet rs = null; //@scan1
- try
- {
- statement = connection_.createStatement(); // @F1a
- rs = statement.executeQuery("SELECT LOCATION FROM QSYS2" + getCatalogSeparator() + "SYSCATALOGS WHERE RDBTYPE = 'LOCAL' AND RDBASPSTAT='AVAILABLE' "); // @F1a
- while (rs.next()) // @F1a
- { // @F1a
- RDBEntries.add(rs.getString(1).trim()); // @F1a
- }
- }finally //@scan1
- {
- try{
- if(rs != null)
- rs.close();
- }catch(Exception e){} //allow next close to execute
- if(statement != null)
- statement.close();
- }
- int count = RDBEntries.size(); // @F1a
- if (count > 0) // @F1a
- { // @F1a
- data = new Object[count][1]; // @F1a
- nulls = new boolean[count][1]; // @F1a
- dataMappingErrors = new boolean[count][1];
- for (int i=0; i<count; i++) // @F1a
- { // @F1a
- data[i][0] = RDBEntries.elementAt(i); // @F1a
- nulls[i][0] = false; // @F1a
- dataMappingErrors[i][0] = false;
- } // @F1a
- } // @F1a
- else
- { // @F1a // @F1a
- if (JDTrace.isTraceOn()) // @F1a
- JDTrace.logInformation (this, "Could not retrieve list of RDBs from system (count = 0)."); // @F1a
- } // @F1a
- } // @F1a
- catch (Exception e) // @F1a
- { // @F1a
- if (JDTrace.isTraceOn()) // @F1a
- JDTrace.logInformation (this, "Could not retrieve list of RDBs from system (exception)."); // @F1a
- } // @F1a
- } // @F1a
-
- JDSimpleRowCache rowCache = new JDSimpleRowCache (formatRow, data, nulls, dataMappingErrors);
- return new AS400JDBCResultSet (rowCache, connection_.getCatalog(), "Catalogs", connection_, null); //@in2
- }
-
-
-
- /**
- Returns the naming convention used when referring to tables.
- This depends on the naming convention specified in the connection
- properties.
-
- @return If using SQL naming convention, "." is returned. If
- using system naming convention, "/" is returned.
-
- @exception SQLException This exception is never thrown.
- **/
- public String getCatalogSeparator ()
- throws SQLException
- {
- String catalogSeparator;
- if (connection_.getProperties().equals (JDProperties.NAMING, JDProperties.NAMING_SQL))
- catalogSeparator = ".";
- else
- catalogSeparator = "/";
-
- return catalogSeparator;
- }
-
-
-
- /**
- Returns the DB2 for IBM i SQL term for "catalog".
-
- @return The term "System".
-
- @exception SQLException This exception is never thrown.
- **/
- public String getCatalogTerm ()
- throws SQLException
- {
- return AS400JDBCDriver.getResource ("CATALOG_TERM");
- }
-
-
-
- /**
- Returns a description of the access rights for a table's columns.
-
- @param catalog The catalog name. If null is specified, this parameter
- is ignored. If empty string is specified,
- an empty result set is returned.
- @param schema The schema name. If null is specified, the
- default SQL schema specified in the URL is used.
- If null is specified and a default SQL schema was not
- specified in the URL, the first library specified
- in the libraries properties file is used.
- If null is specified and a default SQL schema was
- not specified in the URL and a library was not
- specified in the libraries properties file,
- QGPL is used.
- If empty string is specified, an empty result set will
- be returned.
- @param table The table name. If null or empty string is specified,
- an empty result set is returned.
- @param columnPattern The column name pattern. If null is specified,
- no value is sent to the system and the system
- default of *all is used. If empty string
- is specified, an empty result set is returned.
-
- @return The ResultSet containing access rights for a
- table's columns.
-
- @exception SQLException If the connection is not open
- or an error occurs.
- **/
-
- public ResultSet getColumnPrivileges (String catalog,
- String schema,
- String table,
- String columnPattern)
- throws SQLException
- {
- connection_.checkOpen ();
- // int vrm = connection_.getVRM(); //@trunc3
-
- //@mdsp SYSIBM SP Call - move block to top of method
- if (connection_.getProperties().getString(JDProperties.METADATA_SOURCE).equals( JDProperties.METADATA_SOURCE_STORED_PROCEDURE))
- {
- //@PDC change to use sysibm.sqlcolprivileges stored procedure
-
- // Set the library name
- //@mdsp follow Native JDBC logic
- /*if (schema == null)
- { // use default SQL schema or qgpl
- schema = normalize(connection_.getDefaultSchema());
- }
- else schema = normalize(schema);
-
- // Set the table name
- table = normalize(table);
- */
- // Set the column name and search pattern
- // If null, do not set parameter. The system default
- // value of *ALL is used.
-
- CallableStatement cstmt = connection_.prepareCall("call SYSIBM" + getCatalogSeparator () + "SQLCOLPRIVILEGES (?, ?, ?, ?, ?)");
-
- cstmt.setString(1, normalize(catalog));
- cstmt.setString(2, normalize(schema));
- cstmt.setString(3, normalize(table));
- cstmt.setString(4, normalize(columnPattern));
- cstmt.setObject(5, "DATATYPE='JDBC';DYNAMIC=0;REPORTPUBLICPRIVILEGES=1;CURSORHOLD=1"); //@pdc options per db2 common design. //@mdsp more native synch
- ResultSet rs = cstmt.executeQuery();
- if(rs != null) //@mdrs
- ((AS400JDBCResultSet)rs).isMetadataResultSet = true;//@mdrs
- else
- cstmt.close(); //@mdrs2
-
- return rs; //@mdrs
- }
-
- //--------------------------------------------------------
- // Set up the result set in the format required by JDBC
- //--------------------------------------------------------
-
- String[] fieldNames = {"TABLE_CAT",
- "TABLE_SCHEM",
- "TABLE_NAME",
- "COLUMN_NAME",
- "GRANTOR",
- "GRANTEE",
- "PRIVILEGE",
- "IS_GRANTABLE",
- };
-
- SQLData[] sqlData = { new SQLVarchar (128, settings_), // catalog
- new SQLVarchar (128, settings_), // library
- new SQLVarchar (128, settings_), // table
- new SQLVarchar (128, settings_), // column
- new SQLVarchar (128, settings_), // grantor
- new SQLVarchar (128, settings_), // grantee
- new SQLVarchar (128, settings_), // privilege
- new SQLVarchar (3, settings_), // is_grantable
- };
- int[] fieldNullables = {columnNullable, // catalog
- columnNullable, // library
- columnNoNulls, // table
- columnNoNulls, // column
- columnNullable, // grantor
- columnNoNulls, // grantee
- columnNoNulls, // privilege
- columnNullable, // is_grantable
- };
-
- JDSimpleRow formatRow = new JDSimpleRow (fieldNames, sqlData, fieldNullables);
-
- JDRowCache rowCache = null; // Creates a set of rows
- // that are readable one at a time.
-
-
-
- // Check for conditions that would result in an empty result set
- // Must check for null first to avoid NullPointerException
- if (!isCatalogValid(catalog) || // catalog is empty string
-
- // schema is not null and is empty string
- ((schema != null) && (schema.length()==0)) ||
-
- // Table is null
- table==null ||
-
- // Table is empty string
- table.length()==0 ||
-
- // columnPattern is not null and is empty string
- ((columnPattern != null) && (columnPattern.length()==0)))
- { // Return empty result set
- rowCache = new JDSimpleRowCache (formatRow);
- return new AS400JDBCResultSet (rowCache, connection_.getCatalog(), "ColumnPrivileges", connection_, null); //@in2 //@PDC
-
- }
- else
- {
- // parameter values are valid, build request & send
- // Create a request
- //@P0C
- DBReturnObjectInformationRequestDS request = null;
- DBReplyRequestedDS reply = null;
- try
- {
- request = DBDSPool.getDBReturnObjectInformationRequestDS (
- DBReturnObjectInformationRequestDS.FUNCTIONID_FIELD_INFO,
- id_, DBBaseRequestDS.ORS_BITMAP_RETURN_DATA +
- DBBaseRequestDS.ORS_BITMAP_DATA_FORMAT +
- DBBaseRequestDS.ORS_BITMAP_RESULT_DATA, 0);
- // Set the library name
- if (schema == null)
- { // use default SQL schema or qgpl
- request.setLibraryName(normalize(connection_.getDefaultSchema()), connection_.converter_); // @E4C @P0C
- }
- else request.setLibraryName(normalize(schema), connection_.converter_); // @E4C @P0C
-
- // Set the table name
- request.setFileName(normalize(table), connection_.converter_); // @E4C @P0C
-
-
- // Set the column name and search pattern
- // If null, do not set parameter. The system default
- // value of *ALL is used.
- if (!(columnPattern==null))
- {
- JDSearchPattern column = new JDSearchPattern(columnPattern);
- request.setFieldName(column.getPatternString(), connection_.converter_); //@P0C
- request.setFieldNameSearchPatternIndicator(column.getIndicator());
- }
-
- // Set the Field Information to Return Bitmap
- // Return library, table, and column
- request.setFieldReturnInfoBitmap(0xA8000000);
-
- // Set the short / long file and field name indicator
- request.setFileShortOrLongNameIndicator(0xF0); // Long
-
- // Set the Field Information Order By Indicator parameter
- // Order by: Schema and File
- request.setFileInfoOrderByIndicator (2);
-
-
- //--------------------------------------------------------
- // Send the request and cache all results from the system
- //--------------------------------------------------------
- reply = connection_.sendAndReceive(request);
-
-
- // Check for errors - throw exception if errors were
- // returned
- int errorClass = reply.getErrorClass();
- if (errorClass !=0)
- {
- int returnCode = reply.getReturnCode();
- JDError.throwSQLException (this, connection_, id_,
- errorClass, returnCode);
- }
- // Get the data format and result data
- DBDataFormat dataFormat = reply.getDataFormat();
- DBData resultData = reply.getResultData();
- if (resultData != null)
- {
- JDServerRow row = new JDServerRow (connection_, id_, dataFormat, settings_);
- JDRowCache serverRowCache = new JDSimpleRowCache(new JDServerRowCache(row, connection_, id_, 1, resultData, true, ResultSet.TYPE_SCROLL_INSENSITIVE));
- // Create the mapped row format that is returned in the
- // result set.
- // This does not actual move the data, it just sets up
- // the mapping.
- JDFieldMap[] maps = new JDFieldMap[8];
- maps[0] = new JDHardcodedFieldMap (connection_.getCatalog ());
- maps[1] = new JDSimpleFieldMap (1); // library
- maps[2] = new JDSimpleFieldMap (2); // table
- maps[3] = new JDSimpleFieldMap (3); // column
- maps[4] = new JDHardcodedFieldMap(new SQLVarchar(0, settings_), true, false ); // grantor
- maps[5] = new JDHardcodedFieldMap (getUserName ()); // grantee - return userid
- maps[6] = new JDHardcodedFieldMap(""); // privilege
- maps[7] = new JDHardcodedFieldMap(new SQLVarchar(0, settings_),true, false ); // is_grantable
- // Create the mapped row cache that is returned in the
- // result set
- JDMappedRow mappedRow = new JDMappedRow (formatRow, maps);
-
- rowCache = new JDMappedRowCache (mappedRow, serverRowCache);
- }
- else
- rowCache = new JDSimpleRowCache(formatRow);
- } catch (DBDataStreamException e)
- {
- if (reply != null) { reply.returnToPool(); reply = null; }
- JDError.throwSQLException (this, JDError.EXC_INTERNAL, e);
- }
- finally
- {
- if (request != null) { request.returnToPool(); request = null; }
- // if (reply != null) { reply.returnToPool(); reply = null; }
- }
- // Return the results
- return new AS400JDBCResultSet (rowCache, connection_.getCatalog(), "ColumnPrivileges", connection_, reply); //@in2
-
- } // End of else to build and send request
-
-
-
- }
-
-
-
-
- /**
- Returns a description of the table's columns available in a
- catalog.
-
- @param catalog The catalog name. If null is specified, this parameter
- is ignored. If empty string is specified,
- an empty result set is returned.
- @param schemaPattern The schema name pattern.
- If the "metadata source" connection property is set to 0
- and null is specified, no value is sent to the system and
- the default of *USRLIBL is used.
- If the "metadata source" connection property is set to 1
- and null is specified, then information from all schemas
- will be returned.
- If an empty string
- is specified, an empty result set is returned.
- @param tablePattern The table name pattern. If null is specified,
- no value is sent to the system and the system
- default of *ALL is used. If empty string
- is specified, an empty result set is returned.
- @param columnPattern The column name pattern. If null is specified,
- no value is sent to the system and the system
- default of *ALL is used. If empty string
- is specified, an empty result set is returned.
-
- @return The ResultSet containing the table's columns available
- in a catalog.
-
- @exception SQLException If the connection is not open
- or an error occurs.
- **/
- public ResultSet getColumns (String catalog,
- String schemaPattern,
- String tablePattern,
- String columnPattern)
- throws SQLException
- {
-
- DBReplyRequestedDS reply = null;
-
- connection_.checkOpen ();
-
-
- boolean isJDBC3 = JDUtilities.JDBCLevel_ >= 30; //@F2A @j4a
-
- String[] fieldNames = null; //@F2C
- SQLData[] sqlData = null; //@F2C
- int[] fieldNullables = null; //@F2C
- //@F2A Result sets must be different depending on whether we are running under JDBC 3.0
- //@pda jdbc40 is also contained in same block as jdbc30, since this file is jdbc40 only compiled.
- int vrm = connection_.getVRM(); //@trunc3
-
- //@mdsp SYSIBM SP Call
- if (connection_.getProperties().getString(JDProperties.METADATA_SOURCE).equals( JDProperties.METADATA_SOURCE_STORED_PROCEDURE))
- {
- CallableStatement cs = connection_.prepareCall("CALL SYSIBM" + getCatalogSeparator() + "SQLCOLUMNS(?,?,?,?,?)");
-
- cs.setString(1, normalize(catalog));
- cs.setString(2, normalize(schemaPattern));
- cs.setString(3, normalize(tablePattern));
- cs.setString(4, normalize(columnPattern));
- /* ifdef JDBC40 */
- // Use 4.1 if JDBC version is 4.1
- if (javaVersion > 16) {
- cs.setString(5, "DATATYPE='JDBC';JDBCVER='4.1';DYNAMIC=0;REPORTPUBLICPRIVILEGES=1;CURSORHOLD=1"); //@ver4
- } else {
- cs.setString(5, "DATATYPE='JDBC';JDBCVER='4.0';DYNAMIC=0;REPORTPUBLICPRIVILEGES=1;CURSORHOLD=1"); //@ver4
- }
- /* endif */
- /* ifndef JDBC40
- cs.setString(5, "DATATYPE='JDBC';DYNAMIC=0;REPORTPUBLICPRIVILEGES=1;CURSORHOLD=1");
- endif */
- cs.execute();
-
- ResultSet rs = cs.getResultSet(); //@mdrs
- if(rs != null) //@mdrs
-
- ((AS400JDBCResultSet)rs).isMetadataResultSet = true;//@mdrs
- else
- cs.close(); //@mdrs2
-
- return rs; //@mdrs
-
- // Create an return the result set for the request.
- // Note: This will failed until SQLCOLUMNS returns more columns
- // return new DB2RSGetColumns40(x, isTransactional);
- }
-
- if (!isJDBC3) //@F2A
- {
- // Set up the result set in the format required by JDBC
- fieldNames = new String[] {"TABLE_CAT",
- "TABLE_SCHEM",
- "TABLE_NAME",
- "COLUMN_NAME",
- "DATA_TYPE",
- "TYPE_NAME",
- "COLUMN_SIZE",
- "BUFFER_LENGTH",
- "DECIMAL_DIGITS",
- "NUM_PREC_RADIX",
- "NULLABLE",
- "REMARKS",
- "COLUMN_DEF",
- "SQL_DATA_TYPE",
-