001: /*
002: * tinySQLStatement
003: *
004: * Statement object for the tinySQL driver
005: *
006: * A lot of this code is based on or directly taken from
007: * George Reese's (borg@imaginary.com) mSQL driver.
008: *
009: * So, it's probably safe to say:
010: *
011: * Portions of this code Copyright (c) 1996 George Reese
012: *
013: * The rest of it:
014: *
015: * Copyright 1996, Brian C. Jepson
016: * (bjepson@ids.net)
017: * $Author: davis $
018: * $Date: 2004/12/18 21:28:47 $
019: * $Revision: 1.1 $
020: *
021: * This library is free software; you can redistribute it and/or
022: * modify it under the terms of the GNU Lesser General Public
023: * License as published by the Free Software Foundation; either
024: * version 2.1 of the License, or (at your option) any later version.
025: *
026: * This library is distributed in the hope that it will be useful,
027: * but WITHOUT ANY WARRANTY; without even the implied warranty of
028: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
029: * Lesser General Public License for more details.
030: *
031: * You should have received a copy of the GNU Lesser General Public
032: * License along with this library; if not, write to the Free Software
033: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
034: *
035: */
036:
037: package com.sqlmagic.tinysql;
038:
039: import java.sql.SQLException;
040: import java.sql.SQLWarning;
041: import java.sql.ResultSet;
042: import java.sql.Connection;
043:
044: /**
045: * @author Thomas Morgner <mgs@sherito.org> statementString contains the last
046: * used SQL-Query. Support for set/getFetchSize, ResultSets are created with a
047: * reference to the creating statement
048: */
049: public class tinySQLStatement implements java.sql.Statement {
050:
051: /**
052: * Holds the last used queryString. execute() has to be synchronized,
053: * to guarantee thread-safety
054: */
055: private String statementString;
056: /**
057: *
058: * A connection object to execute queries and... stuff
059: *
060: */
061: private tinySQLConnection connection;
062:
063: /**
064: *
065: * A result set returned from this query
066: *
067: */
068: private tinySQLResultSet result;
069:
070: /**
071: *
072: * The max field size for tinySQL
073: * This can be pretty big, before things start to break.
074: *
075: */
076: private int max_field_size = 0;
077:
078: /**
079: *
080: * The max rows supported by tinySQL
081: * I can't think of any limits, right now, but I'm sure some
082: * will crop up...
083: *
084: */
085: private int max_rows = 65536;
086:
087: /**
088: *
089: * The number of seconds the driver will allow for a SQL statement to
090: * execute before giving up. The default is to wait forever (0).
091: *
092: */
093: private int timeout = 0;
094:
095: /**
096: * How many rows to fetch in a single run. Default is now 4096 rows.
097: */
098: private int fetchsize = 4096;
099: /**
100: * Debug flag
101: */
102: private static boolean debug = false;
103:
104: /**
105: *
106: * Constructs a new tinySQLStatement object.
107: * @param conn the tinySQLConnection object
108: *
109: */
110: public tinySQLStatement(tinySQLConnection conn) {
111:
112: connection = conn;
113: if (debug)
114: System.out
115: .println("connection is " + connection.toString());
116:
117: }
118:
119: /**
120: *
121: * Execute an SQL statement and return a result set.
122: * @see java.sql.Statement#executeQuery
123: * @exception SQLException raised for any errors
124: * @param sql the SQL statement string
125: * @return the result set from the query
126: *
127: */
128: public synchronized ResultSet executeQuery(String sql)
129: throws SQLException {
130:
131: // tinySQL only supports one result set at a time, so
132: // don't let them get another one, just in case it's
133: // hanging out.
134: //
135: tinySQLResultSet trs;
136: result = null;
137: statementString = sql;
138:
139: // create a new tinySQLResultSet with the tsResultSet
140: // returned from connection.executetinySQL()
141: //
142: if (debug)
143: System.out.println("executeQuery conn is "
144: + connection.toString());
145: trs = new tinySQLResultSet(connection.executetinySQL(this ),
146: this );
147: return trs;
148: }
149:
150: /**
151: *
152: * Execute an update, insert, delete, create table, etc. This can
153: * be anything that doesn't return rows.
154: * @see java.sql.Statement#executeUpdate
155: * @exception java.sql.SQLException thrown when an error occurs executing
156: * the SQL
157: * @return either the row count for INSERT, UPDATE or DELETE or 0 for SQL statements that return nothing
158: */
159: public synchronized int executeUpdate(String sql)
160: throws SQLException {
161:
162: statementString = sql;
163: return connection.executetinyUpdate(this );
164:
165: }
166:
167: /**
168: *
169: * Executes some SQL and returns true or false, depending on
170: * the success. The result set is stored in result, and can
171: * be retrieved with getResultSet();
172: * @see java.sql.Statement#execute
173: * @exception SQLException raised for any errors
174: * @param sql the SQL to be executed
175: * @return true if there is a result set available
176: */
177: public boolean execute(String sql) throws SQLException {
178:
179: // a result set object
180: //
181: tsResultSet r;
182:
183: // execute the query
184: //
185: r = connection.executetinySQL(this );
186:
187: // check for a null result set. If it wasn't null,
188: // use it to create a tinySQLResultSet, and return whether or
189: // not it is null (not null returns true).
190: //
191: if (r == null) {
192: result = null;
193: } else {
194: result = new tinySQLResultSet(r, this );
195: }
196: return (result != null);
197:
198: }
199:
200: /**
201: * Returns the current query-String
202: */
203: public String getSQLString() {
204: return statementString;
205: }
206:
207: /**
208: *
209: * Close any result sets. This is not used by tinySQL.
210: * @see java.sql.Statement#close
211: *
212: */
213: public void close() throws SQLException {
214: }
215:
216: /**
217: *
218: * Returns the last result set
219: * @see java.sql.Statement#getResultSet
220: * @return null if no result set is available, otherwise a result set
221: *
222: */
223: public ResultSet getResultSet() throws SQLException {
224:
225: ResultSet r;
226:
227: r = result; // save the existing result set
228: result = null; // null out the existing result set
229: return r; // return the previously extant result set
230: }
231:
232: /**
233: *
234: * Return the row count of the last operation. tinySQL does not support
235: * this, so it returns -1
236: * @see java.sql.Statement#getUpdateCount
237: * @return -1
238: */
239: public int getUpdateCount() throws SQLException {
240: return -1;
241: }
242:
243: /**
244: *
245: * This returns true if there are any pending result sets. This
246: * should only be true after invoking execute()
247: * @see java.sql.Statement#getMoreResults
248: * @return true if rows are to be gotten
249: *
250: */
251: public boolean getMoreResults() throws SQLException {
252:
253: return (result != null);
254:
255: }
256:
257: /**
258: *
259: * Get the maximum field size to return in a result set.
260: * @see java.sql.Statement#getMaxFieldSize
261: * @return the value of max field size
262: *
263: */
264: public int getMaxFieldSize() throws SQLException {
265: return max_field_size;
266: }
267:
268: /**
269: *
270: * set the max field size.
271: * @see java.sql.Statement#setMaxFieldSize
272: * @param max the maximum field size
273: *
274: */
275: public void setMaxFieldSize(int max) throws SQLException {
276: max_field_size = max;
277: }
278:
279: /**
280: *
281: * Get the maximum row count that can be returned by a result set.
282: * @see java.sql.Statement#getMaxRows
283: * @return the maximum rows
284: *
285: */
286: public int getMaxRows() throws SQLException {
287: return max_rows;
288: }
289:
290: /**
291: *
292: * Get the maximum row count that can be returned by a result set.
293: * @see java.sql.Statement.setMaxRows
294: * @param max the max rows
295: *
296: */
297: public void setMaxRows(int max) throws SQLException {
298: max_rows = max;
299: }
300:
301: /**
302: *
303: * If escape scanning is on (the default) the driver will do
304: * escape substitution before sending the SQL to the database.
305: * @see java.sql.Statement#setEscapeProcessing
306: * @param enable this does nothing right now
307: *
308: */
309: public void setEscapeProcessing(boolean enable) throws SQLException {
310: throw new SQLException("The tinySQL Driver doesn't "
311: + "support escape processing.");
312: }
313:
314: /**
315: *
316: * Discover the query timeout.
317: * @see java.sql.Statement#getQueryTimeout
318: * @see setQueryTimeout
319: * @return the timeout value for this statement
320: *
321: */
322: public int getQueryTimeout() throws SQLException {
323: return timeout;
324: }
325:
326: /**
327: *
328: * Set the query timeout.
329: * @see java.sql.Statement#setQueryTimeout
330: * @see getQueryTimeout
331: * @param x the new query timeout value
332: *
333: */
334: public void setQueryTimeout(int x) throws SQLException {
335: timeout = x;
336: }
337:
338: /**
339: *
340: * This can be used by another thread to cancel a statement. This
341: * doesn't matter for tinySQL, as far as I can tell.
342: * @see java.sql.Statement#cancel
343: *
344: */
345: public void cancel() {
346: }
347:
348: /**
349: *
350: * Get the warning chain associated with this Statement
351: * @see java.sql.Statement#getWarnings
352: * @return the chain of warnings
353: *
354: */
355: public final SQLWarning getWarnings() throws SQLException {
356: return null;
357: }
358:
359: /**
360: *
361: * Clear the warning chain associated with this Statement
362: * @see java.sql.Statement#clearWarnings
363: *
364: */
365: public void clearWarnings() throws SQLException {
366: }
367:
368: /**
369: *
370: * Sets the cursor name for this connection. Presently unsupported.
371: *
372: */
373: public void setCursorName(String unused) throws SQLException {
374: throw new SQLException("tinySQL does not support cursors.");
375: }
376:
377: //--------------------------JDBC 2.0-----------------------------
378:
379: /**
380: * JDBC 2.0
381: *
382: * Gives the driver a hint as to the direction in which
383: * the rows in a result set
384: * will be processed. The hint applies only to result sets created
385: * using this Statement object. The default value is
386: * ResultSet.FETCH_FORWARD.
387: * <p>Note that this method sets the default fetch direction for
388: * result sets generated by this <code>Statement</code> object.
389: * Each result set has its own methods for getting and setting
390: * its own fetch direction.
391: * @param direction the initial direction for processing rows
392: * @exception SQLException if a database access error occurs
393: * or the given direction
394: * is not one of ResultSet.FETCH_FORWARD, ResultSet.FETCH_REVERSE, or
395: * ResultSet.FETCH_UNKNOWN
396: */
397: public void setFetchDirection(int direction) throws SQLException {
398: throw new SQLException(
399: "tinySQL does not support setFetchDirection.");
400: }
401:
402: /**
403: * JDBC 2.0
404: *
405: * Retrieves the direction for fetching rows from
406: * database tables that is the default for result sets
407: * generated from this <code>Statement</code> object.
408: * If this <code>Statement</code> object has not set
409: * a fetch direction by calling the method <code>setFetchDirection</code>,
410: * the return value is implementation-specific.
411: *
412: * @return the default fetch direction for result sets generated
413: * from this <code>Statement</code> object
414: * @exception SQLException if a database access error occurs
415: */
416: public int getFetchDirection() throws SQLException {
417: throw new SQLException(
418: "tinySQL does not support getFetchDirection.");
419: }
420:
421: /**
422: * JDBC 2.0
423: *
424: * Gives the JDBC driver a hint as to the number of rows that should
425: * be fetched from the database when more rows are needed. The number
426: * of rows specified affects only result sets created using this
427: * statement. If the value specified is zero, then the hint is ignored.
428: * The default value is zero.
429: *
430: * @param rows the number of rows to fetch
431: * @exception SQLException if a database access error occurs, or the
432: * condition 0 <= rows <= this.getMaxRows() is not satisfied.
433: */
434: public void setFetchSize(int rows) throws SQLException {
435: if ((rows <= 0) || (rows >= this .getMaxRows()))
436: throw new SQLException(
437: "Condition 0 <= rows <= this.getMaxRows() is not satisfied");
438:
439: fetchsize = rows;
440: }
441:
442: /**
443: * JDBC 2.0
444: *
445: * Retrieves the number of result set rows that is the default
446: * fetch size for result sets
447: * generated from this <code>Statement</code> object.
448: * If this <code>Statement</code> object has not set
449: * a fetch size by calling the method <code>setFetchSize</code>,
450: * the return value is implementation-specific.
451: * @return the default fetch size for result sets generated
452: * from this <code>Statement</code> object
453: * @exception SQLException if a database access error occurs
454: */
455: public int getFetchSize() throws SQLException {
456: return fetchsize;
457: }
458:
459: /**
460: * JDBC 2.0
461: *
462: * Retrieves the result set concurrency.
463: */
464: public int getResultSetConcurrency() throws SQLException {
465: throw new SQLException(
466: "tinySQL does not support ResultSet concurrency.");
467: }
468:
469: /**
470: * JDBC 2.0
471: *
472: * Determine the result set type.
473: */
474: public int getResultSetType() throws SQLException {
475: throw new SQLException(
476: "tinySQL does not support getResultSetType.");
477: }
478:
479: /**
480: * JDBC 2.0
481: *
482: * Adds a SQL command to the current batch of commmands for the statement.
483: * This method is optional.
484: *
485: * @param sql typically this is a static SQL INSERT or UPDATE statement
486: * @exception SQLException if a database access error occurs, or the
487: * driver does not support batch statements
488: */
489: public void addBatch(String sql) throws SQLException {
490: throw new SQLException("tinySQL does not support addBatch.");
491: }
492:
493: /**
494: * JDBC 2.0
495: *
496: * Makes the set of commands in the current batch empty.
497: * This method is optional.
498: *
499: * @exception SQLException if a database access error occurs or the
500: * driver does not support batch statements
501: */
502: public void clearBatch() throws SQLException {
503: throw new SQLException("tinySQL does not support clearBatch.");
504: }
505:
506: /**
507: * JDBC 2.0
508: *
509: * Submits a batch of commands to the database for execution.
510: * This method is optional.
511: *
512: * @return an array of update counts containing one element for each
513: * command in the batch. The array is ordered according
514: * to the order in which commands were inserted into the batch.
515: * @exception SQLException if a database access error occurs or the
516: * driver does not support batch statements
517: */
518: public int[] executeBatch() throws SQLException {
519: throw new SQLException("tinySQL does not support executeBatch.");
520: }
521:
522: /**
523: * JDBC 2.0
524: *
525: * Returns the <code>Connection</code> object
526: * that produced this <code>Statement</code> object.
527: * @return the connection that produced this statement
528: * @exception SQLException if a database access error occurs
529: */
530: public Connection getConnection() throws SQLException {
531: return connection;
532: }
533:
534: }
|