KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > in > co > daffodil > db > jdbc > DaffodilDBPreparedStatement


1 package in.co.daffodil.db.jdbc;
2
3 import java.math.*;
4 import java.sql.*;
5 import java.sql.PreparedStatement JavaDoc;
6 import java.util.*;
7 import com.daffodilwoods.daffodildb.client.*;
8 import com.daffodilwoods.daffodildb.server.datadictionarysystem.*;
9 import com.daffodilwoods.daffodildb.server.serversystem.*;
10 import com.daffodilwoods.database.resource.*;
11 import com.daffodilwoods.daffodildb.server.sql99.dql.listenerevents.*;
12 import java.lang.reflect.Constructor JavaDoc;
13 import com.daffodilwoods.database.general._ParameterMetaData;
14 import com.daffodilwoods.daffodildb.server.sql99.dml.DMLResult;
15 import com.daffodilwoods.daffodildb.server.sql99.common.*;
16
17 /**
18  * An object that represents a precompiled SQL statement.
19  * <P>A SQL statement is precompiled and stored in a
20  * <code>PreparedStatement</code> object. This object can then be used to
21  * efficiently execute this statement multiple times.
22  *
23  * <P><B>Note:</B> The setter methods (<code>setShort</code>, <code>setString</code>,
24  * and so on) for setting IN parameter values
25  * must specify types that are compatible with the defined SQL type of
26  * the input parameter. For instance, if the IN parameter has SQL type
27  * <code>INTEGER</code>, then the method <code>setInt</code> should be used.
28  *
29  * <p>If arbitrary parameter type conversions are required, the method
30  * <code>setObject</code> should be used with a target SQL type.
31  * <P>
32  * In the following example of setting a parameter, <code>con</code> represents
33  * an active connection:
34  * <PRE>
35  * PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES
36  * SET SALARY = ? WHERE ID = ?");
37  * pstmt.setBigDecimal(1, 153833.00)
38  * pstmt.setInt(2, 110592)
39  * </PRE>
40  *
41  * @see Connection#prepareStatement
42  * @see ResultSet
43  * <br><br>
44  * <B>Last Updated </B>
45  * <U> Dec. 20,2004 </U><br>
46  * <I>Purpose :To provide method synchronization . </I><br>
47  * <B>Author</B> Manoj Kr. Sheoran<br>
48  */

49
50
51 public class DaffodilDBPreparedStatement
52     extends DaffodilDBStatement
53     implements PreparedStatement JavaDoc {
54
55   String JavaDoc query;
56   Object JavaDoc[] parameters;
57   boolean[] parametersSet;
58   int parametersCount;
59   ArrayList parameterBatch;
60   DaffodilDBResultSetMetaData metaData;
61   _PreparedStatement serverPreparedStatement;
62   int autoGeneratedKeyType ;
63   Object JavaDoc autoGeneratedKeyParams;
64   /**
65    * Ture in case when UDF is used.
66    */

67    boolean userDefinedFunction ;
68    private Object JavaDoc[] executeObject = null;
69
70
71
72   public DaffodilDBPreparedStatement(DaffodilDBConnection connection,
73                                      String JavaDoc query) throws SQLException {
74     this(connection, query, ResultSet.TYPE_FORWARD_ONLY,
75          ResultSet.CONCUR_READ_ONLY);
76   }
77
78   public DaffodilDBPreparedStatement(DaffodilDBConnection connection,
79                                      String JavaDoc sql, int resultSetType,
80                                      int resultSetConcurrency) throws
81       SQLException {
82     this(connection, sql, resultSetType, resultSetConcurrency,
83          1 /*ResultSet.HOLD_CURSORS_OVER_COMMIT*/,_Connection.NOAUTOGENERATEDKEYS,null);
84   }
85
86   public DaffodilDBPreparedStatement(DaffodilDBConnection connection,
87                                      String JavaDoc sql, int autoGeneratedKeys) throws
88       SQLException {
89     this(connection, sql, ResultSet.TYPE_FORWARD_ONLY,
90          ResultSet.CONCUR_READ_ONLY,
91          1/*ResultSet.HOLD_CURSORS_OVER_COMMIT*/,
92          autoGeneratedKeys == NO_GENERATED_KEYS ?_Connection.NOAUTOGENERATEDKEYS
93                                       : _Connection.AUTOGENERATEDKEYS, null);
94   }
95
96   public DaffodilDBPreparedStatement(DaffodilDBConnection connection,
97                                      String JavaDoc sql, int[] columnIndexes) throws
98       SQLException {
99     this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
100          1 /*ResultSet.HOLD_CURSORS_OVER_COMMIT*/,_Connection.COLUMNINDEXES,columnIndexes);
101   }
102
103   public DaffodilDBPreparedStatement(DaffodilDBConnection connection,
104                                      String JavaDoc sql, String JavaDoc[] columnNames) throws
105       SQLException {
106     this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
107          1 /*ResultSet.HOLD_CURSORS_OVER_COMMIT*/,_Connection.COLUMNNAMES,columnNames);
108   }
109
110   public DaffodilDBPreparedStatement(DaffodilDBConnection connection,
111                                      String JavaDoc sql, int resultSetType,
112                                      int resultSetConcurrency,
113                                      int resultSetHoldability) throws
114       SQLException {
115     this(connection, sql, resultSetType, resultSetConcurrency,
116          resultSetHoldability,_Connection.NOAUTOGENERATEDKEYS,null);
117   }
118
119
120   public DaffodilDBPreparedStatement(DaffodilDBConnection connection,
121                                      String JavaDoc sql, int resultSetType,
122                                      int resultSetConcurrency,
123                                      int resultSetHoldability,int autoType0, Object JavaDoc autoParam0) throws
124       SQLException {
125     super(connection, resultSetType, resultSetConcurrency, resultSetHoldability);
126     if (sql == null || sql.length() == 0) {
127       DException dex = new DException("DSE828", null);
128       throw dex.getSqlException(connection.getLocale());
129     }
130     query = sql;
131     autoGeneratedKeyType = autoType0;
132     autoGeneratedKeyParams = autoParam0;
133     setPreparedStatement();
134   }
135
136
137
138   /**
139    * Executes the SQL statement in this <code>PreparedStatement</code> object,
140    * which may be any kind of SQL statement.
141    * Some prepared statements return multiple results; the <code>execute</code>
142    * method handles these complex statements as well as the simpler
143    * form of statements handled by the methods <code>executeQuery</code>
144    * and <code>executeUpdate</code>.
145    * <P>
146    * The <code>execute</code> method returns a <code>boolean</code> to
147    * indicate the form of the first result. You must call either the method
148    * <code>getResultSet</code> or <code>getUpdateCount</code>
149    * to retrieve the result; you must call <code>getMoreResults</code> to
150    * move to any subsequent result(s).
151    *
152    * @return <code>true</code> if the first result is a <code>ResultSet</code>
153    * object; <code>false</code> if the first result is an update
154    * count or there is no result
155    * @exception SQLException if a database access error occurs or an argument
156    * is supplied to this method
157    * @see Statement#execute
158    * @see Statement#getResultSet
159    * @see Statement#getUpdateCount
160    * @see Statement#getMoreResults
161    */

