mysqli.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,588 行 · 第 1/3 页
JAVA
1,588 行
/* * 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.QuercusException;import com.caucho.quercus.UnimplementedException;import com.caucho.quercus.annotation.Optional;import com.caucho.quercus.annotation.ResourceType;import com.caucho.quercus.annotation.ReturnNullAsFalse;import com.caucho.quercus.env.BooleanValue;import com.caucho.quercus.env.Env;import com.caucho.quercus.env.LongValue;import com.caucho.quercus.env.StringValue;import com.caucho.quercus.env.UnicodeValueImpl;import com.caucho.quercus.env.Value;import com.caucho.util.L10N;import java.io.UnsupportedEncodingException;import java.sql.Connection;import java.sql.DataTruncation;import java.sql.DatabaseMetaData;import java.sql.Driver;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.SQLWarning;import java.sql.Statement;import java.util.ArrayList;import java.util.logging.Level;import java.util.logging.Logger;/** * mysqli object oriented API facade */@ResourceType("mysql link")public class Mysqli extends JdbcConnectionResource { private static final Logger log = Logger.getLogger(Mysqli.class.getName()); private static final L10N L = new L10N(Mysqli.class); protected static final String DRIVER = "com.mysql.jdbc.Driver"; /** * mysqli_multi_query populates _resultValues * NB: any updates (ie: INSERT, UPDATE, DELETE) will * have the update counts ignored. * * Has been stored tells moreResults whether the * _nextResultValue has been stored already. * If so, more results will return true only if * there is another result. * * _hasBeenStored is set to true by default. * if _hasBeenUsed == false, then * _resultValues.get(_nextResultValue) * is ready to be used by the next call to * mysqli_store_result or mysqli_use_result. */ private ArrayList<JdbcResultResource> _resultValues = new ArrayList<JdbcResultResource>(); private int _nextResultValue = 0; private boolean _hasBeenUsed = true; private static volatile String _checkedDriverVersion = null; private static Object _checkDriverLock = new Object(); private LastSqlType _lastSql; /** * This is the constructor for the mysqli class. * It can be invoked by PHP or and by Java code. */ public Mysqli(Env env, @Optional("localhost") StringValue host, @Optional StringValue user, @Optional StringValue password, @Optional StringValue db, @Optional("3306") int port, @Optional StringValue socket) { super(env); String hostStr; if (host.length() == 0) hostStr = "localhost"; else hostStr = host.toString(); connectInternal(env, hostStr, user.toString(), password.toString(), db.toString(), port, socket.toString(), 0, null, null); } /** * This constructor can only be invoked by other method * implementations in the mysql and mysqli modules. It * accepts String arguments and supports additional * arguments not available in the mysqli constructor. */ Mysqli(Env env, String host, String user, String password, String db, int port, String socket, int flags, String driver, String url) { super(env); if (host == null || host.length() == 0) host = "localhost"; connectInternal(env, host, user, password, db, port, socket, flags, driver, url); } protected Mysqli(Env env) { super(env); } public String getResourceType() { return "mysql link"; } public boolean isLastSqlDescribe() { return _lastSql == LastSqlType.DESCRIBE; } /** * Connects to the underlying database. */ protected Connection connectImpl(Env env, String host, String userName, String password, String dbname, int port, String socket, int flags, String driver, String url) { if (isConnected()) { env.warning(L.l("Connection is already opened to '{0}'", this)); return null; } if (port <= 0) { port = 3306; } try { if (host == null || host.equals("")) { host = "localhost"; } if (driver == null || driver.equals("")) { driver = DRIVER; } if (url == null || url.equals("")) { url = getUrl(host, port, dbname, ENCODING, (flags & MysqliModule.MYSQL_CLIENT_INTERACTIVE) != 0, (flags & MysqliModule.MYSQL_CLIENT_COMPRESS) != 0, (flags & MysqliModule.MYSQL_CLIENT_SSL) != 0); } Connection jConn = env.getConnection(driver, url, userName, password); checkDriverVersion(env, jConn); return jConn; } catch (SQLException e) { env.warning(L.l("A link to the server could not be established.\n url={0}\n driver={1}\n {2}", url, driver, e.toString()), e); env.setSpecialValue("mysqli.connectErrno", new LongValue(e.getErrorCode())); env.setSpecialValue("mysqli.connectError", env.createString(e.getMessage())); return null; } catch (Exception e) { env.warning(L.l("A link to the server could not be established.\n url={0}\n driver={1}\n {2}", url, driver, e.toString()), e); env.setSpecialValue("mysqli.connectError", env.createString(e.toString())); return null; } } protected static String getUrl(String host, int port, String dbname, String encoding, boolean useInteractive, boolean useCompression, boolean useSsl) { StringBuilder urlBuilder = new StringBuilder(); urlBuilder.append("jdbc:mysql://"); urlBuilder.append(host); urlBuilder.append(":"); urlBuilder.append(port); urlBuilder.append("/"); urlBuilder.append(dbname); // Ignore MYSQL_CLIENT_LOCAL_FILES and MYSQL_CLIENT_IGNORE_SPACE flags. if (useInteractive) { char sep = (urlBuilder.indexOf("?") < 0) ? '?' : '&'; urlBuilder.append(sep); urlBuilder.append("interactiveClient=true"); } if (useCompression) { char sep = (urlBuilder.indexOf("?") < 0) ? '?' : '&'; urlBuilder.append(sep); urlBuilder.append("useCompression=true"); } if (useSsl) { char sep = (urlBuilder.indexOf("?") < 0) ? '?' : '&'; urlBuilder.append(sep); urlBuilder.append("useSSL=true"); } // Explicitly indicate that we want iso-8859-1 encoding so // we would know what encoding to use to convert StringValues // to Strings // php/140b if (encoding != null) { char sep = urlBuilder.indexOf("?") < 0 ? '?' : '&'; urlBuilder.append(sep); urlBuilder.append("characterEncoding="); urlBuilder.append(encoding); }/* //urlBuilder.append("&useInformationSchema=true"); // required to get the result table name alias, // doesn't work in mysql JDBC 5.1.6, but set it anyways in case // the mysql guys fix it // // php/141p urlBuilder.append("&useOldAliasMetadataBehavior=true");*/ return urlBuilder.toString(); } /** * Quercus function to get the field 'affected_rows'. */ public int getaffected_rows() { return affected_rows(); } /** * returns the number of affected rows. */ public int affected_rows() { return validateConnection().getAffectedRows(); } /** * sets the autocommit mode */ public boolean autocommit(boolean isAutoCommit) { return validateConnection().setAutoCommit(isAutoCommit); } /** * Changes the user and database * * @param user the new user * @param password the new password * @param db the new database */ public boolean change_user(StringValue user, StringValue password, StringValue db) { // XXX: Docs for mysqli_change_user indicate that if new user authorization fails, // then the existing user perms are retained. close(getEnv()); String userStr; String passwordStr; String dbStr; if (user.length() == 0) { userStr = getUserName(); } else { userStr = user.toString(); } if (password.length() == 0) passwordStr = getPassword(); else passwordStr = password.toString(); if (db.length() == 0) dbStr = getCatalog().toString(); else dbStr = db.toString(); return connectInternal(getEnv(), _host, userStr, passwordStr, dbStr, _port, _socket, _flags, _driver, _url); } /** * Returns the client encoding. * * XXX: stubbed out. has to be revised once we * figure out what to do with character encoding */ public StringValue character_set_name(Env env) { return env.createString(getCharacterSetName()); } /** * Alias for character_set_name */ public StringValue client_encoding(Env env) { return character_set_name(env); } /** * Quercus function to get the field 'errno'. */ public int geterrno() { return errno(); } /** * Returns the error code for the most recent function call */ public int errno() { if (isConnected()) return getErrorCode(); else return 0; } /** * Quercus function to get the field 'error'. */ public StringValue geterror(Env env) { return error(env); } /** * Escapes the string */ public StringValue escape_string(StringValue str) { return real_escape_string(str); } /** * Quercus function to get the field 'client_info'. */ public StringValue getclient_info(Env env) { return getClientInfo(env); } /** * Returns the client information. */ static StringValue getClientInfo(Env env) { String version = env.getQuercus().getMysqlVersion(); if (version != null) { // php/1f2h // Initialized to a specific version via: // <init mysql-version="X.X.X"> } else { // php/142h if (_checkedDriverVersion != null && _checkedDriverVersion != "") { // A connection has already been made and the driver // version has been validated. version = _checkedDriverVersion; } else { // A connection has not been made or a valid driver // version was not found. The JDBC API provides no // way to get the release number without a connection, // so just grab the major and minor number and use // zero for the release number. try { Driver driver = DriverManager.getDriver("jdbc:mysql://localhost/"); version = driver.getMajorVersion() + "." + driver.getMinorVersion() + ".00"; } catch (SQLException e) { version = "0.00.00"; } } } return env.createString(version); } /** * Quercus function to get the field 'client_version'. */ public int getclient_version(Env env) { return MysqliModule.mysqli_get_client_version(env); } /** * Returns the database name. */ public Value get_dbname(Env env) { return getCatalog(); } /** * Quercus function to get the field 'host_info'. */ public StringValue gethost_info(Env env) { return get_host_info(env); } /** * Returns the host information. */ public StringValue get_host_info(Env env) { return env.createString(getHost() + " via TCP socket"); } /** * Returns the host name. */ public StringValue get_host_name(Env env) { return env.createString(getHost()); } /** * Quercus function to get the field 'info'. */ public Value getinfo(Env env) { return info(env); } /** * Return info string about the most recently executed * query. Documentation for mysql_info() indicates that * only some kinds of INSERT, UPDATE, LOAD, and ALTER * statements return results. A SELECT statement always * returns FALSE. The ConnectorJ module should provide a * way to get this result string since it is read from * the server, but that is not supported. This function * errors on the side of returning more results than * it should since it is an acceptable compromise. */ Value info(Env env) { if (getResultResource() != null) { // Last SQL statement was a SELECT return BooleanValue.FALSE; } // INSERT result: "Records: 23 Duplicates: 0 Warnings: 0" // LOAD result: "Records: 42 Deleted: 0 Skipped: 0 Warnings: 0" // ALTER TABLE result: "Records: 60 Duplicates: 0 Warnings: 0" // UPDATE result: "Rows matched: 1 Changed: 1 Warnings: 0" StringBuilder buff = new StringBuilder();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?