jdbcstatementresource.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 754 行 · 第 1/2 页
JAVA
754 行
/* * 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 Charles Reich */package com.caucho.quercus.lib.db;import com.caucho.quercus.env.BooleanValue;import com.caucho.quercus.env.Env;import com.caucho.quercus.env.NullValue;import com.caucho.quercus.env.StringValue;import com.caucho.quercus.env.UnsetValue;import com.caucho.quercus.env.Value;import com.caucho.quercus.env.Var;import com.caucho.quercus.env.StringValue;import com.caucho.util.L10N;import com.caucho.util.Log;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.SQLException;import java.sql.Types;import java.util.logging.Level;import java.util.logging.Logger;/** * Represents a JDBC Statement value. */public class JdbcStatementResource { private static final Logger log = Log.open(JdbcStatementResource.class); private static final L10N L = new L10N(JdbcStatementResource.class); private JdbcConnectionResource _conn; private ResultSet _rs; private String _query; private PreparedStatement _stmt; private ResultSetMetaData _metaData; private JdbcResultResource _resultResource = null; private char[] _types; private Value[] _params; private Value[] _results; private String _errorMessage = ""; private int _errorCode; // Statement type // (SELECT, UPDATE, DELETE, INSERT, CREATE, DROP, ALTER, BEGIN, DECLARE, UNKNOWN) private String _stmtType; /** * Constructor for JdbcStatementResource * * @param connV a JdbcConnectionResource connection */ public JdbcStatementResource(JdbcConnectionResource connV) { _conn = connV; } /** * Creates _types and _params array for this prepared statement. * * @param types = string of i,d,s,b (ie: "idds") * @param params = array of values (probably Vars) * @return true on success ir false on failure */ protected boolean bindParams(Env env, String types, Value[] params) { // This will create the _types and _params arrays // for this prepared statement. final int size = types.length(); // Check to see that types and params have the same length if (params.length == 0 || size != params.length) { env.warning(L.l("number of types does not match number of parameters")); return false; } // Check to see that types only contains i,d,s,b for (int i = 0; i < size; i++) { if ("idsb".indexOf(types.charAt(i)) < 0) { env.warning(L.l("invalid type string {0}", types)); return false; } } _types = new char[size]; _params = new Value[size]; for (int i = 0; i < size; i++) { _types[i] = types.charAt(i); _params[i] = params[i]; } return true; } /** * Associate (bind) columns in the result set to variables. * <p/> * NB: we assume that the statement has been executed and * compare the # of outParams w/ the # of columns in the * resultset because we cannot know in advance how many * columns "SELECT * FROM TableName" can return. * <p/> * PHP 5.0 seems to provide some rudimentary checking on # of * outParams even before the statement has been executed * and only issues a warning in the case of "SELECT * FROM TableName". * <p/> * Our implementation REQUIRES the execute happen first. * * @param env the PHP executing environment * @param outParams the output variables * @return true on success or false on failure */ public boolean bindResults(Env env, Value[] outParams) { final int size = outParams.length; int numColumns; try { ResultSetMetaData md = getMetaData(); numColumns = md.getColumnCount(); } catch (SQLException e) { log.log(Level.FINE, e.toString(), e); return false; } for (int i = 0; i < size; i++) { Value val = outParams[i]; if (! (val instanceof Var)) { env.error(L.l("Only variables can be passed by reference")); return false; } } if ((size == 0) || (size != numColumns)) { env.warning(L.l("number of bound variables does not equal number of columns")); return false; } _results = new Value[size]; System.arraycopy(outParams, 0, _results, 0, size); return true; } /** * Closes the result set, if any, and closes this statement. */ public void close() { try { ResultSet rs = _rs; _rs = null; if (rs != null) rs.close(); if (_stmt != null) _stmt.close(); } catch (SQLException e) { _errorMessage = e.getMessage(); _errorCode = e.getErrorCode(); log.log(Level.FINE, e.toString(), e); } } /** * Advance the cursor the number of rows given by offset. * * @param offset the number of rows to move the cursor * @return true on success or false on failure */ protected boolean dataSeek(int offset) { return JdbcResultResource.setRowNumber(_rs, offset); } /** * Returns the error number for the last error. * * @return the error number */ public int errorCode() { return _errorCode; } /** * Returns the error message for the last error. * * @return the error message */ public String errorMessage() { return _errorMessage; } /** * Executes a prepared Query. * * @param env the PHP executing environment * @return true on success or false on failure */ public boolean execute(Env env) { try { if (_types != null) { int size = _types.length; for (int i = 0; i < size; i++) { switch (_types[i]) { case 'i': _stmt.setInt(i + 1, _params[i].toInt()); break; case 'd': _stmt.setDouble(i + 1, _params[i].toDouble()); break; // XXX: blob needs to be redone // Currently treated as a string case 'b': _stmt.setString(i + 1, _params[i].toString()); break; case 's': _stmt.setString(i + 1, _params[i].toString()); break; default: break; } } } return executeStatement(); } catch (SQLException e) { env.warning(L.l(e.toString())); log.log(Level.FINE, e.toString(), e); _errorMessage = e.getMessage(); _errorCode = e.getErrorCode(); return false; } } /** * Executes underlying statement * Known subclasses: see PostgresStatement.execute */ protected boolean executeStatement() throws SQLException { try { if (_stmt.execute()) { _conn.setAffectedRows(0); _rs = _stmt.getResultSet(); } else { _conn.setAffectedRows(_stmt.getUpdateCount()); } return true; } catch (SQLException e) { _errorMessage = e.getMessage(); _errorCode = e.getErrorCode(); throw e; } } /** * Fetch results from a prepared statement into bound variables. * * @return true on success, false on error, null if no more rows */ public Value fetch(Env env) { try { if (_rs == null) return NullValue.NULL; if (_rs.next()) { if (_metaData == null) _metaData = _rs.getMetaData(); JdbcResultResource resultResource = getResultMetadata(); int size = _results.length; for (int i = 0; i < size; i++) { _results[i].set(_resultResource.getColumnValue(env, _rs, _metaData, i + 1)); } return BooleanValue.TRUE; } else { return NullValue.NULL; } } catch (SQLException e) { log.log(Level.FINE, e.toString(), e); return BooleanValue.FALSE; } } /** * Frees the associated result. * * @return true on success or false on failure */ public boolean freeResult() { try { ResultSet rs = _rs; _rs = null; if (rs != null) rs.close(); if (_resultResource != null) { _resultResource.close(); _resultResource = null; } return true; } catch (SQLException e) { _errorMessage = e.getMessage(); _errorCode = e.getErrorCode(); log.log(Level.FINE, e.toString(), e); return false; } } /** * Returns the meta data for corresponding to the current result set. * * @return the result set meta data */ protected ResultSetMetaData getMetaData() throws SQLException { if (_metaData == null) _metaData = _rs.getMetaData(); return _metaData; } /**
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?