162
163   public synchronized boolean execute() throws SQLException {
164     checkConnection();
165     writeToLog(query);
166     createEnvironmentToExecute(true);
167     checkIfAllParametersSet();
168     printQueryParam();
169     if (resultSet != null) {
170       resultSet.close();
171       resultSet = null;
172     }
173     updateCount = -1;
174     currentResultIndex = 0;
175     Object JavaDoc[] reqObject = null;
176     try {
177       synchronized (connection) {
178         executeResult = new Object JavaDoc[] {
179             serverPreparedStatement.execute(parameters.length == 0 ? null :
180                                             parameters, queryTimeOut)};
181         reqObject = getRequiredObjectOfExecute(
182             executeResult[0], resultSetConcurrency,maxRows);
183       }
184     }
185     catch (DException dxe) {
186       throw dxe.getSqlException(connection.getLocale());
187     }
188
189     if (reqObject[0] instanceof _RecordSetBuffer) {
190       executeResult[0] = reqObject[0];
191       _RecordSetBuffer recordSetBuffer = (_RecordSetBuffer) executeResult[0];
192       resultSet = new DaffodilDBResultSet(this);
193       resultSet.setRecordSetBuffer(recordSetBuffer);
194       int oldResultSetCon = resultSetConcurrency;
195       resultSetConcurrency = reqObject[1].hashCode();
196       if(oldResultSetCon != resultSetConcurrency )
197         addWarning("the resultSet Concurency is set ResultSet.CONCUR_READ_ONLY " ) ;
198
199       setResultSetAttributes();
200       setRecordSetBufferAttributes(recordSetBuffer);
201       resultSetConcurrency = oldResultSetCon;
202       return true;
203     }
204     if(reqObject[0] instanceof DMLResult){
205       dmlResult = (DMLResult)reqObject[0];
206       executeResult[0] = new Integer JavaDoc(dmlResult.rowsEffected);
207     }else{
208       executeResult[0] = reqObject[0];
209     }
210     updateCount = executeResult[0].hashCode();
211     updateCount = updateCount == Integer.MIN_VALUE ? 0 : updateCount;
212     return false;
213   }
214
215   /**
216    * Executes the SQL query in this <code>PreparedStatement</code> object
217    * and returns the <code>ResultSet</code> object generated by the query.
218    *
219        * @return a <code>ResultSet</code> object that contains the data produced by the
220    * query; never <code>null</code>
221    * @exception SQLException if a database access error occurs or the SQL
222    * statement does not return a <code>ResultSet</code> object
223    */

224
225   public synchronized ResultSet executeQuery() throws SQLException {
226     checkConnection();
227     writeToLog("Query",query);
228     createEnvironmentToExecute(true);
229     checkIfAllParametersSet();
230     printQueryParam();
231     if (resultSet != null) {
232       resultSet.close();
233       resultSet = null;
234     }
235     updateCount = -1;
236
237     Object JavaDoc result[] = null;
238     try {
239       if (serverPreparedStatement.getQueryType() !=
240           _PreparedStatement.queryexpression) {
241         DException ex = new DException("DSE86", null);
242         throw ex.getSqlException(connection.getLocale());
243       }
244       synchronized (connection ) {
245         result = getRequiredObjectOfExecute(
246             serverPreparedStatement.execute(parameters.length == 0 ? null :
247                                             parameters, queryTimeOut),
248             resultSetConcurrency,maxRows);
249       }
250     }
251     catch (DException dxe) {
252       throw dxe.getSqlException(connection.getLocale());
253     }
254     _RecordSetBuffer recordSetBuffer = (_RecordSetBuffer)result[0];
255     resultSet = new DaffodilDBResultSet(this);
256     resultSet.setRecordSetBuffer(recordSetBuffer);
257     int oldResultSetCon = resultSetConcurrency;
258     resultSetConcurrency = result[1].hashCode();
259     if(oldResultSetCon != resultSetConcurrency )
260       addWarning("the resultSet Concurency is set ResultSet.CONCUR_READ_ONLY " ) ;
261     setResultSetAttributes();
262     setRecordSetBufferAttributes(recordSetBuffer);
263     resultSetConcurrency = oldResultSetCon;
264     return resultSet;
265   }
266
267   /**
268    * Executes the SQL statement in this <code>PreparedStatement</code> object,
269    * which must be an SQL <code>INSERT</code>, <code>UPDATE</code> or
270    * <code>DELETE</code> statement; or an SQL statement that returns nothing,
271    * such as a DDL statement.
272    *
273    * @return either (1) the row count for <code>INSERT</code>, <code>UPDATE</code>,
274    * or <code>DELETE</code> statements
275    * or (2) 0 for SQL statements that return nothing
276    * @exception SQLException if a database access error occurs or the SQL
277    * statement returns a <code>ResultSet</code> object
278    */

