jdbcresultresource.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,364 行 · 第 1/3 页
JAVA
1,364 行
/* * 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 Scott Ferguson */package com.caucho.quercus.lib.db;import com.caucho.quercus.env.*;import com.caucho.util.L10N;import com.caucho.util.Log;import java.io.IOException;import java.io.InputStream;import java.io.Reader;import java.nio.charset.Charset;import java.nio.charset.CharsetEncoder;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.SQLException;import java.sql.Statement;import java.sql.Types;import java.sql.Date;import java.sql.Timestamp;import java.sql.Time;import java.util.logging.Level;import java.util.logging.Logger;/** * Represents a JDBC Result value. */public class JdbcResultResource { private static final Logger log = Log.open(JdbcResultResource.class); private static final L10N L = new L10N(JdbcResultResource.class); public static final int FETCH_ASSOC = 0x1; public static final int FETCH_NUM = 0x2; public static final int FETCH_BOTH = FETCH_ASSOC | FETCH_NUM; public static final String INTEGER = "int"; public static final String BLOB = "blob"; public static final String STRING = "string"; public static final String DATE = "date"; public static final String DATETIME = "datetime"; public static final String REAL = "real"; public static final String TIME = "time"; public static final String TIMESTAMP = "timestamp"; public static final String UNKNOWN = "unknown"; public static final String YEAR = "year"; private Statement _stmt; protected ResultSet _rs; private boolean _isValid; private int _fieldOffset; private JdbcConnectionResource _conn; private Env _env; protected ResultSetMetaData _metaData; private Value[] _columnNames; private int _affectedRows; /** * Constructor for JdbcResultResource * * @param stmt the corresponding statement * @param rs the corresponding result set * @param conn the corresponding connection */ public JdbcResultResource(Env env, Statement stmt, ResultSet rs, JdbcConnectionResource conn) { _env = env; _stmt = stmt; _rs = rs; _conn = conn; } /** * Constructor for JdbcResultResource * * @param metaData the corresponding result set meta data * @param conn the corresponding connection */ public JdbcResultResource(Env env, ResultSetMetaData metaData, JdbcConnectionResource conn) { _env = env; _metaData = metaData; _conn = conn; _env = conn.getEnv(); } /** * Closes the result set. */ public void close() { try { ResultSet rs = _rs; _rs = null; if (rs != null) rs.close(); _stmt = null; _env = null; _conn = null; } catch (SQLException e) { log.log(Level.FINE, e.toString(), e); } } /** * Fetch the next line as an array. * * @param type one of FETCH_ASSOC, FETCH_NUM, or FETCH_BOTH (default) * By using the FETCH_ASSOC constant this function will behave * identically to the mysqli_fetch_assoc(), while FETCH_NUM will * behave identically to the mysqli_fetch_row() function. The final * option FETCH_BOTH will create a single array with the attributes * of both. * * @return the next result row as an associative, * a numeric array, or both. */ public ArrayValue fetchArray(Env env, int type) { try { if (_rs == null) return null; if (_rs.next()) { _isValid = true; ArrayValue array = new ArrayValueImpl(); ResultSetMetaData md = getMetaData(); int count = md.getColumnCount(); if ((type & FETCH_ASSOC) != 0) { _columnNames = new Value[count]; for (int i = 0; i < count; i++) { String columnName = md.getColumnLabel(i + 1); _columnNames[i] = env.createString(columnName); } } for (int i = 0; i < count; i++) { Value value = getColumnValue(env, _rs, md, i + 1); if ((type & FETCH_NUM) != 0) array.put(LongValue.create(i), value); if ((type & FETCH_ASSOC) != 0) array.put(_columnNames[i], value); } return array; } else { return null; } } catch (SQLException e) { log.log(Level.FINE, e.toString(), e); return null; } } /** * Returns an associative array representing the row. * * @return an associative array representing the row * or null if there are no more rows in the result set */ public ArrayValue fetchAssoc(Env env) { return fetchArray(env, JdbcResultResource.FETCH_ASSOC); } /** * Returns an object with the following fields: name, table, max_length, * not_null, primary_key, multiple_key, numeric, * blob, type, unsigned, zerofill. * <p/> * NOTE: does not have a field for unique_key. * * @param env the PHP executing environment * @param maxLength the field maximum length * @param tableName the field table name * @param type the field type * @return the next field in the result set or * false if no information is available */ public Value fetchField(Env env, int maxLength, String tableName, String type) { if (_rs == null) return null; ObjectValue result = env.createObject(); LongValue one = new LongValue(1); LongValue zero = new LongValue(0); try { if (! _isValid) { _isValid = true; _rs.next(); } result.putField(env, "name", env.createString(_rs.getString(1))); result.putField(env, "table", env.createString(tableName)); result.putField(env, "max_length", new LongValue(maxLength)); if (! isInResultString(4, "YES")) result.putField(env, "not_null", one); else result.putField(env, "not_null", zero); if (isInResultString(5, "PRI")) result.putField(env, "primary_key", one); else result.putField(env, "primary_key", zero); if (isInResultString(5, "MUL")) result.putField(env, "multiple_key", one); else result.putField(env, "multiple_key", zero); if (isInResultString(2, "int") || isInResultString(2, "real")) result.putField(env, "numeric", one); else result.putField(env, "numeric", zero); if (isInResultString(2, "blob")) result.putField(env, "blob", one); else result.putField(env, "blob", zero); result.putField(env, "type", env.createString(type)); if (isInResultString(2, "unsigned")) result.putField(env, "unsigned", one); else result.putField(env, "unsigned", zero); if (isInResultString(2, "zerofill")) result.putField(env, "zerofill", one); else result.putField(env, "zerofill", zero); return result; } catch (SQLException e) { log.log(Level.FINE, e.toString(), e); return BooleanValue.FALSE; } } /** * Returns an object with properties that correspond to the fetched row and * moves the internal data pointer ahead. * * @param env the PHP executing environment * @return an object representing the current fetched row */ public Value fetchObject(Env env) { if (_rs == null) return NullValue.NULL; try { if (_rs.next()) { _isValid = true; Value result = env.createObject(); ResultSetMetaData md = getMetaData(); int count = md.getColumnCount(); for (int i = 0; i < count; i++) { String name = md.getColumnLabel(i + 1); Value value = getColumnValue(env, _rs, md, i + 1); result.putField(env, name, value); } return result; } else { return NullValue.NULL; } } catch (SQLException e) { log.log(Level.FINE, e.toString(), e); return NullValue.NULL; } } /** * Returns an array representing the row. * * @return an array containing the fecthed row */ public ArrayValue fetchRow(Env env) { return fetchArray(env, JdbcResultResource.FETCH_NUM); } /** * Get the number of affected rows. * * @return the number of affected rows */ public int getAffectedRows() { return _affectedRows; } /** * Gets the column number based on a generic Value. * * @param fieldNameOrNumber the field index or it's name * @param base the numbering base: 0 or 1 (usually zero). * @return the column number (always 0-based) or -1 on error */ protected int getColumnNumber(Value fieldNameOrNumber, int base) throws SQLException { int fieldNumber = -1; if ((fieldNameOrNumber != null) && fieldNameOrNumber.isLongConvertible()) { // fieldNameOrNumber is the field number. // Convert it to 0-based. fieldNumber = fieldNameOrNumber.toInt() - base; } if (fieldNumber < 0) { // fieldNameOrNumber is the field name // Get column number (0-based). fieldNumber = getColumnNumber(fieldNameOrNumber.toString()); } return fieldNumber; } /** * Gets the column number. * * @return the column number (0-based) or -1 on error */ protected int getColumnNumber(String colName) throws SQLException { return getColumnNumber(colName, getMetaData()); } /** * Helper function for getResultField returns a 0-based column number * * @param colName the column name * @param rsmd the result set meta data * @return the column number (0-based) or -1 on error */ private int getColumnNumber(String colName, ResultSetMetaData rsmd) throws SQLException { int numColumns = rsmd.getColumnCount(); if (colName.indexOf('.') == -1) { for (int i = 1; i <= numColumns; i++) { if (colName.equals(rsmd.getColumnLabel(i))) return (i - 1); } return -1; } else { for (int i = 1; i <= numColumns; i++) { if (colName.equals(rsmd.getTableName(i) + '.' + rsmd.getColumnLabel(i))) return (i - 1); } return -1; } } /** * Get the column value in the specified result set. * * @param env the PHP executing environment * @param rs the result set * @param metaData the result set meta data * @param column the column number * @return the column value */ public Value getColumnValue(Env env, ResultSet rs, ResultSetMetaData metaData, int column) throws SQLException { // Note: typically, the PHP column value is returned as // a String, except for binary values. try { switch (metaData.getColumnType(column)) { case Types.NULL: return NullValue.NULL; case Types.BIT: { String typeName = metaData.getColumnTypeName(column); // Postgres matches BIT for BOOL columns if (!typeName.equals("bool")) { long value = rs.getLong(column); if (rs.wasNull()) return NullValue.NULL; else return _env.createString(String.valueOf(value)); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?