001: package com.quadcap.jdbc;
002:
003: /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
004: *
005: * This software is distributed under the Quadcap Free Software License.
006: * This software may be used or modified for any purpose, personal or
007: * commercial. Open Source redistributions are permitted. Commercial
008: * redistribution of larger works derived from, or works which bundle
009: * this software requires a "Commercial Redistribution License"; see
010: * http://www.quadcap.com/purchase.
011: *
012: * Redistributions qualify as "Open Source" under one of the following terms:
013: *
014: * Redistributions are made at no charge beyond the reasonable cost of
015: * materials and delivery.
016: *
017: * Redistributions are accompanied by a copy of the Source Code or by an
018: * irrevocable offer to provide a copy of the Source Code for up to three
019: * years at the cost of materials and delivery. Such redistributions
020: * must allow further use, modification, and redistribution of the Source
021: * Code under substantially the same terms as this license.
022: *
023: * Redistributions of source code must retain the copyright notices as they
024: * appear in each source code file, these license terms, and the
025: * disclaimer/limitation of liability set forth as paragraph 6 below.
026: *
027: * Redistributions in binary form must reproduce this Copyright Notice,
028: * these license terms, and the disclaimer/limitation of liability set
029: * forth as paragraph 6 below, in the documentation and/or other materials
030: * provided with the distribution.
031: *
032: * The Software is provided on an "AS IS" basis. No warranty is
033: * provided that the Software is free of defects, or fit for a
034: * particular purpose.
035: *
036: * Limitation of Liability. Quadcap Software shall not be liable
037: * for any damages suffered by the Licensee or any third party resulting
038: * from use of the Software.
039: */
040:
041: import java.io.IOException;
042: import java.io.InputStream;
043: import java.io.Reader;
044:
045: import java.util.Calendar;
046: import java.util.Vector;
047:
048: import java.math.BigDecimal;
049:
050: //#ifndef JDK11
051: import java.sql.Array;
052: import java.sql.Blob;
053: import java.sql.Clob;
054: import java.sql.Ref; //#endif
055:
056: import java.sql.Date;
057: import java.sql.SQLException;
058: import java.sql.SQLWarning;
059: import java.sql.Time;
060: import java.sql.Timestamp;
061: import java.sql.Types;
062:
063: import antlr.RecognitionException;
064:
065: import com.quadcap.sql.InsertBlob;
066: import com.quadcap.sql.ParameterExpression;
067: import com.quadcap.sql.SQLParser;
068: import com.quadcap.sql.Stmt;
069:
070: import com.quadcap.io.AsciiReader;
071: import com.quadcap.io.ReaderInputStream;
072:
073: import com.quadcap.sql.file.BlockFile;
074:
075: import com.quadcap.sql.types.*;
076:
077: import com.quadcap.util.Debug;
078:
079: /**
080: * This class implements the <code>java.sql.PreparedStatement</code>
081: * interface, and provides facilities for execution of pre-compiled
082: * SQL statements. This release of QED performs all of the SQL parsing
083: * during the prepare phase, so that subsequent execution of the
084: * compiled statement is considerably faster than directly executing
085: * the statement using the <code>Statement</code> interface.
086: *
087: * @author Stan Bailes
088: */
089: public class PreparedStatement extends Statement implements
090: java.sql.PreparedStatement {
091: Stmt stmt;
092: Vector params;
093: //#ifdef DEBUG
094: String sql;
095:
096: //#endif
097:
098: /**
099: * @deprecated in order to not appear in public javadoc
100: */
101: public PreparedStatement(Connection conn, String sql)
102: throws SQLException, IOException {
103: super (conn);
104: //#ifdef DEBUG
105: this .sql = sql;
106: if (Statement.trace.bit(0)) {
107: Debug.println("prepare(" + sql + ")");
108: }
109: //#endif
110: session.makeTransaction();
111: SQLParser p = new SQLParser(session, sql, escapeProcessing);
112: String auth = qConn.getAuth();
113: try {
114: stmt = p.statement();
115: params = p.getParameters();
116: } catch (RecognitionException e) {
117: throw new SQLException(e.toString(), "42000");
118: } catch (antlr.TokenStreamException e) {
119: throw new SQLException(e.toString(), "Q0010");
120: } finally {
121: // XXX
122: // This is a hack. 'create schema' will temporarily set the
123: // 'auth' to the schema name, and this is the first place where
124: // we get a chance to restore the correct auth.
125: //
126: // This is made worse by the fact that names are resolved during
127: // the parse phase, and could be made better if antlr parser
128: // rules allowed you to specify a 'finally' handler.
129:
130: // Also 'create schema' where the schema name is a parameter is
131: // going to fail badly.
132: qConn.setAuth(auth, null);
133: }
134: }
135:
136: /**
137: * This QED release doesn't support batch statement execution.
138: *
139: * @exception SQLException "not implemented"
140: */
141: public void addBatch() throws SQLException {
142: throw new SQLException("not implemented", "0A000");
143: }
144:
145: ParameterExpression getParam(int i) {
146: return (ParameterExpression) params.elementAt(i - 1);
147: }
148:
149: /**
150: * Clear the values of any parameters to this prepared statement;
151: * i.e., set them all to <code>NULL</code>
152: *
153: * @exception SQLException may be thrown
154: */
155: public void clearParameters() throws SQLException {
156: for (int i = 1; i <= params.size(); i++) {
157: ParameterExpression pe = getParam(i);
158: pe.setValue(ValueNull.valueNull);
159: }
160: }
161:
162: /**
163: * Execute the current SQL statement, returning <code>true</code>
164: * if the statement generates a <code>ResultSet</code> object.
165: *
166: * @return true if execution of the statement results in the creation
167: * of a <code>ResultSet</code>
168: * @see #getResultSet()
169: * @exception SQLException may be thrown
170: */
171: public boolean execute() throws SQLException {
172: //#ifdef DEBUG
173: if (Statement.trace.bit(1)) {
174: Debug.println("PreparedStatement.execute(" + sql + ")");
175: }
176: //#endif
177: this .rs = null;
178: this .updateCount = -1;
179:
180: if (this .qConn.isClosed()) {
181: throw new SQLException("Connection closed");
182: }
183: try {
184: session.doStatement(stmt);
185: this .rs = (ResultSet) session.getResultSet(this );
186: if (rs != null) {
187: return true;
188: } else {
189: this .updateCount = session.getUpdateCount();
190: return false;
191: }
192: } catch (IOException e) {
193: try {
194: session.endStatement(true);
195: } catch (IOException e1) {
196: }
197: throw new SQLException(e.toString(), "Q0011");
198: } catch (SQLException e) {
199: try {
200: session.endStatement(true);
201: } catch (IOException e1) {
202: }
203: throw e;
204: } catch (Throwable e) {
205: Debug.print(e);
206: try {
207: session.endStatement(true);
208: } catch (IOException e1) {
209: }
210: throw new SQLException(e.toString(), "Q0013");
211: }
212: }
213:
214: /**
215: * Execute the prepared SQL query statement, returning the
216: * <code>ResultSet</code> object containing the results of the
217: * query.
218: *
219: * @return a <code>ResultSet</code> object containing the results of
220: * the query
221: * @exception SQLException may be thrown
222: */
223: public java.sql.ResultSet executeQuery() throws SQLException {
224: if (execute()) {
225: return this .rs;
226: } else {
227: return null;
228: }
229: }
230:
231: /**
232: * Execute the prepared SQL update statement, returning the update
233: * count, meaning the number of rows updated or inserted by this
234: * statement.
235: *
236: * @return the update count
237: * @exception SQLException may be thrown
238: */
239: public int executeUpdate() throws SQLException {
240: if (!execute()) {
241: return updateCount;
242: } else {
243: return 0;
244: }
245: }
246:
247: /**
248: * QED doesn't implement this feature, which requires information
249: * about the <code>ResultSet</code> that will be generated by this
250: * <code>PreparedStatement</code> object when it is executed.
251: * Instead, first call <code>execute()</code> or
252: * <code>executeQuery()</code>, then call
253: * <code>ResultSet.getMetaData()</code> on the
254: * <code>ResultSet</code> object that is returned.
255: *
256: * @return null
257: */
258: public java.sql.ResultSetMetaData getMetaData() {
259: return null;
260: }
261:
262: /**
263: * Set the statement parameter to the specified character value using an
264: * <code>InputStream</code> that contains a stream of ASCII bytes.
265: * The ASCII bytes are converted to Unicode character values before
266: * being inserted into the database.
267: *
268: * @param col the parameter index
269: * @param is an input stream containing ASCII bytes.
270: * @param length the number of bytes to read from the stream
271: * @return an <code>InputStream</code>
272: * @exception SQLException may be thrown
273: */
274: public void setAsciiStream(int col, InputStream in, int length)
275: throws SQLException {
276: try {
277: if (in == null) {
278: setParamValue(col, ValueNull.valueNull);
279: } else {
280: ValueClob clob = new ValueClob(session.getDatabase(),
281: session.makeTransaction(), new AsciiReader(in),
282: length);
283: setParamValue(col, clob);
284: session.doStep(new InsertBlob(session, clob));
285: clob.close();
286: }
287:
288: } catch (IOException e) {
289: Debug.print(e);
290: throw new SQLException(e.toString(), "Q001H");
291: }
292: }
293:
294: final void setParamValue(int col, Value v) throws SQLException {
295: //#ifdef DEBUG
296: if (Statement.trace.bit(4)) {
297: Debug.println("setValue(" + col + ", " + v + ")");
298: }
299: //#endif
300: getParam(col).setValue(v);
301: }
302:
303: /**
304: * Set the statement parameter to the specified
305: * <code>BigDecimal</code> value.
306: *
307: * @param col the parameter index
308: * @param val the new value
309: * @exception SQLException may be thrown
310: */
311: public void setBigDecimal(int col, BigDecimal val)
312: throws SQLException {
313: if (val == null) {
314: setParamValue(col, ValueNull.valueNull);
315: } else {
316: setParamValue(col, new ValueScaledInteger(val));
317: }
318: }
319:
320: /**
321: * Set the statement parameter to the specified binary value using an
322: * <code>InputStream</code> that contains a stream of bytes.
323: *
324: * @param col the parameter index
325: * @param is an input stream containing ASCII bytes.
326: * @param length the number of bytes to read from the stream
327: * <p>
328: * If 'length > 0', then the blob's length will be set to the value
329: * of the 'length' parameter.
330: * <p>
331: * If 'length < 0', then the blob's length will be set to the number
332: * of bytes read.
333: * @return an <code>InputStream</code>
334: * @exception SQLException may be thrown
335: */
336: public void setBinaryStream(int col, InputStream in, int length)
337: throws SQLException {
338: try {
339: if (in == null) {
340: setParamValue(col, ValueNull.valueNull);
341: } else {
342: ValueBlob blob = new ValueBlob(session.getDatabase(),
343: session.makeTransaction(), in, length);
344: setParamValue(col, blob);
345: session.doStep(new InsertBlob(session, blob));
346: blob.close();
347: }
348:
349: } catch (IOException e) {
350: Debug.print(e);
351: throw new SQLException(e.toString(), "Q001H");
352: }
353: }
354:
355: /**
356: * Set the statement parameter to the specified
357: * <code>boolean</code> value.
358: *
359: * @param col the parameter index
360: * @param val the new value
361: * @exception SQLException may be thrown
362: */
363: public void setBoolean(int col, boolean val) throws SQLException {
364: setParamValue(col, new ValueBoolean(val));
365: }
366:
367: /**
368: * Set the statement parameter to the specified
369: * <code>byte</code> value.
370: *
371: * @param col the parameter index
372: * @param val the new value
373: * @exception SQLException may be thrown
374: */
375: public void setByte(int col, byte val) throws SQLException {
376: setParamValue(col, new ValueShort(val));
377: }
378:
379: /**
380: * Set the statement parameter to the specified
381: * <code>byte</code> array value.
382: *
383: * @param col the parameter index
384: * @param val the new value
385: * @exception SQLException may be thrown
386: */
387: public void setBytes(int col, byte[] val) throws SQLException {
388: if (val == null) {
389: setParamValue(col, ValueNull.valueNull);
390: } else {
391: setParamValue(col, new ValueOctets(val));
392: }
393: }
394:
395: /**
396: * Set the statement parameter to the specified character value using a
397: * <code>Reader</code> that contains a stream of Unicode characters.
398: *
399: * @param col the parameter index
400: * @param r a reader containing the value's characters.
401: * @param length the number of bytes to read from the stream
402: * @return an <code>InputStream</code>
403: * @exception SQLException may be thrown
404: */
405: public void setCharacterStream(int col, Reader r, int length)
406: throws SQLException {
407: try {
408: if (r == null) {
409: setParamValue(col, ValueNull.valueNull);
410: } else {
411: ValueClob clob = new ValueClob(session.getDatabase(),
412: session.makeTransaction(), r, length);
413: setParamValue(col, clob);
414: session.doStep(new InsertBlob(session, clob));
415: clob.close();
416: }
417:
418: } catch (IOException e) {
419: Debug.print(e);
420: throw new SQLException(e.toString(), "Q001H");
421: }
422: }
423:
424: /**
425: * Set the statement parameter to the specified
426: * <code>Date</code> value.
427: *
428: * @param col the parameter index
429: * @param val the new value
430: * @exception SQLException may be thrown
431: */
432: public void setDate(int col, Date val) throws SQLException {
433: if (val == null) {
434: setParamValue(col, ValueNull.valueNull);
435: } else {
436: setParamValue(col, new ValueDate(val.getTime()));
437: }
438: }
439:
440: /**
441: * Set the statement parameter to the specified
442: * <code>Date</code> value.
443: *
444: * @param col the parameter index
445: * @param val the new value
446: * @param cal a <code>Calendar<code> object that is used for converting
447: * the database date to the local timezone. The database date is
448: * adjusted based on the <code>Calendar</code> timezone and DST offset.
449: * @exception SQLException may be thrown
450: */
451: public void setDate(int col, Date val, Calendar cal)
452: throws SQLException {
453: if (val == null) {
454: setParamValue(col, ValueNull.valueNull);
455: } else {
456: cal.setTime(val);
457: setParamValue(col, new ValueDate(cal.getTime().getTime()));
458: }
459: }
460:
461: /**
462: * Set the statement parameter to the specified
463: * <code>double</code> value.
464: *
465: * @param col the parameter index
466: * @param val the new value
467: * @exception SQLException may be thrown
468: */
469: public void setDouble(int col, double val) throws SQLException {
470: setParamValue(col, new ValueDouble(val));
471: }
472:
473: /**
474: * Set the statement parameter to the specified
475: * <code>float</code> value.
476: *
477: * @param col the parameter index
478: * @param val the new value
479: * @exception SQLException may be thrown
480: */
481: public void setFloat(int col, float val) throws SQLException {
482: setParamValue(col, new ValueDouble(val));
483: }
484:
485: /**
486: * Set the statement parameter to the specified
487: * <code>int</code> value.
488: *
489: * @param col the parameter index
490: * @param val the new value
491: * @exception SQLException may be thrown
492: */
493: public void setInt(int col, int val) throws SQLException {
494: setParamValue(col, new ValueInteger(val));
495: }
496:
497: /**
498: * Set the statement parameter to the specified
499: * <code>long</code> value.
500: *
501: * @param col the parameter index
502: * @param val the new value
503: * @exception SQLException may be thrown
504: */
505: public void setLong(int col, long val) throws SQLException {
506: setParamValue(col, new ValueLong(val));
507: }
508:
509: /**
510: * Set the statement parameter to the specified
511: * <code>null</code> value.
512: *
513: * @param col the parameter index
514: * @param type the JDBC type of the parameter. This is ignored by QED
515: * because a null is a null is a null.
516: * @exception SQLException may be thrown
517: */
518: public void setNull(int col, int type) throws SQLException {
519: setParamValue(col, ValueNull.valueNull);
520: }
521:
522: /**
523: * Set the statement parameter to the specified
524: * <code>null</code> value.
525: *
526: * @param col the parameter index
527: * @param type the JDBC type of the parameter. This is ignored by QED
528: * because a null is a null is a null.
529: * @param typename the fully qualified type name of the parameter.
530: * This is ignored by QED
531: * because a null is a null is a null.
532: * @exception SQLException may be thrown
533: */
534: public void setNull(int col, int type, String typename)
535: throws SQLException {
536: setParamValue(col, ValueNull.valueNull);
537: }
538:
539: /**
540: * Set the statement parameter to the specified
541: * <code>Object</code> value.
542: *
543: * @param col the parameter index
544: * @param val the new value
545: * @exception SQLException may be thrown
546: */
547: public void setObject(int col, Object val) throws SQLException {
548: if (val instanceof Blob) {
549: Blob blob = (Blob) val;
550: setBinaryStream(col, blob.getBinaryStream(), (int) blob
551: .length());
552: } else if (val instanceof Clob) {
553: Clob clob = (Clob) val;
554: setCharacterStream(col, clob.getCharacterStream(),
555: (int) clob.length());
556: } else {
557: setParamValue(col, Value.fromObject(val));
558: }
559: }
560:
561: /**
562: * Set the statement parameter to the specified
563: * <code>Object</code> value.
564: *
565: * @param col the parameter index
566: * @param val the new value
567: * @param type the JDBC type of the parameter.
568: * @exception SQLException may be thrown
569: */
570: public void setObject(int col, Object val, int type)
571: throws SQLException {
572: Type t = Value.typeForJdbcType(type);
573: Value v = Value.fromObject(val);
574: setParamValue(col, t.convert(v));
575: }
576:
577: /**
578: * Set the statement parameter to the specified
579: * <code>Object</code> value.
580: *
581: * @param col the parameter index
582: * @param val the new value
583: * @param type the JDBC type of the parameter.
584: * @param scale for numeric types, the precision of the value.
585: * @exception SQLException may be thrown
586: */
587: public void setObject(int col, Object val, int type, int scale)
588: throws SQLException {
589: Value v = Value.fromObject(val);
590: Type t = null;
591: switch (type) {
592: case Types.NUMERIC:
593: case Types.DECIMAL:
594: t = new TypeDecimal(32, scale);
595: break;
596: default:
597: t = Value.typeForJdbcType(type);
598: }
599: setParamValue(col, t.convert(v));
600: }
601:
602: /**
603: * Set the statement parameter to the specified
604: * <code>short</code> value.
605: *
606: * @param col the parameter index
607: * @param val the new value
608: * @exception SQLException may be thrown
609: */
610: public void setShort(int col, short val) throws SQLException {
611: setParamValue(col, new ValueShort(val));
612: }
613:
614: /**
615: * Set the statement parameter to the specified
616: * <code>String</code> value.
617: *
618: * @param col the parameter index
619: * @param val the new value
620: * @exception SQLException may be thrown
621: */
622: public void setString(int col, String val) throws SQLException {
623: if (val == null) {
624: setParamValue(col, ValueNull.valueNull);
625: } else {
626: setParamValue(col, new ValueString(val));
627: }
628: }
629:
630: /**
631: * Set the statement parameter to the specified
632: * <code>Time</code> value.
633: *
634: * @param col the parameter index
635: * @param val the new value
636: * @exception SQLException may be thrown
637: */
638: public void setTime(int col, Time val) throws SQLException {
639: if (val == null) {
640: setParamValue(col, ValueNull.valueNull);
641: } else {
642: setParamValue(col, new ValueTime(val.getTime()));
643: }
644: }
645:
646: /**
647: * Set the statement parameter to the specified
648: * <code>Time</code> value.
649: *
650: * @param col the parameter index
651: * @param val the new value
652: * @param cal a <code>Calendar<code> object that is used for converting
653: * the database date to the local timezone. The database date is
654: * adjusted based on the <code>Calendar</code> timezone and DST offset.
655: * @exception SQLException may be thrown
656: */
657: public void setTime(int col, Time val, Calendar cal)
658: throws SQLException {
659: if (val == null) {
660: setParamValue(col, ValueNull.valueNull);
661: } else {
662: long t = val.getTime();
663: cal.setTime(val);
664: t -= (cal.get(Calendar.ZONE_OFFSET) + cal
665: .get(Calendar.DST_OFFSET));
666: setParamValue(col, new ValueTime(t));
667: }
668: }
669:
670: /**
671: * Set the statement parameter to the specified
672: * <code>Timestamp</code> value.
673: *
674: * @param col the parameter index
675: * @param val the new value
676: * @exception SQLException may be thrown
677: */
678: public void setTimestamp(int col, Timestamp val)
679: throws SQLException {
680: if (val == null) {
681: setParamValue(col, ValueNull.valueNull);
682: } else {
683: setParamValue(col, new ValueTimestamp(val));
684: }
685: }
686:
687: /**
688: * Set the statement parameter to the specified
689: * <code>Timestamp</code> value.
690: *
691: * @param col the parameter index
692: * @param val the new value
693: * @param cal a <code>Calendar<code> object that is used for converting
694: * the database date to the local timezone. The database date is
695: * adjusted based on the <code>Calendar</code> timezone and DST offset.
696: * @exception SQLException may be thrown
697: */
698: public void setTimestamp(int col, Timestamp val, Calendar cal)
699: throws SQLException {
700: if (val == null) {
701: setParamValue(col, ValueNull.valueNull);
702: } else {
703: long t = val.getTime();
704: cal.setTime(val);
705: t -= (cal.get(Calendar.ZONE_OFFSET) + cal
706: .get(Calendar.DST_OFFSET));
707: Timestamp r = new Timestamp(t);
708: r.setNanos(val.getNanos());
709: setParamValue(col, new ValueTimestamp(r));
710: }
711: }
712:
713: /**
714: * @deprecated
715: */
716: public void setUnicodeStream(int col, InputStream in, int length)
717: throws SQLException {
718: setBinaryStream(col, in, length);
719: }
720:
721: /**
722: * @deprecated
723: */
724: public PreparedStatement(Connection conn, String sql,
725: int resultSetType, int resultSetConcurrency)
726: throws SQLException, IOException {
727: this (conn, sql);
728: this .resultSetType = resultSetType;
729: this .resultSetConcurrency = resultSetConcurrency;
730: }
731:
732: //#ifndef JDK11
733: /**
734: * Set the statement parameter to the specified
735: * <code>ARRAY</code> value.
736: * This QED release doesn't support ARRAY types, so a
737: * "not implemented" exception is thrown
738: *
739: * @param col the parameter index
740: * @param val the new value
741: * @exception SQLException "not implemented"
742: */
743: public void setArray(int col, Array val) throws SQLException {
744: throw new SQLException("not implemented", "0A000");
745: }
746:
747: /**
748: * Set the statement parameter to the specified
749: * <code>Blob</code> value.
750: *
751: * @param col the parameter index
752: * @param val the new value
753: * @exception SQLException may be thrown
754: */
755: public void setBlob(int col, Blob val) throws SQLException {
756: if (val == null) {
757: setParamValue(col, ValueNull.valueNull);
758: } else {
759: if (val instanceof ValueBlob) {
760: setParamValue(col, (ValueBlob) val);
761: } else {
762: setBinaryStream(col, val.getBinaryStream(), (int) (val
763: .length()));
764: }
765: }
766: }
767:
768: /**
769: * Set the statement parameter to the specified
770: * <code>Clob</code> value.
771: *
772: * @param col the parameter index
773: * @param val the new value
774: * @exception SQLException may be thrown
775: */
776: public void setClob(int col, Clob val) throws SQLException {
777: if (val == null) {
778: setParamValue(col, ValueNull.valueNull);
779: } else {
780: setAsciiStream(col, val.getAsciiStream(), (int) (val
781: .length()));
782: }
783: }
784:
785: /**
786: * Set the statement parameter to the specified
787: * <code>REF</code> value.
788: * This QED release doesn't support ARRAY types, so a
789: * "not implemented" exception is thrown
790: *
791: * @param col the parameter index
792: * @param val the new value
793: * @exception SQLException "not implemented"
794: */
795: public void setRef(int col, Ref val) throws SQLException {
796: throw new SQLException("not implemented", "0A000");
797: }
798:
799: //#endif
800:
801: //------------------------- JDBC 3.0 -----------------------------------
802: //#ifdef JDK14
803:
804: /**
805: * Sets the designated parameter to the given <code>java.net.URL</code>
806: * value.
807: * The driver converts this to an SQL <code>DATALINK</code> value
808: * when it sends it to the database.
809: *
810: * <p>QED simply converts the URL to a string</p>
811: *
812: * @param parameterIndex the first parameter is 1, the second is 2, ...
813: * @param x the <code>java.net.URL</code> object to be set
814: * @exception SQLException if a database access error occurs
815: * @since 1.4
816: */
817: public void setURL(int parameterIndex, java.net.URL x)
818: throws SQLException {
819: setString(parameterIndex, x.toString());
820: }
821:
822: /**
823: * Retrieves the number, types and properties of this
824: * <code>PreparedStatement</code> object's parameters.
825: *
826: * <p><i>QED: Not implemented</i></p>
827: *
828: * @return a <code>ParameterMetaData</code> object that contains information
829: * about the number, types and properties of this
830: * <code>PreparedStatement</code> object's parameters
831: * @exception SQLException if a database access error occurs
832: * @see ParameterMetaData
833: * @since 1.4
834: */
835: public java.sql.ParameterMetaData getParameterMetaData()
836: throws SQLException {
837: throw new SQLException("Not implemented");
838: }
839:
840: //#endif
841:
842: public String toString() {
843: StringBuffer sb = new StringBuffer(
844: "com.quadcap.jdbc.PreparedStatement(");
845: if (params != null)
846: for (int i = 1; i <= params.size(); i++) {
847: if (i > 1)
848: sb.append(",");
849: ParameterExpression e = getParam(i);
850: Value v = e.getValue(null, null);
851: sb.append(String.valueOf(v));
852: }
853: sb.append(")");
854: return sb.toString();
855: }
856:
857: }
|