279
280   public synchronized int executeUpdate() throws SQLException {
281     checkConnection();
282     writeToLog("Update", query );
283     createEnvironmentToExecute(true);
284     checkIfAllParametersSet();
285     printQueryParam();
286     if (resultSet != null) {
287       resultSet.close();
288       resultSet = null;
289     }
290     updateCount = -1;
291
292     Object JavaDoc result = null;
293     try {
294       if (serverPreparedStatement.getQueryType() ==
295           _PreparedStatement.queryexpression) {
296         DException ex = new DException("DSE533",null);
297         throw ex.getSqlException(connection.getLocale());
298       }
299       synchronized (connection) {
300         result = serverPreparedStatement.execute(parameters.length == 0 ? null :
301                                                  parameters, queryTimeOut);
302       }
303     }
304     catch (DException dxe) {
305       throw dxe.getSqlException(connection.getLocale());
306     }
307     if (result instanceof _SelectIterator) {
308       DException dex = new DException("DSE819", null);
309       throw dex.getSqlException(connection.getLocale());
310     }
311     if(result instanceof DMLResult){
312       dmlResult = (DMLResult)result;
313       updateCount = dmlResult.rowsEffected;
314     }else{
315       updateCount = result.hashCode();
316       updateCount = updateCount == Integer.MIN_VALUE ? 0 : updateCount;
317     }
318     return updateCount;
319   }
320
321   /**
322    * Sets the designated parameter to SQL <code>NULL</code>.
323    *
324    * <P><B>Note:</B> You must specify the parameter's SQL type.
325    *
326    * @param parameterIndex the first parameter is 1, the second is 2, ...
327    * @param sqlType the SQL type code defined in <code>java.sql.Types</code>
328    * @exception SQLException if a database access error occurs
329    */

330
331   public synchronized void setNull(int parameterIndex, int sqlType) throws SQLException {
332     setObject(parameterIndex, null, sqlType);
333   }
334
335   /**
336        * Sets the designated parameter to the given Java <code>boolean</code> value.
337    * The driver converts this
338    * to an SQL <code>BIT</code> value when it sends it to the database.
339    *
340    * @param parameterIndex the first parameter is 1, the second is 2, ...
341    * @param x the parameter value
342    * @exception SQLException if a database access error occurs
343    */

344
345   public synchronized void setBoolean(int parameterIndex, boolean x) throws SQLException {
346     setObject(parameterIndex, Utilities.getBooleanValue(x));
347   }
348
349   /**
350    * Sets the designated parameter to the given Java <code>byte</code> value.
351    * The driver converts this
352    * to an SQL <code>TINYINT</code> value when it sends it to the database.
353    *
354    * @param parameterIndex the first parameter is 1, the second is 2, ...
355    * @param x the parameter value
356    * @exception SQLException if a database access error occurs
357    */

358
359   public synchronized void setByte(int parameterIndex, byte x) throws SQLException {
360     setObject(parameterIndex, new Byte JavaDoc(x));
361   }
362
363   /**
364    * Sets the designated parameter to the given Java <code>short</code> value.
365    * The driver converts this
366    * to an SQL <code>SMALLINT</code> value when it sends it to the database.
367    *
368    * @param parameterIndex the first parameter is 1, the second is 2, ...
369    * @param x the parameter value
370    * @exception SQLException if a database access error occurs
371    */

372
373   public synchronized void setShort(int parameterIndex, short x) throws SQLException {
374     setObject(parameterIndex, new Short JavaDoc(x));
375   }
376
377   /**
378    * Sets the designated parameter to the given Java <code>int</code> value.
379    * The driver converts this
380    * to an SQL <code>INTEGER</code> value when it sends it to the database.
381    *
382    * @param parameterIndex the first parameter is 1, the second is 2, ...
383    * @param x the parameter value
384    * @exception SQLException if a database access error occurs
385    */

386
387   public synchronized void setInt(int parameterIndex, int x) throws SQLException {
388     setObject(parameterIndex, new Integer JavaDoc(x));
389   }
390
391   /**
392    * Sets the designated parameter to the given Java <code>long</code> value.
393    * The driver converts this
394    * to an SQL <code>BIGINT</code> value when it sends it to the database.
395    *
396    * @param parameterIndex the first parameter is 1, the second is 2, ...
397    * @param x the parameter value
398    * @exception SQLException if a database access error occurs
399    */

400
401   public synchronized void setLong(int parameterIndex, long x) throws SQLException {
402     setObject(parameterIndex, new Long JavaDoc(x));
403   }
404
405   /**
406    * Sets the designated parameter to the given Java <code>float</code> value.
407    * The driver converts this
408    * to an SQL <code>FLOAT</code> value when it sends it to the database.
409    *
410    * @param parameterIndex the first parameter is 1, the second is 2, ...
411    * @param x the parameter value
412    * @exception SQLException if a database access error occurs
413    */

414
415   public synchronized void setFloat(int parameterIndex, float x) throws SQLException {
416     setObject(parameterIndex, new Float JavaDoc(x));
417   }
418
419   /**
420    * Sets the designated parameter to the given Java <code>double</code> value.
421    * The driver converts this
422    * to an SQL <code>DOUBLE</code> value when it sends it to the database.
423    *
424    * @param parameterIndex the first parameter is 1, the second is 2, ...
425    * @param x the parameter value
426    * @exception SQLException if a database access error occurs
427    */

428
429   public synchronized void setDouble(int parameterIndex, double x) throws SQLException {
430     setObject(parameterIndex, new Double JavaDoc(x));
431   }
432
433   /**
434    * Sets the designated parameter to the given <code>java.math.BigDecimal</code> value.
435    * The driver converts this to an SQL <code>NUMERIC</code> value when
436    * it sends it to the database.
437    *
438    * @param parameterIndex the first parameter is 1, the second is 2, ...
439    * @param x the parameter value
440    * @exception SQLException if a database access error occurs
441    */

442
443   public synchronized void setBigDecimal(int parameterIndex, BigDecimal x) throws
444       SQLException {
445     setObject(parameterIndex, x);
446   }
447
448   /**
449    * Sets the designated parameter to the given Java <code>String</code> value.
450    * The driver converts this
451    * to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value
452    * (depending on the argument's
453    * size relative to the driver's limits on <code>VARCHAR</code> values)
454    * when it sends it to the database.
455    *
456    * @param parameterIndex the first parameter is 1, the second is 2, ...
457    * @param x the parameter value
458    * @exception SQLException if a database access error occurs
459    */

