mysqli.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,588 行 · 第 1/3 页
JAVA
1,588 行
* mysqli_stmt_prepare */ public MysqliStatement stmt_init(Env env) { return new MysqliStatement((Mysqli) validateConnection()); } /** * Transfers the result set from the last query on the * database connection represented by conn. * * Used in conjunction with mysqli_multi_query */ @ReturnNullAsFalse public JdbcResultResource store_result(Env env) { return ((Mysqli) validateConnection()).storeResult(); } /** * Quercus function to get the field 'thread_id'. */ public Value getthread_id(Env env) { return thread_id(env); } /** * Query an identifier that corresponds to this specific * connection. Mysql calls this integer identifier a * thread id, but it is really a connection id. * Return an integer on success, FALSE on failure. */ Value thread_id(Env env) { try { JdbcConnectionResource connV = validateConnection(); Connection conn = connV.getConnection(env); if (conn == null) return BooleanValue.FALSE; Statement stmt = null; try { stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT CONNECTION_ID()"); if (rs.next()) return LongValue.create(rs.getLong(1)); else return BooleanValue.FALSE; } finally { if (stmt != null) stmt.close(); } } catch (SQLException e) { log.log(Level.FINE, e.toString(), e); return BooleanValue.FALSE; } } /** * Kills the given mysql thread id. Killing the connection * is not the same as simply closing the connection. For * example, table locks are released by a KILL. */ public boolean kill(Env env, int threadId) { try { JdbcConnectionResource connV = validateConnection(); Connection conn = connV.getConnection(env); if (conn == null) return false; Statement stmt = null; boolean result = false; try { stmt = conn.createStatement(); env.getQuercus().markForPoolRemoval(conn); ResultSet rs = stmt.executeQuery("KILL CONNECTION " + threadId); result = true; // close the underlying java.sql connection, not Mysqli itself conn.close(); } catch (SQLException e) { // exception thrown if cannot find specified thread id } finally { if (stmt != null) stmt.close(); } return result; } catch (SQLException e) { log.log(Level.FINE, e.toString(), e); return false; } } /** * Returns true for thread_safe */ public boolean thread_safe() { return true; } /** * Transfers the result set from the last query on the * database connection represented by conn. * * Used in conjunction with mysqli_multi_query */ @ReturnNullAsFalse public JdbcResultResource use_result(Env env) { return ((Mysqli) validateConnection()).storeResult(); } /** * Quercus function to get the field 'warning_count'. */ public int getwarning_count(Env env) { return warning_count(env); } /** * returns the number of warnings from the last query * in the connection object. * * @return number of warnings */ public int warning_count(Env env) { return ((Mysqli) validateConnection()).getWarningCount(env); } /** * Creates a database-specific result. */ @Override protected JdbcResultResource createResult(Env env, Statement stmt, ResultSet rs) { return new MysqliResult(env, stmt, rs, this); } /** * This functions queries the connection with "SHOW WARNING" * * @return # of warnings */ private int getWarningCount(Env env) { if (getWarnings() != null) { JdbcResultResource warningResult; warningResult = metaQuery(env, "SHOW WARNINGS", getCatalog().toString()); int warningCount = 0; if (warningResult != null) { warningCount = JdbcResultResource.getNumRows(warningResult.getResultSet()); } if (warningCount >= 0) return warningCount; else return 0; } else return 0; } /** * Used by the * various mysqli functions to query the database * for metadata about the resultset which is * not in ResultSetMetaData. * * This function DOES NOT clear existing resultsets. */ protected MysqliResult metaQuery(Env env, String sql, String catalog) { clearErrors(); Value currentCatalog = getCatalog(); try { Connection conn = getConnection(env); if (conn == null) return null; conn.setCatalog(catalog); // need to create statement after setting catalog or // else statement will have wrong catalog Statement stmt = conn.createStatement(); stmt.setEscapeProcessing(false); if (stmt.execute(sql)) { MysqliResult result = (MysqliResult) createResult(getEnv(), stmt, stmt.getResultSet()); conn.setCatalog(currentCatalog.toString()); return result; } else { conn.setCatalog(currentCatalog.toString()); return null; } } catch (SQLException e) { saveErrors(e); log.log(Level.WARNING, e.toString(), e); return null; } } /** * indicates if one or more result sets are * available from a multi query * * _hasBeenStored tells moreResults whether the * _nextResultValue has been stored already. * If so, more results will return true only if * there is another result. */ private boolean moreResults() { return !_hasBeenUsed || _nextResultValue < _resultValues.size() - 1; } /** * Used for multiple queries. the * JdbcConnectionResource now stores the * result sets so that mysqli_store_result * and mysqli_use_result can return result values. * * XXX: this may not function correctly in the * context of a transaction. Unclear wether * mysqli_multi_query was designed with transactions * in mind. * * XXX: multiQuery sets fieldCount to true or false * depending on the last query entered. Not sure what * actual PHP intention is. */ private boolean multiQuery(Env env, StringValue sql) { clearErrors(); // Empty _resultValues on new call to query // But DO NOT close the individual result sets. // They may still be in use. _resultValues.clear(); ArrayList<String> splitQuery = splitMultiQuery(sql); Statement stmt = null; try { setResultResource(null); for (String s : splitQuery) { Connection conn = getConnection(env); if (conn == null) return false; stmt = conn.createStatement(); stmt.setEscapeProcessing(false); if (stmt.execute(s)) { setAffectedRows(0); setResultResource(createResult(getEnv(), stmt, stmt.getResultSet())); _resultValues.add(getResultResource()); setWarnings(stmt.getWarnings()); } else { setAffectedRows(stmt.getUpdateCount()); setWarnings(stmt.getWarnings()); } } } catch (DataTruncation truncationError) { try { setAffectedRows(stmt.getUpdateCount()); setWarnings(stmt.getWarnings()); } catch (SQLException e) { saveErrors(e); log.log(Level.WARNING, e.toString(), e); return false; } } catch (SQLException e) { saveErrors(e); log.log(Level.WARNING, e.toString(), e); return false; } if (_resultValues.size() > 0) { _nextResultValue = 0; _hasBeenUsed = false; } return true; } /** * prepares the next resultset from * a multi_query */ private boolean nextResult() { if (_nextResultValue + 1 < _resultValues.size()) { _hasBeenUsed = false; _nextResultValue++; return true; } else return false; } /** * splits a string of multiple queries separated * by ";" into an arraylist of strings */ private ArrayList<String> splitMultiQuery(StringValue sqlStr) { ArrayList<String> result = new ArrayList<String>(); StringBuilder queryBuffer = new StringBuilder(64); final String sql = sqlStr.toString(); final int length = sql.length(); boolean inQuotes = false; char c; for (int i = 0; i < length; i++) { c = sql.charAt(i); if (c == '\\') { queryBuffer.append(c); if (i < length - 1) { queryBuffer.append(sql.charAt(i+1)); i++; } continue; } if (inQuotes) { queryBuffer.append(c); if (c == '\'') { inQuotes = false; } continue; } if (c == '\'') { queryBuffer.append(c); inQuotes = true; continue; } if (c == ';') { result.add(queryBuffer.toString().trim()); queryBuffer = new StringBuilder(64); } else queryBuffer.append(c); } if (queryBuffer.length() > 0) result.add(queryBuffer.toString().trim()); return result; } /** * returns the next jdbcResultValue */ private JdbcResultResource storeResult() { if (!_hasBeenUsed) { _hasBeenUsed = true; return _resultValues.get(_nextResultValue); } else return null; } // Indicate that this connection is a "persistent" connections, // meaning it can't be closed. public void setPersistent() { } /** * Verify that the ConnectorJ driver version is 3.1.14 or newer. * Older versions of this driver return incorrect type information * and suffer from encoding related bugs. */ protected static void checkDriverVersion(Env env, Connection conn) throws SQLException { if (_checkedDriverVersion != null) return; synchronized(_checkDriverLock) { // to prevent multiple checks if (_checkedDriverVersion == null) { _checkedDriverVersion = checkDriverVersionImpl(env, conn); if (_checkedDriverVersion.length() != 0) return; String message = "Unable to detect MySQL Connector/J JDBC driver " + "version. The recommended JDBC version is " + "3.1.14+/5+."; log.log(Level.WARNING, message); env.warning(message); } } } private static String checkDriverVersionImpl(Env env, Connection conn) throws SQLException { DatabaseMetaData databaseMetaData = null; try { databaseMetaData = conn.getMetaData(); } catch (SQLException e) { log.log(Level.FINEST, e.toString(), e); } // If getMetaData() returns null or raises a SQLException, // then we can't verify the driver version. if (databaseMetaData == null) return ""; String fullVersion = null; try { fullVersion = databaseMetaData.getDriverVersion(); } catch (SQLException e) { log.log(Level.FINEST, e.toString(), e); } // If getDriverVersion() returns null or raises a SQLException, // then we can't verify the driver version. if (fullVersion == null) { return ""; } String version = fullVersion; // Extract full version number. int start; int end = version.indexOf(' '); String checkedDriverVersion = ""; if (end != -1) { version = version.substring(0, end); start = version.lastIndexOf('-'); if (start != -1) { version = version.substring(start + 1); // version string should look like "3.1.14" int major; int minor; int release; start = version.indexOf('.'); end = version.lastIndexOf('.'); major = Integer.valueOf(version.substring(0, start)); minor = Integer.valueOf(version.substring(start+1, end)); release = Integer.valueOf(version.substring(end+1)); checkedDriverVersion = major + "." + minor + "." + release; if (major >= 5 || major == 3 && (minor > 1 || minor == 1 && release >= 14)) { } else { String message = L.l("Your MySQL Connector/J JDBC {0} driver may " + "have issues with character encoding. The " + "recommended JDBC version is 3.1.14/5+.", version); log.log(Level.WARNING, message); env.warning(message); } } } return checkedDriverVersion; } // Invoked to close a connection. public boolean close(Env env) { /* if (_isPersistent) return true; */ return super.close(env); } public enum LastSqlType { NONE, UPDATE, DESCRIBE };}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?