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 + -
显示快捷键?