460
461   public synchronized void setString(int parameterIndex, String JavaDoc x) throws SQLException {
462     setObject(parameterIndex, x);
463   }
464
465   /**
466    * Sets the designated parameter to the given Java array of bytes. The driver converts
467    * this to an SQL <code>VARBINARY</code> or <code>LONGVARBINARY</code>
468    * (depending on the argument's size relative to the driver's limits on
469    * <code>VARBINARY</code> values) when it sends it to the database.
470    *
471    * @param parameterIndex the first parameter is 1, the second is 2, ...
472    * @param x the parameter value
473    * @exception SQLException if a database access error occurs
474    */

475
476   public synchronized void setBytes(int parameterIndex, byte x[]) throws SQLException {
477     setObject(parameterIndex, x);
478   }
479
480   /**
481    * Sets the designated parameter to the given <code>java.sql.Date</code> value.
482    * The driver converts this
483    * to an SQL <code>DATE</code> value when it sends it to the database.
484    *
485    * @param parameterIndex the first parameter is 1, the second is 2, ...
486    * @param x the parameter value
487    * @exception SQLException if a database access error occurs
488    */

489
490   public synchronized void setDate(int parameterIndex, java.sql.Date JavaDoc x) throws SQLException {
491     setObject(parameterIndex, x);
492   }
493
494   /**
495    * Sets the designated parameter to the given <code>java.sql.Time</code> value.
496    * The driver converts this
497    * to an SQL <code>TIME</code> value when it sends it to the database.
498    *
499    * @param parameterIndex the first parameter is 1, the second is 2, ...
500    * @param x the parameter value
501    * @exception SQLException if a database access error occurs
502    */

503
504   public synchronized void setTime(int parameterIndex, java.sql.Time JavaDoc x) throws SQLException {
505     setObject(parameterIndex, x);
506   }
507
508   /**
509    * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value.
510    * The driver
511        * converts this to an SQL <code>TIMESTAMP</code> value when it sends it to the
512    * database.
513    *
514    * @param parameterIndex the first parameter is 1, the second is 2, ...
515    * @param x the parameter value
516    * @exception SQLException if a database access error occurs
517    */

518
519   public synchronized void setTimestamp(int parameterIndex, java.sql.Timestamp JavaDoc x) throws
520       SQLException {
521     setObject(parameterIndex, x);
522   }
523
524   /**
525    * Sets the designated parameter to the given input stream, which will have
526    * the specified number of bytes.
527    * When a very large ASCII value is input to a <code>LONGVARCHAR</code>
528    * parameter, it may be more practical to send it via a
529    * <code>java.io.InputStream</code>. Data will be read from the stream
530    * as needed until end-of-file is reached. The JDBC driver will
531    * do any necessary conversion from ASCII to the database char format.
532    *
533    * <P><B>Note:</B> This stream object can either be a standard
534    * Java stream object or your own subclass that implements the
535    * standard interface.
536    *
537    * @param parameterIndex the first parameter is 1, the second is 2, ...
538    * @param x the Java input stream that contains the ASCII parameter value
539    * @param length the number of bytes in the stream
540    * @exception SQLException if a database access error occurs
541    */

542
543   public synchronized void setAsciiStream(int parameterIndex, java.io.InputStream JavaDoc x,
544                              int length) throws SQLException {
545     byte[] bytes = new byte[length];
546     try {
547       x.read(bytes, 0, length);
548     }
549     catch (java.io.IOException JavaDoc ex) {
550       DException dxe = new DException("DSE513", null);
551       throw dxe.getSqlException(connection.getLocale());
552     }
553     setObject(parameterIndex, bytes);
554   }
555
556   /**
557    * Sets the designated parameter to the given input stream, which
558    * will have the specified number of bytes. A Unicode character has
559    * two bytes, with the first byte being the high byte, and the second
560    * being the low byte.
561    *
562    * When a very large Unicode value is input to a <code>LONGVARCHAR</code>
563    * parameter, it may be more practical to send it via a
564    * <code>java.io.InputStream</code> object. The data will be read from the
565    * stream as needed until end-of-file is reached. The JDBC driver will
566    * do any necessary conversion from Unicode to the database char format.
567    *
568    * <P><B>Note:</B> This stream object can either be a standard
569    * Java stream object or your own subclass that implements the
570    * standard interface.
571    *
572    * @param parameterIndex the first parameter is 1, the second is 2, ...
573    * @param x a <code>java.io.InputStream</code> object that contains the
574    * Unicode parameter value as two-byte Unicode characters
575    * @param length the number of bytes in the stream
576    * @exception SQLException if a database access error occurs
577    * @deprecated
578    */

579
580   public synchronized void setUnicodeStream(int parameterIndex, java.io.InputStream JavaDoc x,
581                                int length) throws SQLException {
582     byte[] bytes = new byte[length];
583     try {
584       x.read(bytes, 0, length);
585     }
586     catch (java.io.IOException JavaDoc ex) {
587       DException dxe = new DException("DSE513", null);
588       throw dxe.getSqlException(connection.getLocale());
589     }
590     setObject(parameterIndex, bytes);
591   }
592
593   /**
594    * Sets the designated parameter to the given input stream, which will have
595    * the specified number of bytes.
596    * When a very large binary value is input to a <code>LONGVARBINARY</code>
597    * parameter, it may be more practical to send it via a
598    * <code>java.io.InputStream</code> object. The data will be read from the
599    * stream as needed until end-of-file is reached.
600    *
601    * <P><B>Note:</B> This stream object can either be a standard
602    * Java stream object or your own subclass that implements the
603    * standard interface.
604    *
605    * @param parameterIndex the first parameter is 1, the second is 2, ...
606    * @param x the java input stream which contains the binary parameter value
607    * @param length the number of bytes in the stream
608    * @exception SQLException if a database access error occurs
609    */

610   public synchronized void setBinaryStream(int parameterIndex, java.io.InputStream JavaDoc x,
611                               int length) throws SQLException {
612     byte[] bytes = new byte[length];
613     try {
614       x.read(bytes, 0, length);
615     }
616     catch (java.io.IOException JavaDoc ex) {
617       DException dxe = new DException("DSE513", null);
618       throw dxe.getSqlException(connection.getLocale());
619     }
620     setObject(parameterIndex, bytes);
621   }
622
623   /**
624    * Clears the current parameter values immediately.
625    * <P>In general, parameter values remain in force for repeated use of a
626    * statement. Setting a parameter value automatically clears its
627    * previous value. However, in some cases it is useful to immediately
628    * release the resources used by the current parameter values; this can
629    * be done by calling the method <code>clearParameters</code>.
630    *
631    * @exception SQLException if a database access error occurs
632    */

