001: /*
002: * PreparedStatement object for the tinySQL driver
003: *
004: * A lot of this code is based on or directly taken from
005: * George Reese's (borg@imaginary.com) mSQL driver.
006: *
007: * So, it's probably safe to say:
008: *
009: * Portions of this code Copyright (c) 1996 George Reese
010: *
011: * The rest of it:
012: *
013: * Copyright 1996, Brian C. Jepson
014: * (bjepson@ids.net)
015: *
016: * $Author: davis $
017: * $Date: 2004/12/18 21:31:53 $
018: * $Revision: 1.1 $
019: *
020: * This library is free software; you can redistribute it and/or
021: * modify it under the terms of the GNU Lesser General Public
022: * License as published by the Free Software Foundation; either
023: * version 2.1 of the License, or (at your option) any later version.
024: *
025: * This library is distributed in the hope that it will be useful,
026: * but WITHOUT ANY WARRANTY; without even the implied warranty of
027: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
028: * Lesser General Public License for more details.
029: *
030: * You should have received a copy of the GNU Lesser General Public
031: * License along with this library; if not, write to the Free Software
032: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
033: *
034: */
035:
036: package com.sqlmagic.tinysql;
037:
038: import java.sql.SQLException;
039: import java.sql.SQLWarning;
040: import java.sql.ResultSet;
041: import java.sql.Connection;
042: import java.sql.ResultSetMetaData;
043: import java.sql.Date;
044: import java.util.*;
045: import java.math.*;
046:
047: /**
048: * @author Thomas Morgner <mgs@sherito.org> statementString contains the last
049: * used SQL-Query. Support for set/getFetchSize, ResultSets are created with a
050: * reference to the creating statement
051: */
052: public class tinySQLPreparedStatement implements
053: java.sql.PreparedStatement {
054:
055: /**
056: * Holds the original prepare stement including ? placeholders for
057: * values that will be replaced later.
058: */
059: private String statementString;
060: /**
061: * Holds the list of substitution values to be used in the prepared
062: * statement.
063: */
064: private Vector substitute = (Vector) null;
065: /**
066: * Holds the list of table file objects so that they can be closed
067: * when all the updates have been completed.
068: */
069: private Vector tableList = new Vector();
070: /**
071: * Holds the error message for invalid substitution index.
072: */
073: private String invalidIndex = (String) null;
074: /**
075: * Holds the last used queryString. execute() has to be synchronized,
076: * to guarantee thread-safety
077: */
078: /**
079: *
080: * A connection object to execute queries and... stuff
081: *
082: */
083: private tinySQLConnection connection;
084:
085: /**
086: *
087: * A result set returned from this query
088: *
089: */
090: private tinySQLResultSet result;
091: /**
092: *
093: * A set of actions returned by tinySQLParser (see tinySQL.java)
094: *
095: */
096: private Vector actions = (Vector) null;
097:
098: /**
099: *
100: * The max field size for tinySQL
101: * This can be pretty big, before things start to break.
102: *
103: */
104: private int max_field_size = 0;
105:
106: /**
107: *
108: * The max rows supported by tinySQL
109: * I can't think of any limits, right now, but I'm sure some
110: * will crop up...
111: *
112: */
113: private int max_rows = 65536;
114:
115: /**
116: *
117: * The number of seconds the driver will allow for a SQL statement to
118: * execute before giving up. The default is to wait forever (0).
119: *
120: */
121: private int timeout = 0;
122:
123: /**
124: * How many rows to fetch in a single run. Default is now 4096 rows.
125: */
126: private int fetchsize = 4096;
127: /**
128: * Debug flag
129: */
130: private static boolean debug = false;
131:
132: /**
133: *
134: * Constructs a new tinySQLStatement object.
135: * @param conn the tinySQLConnection object
136: *
137: */
138: public tinySQLPreparedStatement(tinySQLConnection conn,
139: String inputString) {
140:
141: int nextQuestionMark, startAt;
142: connection = conn;
143: startAt = 0;
144: statementString = inputString;
145: while ((nextQuestionMark = statementString
146: .indexOf("?", startAt)) > -1) {
147: if (substitute == (Vector) null)
148: substitute = new Vector();
149: substitute.addElement(new String(""));
150: startAt = nextQuestionMark + 1;
151: }
152: invalidIndex = " is not in the range 1 to "
153: + Integer.toString(substitute.size());
154: if (debug)
155: System.out.println("Prepare statement has "
156: + substitute.size() + " parameters.");
157:
158: }
159:
160: /**
161: *
162: * Execute an SQL statement and return a result set.
163: * @see java.sql.PreparedStatement#executeQuery
164: * @exception SQLException raised for any errors
165: * @param sql the SQL statement string
166: * @return the result set from the query
167: *
168: */
169: public synchronized ResultSet executeQuery() throws SQLException {
170:
171: // tinySQL only supports one result set at a time, so
172: // don't let them get another one, just in case it's
173: // hanging out.
174: //
175: result = null;
176:
177: // create a new tinySQLResultSet with the tsResultSet
178: // returned from connection.executetinySQL()
179: //
180: if (debug)
181: System.out.println("executeQuery conn is "
182: + connection.toString());
183: return new tinySQLResultSet(connection.executetinySQL(this ),
184: this );
185:
186: }
187:
188: public synchronized ResultSet executeQuery(String sql)
189: throws SQLException {
190:
191: // tinySQL only supports one result set at a time, so
192: // don't let them get another one, just in case it's
193: // hanging out.
194: //
195: result = null;
196: statementString = sql;
197:
198: // create a new tinySQLResultSet with the tsResultSet
199: // returned from connection.executetinySQL()
200: //
201: if (debug)
202: System.out.println("executeQuery conn is "
203: + connection.toString());
204: return new tinySQLResultSet(connection.executetinySQL(this ),
205: this );
206:
207: }
208:
209: /**
210: *
211: * Execute an update, insert, delete, create table, etc. This can
212: * be anything that doesn't return rows.
213: * @see java.sql.PreparedStatement#executeUpdate
214: * @exception java.sql.SQLException thrown when an error occurs executing
215: * the SQL
216: * @return either the row count for INSERT, UPDATE or DELETE or 0 for SQL statements that return nothing
217: */
218: public synchronized int executeUpdate(String sql)
219: throws SQLException {
220:
221: statementString = sql;
222: return connection.executetinyUpdate(this );
223:
224: }
225:
226: public synchronized int executeUpdate() throws SQLException {
227:
228: return connection.executetinyUpdate(this );
229:
230: }
231:
232: /**
233: *
234: * Executes some SQL and returns true or false, depending on
235: * the success. The result set is stored in result, and can
236: * be retrieved with getResultSet();
237: * @see java.sql.PreparedStatement#execute
238: * @exception SQLException raised for any errors
239: * @param sql the SQL to be executed
240: * @return true if there is a result set available
241: */
242: public boolean execute() throws SQLException {
243:
244: // a result set object
245: //
246: tsResultSet r;
247:
248: // execute the query
249: //
250: r = connection.executetinySQL(this );
251:
252: // check for a null result set. If it wasn't null,
253: // use it to create a tinySQLResultSet, and return whether or
254: // not it is null (not null returns true).
255: //
256: if (r == null) {
257: result = null;
258: } else {
259: result = new tinySQLResultSet(r, this );
260: }
261: return (result != null);
262:
263: }
264:
265: public boolean execute(String sql) throws SQLException {
266:
267: // a result set object
268: //
269: tsResultSet r;
270: statementString = sql;
271:
272: // execute the query
273: //
274: r = connection.executetinySQL(this );
275:
276: // check for a null result set. If it wasn't null,
277: // use it to create a tinySQLResultSet, and return whether or
278: // not it is null (not null returns true).
279: //
280: if (r == null) {
281: result = null;
282: } else {
283: result = new tinySQLResultSet(r, this );
284: }
285: return (result != null);
286:
287: }
288:
289: /**
290: * Returns the current query-String
291: */
292: public String getSQLString() {
293: return statementString;
294: }
295:
296: /**
297: *
298: * Close any result sets. This is not used by tinySQL.
299: * @see java.sql.PreparedStatement#close
300: *
301: */
302: public void close() throws SQLException {
303: int i;
304: tinySQLTable nextTable;
305: for (i = 0; i < tableList.size(); i++) {
306: nextTable = (tinySQLTable) tableList.elementAt(i);
307: if (debug)
308: System.out.println("Closing " + nextTable.table);
309: nextTable.close();
310: }
311: }
312:
313: /**
314: *
315: * Returns the last result set
316: * @see java.sql.PreparedStatement#getResultSet
317: * @return null if no result set is available, otherwise a result set
318: *
319: */
320: public ResultSet getResultSet() throws SQLException {
321:
322: ResultSet r;
323:
324: r = result; // save the existing result set
325: result = null; // null out the existing result set
326: return r; // return the previously extant result set
327: }
328:
329: /**
330: *
331: * Return the row count of the last operation. tinySQL does not support
332: * this, so it returns -1
333: * @see java.sql.PreparedStatement#getUpdateCount
334: * @return -1
335: */
336: public int getUpdateCount() throws SQLException {
337: return -1;
338: }
339:
340: /**
341: *
342: * This returns true if there are any pending result sets. This
343: * should only be true after invoking execute()
344: * @see java.sql.PreparedStatement#getMoreResults
345: * @return true if rows are to be gotten
346: *
347: */
348: public boolean getMoreResults() throws SQLException {
349:
350: return (result != null);
351:
352: }
353:
354: /**
355: *
356: * Get the maximum field size to return in a result set.
357: * @see java.sql.PreparedStatement#getMaxFieldSize
358: * @return the value of max field size
359: *
360: */
361: public int getMaxFieldSize() throws SQLException {
362: return max_field_size;
363: }
364:
365: /**
366: *
367: * set the max field size.
368: * @see java.sql.PreparedStatement#setMaxFieldSize
369: * @param max the maximum field size
370: *
371: */
372: public void setMaxFieldSize(int max) throws SQLException {
373: max_field_size = max;
374: }
375:
376: /**
377: *
378: * Get the maximum row count that can be returned by a result set.
379: * @see java.sql.PreparedStatement#getMaxRows
380: * @return the maximum rows
381: *
382: */
383: public int getMaxRows() throws SQLException {
384: return max_rows;
385: }
386:
387: /**
388: *
389: * Get the maximum row count that can be returned by a result set.
390: * @see java.sql.PreparedStatement.setMaxRows
391: * @param max the max rows
392: *
393: */
394: public void setMaxRows(int max) throws SQLException {
395: max_rows = max;
396: }
397:
398: /**
399: *
400: * If escape scanning is on (the default) the driver will do
401: * escape substitution before sending the SQL to the database.
402: * @see java.sql.PreparedStatement#setEscapeProcessing
403: * @param enable this does nothing right now
404: *
405: */
406: public void setEscapeProcessing(boolean enable) throws SQLException {
407: throw new SQLException("The tinySQL Driver doesn't "
408: + "support escape processing.");
409: }
410:
411: /**
412: *
413: * Discover the query timeout.
414: * @see java.sql.PreparedStatement#getQueryTimeout
415: * @see setQueryTimeout
416: * @return the timeout value for this statement
417: *
418: */
419: public int getQueryTimeout() throws SQLException {
420: return timeout;
421: }
422:
423: /**
424: *
425: * Set the query timeout.
426: * @see java.sql.PreparedStatement#setQueryTimeout
427: * @see getQueryTimeout
428: * @param x the new query timeout value
429: *
430: */
431: public void setQueryTimeout(int x) throws SQLException {
432: timeout = x;
433: }
434:
435: /**
436: *
437: * This can be used by another thread to cancel a statement. This
438: * doesn't matter for tinySQL, as far as I can tell.
439: * @see java.sql.PreparedStatement#cancel
440: *
441: */
442: public void cancel() {
443: }
444:
445: /**
446: *
447: * Get the warning chain associated with this Statement
448: * @see java.sql.PreparedStatement#getWarnings
449: * @return the chain of warnings
450: *
451: */
452: public final SQLWarning getWarnings() throws SQLException {
453: return null;
454: }
455:
456: /**
457: *
458: * Clear the warning chain associated with this Statement
459: * @see java.sql.PreparedStatement#clearWarnings
460: *
461: */
462: public void clearWarnings() throws SQLException {
463: }
464:
465: /**
466: *
467: * Sets the cursor name for this connection. Presently unsupported.
468: *
469: */
470: public void setCursorName(String unused) throws SQLException {
471: throw new SQLException("tinySQL does not support cursors.");
472: }
473:
474: //--------------------------JDBC 2.0-----------------------------
475:
476: /**
477: * JDBC 2.0
478: *
479: * Gives the driver a hint as to the direction in which
480: * the rows in a result set
481: * will be processed. The hint applies only to result sets created
482: * using this Statement object. The default value is
483: * ResultSet.FETCH_FORWARD.
484: * <p>Note that this method sets the default fetch direction for
485: * result sets generated by this <code>Statement</code> object.
486: * Each result set has its own methods for getting and setting
487: * its own fetch direction.
488: * @param direction the initial direction for processing rows
489: * @exception SQLException if a database access error occurs
490: * or the given direction
491: * is not one of ResultSet.FETCH_FORWARD, ResultSet.FETCH_REVERSE, or
492: * ResultSet.FETCH_UNKNOWN
493: */
494: public void setFetchDirection(int direction) throws SQLException {
495: throw new SQLException(
496: "tinySQL does not support setFetchDirection.");
497: }
498:
499: /**
500: * JDBC 2.0
501: *
502: * Retrieves the direction for fetching rows from
503: * database tables that is the default for result sets
504: * generated from this <code>Statement</code> object.
505: * If this <code>Statement</code> object has not set
506: * a fetch direction by calling the method <code>setFetchDirection</code>,
507: * the return value is implementation-specific.
508: *
509: * @return the default fetch direction for result sets generated
510: * from this <code>Statement</code> object
511: * @exception SQLException if a database access error occurs
512: */
513: public int getFetchDirection() throws SQLException {
514: throw new SQLException(
515: "tinySQL does not support getFetchDirection.");
516: }
517:
518: /**
519: * JDBC 2.0
520: *
521: * Gives the JDBC driver a hint as to the number of rows that should
522: * be fetched from the database when more rows are needed. The number
523: * of rows specified affects only result sets created using this
524: * statement. If the value specified is zero, then the hint is ignored.
525: * The default value is zero.
526: *
527: * @param rows the number of rows to fetch
528: * @exception SQLException if a database access error occurs, or the
529: * condition 0 <= rows <= this.getMaxRows() is not satisfied.
530: */
531: public void setFetchSize(int rows) throws SQLException {
532: if ((rows <= 0) || (rows >= this .getMaxRows()))
533: throw new SQLException(
534: "Condition 0 <= rows <= this.getMaxRows() is not satisfied");
535:
536: fetchsize = rows;
537: }
538:
539: /**
540: * JDBC 2.0
541: *
542: * Retrieves the number of result set rows that is the default
543: * fetch size for result sets
544: * generated from this <code>Statement</code> object.
545: * If this <code>Statement</code> object has not set
546: * a fetch size by calling the method <code>setFetchSize</code>,
547: * the return value is implementation-specific.
548: * @return the default fetch size for result sets generated
549: * from this <code>Statement</code> object
550: * @exception SQLException if a database access error occurs
551: */
552: public int getFetchSize() throws SQLException {
553: return fetchsize;
554: }
555:
556: /**
557: * JDBC 2.0
558: *
559: * Retrieves the result set concurrency.
560: */
561: public int getResultSetConcurrency() throws SQLException {
562: throw new SQLException(
563: "tinySQL does not support ResultSet concurrency.");
564: }
565:
566: /**
567: * JDBC 2.0
568: *
569: * Determine the result set type.
570: */
571: public int getResultSetType() throws SQLException {
572: throw new SQLException(
573: "tinySQL does not support getResultSetType.");
574: }
575:
576: /**
577: * JDBC 2.0
578: *
579: * Adds a SQL command to the current batch of commmands for the statement.
580: * This method is optional.
581: *
582: * @param sql typically this is a static SQL INSERT or UPDATE statement
583: * @exception SQLException if a database access error occurs, or the
584: * driver does not support batch statements
585: */
586: public void addBatch() throws SQLException {
587: throw new SQLException("tinySQL does not support addBatch.");
588: }
589:
590: public void addBatch(String sql) throws SQLException {
591: throw new SQLException("tinySQL does not support addBatch.");
592: }
593:
594: /**
595: * JDBC 2.0
596: *
597: * Makes the set of commands in the current batch empty.
598: * This method is optional.
599: *
600: * @exception SQLException if a database access error occurs or the
601: * driver does not support batch statements
602: */
603: public void clearBatch() throws SQLException {
604: throw new SQLException("tinySQL does not support clearBatch.");
605: }
606:
607: /**
608: * JDBC 2.0
609: *
610: * Submits a batch of commands to the database for execution.
611: * This method is optional.
612: *
613: * @return an array of update counts containing one element for each
614: * command in the batch. The array is ordered according
615: * to the order in which commands were inserted into the batch.
616: * @exception SQLException if a database access error occurs or the
617: * driver does not support batch statements
618: */
619: public int[] executeBatch() throws SQLException {
620: throw new SQLException("tinySQL does not support executeBatch.");
621: }
622:
623: /**
624: * JDBC 2.0
625: *
626: * Returns the <code>Connection</code> object
627: * that produced this <code>Statement</code> object.
628: * @return the connection that produced this statement
629: * @exception SQLException if a database access error occurs
630: */
631: public Connection getConnection() throws SQLException {
632: return connection;
633: }
634:
635: /*
636: * Set methods for the prepared statement.
637: */
638: public void setBoolean(int parameterIndex, boolean inputValue)
639: throws SQLException {
640: if (inputValue)
641: setString(parameterIndex, "TRUE");
642: else
643: setString(parameterIndex, "FALSE");
644: }
645:
646: public void setInt(int parameterIndex, int inputValue)
647: throws SQLException {
648: setString(parameterIndex, Integer.toString(inputValue));
649: }
650:
651: public void setDouble(int parameterIndex, double inputValue)
652: throws SQLException {
653: setString(parameterIndex, Double.toString(inputValue));
654: }
655:
656: public void setBigDecimal(int parameterIndex, BigDecimal inputValue)
657: throws SQLException {
658: setString(parameterIndex, inputValue.toString());
659: }
660:
661: public void setDate(int parameterIndex, java.sql.Date inputValue,
662: java.util.Calendar inputCalendar) throws SQLException {
663: String dateString;
664: /*
665: * Convert string to YYYYMMDD format that dBase needs.
666: */
667: if (inputValue == (java.sql.Date) null) {
668: setString(parameterIndex, (String) null);
669: } else if (inputValue.toString().trim().length() < 8) {
670: setString(parameterIndex, (String) null);
671: } else {
672: dateString = inputValue.toString().trim();
673: /*
674: * Convert date string to the standard YYYYMMDD format
675: */
676: dateString = UtilString.dateValue(dateString);
677: setString(parameterIndex, dateString);
678: }
679: }
680:
681: public void setDate(int parameterIndex, java.sql.Date inputValue)
682: throws SQLException {
683: String dateString;
684: /*
685: * Convert string to YYYYMMDD format that dBase needs.
686: */
687: dateString = UtilString.dateValue(inputValue.toString());
688: setString(parameterIndex, dateString);
689: }
690:
691: public void setTime(int parameterIndex, java.sql.Time inputValue,
692: java.util.Calendar inputCalendar) throws SQLException {
693: setString(parameterIndex, inputValue.toString());
694: }
695:
696: public void setTime(int parameterIndex, java.sql.Time inputValue)
697: throws SQLException {
698: setString(parameterIndex, inputValue.toString());
699: }
700:
701: public void setTimestamp(int parameterIndex,
702: java.sql.Timestamp inputValue,
703: java.util.Calendar inputCalendar) throws SQLException {
704: setString(parameterIndex, inputValue.toString());
705: }
706:
707: public void setTimestamp(int parameterIndex,
708: java.sql.Timestamp inputValue) throws SQLException {
709: setString(parameterIndex, inputValue.toString());
710: }
711:
712: public void setAsciiStream(int parameterIndex,
713: java.io.InputStream inputValue, int streamLength)
714: throws SQLException {
715: setString(parameterIndex, inputValue.toString());
716: }
717:
718: public void setUnicodeStream(int parameterIndex,
719: java.io.InputStream inputValue, int streamLength)
720: throws SQLException {
721: setString(parameterIndex, inputValue.toString());
722: }
723:
724: public void setBinaryStream(int parameterIndex,
725: java.io.InputStream inputValue, int streamLength)
726: throws SQLException {
727: setString(parameterIndex, inputValue.toString());
728: }
729:
730: public void setCharacterStream(int parameterIndex,
731: java.io.Reader inputValue, int streamLength)
732: throws SQLException {
733: setString(parameterIndex, inputValue.toString());
734: }
735:
736: public void setRef(int parameterIndex, java.sql.Ref inputValue)
737: throws SQLException {
738: setString(parameterIndex, inputValue.toString());
739: }
740:
741: public void setBlob(int parameterIndex, java.sql.Blob inputValue)
742: throws SQLException {
743: setString(parameterIndex, inputValue.toString());
744: }
745:
746: public void setArray(int parameterIndex, java.sql.Array inputValue)
747: throws SQLException {
748: setString(parameterIndex, inputValue.toString());
749: }
750:
751: public void setClob(int parameterIndex, java.sql.Clob inputValue)
752: throws SQLException {
753: setString(parameterIndex, inputValue.toString());
754: }
755:
756: public void setByte(int parameterIndex, byte inputValue)
757: throws SQLException {
758: setString(parameterIndex, Byte.toString(inputValue));
759: }
760:
761: public void setBytes(int parameterIndex, byte[] inputValue)
762: throws SQLException {
763: setString(parameterIndex, Byte.toString(inputValue[0]));
764: }
765:
766: public void setShort(int parameterIndex, short inputValue)
767: throws SQLException {
768: setString(parameterIndex, Short.toString(inputValue));
769: }
770:
771: public void setFloat(int parameterIndex, float inputValue)
772: throws SQLException {
773: setString(parameterIndex, Float.toString(inputValue));
774: }
775:
776: public void setLong(int parameterIndex, long inputValue)
777: throws SQLException {
778: setString(parameterIndex, Long.toString(inputValue));
779: }
780:
781: public void setObject(int parameterIndex, Object inputValue)
782: throws SQLException {
783: setObject(parameterIndex, inputValue, 0, 0);
784: }
785:
786: public void setObject(int parameterIndex, Object inputValue,
787: int targetSQLType) throws SQLException {
788: setObject(parameterIndex, inputValue, targetSQLType, 0);
789: }
790:
791: public void setObject(int parameterIndex, Object inputValue,
792: int targetSQLType, int scale) throws SQLException {
793: setString(parameterIndex, inputValue.toString());
794: }
795:
796: public void setNull(int parameterIndex, int sqlType)
797: throws SQLException {
798: setNull(parameterIndex, sqlType, (String) null);
799: }
800:
801: public void setNull(int parameterIndex, int sqlType,
802: String sqlTypeName) throws SQLException {
803: if (parameterIndex > substitute.size())
804: throw new SQLException("Parameter index " + parameterIndex
805: + invalidIndex);
806: substitute.setElementAt((String) null, parameterIndex - 1);
807: }
808:
809: public void setString(int parameterIndex, String setString)
810: throws SQLException {
811: if (parameterIndex > substitute.size())
812: throw new SQLException("Parameter index " + parameterIndex
813: + invalidIndex);
814: substitute.setElementAt(setString, parameterIndex - 1);
815: }
816:
817: public void clearParameters() throws SQLException {
818: substitute.removeAllElements();
819: }
820:
821: /*
822: * Update the actions based upon the contents of the substitute Vector.
823: * Only INSERT and UPDATE commands are supported at this time.
824: */
825: public void updateActions(Vector inputActions) throws SQLException {
826: Vector values, originalValues;
827: Hashtable action;
828: String actionType, valueString;
829: int i, j, subCount;
830: if (actions == (Vector) null)
831: actions = inputActions;
832: if (actions == (Vector) null)
833: return;
834: for (i = 0; i < actions.size(); i++) {
835: action = (Hashtable) actions.elementAt(i);
836: actionType = (String) action.get("TYPE");
837: if (actionType.equals("INSERT")
838: | actionType.equals("UPDATE")) {
839: /*
840: * Look for the original values (with the ? for parameters).
841: */
842: originalValues = (Vector) action.get("ORIGINAL_VALUES");
843: values = (Vector) action.get("VALUES");
844: if (originalValues == (Vector) null) {
845: originalValues = (Vector) values.clone();
846: action.put("ORIGINAL_VALUES", originalValues);
847: }
848: subCount = 0;
849: for (j = 0; j < originalValues.size(); j++) {
850: valueString = (String) originalValues.elementAt(j);
851: if (valueString.equals("?")) {
852: if (subCount > substitute.size() - 1)
853: throw new SQLException(
854: "Substitution index "
855: + subCount
856: + " not between 0 and "
857: + Integer
858: .toString(substitute
859: .size() - 1));
860: values.setElementAt(substitute
861: .elementAt(subCount), j);
862: subCount++;
863: }
864: }
865: }
866: }
867: }
868:
869: public void addTable(tinySQLTable inputTable) {
870: int i;
871: tinySQLTable nextTable;
872: for (i = 0; i < tableList.size(); i++) {
873: nextTable = (tinySQLTable) tableList.elementAt(i);
874: if (nextTable.table.equals(inputTable.table))
875: return;
876: }
877: tableList.addElement(inputTable);
878: }
879:
880: public Vector getActions() {
881: return actions;
882: }
883:
884: public ResultSetMetaData getMetaData() {
885: return (ResultSetMetaData) null;
886: }
887:
888: }
|