jdbcconnectionresource.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,150 行 · 第 1/2 页
JAVA
1,150 行
/* * 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.QuercusModuleException;import com.caucho.quercus.env.BooleanValue;import com.caucho.quercus.env.Env;import com.caucho.quercus.env.EnvCleanup;import com.caucho.quercus.env.StringValue;import com.caucho.quercus.env.Value;import com.caucho.util.L10N;import com.caucho.util.LruCache;import java.sql.*;import java.util.logging.Level;import java.util.logging.Logger;/** * Represents a JDBC Connection value. */public abstract class JdbcConnectionResource implements EnvCleanup{ private static final L10N L = new L10N(JdbcConnectionResource.class); private static final Logger log = Logger.getLogger(JdbcConnectionResource.class.getName()); private static LruCache<TableKey,JdbcTableMetaData> _tableMetadataMap = new LruCache<TableKey,JdbcTableMetaData>(256); private Connection _conn; // cached statement private Statement _stmt; private DatabaseMetaData _dmd; private JdbcResultResource _rs; private int _affectedRows; private String _errorMessage = null; private int _errorCode; private boolean _fieldCount = false; private SQLWarning _warnings; private Env _env; protected String _host; protected int _port; private String _userName; private String _password; protected String _driver; protected String _url; protected int _flags; protected String _socket; private String _catalog; private boolean _isCatalogOptimEnabled = false; private boolean _isCloseOnClose = true; private boolean _isUsed; protected SqlParseToken _sqlParseToken = new SqlParseToken(); // php/144b, php/1464, php/1465 protected static final String ENCODING = "ISO8859_1"; public JdbcConnectionResource(Env env) { _env = env; } /** * Returns the error string for the most recent function call. * This method is not invoked from PHP code. */ public StringValue error(Env env) { if (isConnected()) return env.createString(getErrorMessage()); else return env.getEmptyString(); } public boolean isConnected() { return _conn != null; } public Env getEnv() { return _env; } public String getHost() { return _host; } public String getUserName() { return _userName; } public String getPassword() { return _password; } public String getDbName() { return _catalog; } public int getPort() { return _port; } public String getDriver() { return _driver; } public String getUrl() { return _url; } /** * Set the current underlying connection and * corresponding information: host, port and * database name. * * @param host server host * @param port server port * @param dbname database name */ final protected boolean connectInternal(Env env, String host, String userName, String password, String dbname, int port, String socket, int flags, String driver, String url) { _host = host; _userName = userName; _password = password; _port = port; _socket = socket; _flags = flags; _driver = driver; _url = url; if (dbname == null) dbname = ""; _catalog = dbname; Connection conn = connectImpl(env, host, userName, password, dbname, port, socket, flags, driver, url); if (conn != null) { _conn = conn; _env.addCleanup(this); try { if ("".equals(_catalog)) _catalog = conn.getCatalog(); } catch (SQLException e) { log.log(Level.FINE, e.toString(), e); } } return conn != null; } /** * Connects to the underlying database. */ protected abstract Connection connectImpl(Env env, String host, String userName, String password, String dbname, int port, String socket, int flags, String driver, String url); /** * Escape the given string for SQL statements. * * @param str a string * @return the string escaped for SQL statements */ protected StringValue realEscapeString(StringValue str) { StringValue buf = _env.createUnicodeBuilder(); final int strLength = str.length(); for (int i = 0; i < strLength; i++) { char c = str.charAt(i); switch (c) { case '\u0000': buf.append('\\'); buf.append(0); break; case '\n': buf.append('\\'); buf.append('n'); break; case '\r': buf.append('\\'); buf.append('r'); break; case '\\': buf.append('\\'); buf.append('\\'); break; case '\'': buf.append('\\'); buf.append('\''); break; case '"': buf.append('\\'); buf.append('\"'); break; case '\032': buf.append('\\'); buf.append('Z'); break; default: buf.append(c); break; } } return buf; } /** * Returns the affected rows from the last query. */ public int getAffectedRows() { return _affectedRows; } public void setAffectedRows(int i) { _affectedRows = i; } /** * @return _fieldCount */ public int getFieldCount() { if (_rs == null) { return 0; } else { return _rs.getFieldCount(); } } /** * Returns JdbcResultResource of available databases */ protected JdbcResultResource getCatalogs() { clearErrors(); try { if (_dmd == null) _dmd = _conn.getMetaData(); ResultSet rs = _dmd.getCatalogs(); if (rs != null) return createResult(_env, _stmt, rs); else return null; } catch (SQLException e) { saveErrors(e); log.log(Level.FINEST, e.toString(), e); return null; } } /** * @return current catalog or false if error */ protected Value getCatalog() { return _env.createString(_catalog); } /** * Returns the client encoding. * * XXX: stubbed out. has to be revised once we * figure out what to do with character encoding */ public String getCharacterSetName() { return "latin1"; } /** * Alias for getCharacterSetName */ public String getClientEncoding() { return getCharacterSetName(); } /** * Set encoding on the client side of the connection. * Return true if the encoding was set, otherwise false. */ public boolean setClientEncoding(String encoding) { return true; } /** * Returns the client version * @deprecated */ public String getClientInfo() { try { if (_dmd == null) _dmd = _conn.getMetaData(); return _dmd.getDatabaseProductVersion(); } catch (SQLException e) { log.log(Level.FINE, e.toString(), e); return null; } } /** * Returns the connection */ public final Connection getConnection(Env env) { _isUsed = true; if (_conn != null) return _conn; else if (_errorMessage != null) { env.warning(_errorMessage); return null; } else { env.warning(L.l("Connection is not available")); return null; } } /** * Returns the underlying SQL connection * associated to this statement. */ protected Connection getJavaConnection() throws SQLException { return _env.getQuercus().getConnection(_conn); } /** * Returns the data source. */ public String getURL() { // return getJavaConnection().getURL(); return _url; } /** * Returns the last error code. */ public int getErrorCode() { return _errorCode; } /** * Returns the last error message. */ public String getErrorMessage() { return _errorMessage; } /** * * returns the URL string for the given connection * IE: jdbc:mysql://localhost:3306/test * XXX: PHP returns Localhost via UNIX socket */ public String getHostInfo() throws SQLException { if (_dmd == null) _dmd = _conn.getMetaData(); return _dmd.getURL(); } /** * returns the server version */ public String getServerInfo() throws SQLException { return getMetaData().getDatabaseProductVersion(); } /** * Returns the table metadata. */ public JdbcTableMetaData getTableMetaData(String catalog, String schema, String table) throws SQLException { try { if (table == null || table.equals("")) return null; TableKey key = new TableKey(getURL(), catalog, schema, table); // XXX: needs invalidation on DROP or ALTER JdbcTableMetaData tableMd = _tableMetadataMap.get(key); if (tableMd != null && tableMd.isValid()) return tableMd; tableMd = new JdbcTableMetaData(catalog, schema, table, getMetaData()); _tableMetadataMap.put(key, tableMd); return tableMd; } catch (SQLException e) { log.log(Level.FINE, e.toString(), e); return null; } } private DatabaseMetaData getMetaData() throws SQLException { if (_dmd == null) _dmd = _conn.getMetaData(); return _dmd; } static int infoToVersion(String info) { String[] result = info.split("[.a-z-]"); if (result.length < 3) return 0; return (Integer.parseInt(result[0]) * 10000 + Integer.parseInt(result[1]) * 100 + Integer.parseInt(result[2])); } /** * Closes the connection. */ public boolean close(Env env) { // php/1418 cleanup(); return true; } /** * Implements the EnvCleanup interface. This method * will deallocate resources associated with this * connection. This method can be invoked via a * call to close(), or it can be invoked when the * environment is being cleaned up after a quercus * request has been processed. */ public void cleanup() { if (log.isLoggable(Level.FINER)) log.finer(this + " cleanup()"); try { Statement stmt = _stmt; _stmt = null; if (stmt != null) stmt.close(); } catch (SQLException e) { log.log(Level.FINER, e.toString(), e); } try { Connection conn = _conn; _conn = null; if (conn != null) { conn.close(); } } catch (SQLException e) { log.log(Level.FINER, e.toString(), e); } } public JdbcConnectionResource validateConnection() { if (_conn == null) { throw _env.createErrorException(L.l("Connection is not properly initialized {0}\nDriver {1}", _url, _driver)); } return this; } /** * Execute a single query. */ protected Value realQuery(Env env, String sql) { clearErrors(); _rs = null;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?