633
634   public synchronized void clearParameters() throws SQLException {
635     checkConnection();
636     Arrays.fill(parametersSet, false);
637     Arrays.fill(parameters, null);
638   }
639
640
641   /**
642    * <p>Sets the value of the designated parameter with the given object. The second
643    * argument must be an object type; for integral values, the
644    * <code>java.lang</code> equivalent objects should be used.
645    *
646    * <p>The given Java object will be converted to the given targetSqlType
647    * before being sent to the database.
648    *
649    * If the object has a custom mapping (is of a class implementing the
650    * interface <code>SQLData</code>),
651    * the JDBC driver should call the method <code>SQLData.writeSQL</code> to
652    * write it to the SQL data stream.
653    * If, on the other hand, the object is of a class implementing
654        * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>Struct</code>,
655    * or <code>Array</code>, the driver should pass it to the database as a
656    * value of the corresponding SQL type.
657    *
658    * <p>Note that this method may be used to pass database-specific
659    * abstract data types.
660    *
661    * @param parameterIndex the first parameter is 1, the second is 2, ...
662    * @param x the object containing the input parameter value
663    * @param targetSqlType the SQL type (as defined in java.sql.Types) to be
664    * sent to the database. The scale argument may further qualify this type.
665    * @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types,
666        * this is the number of digits after the decimal point. For all other
667    * types, this value will be ignored.
668    * @exception SQLException if a database access error occurs
669    * @see Types
670    */

671
672   public synchronized void setObject(int parameterIndex, Object JavaDoc x, int targetSqlType,
673                         int scale) throws SQLException {
674     Object JavaDoc value = null;
675     try {
676       value = Utilities.convertObject(x, targetSqlType);
677     }
678     catch (DException dxe) {
679       throw dxe.getSqlException(connection.getLocale());
680     }
681     if (targetSqlType == java.sql.Types.DECIMAL &&
682         value instanceof java.math.BigDecimal JavaDoc) {
683       java.math.BigDecimal JavaDoc numericValue = (java.math.BigDecimal JavaDoc) value;
684       value = scale == -1 ? numericValue :
685           numericValue.setScale(scale, numericValue.ROUND_DOWN);
686     }
687     setObject(parameterIndex, value);
688   }
689
690   /**
691    * Sets the value of the designated parameter with the given object.
692    * This method is like the method <code>setObject</code>
693    * above, except that it assumes a scale of zero.
694    *
695    * @param parameterIndex the first parameter is 1, the second is 2, ...
696    * @param x the object containing the input parameter value
697    * @param targetSqlType the SQL type (as defined in java.sql.Types) to be
698    * sent to the database
699    * @exception SQLException if a database access error occurs
700    */

701
702   public synchronized void setObject(int parameterIndex, Object JavaDoc x, int targetSqlType) throws
703       SQLException {
704     try {
705       Object JavaDoc o = Utilities.convertObject(x, targetSqlType);
706       setObject(parameterIndex, o);
707     }
708     catch (DException dxe) {
709       throw dxe.getSqlException(connection.getLocale());
710     }
711   }
712
713   /**
714    * <p>Sets the value of the designated parameter using the given object.
715    * The second parameter must be of type <code>Object</code>; therefore, the
716    * <code>java.lang</code> equivalent objects should be used for built-in types.
717    *
718    * <p>The JDBC specification specifies a standard mapping from
719    * Java <code>Object</code> types to SQL types. The given argument
720    * will be converted to the corresponding SQL type before being
721    * sent to the database.
722    *
723    * <p>Note that this method may be used to pass datatabase-
724    * specific abstract data types, by using a driver-specific Java
725    * type.
726    *
727    * If the object is of a class implementing the interface <code>SQLData</code>,
728    * the JDBC driver should call the method <code>SQLData.writeSQL</code>
729    * to write it to the SQL data stream.
730    * If, on the other hand, the object is of a class implementing
731    * <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>Struct</code>,
732    * or <code>Array</code>, the driver should pass it to the database as a
733    * value of the corresponding SQL type.
734    * <P>
735    * This method throws an exception if there is an ambiguity, for example, if the
736    * object is of a class implementing more than one of the interfaces named above.
737    *
738    * @param parameterIndex the first parameter is 1, the second is 2, ...
739    * @param x the object containing the input parameter value
740    * @exception SQLException if a database access error occurs or the type
741    * of the given object is ambiguous
742    */

743
744   public synchronized void setObject(int parameterIndex, Object JavaDoc x) throws SQLException {
745     checkConnection();
746     checkValidParameterIndex(parameterIndex);
747     parametersSet[parameterIndex - 1] = true;
748     parameters[parameterIndex - 1] = x;
749   }
750
751   /** ------------------------------------
752    * JDBC 2.0
753    * -------------------------------------
754    */

755
756   /**
757    * Adds a set of parameters to this <code>PreparedStatement</code>
758    * object's batch of commands.
759    *
760    * @exception SQLException if a database access error occurs
761    * @see Statement#addBatch
762    * @since 1.2
763    */

764
765   public synchronized void addBatch() throws SQLException {
766     checkConnection();
767     checkIfAllParametersSet();
768     try {
769       parameterBatch.add(parameters);
770     }
771     catch (NullPointerException JavaDoc npe) {
772       parameterBatch = new ArrayList(4);
773       parameterBatch.add(parameters);
774     }
775     parametersSet = new boolean[parametersCount];
776     parameters = new Object JavaDoc[parametersCount];
777     Arrays.fill(parametersSet, false);
778   }
779
780   /**
781    * Sets the designated parameter to the given <code>Reader</code>
782    * object, which is the given number of characters long.
783    * When a very large UNICODE value is input to a <code>LONGVARCHAR</code>
784    * parameter, it may be more practical to send it via a
785    * <code>java.io.Reader</code> object. The data will be read from the stream
786    * as needed until end-of-file is reached. The JDBC driver will
787    * do any necessary conversion from UNICODE to the database char format.
788    *
789    * <P><B>Note:</B> This stream object can either be a standard
790    * Java stream object or your own subclass that implements the
791    * standard interface.
792    *
793    * @param parameterIndex the first parameter is 1, the second is 2, ...
794    * @param reader the <code>java.io.Reader</code> object that contains the
795    * Unicode data
796    * @param length the number of characters in the stream
797    * @exception SQLException if a database access error occurs
798    * @since 1.2
799    */

