📄 systemprocedures.java
字号:
/* Derby - Class org.apache.derby.catalog.SystemProcedures Copyright 2003, 2004 The Apache Software Foundation or its licensors, as applicable. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */package org.apache.derby.catalog;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.services.i18n.MessageService;import org.apache.derby.iapi.error.PublicAPI;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.reference.SQLState;import java.sql.ResultSet;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;import java.sql.DatabaseMetaData;import java.util.StringTokenizer;import java.util.NoSuchElementException;import org.apache.derby.jdbc.InternalDriver;import org.apache.derby.iapi.db.Factory;import org.apache.derby.iapi.db.PropertyInfo;import org.apache.derby.impl.jdbc.Util;import org.apache.derby.impl.load.Export;import org.apache.derby.impl.load.Import;import org.apache.derby.impl.jdbc.EmbedDatabaseMetaData;import org.apache.derby.impl.sql.execute.JarDDL;import org.apache.derby.iapi.util.IdUtil;import org.apache.derby.iapi.error.PublicAPI;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.sql.conn.ConnectionUtil;/** Some system built-in procedures, and help routines. Now used for network server. These procedures are built-in to the SYSIBM schema which match the DB2 SYSIBM procedures. Currently information on those can be found at url: ftp://ftp.software.ibm.com/ps/products/db2/info/vr8/pdf/letter/db2l2e80.pdf*/public class SystemProcedures { private final static int SQL_BEST_ROWID = 1; private final static int SQL_ROWVER = 2; private final static String DRIVER_TYPE_OPTION = "DATATYPE"; private final static String ODBC_DRIVER_OPTION = "'ODBC'"; // This token delimiter value is used to separate the tokens for multiple // error messages. This is used in DRDAConnThread /** * <code>SQLERRMC_MESSAGE_DELIMITER</code> When message argument tokes are sent, * this value separates the tokens for mulitiple error messages * Used by Server */ public static String SQLERRMC_MESSAGE_DELIMITER = new String(new char[] {(char)20,(char)20,(char)20}); /** Method used by Cloudscape Network Server to get localized message (original call from jcc. @param sqlcode sqlcode, not used. @param errmcLen sqlerrmc length @param sqlerrmc sql error message tokens, variable part of error message (ie., arguments) plus messageId, separated by separator. @param sqlerrp not used @param errd0 not used @param errd1 not used @param errd2 not used @param errd3 not used @param errd4 not used @param errd5 not used @param warn not used @param sqlState 5-char sql state @param file not used @param localeStr client locale in string @param msg OUTPUT parameter, localized error message @param rc OUTPUT parameter, return code -- 0 for success */ public static void SQLCAMESSAGE(int sqlcode, short errmcLen, String sqlerrmc, String sqlerrp, int errd0, int errd1, int errd2, int errd3, int errd4, int errd5, String warn, String sqlState, String file, String localeStr, String[] msg, int[] rc) { int numMessages = 1; // Figure out if there are multiple exceptions in sqlerrmc. If so get each one // translated and append to make the final result. for (int index=0; ; numMessages++) { if (sqlerrmc.indexOf(SQLERRMC_MESSAGE_DELIMITER, index) == -1) break; index = sqlerrmc.indexOf(SQLERRMC_MESSAGE_DELIMITER, index) + SQLERRMC_MESSAGE_DELIMITER.length(); } // Putting it here instead of prepareCall it directly is because inter-jar reference tool // cannot detect/resolve this otherwise if (numMessages == 1) MessageService.getLocalizedMessage(sqlcode, errmcLen, sqlerrmc, sqlerrp, errd0, errd1, errd2, errd3, errd4, errd5, warn, sqlState, file, localeStr, msg, rc); else { int startIdx=0, endIdx; String sqlError; String[] errMsg = new String[2]; for (int i=0; i<numMessages; i++) { endIdx = sqlerrmc.indexOf(SQLERRMC_MESSAGE_DELIMITER, startIdx); if (i == numMessages-1) // last error message sqlError = sqlerrmc.substring(startIdx); else sqlError = sqlerrmc.substring(startIdx, endIdx); if (i > 0) { /* Strip out the SQLState */ sqlState = sqlError.substring(0, 5); sqlError = sqlError.substring(6); msg[0] += " SQLSTATE: " + sqlState + ": "; } MessageService.getLocalizedMessage(sqlcode, (short)sqlError.length(), sqlError, sqlerrp, errd0, errd1, errd2, errd3, errd4, errd5, warn, sqlState, file, localeStr, errMsg, rc); if (rc[0] == 0) // success { if (i == 0) msg[0] = errMsg[0]; else msg[0] += errMsg[0]; // append the new message } startIdx = endIdx + SQLERRMC_MESSAGE_DELIMITER.length(); } } } /** * Get the default or nested connection corresponding to the URL * jdbc:default:connection. We do not use DriverManager here * as it is not supported in JSR 169. IN addition we need to perform * more checks for null drivers or the driver returing null from connect * as that logic is in DriverManager. * @return The nested connection * @throws SQLException Not running in a SQL statement */ private static Connection getDefaultConn()throws SQLException { InternalDriver id = InternalDriver.activeDriver(); if (id != null) { Connection conn = id.connect("jdbc:default:connection", null); if (conn != null) return conn; } throw Util.noCurrentConnection(); } /** * Get the DatabaseMetaData for the current connection for use in * mapping the jcc SYSIBM.* calls to the Cloudscape DatabaseMetaData methods * * @return The DatabaseMetaData object of the current connection */ private static DatabaseMetaData getDMD() throws SQLException { Connection conn = getDefaultConn(); return conn.getMetaData(); } /** * Map SQLProcedures to EmbedDatabaseMetaData.getProcedures * * @param catalogName SYSIBM.SQLProcedures CatalogName varchar(128), * @param schemaName SYSIBM.SQLProcedures SchemaName varchar(128), * @param procName SYSIBM.SQLProcedures ProcName varchar(128), * @param options SYSIBM.SQLProcedures Options varchar(4000)) * @param rs output parameter, the resultset object containing * the result of getProcedures * If options contains the string 'DATATYPE='ODBC'', call the ODBC * version of this procedure. */ public static void SQLPROCEDURES (String catalogName, String schemaName, String procName, String options, ResultSet[] rs) throws SQLException { rs[0] = isForODBC(options) ? ((EmbedDatabaseMetaData)getDMD()).getProceduresForODBC( catalogName, schemaName, procName) : getDMD().getProcedures(catalogName, schemaName, procName); } /** * Map SQLTables to EmbedDatabaseMetaData.getSchemas, getCatalogs, getTableTypes and getTables * * containing the result of the DatabaseMetaData calls * @param catalogName SYSIBM.SQLTables CatalogName varchar(128), * @param schemaName SYSIBM.SQLTables SchemaName varchar(128), * @param tableName SYSIBM.SQLTables TableName varchar(128), * @param tableType SYSIBM.SQLTables TableType varchar(4000)) * @param options SYSIBM.SQLTables Options varchar(4000)) * @param rs output parameter, the resultset object * JCC overloads this method: * If options contains the string 'GETSCHEMAS=1', call getSchemas * If options contains the string 'GETCATALOGS=1', call getCatalogs * If options contains the string 'GETTABLETYPES=1', call getTableTypes * otherwise, call getTables */ public static void SQLTABLES (String catalogName, String schemaName, String tableName, String tableType, String options, ResultSet[] rs) throws SQLException { String optionValue = getOption("GETCATALOGS", options); if (optionValue != null && optionValue.trim().equals("1")) { rs[0] = getDMD().getCatalogs(); return; } optionValue = getOption("GETTABLETYPES", options); if (optionValue != null && optionValue.trim().equals("1")) { rs[0] = getDMD().getTableTypes(); return; } optionValue = getOption("GETSCHEMAS", options); if (optionValue != null && optionValue.trim().equals("1")) { rs[0] = getDMD().getSchemas(); return; } String[] typeArray = null; if (tableType != null) { StringTokenizer st = new StringTokenizer(tableType,"',"); typeArray = new String[st.countTokens()]; int i = 0; while (st.hasMoreTokens()) { typeArray[i] = st.nextToken(); i++; } } rs[0] = getDMD().getTables(catalogName, schemaName, tableName, typeArray); } /** * Map SQLForeignKeys to EmbedDatabaseMetaData.getImportedKeys, getExportedKeys, and getCrossReference * * @param pkCatalogName SYSIBM.SQLForeignKeys PKCatalogName varchar(128), * @param pkSchemaName SYSIBM.SQLForeignKeys PKSchemaName varchar(128), * @param pkTableName SYSIBM.SQLForeignKeys PKTableName varchar(128), * @param fkCatalogName SYSIBM.SQLForeignKeys FKCatalogName varchar(128), * @param fkSchemaName SYSIBM.SQLForeignKeys FKSchemaName varchar(128), * @param fkTableName SYSIBM.SQLForeignKeys FKTableName varchar(128), * @param options SYSIBM.SQLForeignKeys Options varchar(4000)) * @param rs output parameter, the resultset object * containing the result of the DatabaseMetaData calls * JCC overloads this method: * If options contains the string 'EXPORTEDKEY=1', call getImportedKeys * If options contains the string 'IMPORTEDKEY=1', call getExportedKeys * otherwise, call getCrossReference */ public static void SQLFOREIGNKEYS (String pkCatalogName, String pkSchemaName, String pkTableName, String fkCatalogName, String fkSchemaName, String fkTableName, String options, ResultSet[] rs) throws SQLException { String exportedKeyProp = getOption("EXPORTEDKEY", options); String importedKeyProp = getOption("IMPORTEDKEY", options); if (importedKeyProp != null && importedKeyProp.trim().equals("1")) rs[0] = getDMD().getImportedKeys(fkCatalogName, fkSchemaName,fkTableName); else if (exportedKeyProp != null && exportedKeyProp.trim().equals("1")) rs[0] = getDMD().getExportedKeys(pkCatalogName, pkSchemaName,pkTableName); else rs[0] = getDMD().getCrossReference (pkCatalogName, pkSchemaName, pkTableName, fkCatalogName, fkSchemaName, fkTableName); } /** * Helper for SQLForeignKeys and SQLTables * * @return option String containing the value for a given option * @param pattern String containing the option to search for * @param options String containing the options to search through */ private static String getOption(String pattern, String options) { if (options == null) return null; int start = options.lastIndexOf(pattern); if (start < 0) // not there return null; int valueStart = options.indexOf('=', start); if (valueStart < 0) // invalid options string return null; int valueEnd = options.indexOf(';', valueStart); if (valueEnd < 0) // last option return options.substring(valueStart + 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -