|
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.