800
801   public synchronized void setCharacterStream(int parameterIndex, java.io.Reader JavaDoc reader,
802                                  int length) throws SQLException {
803     try {
804       char[] chars = new char[length];
805       reader.read(chars, 0, length);
806       byte[] bytes = Utilities.convertCharsToBytes(chars);
807       setObject(parameterIndex, bytes);
808     }
809     catch (Exception JavaDoc ex) {
810       DException dxe = new DException("DSE513", null);
811       throw dxe.getSqlException(connection.getLocale());
812     }
813   }
814
815   /**
816    * Sets the designated parameter to the given
817    * <code>REF(&lt;structured-type&gt;)</code> value.
818    * The driver converts this to an SQL <code>REF</code> value when it
819    * sends it to the database.
820    *
821    * @param parameterIndex the first parameter is 1, the second is 2, ...
822    * @param x an SQL <code>REF</code> value
823    * @exception SQLException if a database access error occurs
824    * @since 1.2
825    */

826
827   public synchronized void setRef(int parameterIndex, Ref x) throws SQLException {
828     setObject(parameterIndex, x);
829   }
830
831   /**
832    * Sets the designated parameter to the given <code>Blob</code> object.
833    * The driver converts this to an SQL <code>BLOB</code> value when it
834    * sends it to the database.
835    *
836    * @param parameterIndex the first parameter is 1, the second is 2, ...
837        * @param x a <code>Blob</code> object that maps an SQL <code>BLOB</code> value
838    * @exception SQLException if a database access error occurs
839    * @since 1.2
840    */

841
842   public synchronized void setBlob(int parameterIndex, Blob x) throws SQLException {
843     setObject(parameterIndex, x);
844   }
845
846   /**
847    * Sets the designated parameter to the given <code>Clob</code> object.
848    * The driver converts this to an SQL <code>CLOB</code> value when it
849    * sends it to the database.
850    *
851    * @param parameterIndex the first parameter is 1, the second is 2, ...
852        * @param x a <code>Clob</code> object that maps an SQL <code>CLOB</code> value
853    * @exception SQLException if a database access error occurs
854    * @since 1.2
855    */

856   public synchronized void setClob(int parameterIndex, Clob x) throws SQLException {
857     setObject(parameterIndex, x);
858   }
859
860   /**
861    * Sets the designated parameter to the given <code>Array</code> object.
862    * The driver converts this to an SQL <code>ARRAY</code> value when it
863    * sends it to the database.
864    *
865    * @param parameterIndex the first parameter is 1, the second is 2, ...
866    * @param x an <code>Array</code> object that maps an SQL <code>ARRAY</code> value
867    * @exception SQLException if a database access error occurs
868    * @since 1.2
869    */

870
871   public synchronized void setArray(int parameterIndex, Array x) throws SQLException {
872     setObject(parameterIndex, x);
873   }
874
875   /**
876    * Retrieves a <code>ResultSetMetaData</code> object that contains
877    * information about the columns of the <code>ResultSet</code> object
878    * that will be returned when this <code>PreparedStatement</code> object
879    * is executed.
880    * <P>
881    * Because a <code>PreparedStatement</code> object is precompiled, it is
882    * possible to know about the <code>ResultSet</code> object that it will
883    * return without having to execute it. Consequently, it is possible
884    * to invoke the method <code>getMetaData</code> on a
885    * <code>PreparedStatement</code> object rather than waiting to execute
886    * it and then invoking the <code>ResultSet.getMetaData</code> method
887    * on the <code>ResultSet</code> object that is returned.
888    * <P>
889    * <B>NOTE:</B> Using this method may be expensive for some drivers due
890    * to the lack of underlying DBMS support.
891    *
892    * @return the description of a <code>ResultSet</code> object's columns or
893    * <code>null</code> if the driver cannot return a
894    * <code>ResultSetMetaData</code> object
895    * @exception SQLException if a database access error occurs
896    * @since 1.2
897    * @ todo getMetaData()
898    */

899
900   public synchronized ResultSetMetaData getMetaData() throws SQLException {
901     if (metaData == null) {
902       try {
903         _ColumnCharacteristics clmchs = serverPreparedStatement.
904             getColumnCharacteristics();
905         metaData = new DaffodilDBResultSetMetaData(connection);
906         metaData.setColumnCharacteristics(clmchs);
907       }
908       catch (DException dxe) {
909         throw dxe.getSqlException(connection.getLocale());
910       }
911     }
912     return metaData;
913   }
914
915   /**
916        * Sets the designated parameter to the given <code>java.sql.Date</code> value,
917    * using the given <code>Calendar</code> object. The driver uses
918        * the <code>Calendar</code> object to construct an SQL <code>DATE</code> value,
919    * which the driver then sends to the database. With a
920    * a <code>Calendar</code> object, the driver can calculate the date
921    * taking into account a custom timezone. If no
922    * <code>Calendar</code> object is specified, the driver uses the default
923    * timezone, which is that of the virtual machine running the application.
924    *
925    * @param parameterIndex the first parameter is 1, the second is 2, ...
926    * @param x the parameter value
927    * @param cal the <code>Calendar</code> object the driver will use
928    * to construct the date
929    * @exception SQLException if a database access error occurs
930    * @since 1.2
931    */

