pdo.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,025 行 · 第 1/2 页

JAVA
1,025
字号
/* * 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.UnimplementedException;import com.caucho.quercus.annotation.Optional;import com.caucho.quercus.annotation.ReturnNullAsFalse;import com.caucho.quercus.env.ArrayValue;import com.caucho.quercus.env.BooleanValue;import com.caucho.quercus.env.Env;import com.caucho.quercus.env.EnvCleanup;import com.caucho.quercus.env.LongValue;import com.caucho.quercus.env.StringValue;import com.caucho.quercus.env.Value;import com.caucho.util.L10N;import javax.naming.Context;import javax.naming.InitialContext;import javax.naming.NamingException;import javax.sql.DataSource;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.HashMap;import java.util.LinkedHashMap;import java.util.Map;import java.util.logging.Level;import java.util.logging.Logger;/** * PDO object oriented API facade. */public class PDO implements EnvCleanup {  private static final Logger log = Logger.getLogger(PDO.class.getName());  private static final L10N L = new L10N(PDO.class);  public static final int ATTR_AUTOCOMMIT = 0;  public static final int ATTR_PREFETCH = 1;  public static final int ATTR_TIMEOUT = 2;  public static final int ATTR_ERRMODE = 3;  public static final int ATTR_SERVER_VERSION = 4;  public static final int ATTR_CLIENT_VERSION = 5;  public static final int ATTR_SERVER_INFO = 6;  public static final int ATTR_CONNECTION_STATUS = 7;  public static final int ATTR_CASE = 8;  public static final int ATTR_CURSOR_NAME = 9;  public static final int ATTR_CURSOR = 10;  public static final int ATTR_ORACLE_NULLS = 11;  public static final int ATTR_PERSISTENT = 12;  public static final int ATTR_STATEMENT_CLASS = 13;  public static final int ATTR_FETCH_TABLE_NAMES = 14;  public static final int ATTR_FETCH_CATALOG_NAMES = 15;  public static final int ATTR_DRIVER_NAME = 16;  public static final int ATTR_STRINGIFY_FETCHES = 17;  public static final int ATTR_MAX_COLUMN_LEN = 18;  public static final int CASE_NATURAL = 0;  public static final int CASE_UPPER = 1;  public static final int CASE_LOWER = 2;  public static final int CURSOR_FWDONLY = 0;  public static final int CURSOR_SCROLL = 1;  public static final String ERR_NONE = "00000";  public static final int ERRMODE_SILENT = 0;  public static final int ERRMODE_WARNING = 1;  public static final int ERRMODE_EXCEPTION = 2;  public static final int FETCH_LAZY = 1;  public static final int FETCH_ASSOC = 2;  public static final int FETCH_NUM = 3;  public static final int FETCH_BOTH = 4;  public static final int FETCH_OBJ = 5;  public static final int FETCH_BOUND = 6;  public static final int FETCH_COLUMN = 7;  public static final int FETCH_CLASS = 8;  public static final int FETCH_INTO = 9;  public static final int FETCH_FUNC = 10;  public static final int FETCH_NAMED = 11;  public static final int FETCH_GROUP = 0x00010000;  public static final int FETCH_UNIQUE = 0x00030000;  public static final int FETCH_CLASSTYPE = 0x00040000;  public static final int FETCH_SERIALIZE = 0x00080000;  public static final int FETCH_ORI_NEXT = 0;  public static final int FETCH_ORI_PRIOR = 1;  public static final int FETCH_ORI_FIRST = 2;  public static final int FETCH_ORI_LAST = 3;  public static final int FETCH_ORI_ABS = 4;  public static final int FETCH_ORI_REL = 5;  public static final int NULL_NATURAL = 0;  public static final int NULL_EMPTY_STRING = 1;  public static final int NULL_TO_STRING = 2;  public static final int PARAM_NULL = 0;  public static final int PARAM_INT = 1;  public static final int PARAM_STR = 2;  public static final int PARAM_LOB = 3;  public static final int PARAM_STMT = 4;  public static final int PARAM_BOOL = 5;  public static final int PARAM_INPUT_OUTPUT = 0x80000000;  private final Env _env;  private final String _dsn;  private String _user;  private String _password;  private final PDOError _error;  private Connection _conn;  private Statement _lastStatement;  private PDOStatement _lastPDOStatement;  private String _lastInsertId;  private boolean _inTransaction;    private static String ENCODING = "ISO8859_1";  public PDO(Env env,             String dsn,             @Optional("null") String user,             @Optional("null") String password,             @Optional ArrayValue options)  {    _env = env;    _dsn = dsn;    _user = user;    _password = password;    _error = new PDOError(_env);    // XXX: following would be better as annotation on destroy() method    _env.addCleanup(this);    try {      DataSource ds = getDataSource(env, dsn);      if (ds == null) {        env.warning(L.l("'{0}' is an unknown PDO data source.", dsn));      }      else if (_user != null && ! "".equals(_user))        _conn = ds.getConnection(_user, _password);      else        _conn = ds.getConnection();    } catch (RuntimeException e) {      throw e;    } catch (Exception e) {      env.warning(e.getMessage(), e);      _error.error(e);    }  }  /**   * Starts a transaction.   */  public boolean beginTransaction()  {    if (_conn == null)      return false;    if (_inTransaction)      return false;    _inTransaction = true;    try {      _conn.setAutoCommit(false);      return true;    }    catch (SQLException e) {      _error.error(e);      return false;    }  }  private void closeStatements()  {    Statement lastStatement = _lastStatement;    _lastInsertId = null;    _lastStatement = null;    _lastPDOStatement = null;    try {      if (lastStatement != null)        lastStatement.close();    }    catch (Throwable t) {      log.log(Level.WARNING, t.toString(), t);    }  }  /**   * Commits a transaction.   */  public boolean commit()  {    if (_conn == null)      return false;    if (! _inTransaction)      return false;    _inTransaction = false;    boolean result = false;    try {      _conn.commit();      _conn.setAutoCommit(true);      return true;    }    catch (SQLException e) {      _error.error(e);    }    return result;  }  public void close()  {    cleanup();  }  /**   * Implements the EnvCleanup interface.   */  public void cleanup()  {    Connection conn = _conn;    _conn = null;    closeStatements();    if (conn != null) {      try {        conn.close();      }      catch (SQLException e) {        log.log(Level.WARNING, e.toString(), e);      }    }  }  public String errorCode()  {    return _error.errorCode();  }  public ArrayValue errorInfo()  {    return _error.errorInfo();  }  /**   * Executes a statement, returning the number of rows.   */  public int exec(String query)    throws SQLException  {    if (_conn == null)      return -1;    closeStatements();    Statement stmt = null;    int rowCount;    try {      stmt = _conn.createStatement();      stmt.setEscapeProcessing(false);      if (stmt.execute(query)) {        ResultSet resultSet = null;        try {          resultSet = stmt.getResultSet();          resultSet.last();          rowCount = resultSet.getRow();          _lastStatement = stmt;          stmt = null;        }        finally {          try {            if (resultSet != null)              resultSet.close();          }          catch (SQLException e) {            log.log(Level.FINER, e.toString(), e);          }        }      }      else {        rowCount = stmt.getUpdateCount();        _lastStatement = stmt;        stmt = null;      }    } catch (SQLException e) {      _error.error(e);      return -1;    } finally {      try {        if (stmt != null)          stmt.close();      } catch (SQLException e) {        log.log(Level.FINER, e.toString(), e);      }    }    return rowCount;  }  public Value getAttribute(int attribute)  {    switch (attribute) {      case ATTR_AUTOCOMMIT:        return BooleanValue.create(getAutocommit());      case ATTR_CASE:        return LongValue.create(getCase());      case ATTR_CLIENT_VERSION:        throw new UnimplementedException();      case ATTR_CONNECTION_STATUS:        throw new UnimplementedException();      case ATTR_DRIVER_NAME:        throw new UnimplementedException();      case ATTR_ERRMODE:        return LongValue.create(_error.getErrmode());      case ATTR_ORACLE_NULLS:        return LongValue.create(getOracleNulls());      case ATTR_PERSISTENT:        return BooleanValue.create(getPersistent());      case ATTR_PREFETCH:        return LongValue.create(getPrefetch());      case ATTR_SERVER_INFO:        return StringValue.create(getServerInfo());      case ATTR_SERVER_VERSION:        return StringValue.create(getServerVersion());      case ATTR_TIMEOUT:        return LongValue.create(getTimeout());      default:        _error.unsupportedAttribute(attribute);        // XXX: check what php does        return BooleanValue.FALSE;    }  }  /**   * Returns the auto commit value for the connection.   */  private boolean getAutocommit()  {    if (_conn == null)      return true;    try {      return _conn.getAutoCommit();    }    catch (SQLException e) {      _error.error(e);      return true;    }  }  public ArrayValue getAvailableDrivers()  {    throw new UnimplementedException();  }  public int getCase()  {    throw new UnimplementedException();  }  public int getOracleNulls()  {    throw new UnimplementedException();  }  private boolean getPersistent()  {    return true;  }  private int getPrefetch()  {    throw new UnimplementedException();  }  private String getServerInfo()  {    throw new UnimplementedException();  }  // XXX: might be int return  private String getServerVersion()  {    throw new UnimplementedException();  }  private int getTimeout()  {    throw new UnimplementedException();  }  public String lastInsertId(@Optional String name)  {    if (!(name == null || name.length() == 0))      throw new UnimplementedException("lastInsertId with name");    if (_lastInsertId != null)      return _lastInsertId;    String lastInsertId = null;    if (_lastPDOStatement != null)      lastInsertId =  _lastPDOStatement.lastInsertId(name);    else if (_lastStatement != null) {      ResultSet resultSet = null;      try {        resultSet = _lastStatement.getGeneratedKeys();        if (resultSet.next())          lastInsertId = resultSet.getString(1);      }      catch (SQLException ex) {        _error.error(ex);      }      finally {        try {          if (resultSet != null)            resultSet.close();        }        catch (SQLException ex) {          log.log(Level.WARNING, ex.toString(), ex);        }      }    }    _lastInsertId = lastInsertId == null ? "0" : lastInsertId;    return _lastInsertId;  }  /**   * Prepares a statement for execution.   */  @ReturnNullAsFalse  public PDOStatement prepare(String statement,                              @Optional ArrayValue driverOptions)  {    if (_conn == null)      return null;    try {      closeStatements();      PDOStatement pdoStatement        = new PDOStatement(_env, _conn, statement, true, driverOptions);            _lastPDOStatement = pdoStatement;      return pdoStatement;    } catch (SQLException e) {      _error.error(e);      return null;    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?