|
What this is
Other links
The source code
/*
* MM JDBC Drivers for MySQL
*
* $Id: PreparedStatement.java,v 1.2 1998/08/25 00:53:47 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.
*/
/**
* A SQL Statement is pre-compiled and stored in a PreparedStatement object.
* This object can then be used to efficiently execute this statement multiple
* times.
*
* <p>Note: The setXXX methods for setting IN parameter values must
* specify types that are compatible with the defined SQL type of the input
* parameter. For instance, if the IN parameter has SQL type Integer, then
* setInt should be used.
*
* <p>If arbitrary parameter type conversions are required, then the setObject
* method should be used with a target SQL type.
*
* @see java.sql.ResultSet
* @see java.sql.PreparedStatement
* @author Mark Matthews <mmatthew@worldserver.com>
* @version $Id$
*/
package org.gjt.mm.mysql;
import java.io.*;
import java.math.*;
import java.sql.*;
import java.text.*;
import java.util.*;
public class PreparedStatement extends org.gjt.mm.mysql.Statement
implements java.sql.PreparedStatement
{
private String _Sql = null;
private String[] _TemplateStrings = null;
private String[] _ParameterStrings = null;
private InputStream[] _ParameterStreams = null;
private boolean[] _IsStream = null;
private Connection _Conn = null;
private boolean _do_concat = false;
private boolean _has_limit_clause = false;
/**
* Constructor for the PreparedStatement class.
* Split the SQL statement into segments - separated by the arguments.
* When we rebuild the thing with the arguments, we can substitute the
* args and join the whole thing together.
*
* @param conn the instanatiating connection
* @param sql the SQL statement with ? for IN markers
* @exception java.sql.SQLException if something bad occurs
*/
public PreparedStatement(Connection Conn, String Sql, String Catalog) throws java.sql.SQLException
{
super(Conn, Catalog);
if (Sql.indexOf("||") != -1) {
_do_concat = true;
}
_has_limit_clause = (Sql.toUpperCase().indexOf("LIMIT") != -1);
Vector V = new Vector();
boolean inQuotes = false;
int lastParmEnd = 0, i;
_Sql = Sql;
_Conn = Conn;
for (i = 0; i < _Sql.length(); ++i) {
int c = _Sql.charAt(i);
if (c == '\'')
inQuotes = !inQuotes;
if (c == '?' && !inQuotes)
{
V.addElement(_Sql.substring (lastParmEnd, i));
lastParmEnd = i + 1;
}
}
V.addElement(_Sql.substring (lastParmEnd, _Sql.length()));
_TemplateStrings = new String[V.size()];
_ParameterStrings = new String[V.size() - 1];
_ParameterStreams = new InputStream[V.size() - 1];
_IsStream = new boolean[V.size() - 1];
clearParameters();
for (i = 0 ; i < _TemplateStrings.length; ++i) {
_TemplateStrings[i] = (String)V.elementAt(i);
}
for (int j = 0; j < _ParameterStrings.length; j++) {
_IsStream[j] = false;
}
}
/**
* A Prepared SQL query is executed and its ResultSet is returned
*
* @return a ResultSet that contains the data produced by the
* query - never null
* @exception java.sql.SQLException if a database access error occurs
*/
public java.sql.ResultSet executeQuery() throws java.sql.SQLException
{
boolean do_escape_processing = _escapeProcessing;
_escapeProcessing = false; // Do escape processing part-by-part
Buffer Packet = new Buffer(MysqlIO.getMaxBuf());
Packet.writeByte((byte)MysqlDefs.QUERY);
String Encoding = null;
if (_Conn.useUnicode()) {
Encoding = _Conn.getEncoding();
}
try {
for (int i = 0 ; i < _ParameterStrings.length ; ++i) {
if (_ParameterStrings[i] == null &&
(_IsStream[i] && _ParameterStreams[i] == null)) {
throw new java.sql.SQLException("No value specified for parameter " + (i + 1), "07001");
}
if (Encoding != null) {
Packet.writeStringNoNull(_TemplateStrings[i], Encoding);
}
else {
Packet.writeStringNoNull(_TemplateStrings[i]);
}
if (_IsStream[i]) {
Packet.writeBytesNoNull(streamToBytes(_ParameterStreams[i]));
}
else {
if (do_escape_processing) {
_ParameterStrings[i] = _Escaper.escapeSQL(_ParameterStrings[i]);
}
if (Encoding != null) {
Packet.writeStringNoNull(_ParameterStrings[i], Encoding);
}
else {
Packet.writeStringNoNull(_ParameterStrings[i]);
}
}
}
if (Encoding != null) {
Packet.writeStringNoNull(_TemplateStrings[_ParameterStrings.length], Encoding);
}
else {
Packet.writeStringNoNull(_TemplateStrings[_ParameterStrings.length]);
}
}
catch (java.io.UnsupportedEncodingException UE) {
throw new SQLException("Unsupported character encoding '" + Encoding + "'");
}
if (_Results != null) {
_Results.close();
}
// We need to execute this all together
// So synchronize on the Connection's mutex (because
// even queries going through there synchronize
// on the same mutex.
synchronized (_Conn.getMutex()) {
String OldCatalog = null;
if (!_Conn.getCatalog().equals(_Catalog)) {
OldCatalog = _Conn.getCatalog();
_Conn.setCatalog(_Catalog);
}
if (_Conn.useMaxRows()) {
// 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).
if (_has_limit_clause) {
_Results = _Conn.execSQL(null, _max_rows, Packet);
}
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(null, -1, Packet);
if (OldCatalog != null) {
_Conn.setCatalog(OldCatalog);
}
}
}
else {
_Results = _Conn.execSQL(null, -1, Packet);
}
if (OldCatalog != null) {
_Conn.setCatalog(OldCatalog);
}
}
_last_insert_id = _Results.getUpdateID();
_NextResults = _Results;
_Results.setConnection(_Conn);
_escapeProcessing = do_escape_processing;
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.
*
* @return either the row count for INSERT, UPDATE or DELETE; or
* 0 for SQL statements that return nothing.
* @exception java.sql.SQLException if a database access error occurs
*/
public int executeUpdate() throws java.sql.SQLException
{
boolean do_escape_processing = _escapeProcessing;
_escapeProcessing = false;
Buffer Packet = new Buffer(MysqlIO.getMaxBuf());
Packet.writeByte((byte)MysqlDefs.QUERY);
String Encoding = null;
if (_Conn.useUnicode()) {
Encoding = _Conn.getEncoding();
}
try {
for (int i = 0 ; i < _ParameterStrings.length ; ++i) {
if (_ParameterStrings[i] == null &&
(_IsStream[i] && _ParameterStreams[i] == null)) {
throw new java.sql.SQLException("No value specified for parameter " + (i + 1), "07001");
}
if (Encoding != null) {
Packet.writeStringNoNull(_TemplateStrings[i], Encoding);
}
else {
Packet.writeStringNoNull(_TemplateStrings[i]);
}
if (_IsStream[i]) {
Packet.writeBytesNoNull(streamToBytes(_ParameterStreams[i]));
}
else {
if (do_escape_processing) {
_ParameterStrings[i] = _Escaper.escapeSQL(_ParameterStrings[i]);
}
if (Encoding != null) {
Packet.writeStringNoNull(_ParameterStrings[i], Encoding);
}
else {
Packet.writeStringNoNull(_ParameterStrings[i]);
}
}
}
if (Encoding != null) {
Packet.writeStringNoNull(_TemplateStrings[_ParameterStrings.length], Encoding);
}
else {
Packet.writeStringNoNull(_TemplateStrings[_ParameterStrings.length]);
}
}
catch (java.io.UnsupportedEncodingException UE) {
throw new SQLException("Unsupported character encoding '" + Encoding + "'");
}
// 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(null, -1, Packet);
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();
_escapeProcessing = do_escape_processing;
return truncated_update_count;
}
}
/**
* Set a parameter to SQL NULL
*
* <p>Note: You must specify the parameters SQL type (although
* PostgreSQL ignores it)
*
* @param parameterIndex the first parameter is 1, etc...
* @param sqlType the SQL type code defined in java.sql.Types
* @exception java.sql.SQLException if a database access error occurs
*/
public void setNull(int parameterIndex, int sqlType) throws java.sql.SQLException
{
set(parameterIndex, "null");
}
/**
* Set a parameter to a Java boolean value. The driver converts this
* to a SQL BIT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception java.sql.SQLException if a database access error occurs
*/
public void setBoolean(int parameterIndex, boolean x) throws java.sql.SQLException
{
set(parameterIndex, x ? "'t'" : "'f'");
}
/**
* Set a parameter to a Java byte value. The driver converts this to
* a SQL TINYINT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception java.sql.SQLException if a database access error occurs
*/
public void setByte(int parameterIndex, byte x) throws java.sql.SQLException
{
set(parameterIndex, (new Integer(x)).toString());
}
/**
* Set a parameter to a Java short value. The driver converts this
* to a SQL SMALLINT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception java.sql.SQLException if a database access error occurs
*/
public void setShort(int parameterIndex, short x) throws java.sql.SQLException
{
set(parameterIndex, (new Integer(x)).toString());
}
/**
* Set a parameter to a Java int value. The driver converts this to
* a SQL INTEGER value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception java.sql.SQLException if a database access error occurs
*/
public void setInt(int parameterIndex, int x) throws java.sql.SQLException
{
set(parameterIndex, (new Integer(x)).toString());
}
/**
* Set a parameter to a Java long value. The driver converts this to
* a SQL BIGINT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception java.sql.SQLException if a database access error occurs
*/
public void setLong(int parameterIndex, long x) throws java.sql.SQLException
{
set(parameterIndex, (new Long(x)).toString());
}
/**
* Set a parameter to a Java float value. The driver converts this
* to a SQL FLOAT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception java.sql.SQLException if a database access error occurs
*/
public void setFloat(int parameterIndex, float x) throws java.sql.SQLException
{
set(parameterIndex, (new Float(x)).toString());
}
/**
* Set a parameter to a Java double value. The driver converts this
* to a SQL DOUBLE value when it sends it to the database
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception java.sql.SQLException if a database access error occurs
*/
public void setDouble(int parameterIndex, double x) throws java.sql.SQLException
{
set(parameterIndex, _DoubleFormatter.format(x));
// - Fix for large doubles by Steve Ferguson
}
/**
* Set a parameter to a java.lang.BigDecimal value. The driver
* converts this to a SQL NUMERIC value when it sends it to the
* database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception java.sql.SQLException if a database access error occurs
*/
public void setBigDecimal(int parameterIndex, BigDecimal X) throws java.sql.SQLException
{
if (X == null) {
setNull(parameterIndex, java.sql.Types.DECIMAL);
}
else {
set(parameterIndex, X.toString());
}
}
/**
* Set a parameter to a Java String value. The driver converts this
* to a SQL VARCHAR or LONGVARCHAR value (depending on the arguments
* size relative to the driver's limits on VARCHARs) when it sends it
* to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception java.sql.SQLException if a database access error occurs
*/
public void setString(int parameterIndex, String X) throws java.sql.SQLException
{
// if the passed string is null, then set this column to null
if(X == null) {
set(parameterIndex, "null");
}
else {
StringBuffer B = new StringBuffer();
int i;
B.append('\'');
for (i = 0 ; i < X.length() ; ++i) {
char c = X.charAt(i);
if (c == '\\' || c == '\'' || c == '"') {
B.append((char)'\\');
}
B.append(c);
}
B.append('\'');
set(parameterIndex, B.toString());
}
}
/**
* Set a parameter to a Java array of bytes. The driver converts this
* to a SQL VARBINARY or LONGVARBINARY (depending on the argument's
* size relative to the driver's limits on VARBINARYs) when it sends
* it to the database.
*
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception java.sql.SQLException if a database access error occurs
*/
public void setBytes(int parameterIndex, byte x[]) throws java.sql.SQLException
{
if (x == null) {
setNull(parameterIndex, java.sql.Types.BINARY);
}
else {
ByteArrayInputStream BIn = new ByteArrayInputStream(x);
setBinaryStream(parameterIndex, BIn, x.length);
}
}
/**
* Set a parameter to a java.sql.Date value. The driver converts this
* to a SQL DATE value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception java.sql.SQLException if a database access error occurs
*/
public void setDate(int parameterIndex, java.sql.Date X) throws java.sql.SQLException
{
if (X == null) {
setNull(parameterIndex, java.sql.Types.DATE);
}
else {
SimpleDateFormat DF = new SimpleDateFormat("''yyyy-MM-dd''");
set(parameterIndex, DF.format(X));
}
}
/**
* Set a parameter to a java.sql.Time value. The driver converts
* this to a SQL TIME value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...));
* @param x the parameter value
* @exception java.sql.SQLException if a database access error occurs
*/
public void setTime(int parameterIndex, Time X) throws java.sql.SQLException
{
if (X == null) {
setNull(parameterIndex, java.sql.Types.TIME);
}
else {
set(parameterIndex, "'" + X.toString() + "'");
}
}
/**
* Set a parameter to a java.sql.Timestamp value. The driver converts
* this to a SQL TIMESTAMP value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception java.sql.SQLException if a database access error occurs
*/
public void setTimestamp(int parameterIndex, Timestamp X) throws java.sql.SQLException
{
if (X == null) {
setNull(parameterIndex, java.sql.Types.TIMESTAMP);
}
else {
EscapeProcessor EP = new EscapeProcessor();
String TimestampString = EP.escapeSQL("{ts '" + X.toString() + "'}");
set(parameterIndex, TimestampString);
}
}
/**
* When a very large ASCII value is input to a LONGVARCHAR parameter,
* it may be more practical to send it via a java.io.InputStream.
* JDBC will read the data from the stream as needed, until it reaches
* end-of-file. The JDBC driver will do any necessary conversion from
* ASCII to the database char format.
*
* <P>Note: This stream object can either be a standard Java
* stream object or your own subclass that implements the standard
* interface.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @param length the number of bytes in the stream
* @exception java.sql.SQLException if a database access error occurs
*/
public void setAsciiStream(int parameterIndex, InputStream X, int length) throws java.sql.SQLException
{
if (X == null) {
setNull(parameterIndex, java.sql.Types.VARCHAR);
}
else {
setBinaryStream(parameterIndex, X, length);
}
}
/**
* When a very large Unicode value is input to a LONGVARCHAR parameter,
* it may be more practical to send it via a java.io.InputStream.
* JDBC will read the data from the stream as needed, until it reaches
* end-of-file. The JDBC driver will do any necessary conversion from
* UNICODE to the database char format.
*
* <P>Note: This stream object can either be a standard Java
* stream object or your own subclass that implements the standard
* interface.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception java.sql.SQLException if a database access error occurs
*/
public void setUnicodeStream(int parameterIndex, InputStream X, int length) throws java.sql.SQLException
{
if (X == null) {
setNull(parameterIndex, java.sql.Types.VARCHAR);
}
else {
setBinaryStream(parameterIndex, X, length);
}
}
/**
* When a very large binary value is input to a LONGVARBINARY parameter,
* it may be more practical to send it via a java.io.InputStream.
* JDBC will read the data from the stream as needed, until it reaches
* end-of-file.
*
* <P>Note: This stream object can either be a standard Java
* stream object or your own subclass that implements the standard
* interface.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception java.sql.SQLException if a database access error occurs
*/
public void setBinaryStream(int parameterIndex, InputStream X, int length) throws java.sql.SQLException
{
if (X == null) {
setNull(parameterIndex, java.sql.Types.BINARY);
}
else {
if (parameterIndex < 1 ||
parameterIndex > _TemplateStrings.length) {
throw new java.sql.SQLException("Parameter index out of range (" + parameterIndex + " > " + _TemplateStrings.length + ")", "S1009");
}
_ParameterStreams[parameterIndex - 1] = X;
_IsStream[parameterIndex - 1] = true;
}
}
/**
* In general, parameter values remain in force for repeated used of a
* Statement. Setting a parameter value automatically clears its
* previous value. However, in coms cases, it is useful to immediately
* release the resources used by the current parameter values; this
* can be done by calling clearParameters
*
* @exception java.sql.SQLException if a database access error occurs
*/
public void clearParameters() throws java.sql.SQLException
{
for (int i = 0 ; i < _ParameterStrings.length ; i++) {
_ParameterStrings[i] = null;
_ParameterStreams[i] = null;
_IsStream[i] = false;
}
}
/**
* Set the value of a parameter using an object; use the java.lang
* equivalent objects for integral values.
*
* <P>The given Java object will be converted to the targetSqlType before
* being sent to the database.
*
* <P>note that this method may be used to pass database-specific
* abstract data types. This is done by using a Driver-specific
* Java type and using a targetSqlType of java.sql.Types.OTHER
*
* @param parameterIndex the first parameter is 1...
* @param x the object containing the input parameter value
* @param targetSqlType The SQL type to be send to the database
* @param scale For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC
* types this is the number of digits after the decimal. For
* all other types this value will be ignored.
* @exception java.sql.SQLException if a database access error occurs
*/
public void setObject(int parameterIndex, Object X, int targetSqlType, int scale) throws java.sql.SQLException
{
if (X == null) {
setNull(parameterIndex, java.sql.Types.OTHER);
}
else try {
switch (targetSqlType)
{
case Types.TINYINT:
case Types.SMALLINT:
case Types.INTEGER:
case Types.BIGINT:
case Types.REAL:
case Types.FLOAT:
case Types.DOUBLE:
case Types.DECIMAL:
case Types.NUMERIC:
Number X_as_number;
if (X instanceof Boolean)
X_as_number=((Boolean)X).booleanValue() ? new Integer(1) : new Integer(0);
else if (X instanceof String)
switch (targetSqlType) {
case Types.TINYINT:
case Types.SMALLINT:
case Types.INTEGER:
X_as_number=Integer.valueOf((String)X);
break;
case Types.BIGINT:
X_as_number=Long.valueOf((String)X);
break;
case Types.REAL:
X_as_number=Float.valueOf((String)X);
break;
case Types.FLOAT:
case Types.DOUBLE:
X_as_number=Double.valueOf((String)X);
break;
case Types.DECIMAL:
case Types.NUMERIC:
default:
X_as_number=new java.math.BigDecimal((String)X);
}
else
X_as_number=(Number)X;
switch (targetSqlType) {
case Types.TINYINT:
case Types.SMALLINT:
case Types.INTEGER:
setInt(parameterIndex, X_as_number.intValue());
break;
case Types.BIGINT:
setLong(parameterIndex, X_as_number.longValue());
break;
case Types.REAL:
setFloat(parameterIndex, X_as_number.floatValue());
break;
case Types.FLOAT:
case Types.DOUBLE:
setDouble(parameterIndex, X_as_number.doubleValue());
break;
case Types.DECIMAL:
case Types.NUMERIC:
default:
if (X_as_number instanceof java.math.BigDecimal)
setBigDecimal(parameterIndex, (java.math.BigDecimal)X_as_number);
else if (X_as_number instanceof java.math.BigInteger)
setBigDecimal(parameterIndex, new java.math.BigDecimal((java.math.BigInteger)X_as_number,scale));
else
setBigDecimal(parameterIndex, new java.math.BigDecimal(X_as_number.doubleValue()));
break;
}
break;
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGVARCHAR:
setString(parameterIndex, X.toString());
break;
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
if (X instanceof String)
setBytes(parameterIndex, ((String)X).getBytes());
else
setBytes(parameterIndex, (byte[])X);
break;
case Types.DATE:
case Types.TIMESTAMP:
java.util.Date X_as_date;
if (X instanceof String) {
ParsePosition pp=new ParsePosition(0);
java.text.DateFormat sdf=new java.text.SimpleDateFormat(getDateTimePattern((String)X,false));
X_as_date=sdf.parse((String)X,pp);
} else
X_as_date=(java.util.Date)X;
switch(targetSqlType) {
case Types.DATE:
if (X_as_date instanceof java.sql.Date)
setDate(parameterIndex,(java.sql.Date)X_as_date);
else
setDate(parameterIndex,new java.sql.Date(X_as_date.getTime()));
break;
case Types.TIMESTAMP:
if (X_as_date instanceof java.sql.Timestamp)
setTimestamp(parameterIndex,(java.sql.Timestamp)X_as_date);
else
setTimestamp(parameterIndex,new java.sql.Timestamp(X_as_date.getTime()));
break;
}
break;
case Types.TIME:
if (X instanceof String) {
java.text.DateFormat sdf=new java.text.SimpleDateFormat(getDateTimePattern((String)X,true));
setTime(parameterIndex,new java.sql.Time(sdf.parse((String)X).getTime()));
} else
setTime(parameterIndex,(java.sql.Time)X);
break;
case Types.OTHER:
try {
ByteArrayOutputStream BytesOut = new ByteArrayOutputStream();
ObjectOutputStream ObjectOut = new ObjectOutputStream(BytesOut);
ObjectOut.writeObject(X);
ObjectOut.flush();
ObjectOut.close();
BytesOut.flush();
BytesOut.close();
byte[] buf = BytesOut.toByteArray();
ByteArrayInputStream BytesIn = new ByteArrayInputStream(buf);
setBinaryStream(parameterIndex, BytesIn, -1);
}
catch (Exception E) {
throw new java.sql.SQLException("Invalid argument value: " + E.getClass().getName(), "S1009");
}
break;
default:
throw new java.sql.SQLException("Unknown Types value", "S1000");
}
} catch (Exception ex) {
if (ex instanceof java.sql.SQLException) throw (java.sql.SQLException)ex;
else throw new java.sql.SQLException("Cannot convert "+X.getClass().toString()+" to SQL type requested", "S1000");
}
}
public void setObject(int parameterIndex, Object X, int targetSqlType) throws java.sql.SQLException
{
setObject(parameterIndex, X, targetSqlType, 0);
}
public void setObject(int parameterIndex, Object X) throws java.sql.SQLException
{
if (X == null) {
setNull(parameterIndex, java.sql.Types.OTHER);
}
else {
if (X instanceof String)
setString(parameterIndex, (String)X);
else if (X instanceof BigDecimal)
setBigDecimal(parameterIndex, (BigDecimal)X);
else if (X instanceof Integer)
setInt(parameterIndex, ((Integer)X).intValue());
else if (X instanceof Long)
setLong(parameterIndex, ((Long)X).longValue());
else if (X instanceof Float)
setFloat(parameterIndex, ((Float)X).floatValue());
else if (X instanceof Double)
setDouble(parameterIndex, ((Double)X).doubleValue());
else if (X instanceof byte[])
setBytes(parameterIndex, (byte[])X);
else if (X instanceof java.sql.Date)
setDate(parameterIndex, (java.sql.Date)X);
else if (X instanceof Time)
setTime(parameterIndex, (Time)X);
else if (X instanceof Timestamp)
setTimestamp(parameterIndex, (Timestamp)X);
else if (X instanceof Boolean)
setBoolean(parameterIndex, ((Boolean)X).booleanValue());
else {
try {
ByteArrayOutputStream BytesOut = new ByteArrayOutputStream();
ObjectOutputStream ObjectOut = new ObjectOutputStream(BytesOut);
ObjectOut.writeObject(X);
ObjectOut.flush();
ObjectOut.close();
BytesOut.flush();
BytesOut.close();
byte[] buf = BytesOut.toByteArray();
ByteArrayInputStream BytesIn = new ByteArrayInputStream(buf);
setBinaryStream(parameterIndex, BytesIn, -1);
}
catch (Exception E) {
throw new java.sql.SQLException("Invalid argument value: " + E.getClass().getName(), "S1009");
}
}
}
}
/**
* Some prepared statements return multiple results; the execute method
* handles these complex statements as well as the simpler form of
* statements handled by executeQuery and executeUpdate
*
* @return true if the next result is a ResultSet; false if it is an
* update count or there are no more results
* @exception java.sql.SQLException if a database access error occurs
*/
public boolean execute() throws java.sql.SQLException
{
boolean do_escape_processing = _escapeProcessing;
_escapeProcessing = false;
Buffer Packet = new Buffer(MysqlIO.getMaxBuf());
Packet.writeByte((byte)MysqlDefs.QUERY);
String Encoding = null;
if (_Conn.useUnicode()) {
Encoding = _Conn.getEncoding();
}
try {
for (int i = 0 ; i < _ParameterStrings.length ; ++i) {
if (_ParameterStrings[i] == null &&
(_IsStream[i] && _ParameterStreams[i] == null)) {
throw new java.sql.SQLException("No value specified for parameter " + (i + 1));
}
if (Encoding != null) {
Packet.writeStringNoNull(_TemplateStrings[i], Encoding);
}
else {
Packet.writeStringNoNull(_TemplateStrings[i]);
}
if (_IsStream[i]) {
Packet.writeBytesNoNull(streamToBytes(_ParameterStreams[i]));
}
else {
if (do_escape_processing) {
_ParameterStrings[i] = _Escaper.escapeSQL(_ParameterStrings[i]);
}
if (Encoding != null) {
Packet.writeStringNoNull(_ParameterStrings[i], Encoding);
}
else {
Packet.writeStringNoNull(_ParameterStrings[i]);
}
}
}
if (Encoding != null) {
Packet.writeStringNoNull(_TemplateStrings[_ParameterStrings.length], Encoding);
}
else {
Packet.writeStringNoNull(_TemplateStrings[_ParameterStrings.length]);
}
}
catch (java.io.UnsupportedEncodingException UE) {
throw new SQLException("Unsupported character encoding '" + Encoding + "'");
}
ResultSet RS = null;
synchronized (_Conn.getMutex()) {
String OldCatalog = null;
if (!_Conn.getCatalog().equals(_Catalog)) {
OldCatalog = _Conn.getCatalog();
_Conn.setCatalog(_Catalog);
}
// 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).
if (_Conn.useMaxRows()) {
if (_has_limit_clause) {
RS = _Conn.execSQL(null, _max_rows, Packet);
}
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);
}
RS = _Conn.execSQL(null, -1, Packet);
}
}
else {
RS = _Conn.execSQL(null, -1, Packet);
}
if (OldCatalog != null) {
_Conn.setCatalog(OldCatalog);
}
}
_last_insert_id = RS.getUpdateID();
if (RS != null) {
_Results = RS;
}
_escapeProcessing = do_escape_processing;
RS.setConnection(_Conn);
return (RS != null && RS.reallyResult());
}
public String toString()
{
String Encoding = null;
if (_Conn.useUnicode()) {
Encoding = _Conn.getEncoding();
}
StringBuffer SB = new StringBuffer();
SB.append(super.toString());
SB.append(": ");
try {
for (int i = 0 ; i < _ParameterStrings.length ; ++i) {
if (Encoding != null) {
SB.append(new String(_TemplateStrings[i].getBytes(), Encoding));
}
else {
SB.append(_TemplateStrings[i]);
}
if (_ParameterStrings[i] == null &&
(_IsStream[i] && _ParameterStreams[i] == null)) {
SB.append("** NOT SPECIFIED **");
}
else if (_IsStream[i]) {
SB.append("** STREAM DATA **");
}
else {
if (_escapeProcessing) {
try {
_ParameterStrings[i] = _Escaper.escapeSQL(_ParameterStrings[i]);
}
catch (SQLException SQE) {}
}
if (Encoding != null) {
SB.append(new String(_ParameterStrings[i].getBytes(), Encoding));
}
else {
SB.append(_ParameterStrings[i]);
}
}
}
if (Encoding != null) {
SB.append(new String(_TemplateStrings[_ParameterStrings.length].getBytes(), Encoding));
}
else {
SB.append(_TemplateStrings[_ParameterStrings.length]);
}
}
catch (java.io.UnsupportedEncodingException UE) {
SB.append("\n\n** WARNING **\n\n Unsupported character encoding '");
SB.append(Encoding);
SB.append("'");
}
return SB.toString();
}
/**
* There are a lot of setXXX classes which all basically do
* the same thing. We need a method which actually does the
* set for us.
*
* @param paramIndex the index into the inString
* @param s a string to be stored
* @exception java.sql.SQLException if something goes wrong
*/
private final void set(int paramIndex, String S) throws java.sql.SQLException
{
if (paramIndex < 1 || paramIndex > _TemplateStrings.length) {
throw new java.sql.SQLException("Parameter index out of range (" + paramIndex + " > " + _TemplateStrings.length + ").", "S1009");
}
_ParameterStrings[paramIndex - 1] = S;
}
private final int readblock(InputStream i,byte[] b) throws java.sql.SQLException
{
try {
return i.read(b);
}
catch (Throwable E) {
throw new java.sql.SQLException("Error reading from InputStream " +
E.getClass().getName(), "S1000");
}
}
private final void escapeblock(byte[] buf,ByteArrayOutputStream BytesOut,int
size)
{
int c =0;
for (int i=0;i<size;i++) {
byte b = buf[i];
if (b == '\0') {
BytesOut.write('\\');
BytesOut.write('0');
}
else {
if (b == '\\' || b == '\'' || b == '"') {
BytesOut.write('\\');
}
BytesOut.write(b);
}
}
}
/**
* For the setXXXStream() methods. Basically converts an
* InputStream into a String. Not very efficient, but it
* works.
*
*/
private final byte[] streamToBytes(InputStream In) throws java.sql.SQLException
{
byte[] bi=new byte[128*1024];
ByteArrayOutputStream BytesOut = new ByteArrayOutputStream();
int bc = readblock(In,bi);
BytesOut.write('\'');
while (bc > 0) {
escapeblock(bi,BytesOut,bc);
bc = readblock(In,bi);
}
BytesOut.write('\'');
return BytesOut.toByteArray();
}
private final char getSuccessor(char c,int n)
{
return (c=='y' && n==2) ? 'X' : //ym
((c=='y' && n<4) ? 'y' :
((c=='y') ? 'M' :
((c=='M' && n==2) ? 'Y' : //Md
((c=='M' && n<3) ? 'M' :
((c=='M') ? 'd' :
((c=='d' && n<2) ? 'd' :
((c=='d') ? 'h' :
((c=='h' && n<2) ? 'h' :
((c=='h') ? 'm' :
((c=='m' && n<2) ? 'm' :
((c=='m') ? 's' :
((c=='s' && n<2) ? 's' : 'W' ))))))))))));
}
private final String getDateTimePattern(String dt,boolean toTime) throws Exception
{
int n,z,count,maxvecs;
char c,separator;
StringReader reader=new StringReader(dt+" ");
Vector vec=new Vector();
Vector vec_removelist=new Vector();
Object[] nv=new Object[3];
Object[] v;
nv[0]=new Character('y');
nv[1]=new StringBuffer();
nv[2]=new Integer(0);
vec.addElement(nv);
if (toTime) {
nv=new Object[3];
nv[0]=new Character('h');
nv[1]=new StringBuffer();
nv[2]=new Integer(0);
vec.addElement(nv);
}
while ((z=reader.read())!=-1) {
separator=(char)z;
maxvecs=vec.size();
for(count=0;count<maxvecs;count++) {
v=(Object [])vec.elementAt(count);
n=((Integer)v[2]).intValue();
c = getSuccessor(((Character)v[0]).charValue(),n);
if (!Character.isLetterOrDigit(separator)) {
if ((c==((Character)v[0]).charValue())&&(c!='S'))
vec_removelist.addElement(v);
else {
((StringBuffer)v[1]).append(separator);
if (c=='X' || c=='Y')
v[2]=new Integer(4);
}
} else {
if (c=='X') {
c='y';
nv=new Object[3];
nv[1]=(new StringBuffer(((StringBuffer)v[1]).toString())).append('M');
nv[0]=new Character('M');
nv[2]=new Integer(1);
vec.addElement(nv);
} else if (c=='Y') {
c='M';
nv=new Object[3];
nv[1]=(new StringBuffer(((StringBuffer)v[1]).toString())).append('d');
nv[0]=new Character('d');
nv[2]=new Integer(1);
vec.addElement(nv);
}
((StringBuffer)v[1]).append(c);
if (c==((Character)v[0]).charValue())
v[2]=new Integer(n+1);
else {
v[0]=new Character(c);
v[2]=new Integer(1);
}
}
}
for(Enumeration en=vec_removelist.elements();
en.hasMoreElements();) {
v=(Object [])en.nextElement();
vec.removeElement(v);
}
vec_removelist.removeAllElements();
}
for(Enumeration en=vec.elements();en.hasMoreElements();) {
v=(Object [])en.nextElement();
c=((Character)v[0]).charValue();
n=((Integer)v[2]).intValue();
boolean bk=getSuccessor(c,n)!=c;
boolean atEnd=((c=='s'||c=='m'||(c=='h' && toTime))&&bk);
boolean finishesAtDate=(bk&&(c=='d')&& !toTime);
boolean containsEnd=(((StringBuffer)v[1]).toString().indexOf('W')!=-1);
if ((!atEnd && !finishesAtDate) || (containsEnd)) {
vec_removelist.addElement(v);
}
}
for(Enumeration en=vec_removelist.elements();en.hasMoreElements();)
vec.removeElement(en.nextElement());
vec_removelist.removeAllElements();
v=(Object [])vec.firstElement(); //might throw exception
StringBuffer format=((StringBuffer)v[1]);
format.setLength(format.length()-1);
return format.toString();
}
/**
* Formatter for double - Steve Ferguson
*/
private static NumberFormat _DoubleFormatter;
// Class Initializer
static {
_DoubleFormatter =
NumberFormat.getNumberInstance(java.util.Locale.US);
_DoubleFormatter.setGroupingUsed(false);
// attempt to prevent truncation
_DoubleFormatter.setMaximumFractionDigits(8);
}
};
|
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.