932
933   public synchronized void setDate(int parameterIndex, java.sql.Date JavaDoc x, Calendar cal) throws
934       SQLException {
935     cal.setTime(x);
936     java.sql.Date JavaDoc date = new com.daffodilwoods.daffodildb.utils.DBDate(cal.getTime().getTime());
937     setObject(parameterIndex, date);
938   }
939
940   /**
941        * Sets the designated parameter to the given <code>java.sql.Time</code> value,
942    * using the given <code>Calendar</code> object. The driver uses
943        * the <code>Calendar</code> object to construct an SQL <code>TIME</code> value,
944    * which the driver then sends to the database. With a
945    * a <code>Calendar</code> object, the driver can calculate the time
946    * taking into account a custom timezone. If no
947    * <code>Calendar</code> object is specified, the driver uses the default
948    * timezone, which is that of the virtual machine running the application.
949    *
950    * @param parameterIndex the first parameter is 1, the second is 2, ...
951    * @param x the parameter value
952    * @param cal the <code>Calendar</code> object the driver will use
953    * to construct the time
954    * @exception SQLException if a database access error occurs
955    * @since 1.2
956    */

957
958   public synchronized void setTime(int parameterIndex, java.sql.Time JavaDoc x, Calendar cal) throws
959       SQLException {
960     cal.setTime(x);
961     Time time = new Time(cal.getTime().getTime());
962     setObject(parameterIndex, time);
963   }
964
965   /**
966    * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value,
967    * using the given <code>Calendar</code> object. The driver uses
968    * the <code>Calendar</code> object to construct an SQL <code>TIMESTAMP</code> value,
969    * which the driver then sends to the database. With a
970    * <code>Calendar</code> object, the driver can calculate the timestamp
971    * taking into account a custom timezone. If no
972    * <code>Calendar</code> object is specified, the driver uses the default
973    * timezone, which is that of the virtual machine running the application.
974    *
975    * @param parameterIndex the first parameter is 1, the second is 2, ...
976    * @param x the parameter value
977    * @param cal the <code>Calendar</code> object the driver will use
978    * to construct the timestamp
979    * @exception SQLException if a database access error occurs
980    * @since 1.2
981    */

982
983   public synchronized void setTimestamp(int parameterIndex, java.sql.Timestamp JavaDoc x,
984                            Calendar cal) throws SQLException {
985     cal.setTime(x);
986     Timestamp timeStamp = new Timestamp(cal.getTime().getTime());
987     setObject(parameterIndex, timeStamp);
988   }
989
990   /**
991    * Sets the designated parameter to SQL <code>NULL</code>.
992    * This version of the method < code>setNull</code> should
993    * be used for user-defined types and REF type parameters. Examples
994    * of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and
995    * named array types.
996    *
997    * <P><B>Note:</B> To be portable, applications must give the
998    * SQL type code and the fully-qualified SQL type name when specifying
999    * a NULL user-defined or REF parameter. In the case of a user-defined type
1000   * the name is the type name of the parameter itself. For a REF
1001   * parameter, the name is the type name of the referenced type. If
1002   * a JDBC driver does not need the type code or type name information,
1003   * it may ignore it.
1004   *
1005   * Although it is intended for user-defined and Ref parameters,
1006   * this method may be used to set a null parameter of any JDBC type.
1007   * If the parameter does not have a user-defined or REF type, the given
1008   * typeName is ignored.
1009   *
1010   *
1011   * @param parameterIndex the first parameter is 1, the second is 2, ...
1012   * @param sqlType a value from <code>java.sql.Types</code>
1013   * @param typeName the fully-qualified name of an SQL user-defined type;
1014   * ignored if the parameter is not a user-defined type or REF
1015   * @exception SQLException if a database access error occurs
1016   * @since 1.2
1017   */

1018
1019  public synchronized void setNull(int parameterIndex, int sqlType, String JavaDoc typeName) throws
1020      SQLException {
1021    setObject(parameterIndex, null, sqlType);
1022  }
1023
1024
1025  /**
1026       * Sets the designated parameter to the given <code>java.net.URL</code> value.
1027   * The driver converts this to an SQL <code>DATALINK</code> value
1028   * when it sends it to the database.
1029   *
1030   * @param parameterIndex the first parameter is 1, the second is 2, ...
1031   * @param x the <code>java.net.URL</code> object to be set
1032   * @exception SQLException if a database access error occurs
1033   * @since 1.4
1034   */

1035  public synchronized void setURL(int parameterIndex, java.net.URL JavaDoc x) throws SQLException {
1036    setObject(parameterIndex, x);
1037  }
1038
1039  /**
1040   * Retrieves the number, types and properties of this
1041   * <code>PreparedStatement</code> object's parameters.
1042   *
1043   * @return a <code>ParameterMetaData</code> object that contains information
1044   * about the number, types and properties of this
1045   * <code>PreparedStatement</code> object's parameters
1046   * @exception SQLException if a database access error occurs
1047   * @see ParameterMetaData
1048   * @since 1.4
1049   */

