jdbcconnectionresource.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,150 行 · 第 1/2 页
JAVA
1,150 行
Statement stmt = null; try { Connection conn = getConnection(env); if (conn == null) return BooleanValue.FALSE; if (checkSql(conn, sql)) return BooleanValue.TRUE; // XXX: test for performance boolean canSeek = true; if (canSeek) stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); else stmt = conn.createStatement(); _stmt = stmt; stmt.setEscapeProcessing(false); // php/1406 if (stmt.execute(sql)) { // Statement.execute(String) returns true when SQL statement is a // SELECT statement that returns a result set. ResultSet rs = stmt.getResultSet(); _rs = createResult(_env, stmt, rs); _affectedRows = 0; // XXX: if these are needed, get them lazily for performance // _warnings = stmt.getWarnings(); } else { // Statement.execute(String) returns false when SQL statement does // not returns a result set (UPDATE, INSERT, DELETE, or REPLACE). // php/430a should return a result set // for update statements. It is always // null though. So keep the stmt for // future reference (PostgresModule.pg_last_oid) // php/1f33 // This is overriden in Postgres.java keepResourceValues(stmt); _affectedRows = 0; _affectedRows = stmt.getUpdateCount(); if (_rs != null) _rs.setAffectedRows(_affectedRows); // XXX: if these are neede, get them lazily for performance // _warnings = stmt.getWarnings(); // for php/430a if (! keepStatementOpen()) { _warnings = stmt.getWarnings(); stmt.close(); } } } catch (DataTruncation truncationError) { try { _affectedRows = stmt.getUpdateCount(); //_warnings = stmt.getWarnings(); } catch (SQLException e) { saveErrors(e); log.log(Level.FINEST, e.toString(), e); return BooleanValue.FALSE; } } catch (SQLException e) { saveErrors(e); // php/431h if (keepStatementOpen()) { keepResourceValues(stmt); } else { log.log(Level.FINEST, e.toString(), e); return BooleanValue.FALSE; } } catch (IllegalStateException e) { // #2184, some drivers return this on closed connection saveErrors(new SQLExceptionWrapper(e)); return BooleanValue.FALSE; } if (_rs == null) return BooleanValue.TRUE; return env.wrapJava(_rs); } private boolean checkSql(Connection conn, String sql) { SqlParseToken tok = parseSqlToken(sql, null); if (tok == null) return false; switch (tok.getFirstChar()) { case 'a': case 'A': { // drop/alter clears metadata cache _tableMetadataMap.clear(); break; } case 'd': case 'D': { if (tok.matchesToken("DROP")) { // drop/alter clears metadata cache _tableMetadataMap.clear(); // If DROP is dropping the current database, then clear // the cached database name in the driver. // // php/144a tok = parseSqlToken(sql, tok); if ((tok != null) && tok.matchesToken("DATABASE")) { tok = parseSqlToken(sql, tok); if (tok != null) { String dbname = tok.toUnquotedString(); if (dbname.equals(_catalog)) { try { setCatalog(null); } catch (SQLException e) { log.log(Level.FINEST, e.toString(), e); } } } } } break; } case 'c': case 'C': { if (tok.matchesToken("CREATE")) { // don't pool connections that create tables _env.getQuercus().markForPoolRemoval(conn); } /* else if (tok.matchesToken("COMMIT")) { commit(); setAutoCommit(true); return true; } */ break; } // reason for comment out? no real perf gain? /* case 'b': case 'B': { if (tok.matchesToken("BEGIN")) { // Test for mediawiki performance setAutoCommit(false); return true; } break; } case 'r': case 'R': { if (tok.matchesToken("ROLLBACK")) { rollback(); setAutoCommit(true); return true; } break; } */ } return false; } /** * Parse a token from a string containing a SQL statement. * If the prevToken is null, then the first token in parsed. * If a SQL token can't be found in the string, then null * is returned. If a SQL token is found, data is captured in * the returned SqlParseToken result. */ protected SqlParseToken parseSqlToken(String sql, SqlParseToken prevToken) { if (sql == null) { _sqlParseToken.init(); return null; } final int len = sql.length(); int i, start; // Start at index 0, or where we left off last time if (prevToken == null) i = 0; else i = prevToken._end; while (i < len && Character.isWhitespace(sql.charAt(i))) { i++; } // Must be at least 1 non-whitespace character if ((i + 1) >= len) { _sqlParseToken.init(); return null; } start = i; while (i < len && !Character.isWhitespace(sql.charAt(i))) { i++; } _sqlParseToken.assign(sql, start, i); return _sqlParseToken; } /** * Creates a database-specific result. */ protected JdbcResultResource createResult(Env env, Statement stmt, ResultSet rs) { return new JdbcResultResource(env, stmt, rs, this); } /** * sets auto-commmit to true or false */ public boolean setAutoCommit(boolean mode) { clearErrors(); try { _conn.setAutoCommit(mode); } catch (SQLException e) { saveErrors(e); log.log(Level.FINEST, e.toString(), e); return false; } return true; } /** * commits the transaction of the current connection */ public boolean commit() { clearErrors(); try { _conn.commit(); } catch (SQLException e) { saveErrors(e); log.log(Level.FINEST, e.toString(), e); return false; } return true; } /** * rolls the current transaction back * * NOTE: quercus doesn't seem to support the idea * of savepoints */ public boolean rollback() { clearErrors(); try { _conn.rollback(); } catch (SQLException e) { saveErrors(e); log.log(Level.FINEST, e.toString(), e); return false; } return true; } /** * Sets the catalog */ public void setCatalog(String name) throws SQLException { if (_catalog != null && _catalog.equals(name)) return; clearErrors(); if (! _isUsed && _isCatalogOptimEnabled) { // The database is only connected, but not used, reopen with // a real catalog Connection conn = _conn; _conn = null; if (conn != null) conn.close(); connectInternal(_env, _host, _userName, _password, name, _port, _socket, _flags, _driver, _url); } else { _conn.setCatalog(name); } _catalog = name; } /** * Converts to an object. */ public Object toObject() { return null; } /** * Converts to a string. */ public String toString() { return getClass().getSimpleName() + "[" + _conn + "]"; } /** * This function is overriden in Postgres to keep * result set references for php/430a (see also php/1f33) */ protected void keepResourceValues(Statement stmt) { return; } /** * This function is overriden in Postgres to keep * statement references for php/430a */ protected boolean keepStatementOpen() { return false; } /** * Get the current result resource */ protected JdbcResultResource getResultResource() { return _rs; } /** * Set the current result resource */ protected void setResultResource(JdbcResultResource rs) { _rs = rs; } /** * This function was added for PostgreSQL pg_last_notice * * @return warning messages */ protected SQLWarning getWarnings() { return _warnings; } /** * Pings the database */ public boolean ping(Env env) { try { return isConnected() && ! getConnection(env).isClosed(); } catch (SQLException e) { log.log(Level.FINE, e.toString(), e); env.warning(e.toString(), e); return false; } } /** * Set the current SQL warnings. * * @param warnings the new SQL warnings */ protected void setWarnings(SQLWarning warnings) { _warnings = warnings; } protected void clearErrors() { _errorMessage = null; _errorCode = 0; _warnings = null; } protected void saveErrors(SQLException e) { _errorMessage = e.getMessage(); if (_errorMessage == null || "".equals(_errorMessage)) _errorMessage = e.toString(); _errorCode = e.getErrorCode(); } static class TableKey { private final String _url; private final String _catalog; private final String _schema; private final String _table; TableKey(String url, String catalog, String schema, String table) { _url = url; _catalog = catalog; _schema = schema; _table = table; } public int hashCode() { int hash = 37; if (_url != null) hash = 65537 * hash + _url.hashCode(); if (_catalog != null) hash = 65537 * hash + _catalog.hashCode(); if (_schema != null) hash = 65537 * hash + _schema.hashCode(); if (_table != null) hash = 65537 * hash + _table.hashCode(); return hash; } public boolean equals(Object o) { if (this == o) return true; else if (! (o instanceof TableKey)) return false; TableKey key = (TableKey) o; if ((_url == null) != (key._url == null)) return false; else if (_url != null && ! _url.equals(key._url)) return false; if ((_catalog == null) != (key._catalog == null)) return false; else if (_catalog != null && ! _catalog.equals(key._catalog)) return false; if ((_schema == null) != (key._schema == null)) return false; else if (_schema != null && ! _schema.equals(key._schema)) return false; if ((_table == null) != (key._table == null)) return false; else if (_table != null && ! _table.equals(key._table)) return false; return true; } } /* * This class enables efficient parsing of a SQL token from * a String. An SQL statement can be parsed one token at a * time. One can efficiently check that first letter of * the parse token via matchesFirstChar() without creating * a substring from the original. */ protected static class SqlParseToken { private String _query; private String _token; private int _start; private int _end; private char _firstChar; public void init() { _query = null; _token = null; _start = -1; _end = -1; _firstChar = '\0'; } public void assign(String query, int start, int end) { _query = query; _token = null; _start = start; _end = end; _firstChar = query.charAt(start); } public boolean matchesFirstChar(char upper, char lower) { return (_firstChar == upper) || (_firstChar == lower); } public char getFirstChar() { return _firstChar; } // Case insensitive compare of token string public boolean matchesToken(String token) { if (_token == null) _token = _query.substring(_start, _end); return _token.equalsIgnoreCase(token); } public String toString() { if (_token == null) _token = _query.substring(_start, _end); return _token; } /* * Return the SQL token as a string. If the token * is back quoted, then remove the back quotes and * return the string inside. */ public String toUnquotedString() { String tok = toString(); // Extract database name if back quoted : "DROP DATABASE `DBNAME`" if (tok.length() >= 2 && tok.charAt(0) == '`' && tok.charAt(tok.length() - 1) == '`') { tok = tok.substring(1, tok.length() - 1); } return tok; } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?