oraclemodule.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 2,223 行 · 第 1/5 页
JAVA
2,223 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Rodrigo Westrupp */package com.caucho.quercus.lib.db;import com.caucho.quercus.UnimplementedException;import com.caucho.quercus.annotation.NotNull;import com.caucho.quercus.annotation.Optional;import com.caucho.quercus.annotation.Reference;import com.caucho.quercus.annotation.ReturnNullAsFalse;import com.caucho.quercus.env.*;import com.caucho.quercus.module.AbstractQuercusModule;import com.caucho.util.L10N;import com.caucho.util.Log;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.sql.*;import java.util.Map;import java.util.logging.Level;import java.util.logging.Logger;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * Quercus oracle routines. * * NOTE from php.net: * * "... * These functions allow you to access Oracle 10, Oracle 9, Oracle 8 and Oracle 7 * databases using the Oracle Call Interface (OCI). They support binding of PHP * variables to Oracle placeholders, have full LOB, FILE and ROWID support, and * allow you to use user-supplied define variables. * * Requirements * * You will need the Oracle client libraries to use this extension. * Windows users will need libraries with version at least 10 to use the php_oci8.dll. * * ..." * */public class OracleModule extends AbstractQuercusModule { private static final Logger log = Log.open(OracleModule.class); private static final L10N L = new L10N(OracleModule.class); // WARNING: Do not change order or constant values. // They are mapped to oracle types below. // See arrayPhpToOracleType. public static final int OCI_B_BFILE = 0x01; public static final int OCI_B_CFILEE = 0x02; public static final int OCI_B_CLOB = 0x03; public static final int OCI_B_BLOB = 0x04; public static final int OCI_B_ROWID = 0x05; public static final int OCI_B_CURSOR = 0x06; public static final int OCI_B_NTY = 0x07; public static final int OCI_B_BIN = 0x08; public static final int OCI_DTYPE_FILE = 0x09; public static final int OCI_DTYPE_LOB = 0x0A; public static final int OCI_DTYPE_ROWID = 0x0B; public static final int OCI_D_FILE = 0x0C; public static final int OCI_D_LOB = 0x0D; public static final int OCI_D_ROWID = 0x0E; public static final int OCI_SYSDATE = 0x0F; public static final int OCI_TEMP_CLOB = 0x10; public static final int OCI_TEMP_BLOB = 0x11; public static final int SQLT_BFILEE = 0x12; public static final int SQLT_CFILEE = 0x13; public static final int SQLT_CLOB = 0x14; public static final int SQLT_BLOB = 0x15; public static final int SQLT_RDD = 0x16; public static final int SQLT_NTY = 0x17; public static final int SQLT_LNG = 0x18; public static final int SQLT_LBI = 0x19; public static final int SQLT_BIN = 0x1A; public static final int SQLT_NUM = 0x1B; public static final int SQLT_INT = 0x1C; public static final int SQLT_AFC = 0x1D; public static final int SQLT_CHR = 0x1E; public static final int SQLT_VCS = 0x1F; public static final int SQLT_AVC = 0x20; public static final int SQLT_STR = 0x21; public static final int SQLT_LVC = 0x22; public static final int SQLT_FLT = 0x23; public static final int SQLT_ODT = 0x24; public static final int SQLT_BDOUBLE = 0x25; public static final int SQLT_BFLOAT = 0x26; public static final int SQLT_RSET = 0x27; public static final int SQLT_FILE = 0x28; public static final int SQLT_CFILE = 0x29; // Reserved for future types and extensions // 0x30 - 0x4F // OCI Control Constants 0x50 - ... public static final int OCI_DEFAULT = 0x50; public static final int OCI_DESCRIBE_ONLY = 0x51; public static final int OCI_COMMIT_ON_SUCCESS = 0x52; public static final int OCI_EXACT_FETCH = 0x53; public static final int OCI_FETCHSTATEMENT_BY_COLUMN = 0x54; public static final int OCI_FETCHSTATEMENT_BY_ROW = 0x55; public static final int OCI_ASSOC = 0x56; public static final int OCI_NUM = 0x57; public static final int OCI_BOTH = 0x58; public static final int OCI_RETURN_NULLS = 0x59; public static final int OCI_RETURN_LOBS = 0x5A; public static final int OCI_SYSOPER = 0x5B; public static final int OCI_SYSDBA = 0x5C; public static final int OCI_LOB_BUFFER_FREE = 0x5D; public static final int OCI_SEEK_SET = 0x5E; public static final int OCI_SEEK_CUR = 0x5F; public static final int OCI_SEEK_END = 0x6A; // Cache class oracle.jdbc.OracleTypes to be used below. private static Class classOracleTypes; // Map php to oracle type private static int arrayPhpToOracleType[]; static { try { classOracleTypes = Class.forName("oracle.jdbc.OracleTypes"); arrayPhpToOracleType = new int[] { -1, classOracleTypes.getDeclaredField("BFILE").getInt(null), // OCI_B_BFILE -1, // OCI_B_CFILEE classOracleTypes.getDeclaredField("CLOB").getInt(null), // OCI_B_CLOB classOracleTypes.getDeclaredField("BLOB").getInt(null), // OCI_B_BLOB classOracleTypes.getDeclaredField("ROWID").getInt(null), // OCI_B_ROWID classOracleTypes.getDeclaredField("CURSOR").getInt(null), // OCI_B_CURSOR classOracleTypes.getDeclaredField("OTHER").getInt(null), // OCI_B_NTY classOracleTypes.getDeclaredField("RAW").getInt(null), // OCI_B_BIN -1, // OCI_DTYPE_FILE -1, // OCI_DTYPE_LOB -1, // OCI_DTYPE_ROWID -1, // OCI_D_FILE -1, // OCI_D_LOB -1, // OCI_D_ROWID classOracleTypes.getDeclaredField("TIMESTAMP").getInt(null), // OCI_SYSDATE -1, // OCI_TEMP_CLOB -1, // OCI_TEMP_BLOB classOracleTypes.getDeclaredField("BFILE").getInt(null), // SQLT_BFILEE -1, // SQLT_CFILEE classOracleTypes.getDeclaredField("CLOB").getInt(null), // SQLT_CLOB classOracleTypes.getDeclaredField("BLOB").getInt(null), // SQLT_BLOB classOracleTypes.getDeclaredField("ROWID").getInt(null), // SQLT_RDD classOracleTypes.getDeclaredField("OTHER").getInt(null), // SQLT_NTY classOracleTypes.getDeclaredField("NUMBER").getInt(null), // SQLT_LNG classOracleTypes.getDeclaredField("RAW").getInt(null), // SQLT_LBI classOracleTypes.getDeclaredField("RAW").getInt(null), // SQLT_BIN classOracleTypes.getDeclaredField("NUMBER").getInt(null), // SQLT_NUM classOracleTypes.getDeclaredField("INTEGER").getInt(null), // SQLT_INT classOracleTypes.getDeclaredField("CHAR").getInt(null), // SQLT_AFC classOracleTypes.getDeclaredField("CHAR").getInt(null), // SQLT_CHR classOracleTypes.getDeclaredField("VARCHAR").getInt(null), // SQLT_VCS classOracleTypes.getDeclaredField("CHAR").getInt(null), // SQLT_AVC classOracleTypes.getDeclaredField("VARCHAR").getInt(null), // SQLT_STR classOracleTypes.getDeclaredField("LONGVARCHAR").getInt(null), // SQLT_LVC classOracleTypes.getDeclaredField("FLOAT").getInt(null), // SQLT_FLT classOracleTypes.getDeclaredField("DATE").getInt(null), // SQLT_ODT classOracleTypes.getDeclaredField("DOUBLE").getInt(null), // SQLT_BDOUBLE classOracleTypes.getDeclaredField("FLOAT").getInt(null), // SQLT_BFLOAT classOracleTypes.getDeclaredField("CURSOR").getInt(null), // SQLT_RSET classOracleTypes.getDeclaredField("BFILE").getInt(null), // SQLT_FILE -1 // SQLT_CFILE }; } catch (Exception e) { L.l("Unable to load Oracle types from oracle.jdbc.OracleTypes. Check your Oracle JDBC driver version."); } } public OracleModule() { } /** * Returns true for the oracle extension. */ public String []getLoadedExtensions() { return new String[] { "oci8" }; } /** * Binds PHP array to Oracle PL/SQL array by name. * * oci_bind_array_by_name() binds the PHP array * varArray to the Oracle placeholder name, which * points to Oracle PL/SQL array. Whether it will * be used for input or output will be determined * at run-time. The maxTableLength parameter sets * the maximum length both for incoming and result * arrays. Parameter maxItemLength sets maximum * length for array items. If maxItemLength was * not specified or equals to -1, * oci_bind_array_by_name() will find the longest * element in the incoming array and will use it as * maximum length for array items. type parameter * should be used to set the type of PL/SQL array * items. See list of available types below. * * @param env the PHP executing environment * @param stmt the Oracle statement * @param name the Oracle placeholder * @param varArray the array to be binded * @param maxTableLength maximum table length * @param maxItemLength maximum item length * @param type one of the following types: * <br/> * SQLT_NUM - for arrays of NUMBER. * <br/> * SQLT_INT - for arrays of INTEGER * (Note: INTEGER it is actually a synonym for * NUMBER(38), but SQLT_NUM type won't work in * this case even though they are synonyms). * <br/> * SQLT_FLT - for arrays of FLOAT. * <br/> * SQLT_AFC - for arrays of CHAR. * <br/> * SQLT_CHR - for arrays of VARCHAR2. * <br/> * SQLT_VCS - for arrays of VARCHAR. * <br/> * SQLT_AVC - for arrays of CHARZ. * <br/> * SQLT_STR - for arrays of STRING. * <br/> * SQLT_LVC - for arrays of LONG VARCHAR. * <br/> * SQLT_ODT - for arrays of DATE. * * @return true on success of false on failure */ public static boolean oci_bind_array_by_name(Env env, @NotNull OracleStatement stmt, @NotNull String name, @NotNull ArrayValue varArray, @NotNull int maxTableLength, @Optional("0") int maxItemLength, @Optional("0") int type) { try { // JDBC underlying connection Connection conn = stmt.getJavaConnection(); // Oracle underlying statement PreparedStatement oracleStmt = stmt.getPreparedStatement(); // Create an oracle.sql.ARRAY object to hold the values // oracle.sql.ArrayDescriptor arrayDesc = // oracle.sql.ArrayDescriptor.createDescriptor("number_varray", conn); Class clArrayDescriptor = Class.forName("oracle.sql.ArrayDescriptor"); Method method = clArrayDescriptor.getDeclaredMethod("createDescriptor", new Class[] {String.class, Connection.class}); Object arrayDesc = method.invoke(clArrayDescriptor, new Object[] {"NUMBER_VARRAY", conn}); Value valueArray[] = varArray.valuesToArray(); // int arrayValues[] = {123, 234}; Object objectArray[] = new Object[5]; // {"aaa", "bbb", "ccc"}; for (int i=0; i<valueArray.length; i++) { Object obj = valueArray[i].toJavaObject(); objectArray[i] = obj; } // oracle.sql.ARRAY array = new oracle.sql.ARRAY(arrayDesc, conn, arrayValues); Class clARRAY = Class.forName("oracle.sql.ARRAY"); Constructor constructor = clARRAY.getDeclaredConstructor(new Class[] { clArrayDescriptor, Connection.class, Object.class}); Array oracleArray = (Array) constructor.newInstance(new Object[] {arrayDesc, conn, objectArray}); // Bind array // ((oracle.jdbc.OraclePreparedStatement)oracleStmt).setARRAY(1, array); // cl = Class.forName("oracle.jdbc.OraclePreparedStatement"); // method = cl.getDeclaredMethod("setARRAY", // new Class[] {Integer.TYPE, Object[].class}); if (name == null) { return false; } if (!name.startsWith(":")) { name = ":" + name; } if (name.length() < 2) { return false; } // method.invoke(oracleStmt, new Object[] {name, oracleArray}); Integer index = stmt.getBindingVariable(name); if (index == null) return false; int i = index.intValue(); Object object = varArray.toJavaObject(); if (object instanceof OracleOciCollection) { oracleArray = ((OracleOciCollection) object).getCollection(); oracleStmt.setArray(i, oracleArray); } else if (varArray instanceof ArrayValueImpl) { // oracleStmt.setObject(i, varArray.getKeyArray()); // Object objectArray[] = new Object[] {"aaa", "bbb", "ccc"}; // oracleStmt.setObject(i, objectArray); oracleStmt.setArray(i, oracleArray); } else { oracleStmt.setObject(i, object); } // drop descriptor ???? 'number_varray' ???? return true; } catch (Exception e) { log.log(Level.FINE, e.toString(), e); return false; } } /** * Binds the PHP variable to the Oracle placeholder * * @param type one of the following types: * * SQLT_INT - for integers; * * SQLT_CHR - for VARCHARs; * * SQLT_RSET - for cursors, that were created before with oci_new_cursor() * * OCI_B_BFILE (integer) * * Used with oci_bind_by_name() when binding BFILEs. * * OCI_B_CFILEE (integer) * * Used with oci_bind_by_name() when binding CFILEs. * * OCI_B_CLOB (integer) * * Used with oci_bind_by_name() when binding CLOBs. * * OCI_B_BLOB (integer) * * Used with oci_bind_by_name() when binding BLOBs. * * OCI_B_ROWID (integer) * * Used with oci_bind_by_name() when binding ROWIDs. * * OCI_B_CURSOR (integer) * * Used with oci_bind_by_name() when binding cursors, * previously allocated with oci_new_descriptor(). * * OCI_B_NTY (integer) * * Used with oci_bind_by_name() when binding named data * types. Note: in PHP < 5.0 it was called OCI_B_SQLT_NTY. * * OCI_B_BIN (integer) * * SQLT_FILE (integer) * * SQLT_BFILEE (integer) * * The same as OCI_B_BFILE. * * SQLT_CFILE (integer) * * SQLT_CFILEE (integer) * * The same as OCI_B_CFILEE. * * SQLT_CLOB (integer) * * The same as OCI_B_CLOB. * * SQLT_BLOB (integer) * * The same as OCI_B_BLOB. * * SQLT_RDD (integer) * * The same as OCI_B_ROWID. * * SQLT_NTY (integer) * * The same as OCI_B_NTY. * * SQLT_LNG (integer) * * Used with oci_bind_by_name() to bind LONG values. * * SQLT_LBI (integer) * * Used with oci_bind_by_name() to bind LONG RAW values. * * SQLT_BIN (integer) *
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?