1050  public synchronized ParameterMetaData getParameterMetaData() throws SQLException {
1051    try {
1052      Class JavaDoc cl = Class.forName("in.co.daffodil.db.jdbc.DaffodilDBParameterMetaData");
1053      Constructor JavaDoc cons = cl.getConstructor(new Class JavaDoc[]{
1054      DaffodilDBConnection.class, _ParameterMetaData.class,Boolean JavaDoc.class});
1055      Object JavaDoc obj = cons.newInstance(new Object JavaDoc[]{connection,
1056                                    serverPreparedStatement.getParameterMetaData(),userDefinedFunction ? Boolean.TRUE : Boolean.FALSE
1057    });
1058      return (ParameterMetaData)obj;
1059    }
1060    catch (DException ex) {
1061      throw ex.getSqlException(connection.getLocale());
1062    }
1063    catch (Exception JavaDoc ex) {
1064      return null;
1065    }
1066  }
1067
1068  /*-------------------- Methods specific To DaffodilDBPreparedStatement and subclasses of this ----------------------*/
1069
1070  public synchronized int[] executeBatch() throws SQLException {
1071    checkConnection();
1072    if (parameterBatch == null)
1073      return new int[0];
1074    createEnvironmentToExecute(false);
1075    int size = parameterBatch.size();
1076    int[] abc = new int[size];
1077    Arrays.fill(abc, -3 /*EXECUTE_FAILED*/);
1078    Object JavaDoc obj = null;
1079    synchronized (connection) {
1080      for (int i = 0; i < size; i++) {
1081        try {
1082          if (serverPreparedStatement.getQueryType() ==
1083              _PreparedStatement.queryexpression) {
1084            DException ex = new DException("DSE533", null);
1085            throw new BatchUpdateException(ex.getMessage(), abc);
1086          }
1087          Object JavaDoc[] tempParam = (Object JavaDoc[]) parameterBatch.get(i);
1088          obj = serverPreparedStatement.execute(tempParam.length == 0 ? null
1089                                                : tempParam, queryTimeOut);
1090        }
1091        catch (DException E) {
1092          clearBatch();
1093          throw new BatchUpdateException(E.getMessage(), abc);
1094        }
1095        abc[i] = obj.hashCode();
1096        abc[i] = abc[i] == Integer.MIN_VALUE ? 0 : abc[i];
1097      }
1098    }
1099    clearBatch();
1100    return abc;
1101  }
1102
1103  public synchronized void clearBatch() throws SQLException {
1104    checkConnection();
1105    if (parameterBatch != null)
1106      parameterBatch.clear();
1107    clearParameters();
1108  }
1109
1110  public void addBatch(String JavaDoc query) throws SQLException {
1111    DException dex = new DException("DSE525", null);
1112    throw dex.getSqlException(connection.getLocale());
1113  }
1114
1115  public ResultSet executeQuery(String JavaDoc query) throws SQLException {
1116    DException dex = new DException("DSE567", null);
1117    throw dex.getSqlException(connection.getLocale());
1118  }
1119
1120  public int executeUpdate(String JavaDoc query) throws SQLException {
1121    DException dex = new DException("DSE567", null);
1122    throw dex.getSqlException(connection.getLocale());
1123  }
1124
1125  public boolean execute(String JavaDoc query) throws SQLException {
1126    DException dex = new DException("DSE567", null);
1127    throw dex.getSqlException(connection.getLocale());
1128  }
1129
1130  protected void checkIfAllParametersSet() throws SQLException{
1131    boolean flag = true;
1132    for (int i = 0; flag && i < parametersCount; i++)
1133      flag = flag && parametersSet[i];
1134    if(flag==false) {
1135      DException dex = new DException("DSE1157", null);
1136      throw dex.getSqlException(connection.getLocale());
1137    }
1138  }
1139
1140 protected void checkValidParameterIndex(int i) throws SQLException {
1141    if (i < 1 || i > parametersCount) {
1142      DException dex = new DException("DSE479", new Object JavaDoc[] {new Integer JavaDoc(i),
1143                                      new Integer JavaDoc(parametersCount)});
1144      throw dex.getSqlException(connection.getLocale());
1145    }
1146  }
1147
1148  protected void setPreparedStatement() throws SQLException {
1149    String JavaDoc queryForDB = changeQueryForDB(query);
1150    try {
1151      if(autoGeneratedKeyType == _Connection.NOAUTOGENERATEDKEYS){
1152        serverPreparedStatement = connection.getServerConnection().
1153            getPreparedStatement(queryForDB,
1154                                 resultSetConcurrency ==
1155                                 ResultSet.CONCUR_UPDATABLE ?
1156                                 IteratorConstants.UPDATABLE :
1157                                 IteratorConstants.NONSCROLLABLE);
1158      }
1159      else{
1160        serverPreparedStatement = connection.getServerConnection().
1161            getPreparedStatement(queryForDB,
1162                                 resultSetConcurrency ==
1163                                 ResultSet.CONCUR_UPDATABLE ?
1164                                 IteratorConstants.UPDATABLE :
1165                                 IteratorConstants.NONSCROLLABLE,autoGeneratedKeyType,autoGeneratedKeyParams);
1166      }
1167      parametersCount = serverPreparedStatement.getParameterCount();
1168    }
1169    catch (DException dxe) {
1170      throw dxe.getSqlException(connection.getLocale());
1171    }
1172    parametersSet = new boolean[parametersCount];
1173    parameters = new Object JavaDoc[parametersCount];
1174    Arrays.fill(parametersSet, false);
1175  }
1176
1177  protected void printQueryParam() throws SQLException {
1178  }
1179
1180  public synchronized void close() throws SQLException {
1181  if(connection == null ) // connection already closed.
1182
return;// We can't throw exception here because it's bug of compiere that they close pstmt twice sometime -- Manoj Kr. Sheoran May 2, 2005
1183

1184  if(serverPreparedStatement.getQueryType() == _PreparedStatement.queryexpression && connection.isStatementCachedEnabled()){
1185    this.clearParameters();
1186    connection.addToCache(Utilities.calculatehashCode(query,resultSetType,resultSetConcurrency,resultSetHoldability), this);
1187   }
1188    else
1189     serverPreparedStatement.close();
1190      super.close();
1191  }
1192
1193  protected Object JavaDoc[] getRequiredObjectOfExecute(Object JavaDoc returnObject,
1194                                                  int concurrency,int maxrows) throws
1195      DException, SQLException {
1196    return returnObject instanceof _SelectIterator ? getRequiredObjectOfExecuteQuery(returnObject, concurrency,maxrows) :
1197     new Object JavaDoc[] {returnObject,new Integer JavaDoc (concurrency)};
1198  }
1199
1200  private Object JavaDoc[] getRequiredObjectOfExecuteQuery(Object JavaDoc returnObject,
1201      int concurrency,int maxRows) throws DException, SQLException {
1202    _SelectIterator retriever = (_SelectIterator) returnObject;
1203    if (concurrency == ResultSet.CONCUR_UPDATABLE && retriever.isUpdatable()) {
1204      RecordSetUpdateable rsb = new RecordSetUpdateable();
1205      rsb.setSelectIterator(retriever);
1206      return new Object JavaDoc[]{rsb,new Integer JavaDoc(ResultSet.CONCUR_UPDATABLE)};
1207
1208    }
1209    RecordSet rsb = new RecordSet();
1210    rsb.setSelectIterator(retriever);
1211    return new Object JavaDoc[]{rsb,new Integer JavaDoc(ResultSet.CONCUR_READ_ONLY)};
1212  }
1213  public void setConnection(DaffodilDBConnection con ){
1214    connection = con;
1215  }
1216
1217}
1218
Popular Tags