📄 statement.java
字号:
/*
* MM JDBC Drivers for MySQL
*
* $Id: Statement.java,v 1.2 1998/08/25 00:53:48 mmatthew Exp $
*
* Copyright (C) 1998 Mark Matthews <mmatthew@worldserver.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* See the COPYING file located in the top-level-directory of
* the archive of this library for complete text of license.
*
* Some portions:
*
* Copyright (c) 1996 Bradley McLean / Jeffrey Medeiros
* Modifications Copyright (c) 1996/1997 Martin Rode
* Copyright (c) 1997 Peter T Mount
*/
/**
* A Statement object is used for executing a static SQL statement and
* obtaining the results produced by it.
*
* <p>Only one ResultSet per Statement can be open at any point in time.
* Therefore, if the reading of one ResultSet is interleaved with the
* reading of another, each must have been generated by different
* Statements. All statement execute methods implicitly close a
* statement's current ResultSet if an open one exists.
*
* @see java.sql.Statement
* @see ResultSet
* @author Mark Matthews <mmatthew@worldserver.com>
* @version $Id$
*/
package org.gjt.mm.mysql;
import java.sql.*;
public class Statement implements java.sql.Statement
{
Connection _Conn = null; // The connection who created us
ResultSet _Results = null; // The current results
ResultSet _NextResults = null; // The next result set
SQLWarning _Warnings = null; // The warnings chain.
int _timeout = 0; // The timeout for a query
boolean _escapeProcessing = true; // escape processing flag
EscapeProcessor _Escaper = null; // The escape processor
int _max_field_size = MysqlIO.MAXBUF;
int _max_rows = -1;
long _update_count = -1;
long _last_insert_id = -1;
String _Catalog = null;
/**
* Constructor for a Statement. It simply sets the connection
* that created us.
*
* @param c the Connection instantation that creates us
*/
public Statement(Connection C, String Catalog)
{
if (Driver.trace) {
Object[] Args = {C};
Debug.methodCall(this, "constructor", Args);
}
_Conn = C;
_Escaper = new EscapeProcessor();
_Catalog = Catalog;
}
/**
* Execute a SQL statement that retruns a single ResultSet
*
* @param Sql typically a static SQL SELECT statement
* @return a ResulSet that contains the data produced by the query
* @exception java.sql.SQLException if a database access error occurs
*/
public java.sql.ResultSet executeQuery(String Sql) throws java.sql.SQLException
{
if (Driver.trace) {
Object[] Args = {Sql};
Debug.methodCall(this, "executeQuery", Args);
}
if (_escapeProcessing) {
Sql = _Escaper.escapeSQL(Sql);
}
if (Sql.indexOf("||") != -1) {
Sql = _Escaper.doConcat(Sql);
}
if (_Results != null) {
_Results.close();
}
// If there isn't a limit clause in the SQL
// then limit the number of rows to return in
// an efficient manner. Only do this if
// setMaxRows() hasn't been used on any Statements
// generated from the current Connection (saves
// a query, and network traffic).
synchronized (_Conn.getMutex()) {
String OldCatalog = null;
if (!_Conn.getCatalog().equals(_Catalog)) {
OldCatalog = _Conn.getCatalog();
_Conn.setCatalog(_Catalog);
}
if (_Conn.useMaxRows()) {
// We need to execute this all together
// So synchronize on the Connection's mutex (because
// even queries going through there synchronize
// on the connection
if (Sql.toUpperCase().indexOf("LIMIT") != -1) {
_Results = _Conn.execSQL(Sql, _max_rows);
}
else {
if (_max_rows <= 0) {
_Conn.execSQL("SET OPTION SQL_SELECT_LIMIT="
+ MysqlDefs.MAX_ROWS, -1);
}
else {
_Conn.execSQL("SET OPTION SQL_SELECT_LIMIT=" + _max_rows,-1);
}
_Results = _Conn.execSQL(Sql, -1);
if (OldCatalog != null) {
_Conn.setCatalog(OldCatalog);
}
}
}
else {
_Results = _Conn.execSQL(Sql, -1);
}
if (OldCatalog != null) {
_Conn.setCatalog(OldCatalog);
}
}
_last_insert_id = _Results.getUpdateID();
_NextResults = _Results;
_Results.setConnection(_Conn);
return _Results;
}
/**
* Execute a SQL INSERT, UPDATE or DELETE statement. In addition
* SQL statements that return nothing such as SQL DDL statements
* can be executed
*
* Any IDs generated for AUTO_INCREMENT fields can be retrieved
* by casting this Statement to org.gjt.mm.mysql.Statement and
* calling the getLastInsertID() method.
*
* @param Sql a SQL statement
* @return either a row count, or 0 for SQL commands
* @exception java.sql.SQLException if a database access error occurs
*/
public int executeUpdate(String Sql) throws java.sql.SQLException
{
if (Driver.trace) {
Object[] Args = {Sql};
Debug.methodCall(this, "executeUpdate", Args);
}
if (_escapeProcessing) {
Sql = _Escaper.escapeSQL(Sql);
}
if (Sql.indexOf("||") != -1) {
Sql = _Escaper.doConcat(Sql);
}
// The checking and changing of catalogs
// must happen in sequence, so synchronize
// on the same mutex that _Conn is using
ResultSet RS = null;
synchronized (_Conn.getMutex()) {
String OldCatalog = null;
if (!_Conn.getCatalog().equals(_Catalog)) {
OldCatalog = _Conn.getCatalog();
_Conn.setCatalog(_Catalog);
}
RS = _Conn.execSQL(Sql, -1);
RS.setConnection(_Conn);
if (OldCatalog != null) {
_Conn.setCatalog(OldCatalog);
}
}
if (RS.reallyResult()) {
throw new java.sql.SQLException("Results returned for UPDATE ONLY.", "01S03");
}
else {
_update_count = RS.getUpdateCount();
int truncated_update_count = 0;
if (_update_count > Integer.MAX_VALUE) {
truncated_update_count = Integer.MAX_VALUE;
}
else {
truncated_update_count = (int)_update_count;
}
_last_insert_id = RS.getUpdateID();
return truncated_update_count;
}
}
/**
* In many cases, it is desirable to immediately release a
* Statement's database and JDBC resources instead of waiting
* for this to happen when it is automatically closed. The
* close method provides this immediate release.
*
* <p><B>Note:</B> A Statement is automatically closed when it is
* garbage collected. When a Statement is closed, its current
* ResultSet, if one exists, is also closed.
*
* @exception java.sql.SQLException if a database access error occurs
*/
public void close() throws java.sql.SQLException
{
if (Driver.trace) {
Object[] Args = new Object[0];
Debug.methodCall(this, "close", Args);
}
_Results = null;
_Conn = null;
_Warnings = null;
_Escaper = null;
}
/**
* The maxFieldSize limit (in bytes) is the maximum amount of
* data returned for any column value; it only applies to
* BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR and LONGVARCHAR
* columns. If the limit is exceeded, the excess data is silently
* discarded.
*
* @return the current max column size limit; zero means unlimited
* @exception java.sql.SQLException if a database access error occurs
*/
public int getMaxFieldSize() throws java.sql.SQLException
{
if (Driver.trace) {
Object[] Args = new Object[0];
Debug.methodCall(this, "getMaxFieldSize", Args);
}
return _max_field_size; // Init. set to MAXBUFFER in MysqlIO
}
/**
* Sets the maxFieldSize
*
* @param max the new max column size limit; zero means unlimited
* @exception java.sql.SQLException if size exceeds buffer size
*/
public void setMaxFieldSize(int max) throws java.sql.SQLException
{
if (Driver.trace) {
Object[] Args = {new Integer(max)};
Debug.methodCall(this, "setMaxFieldSize", Args);
}
if (max > MysqlIO.MAXBUF)
throw new java.sql.SQLException("Attempt to set max field size > " + MysqlIO.MAXBUF + " (compile time default)", "S1009");
else
_max_field_size = max;
}
/**
* The maxRows limit is set to limit the number of rows that
* any ResultSet can contain. If the limit is exceeded, the
* excess rows are silently dropped.
*
* @return the current maximum row limit; zero means unlimited
* @exception java.sql.SQLException if a database access error occurs
*/
public int getMaxRows() throws java.sql.SQLException
{
if (Driver.trace) {
Object[] Args = new Object[0];
Debug.methodCall(this, "getMaxRows", Args);
}
if (_max_rows <=0) {
return 0;
}
else {
return _max_rows;
}
}
/**
* Set the maximum number of rows
*
* @param max the new max rows limit; zero means unlimited
* @exception java.sql.SQLException if a database access error occurs
* @see getMaxRows
*/
public void setMaxRows(int max) throws java.sql.SQLException
{
if (Driver.trace) {
Object[] Args = {new Integer(max)};
Debug.methodCall(this, "setMaxRows", Args);
}
if (max > MysqlDefs.MAX_ROWS) {
throw new java.sql.SQLException("setMaxRows() out of range. " + max + " > " + MysqlDefs.MAX_ROWS + ".", "S1009");
}
if (max == 0) {
max = -1;
}
_max_rows = max;
// Most people don't use setMaxRows()
// so don't penalize them
// with the extra query it takes
// to do it efficiently unless we need
// to.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -