Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: postgresql/jdbc2/Statement.java


1   package postgresql.jdbc2;
2   
3   // IMPORTANT NOTE: This file implements the JDBC 2 version of the driver.
4   // If you make any modifications to this file, you must make sure that the
5   // changes are also made (if relevent) to the related JDBC 1 class in the
6   // postgresql.jdbc1 package.
7   
8   import java.sql.*;
9   import java.util.Vector;
10  import postgresql.util.*;
11  
12  /**
13   * A Statement object is used for executing a static SQL statement and
14   * obtaining the results produced by it.
15   *
16   * <p>Only one ResultSet per Statement can be open at any point in time.  
17   * Therefore, if the reading of one ResultSet is interleaved with the
18   * reading of another, each must have been generated by different
19   * Statements.  All statement execute methods implicitly close a
20   * statement's current ResultSet if an open one exists.
21   *
22   * @see java.sql.Statement
23   * @see ResultSet
24   */
25  public class Statement implements java.sql.Statement
26  {
27      Connection connection;    // The connection who created us
28      java.sql.ResultSet result = null;  // The current results
29      SQLWarning warnings = null;  // The warnings chain.
30      int timeout = 0;    // The timeout for a query (not used)
31      boolean escapeProcessing = true;// escape processing flag
32      private Vector batch=null;
33      
34    /**
35     * Constructor for a Statement.  It simply sets the connection
36     * that created us.
37     *
38     * @param c the Connection instantation that creates us
39     */
40    public Statement (Connection c)
41    {
42      connection = c;
43    }
44  
45    /**
46     * Execute a SQL statement that retruns a single ResultSet
47     *
48     * @param sql typically a static SQL SELECT statement
49     * @return a ResulSet that contains the data produced by the query
50     * @exception SQLException if a database access error occurs
51     */
52    public java.sql.ResultSet executeQuery(String sql) throws SQLException
53    {
54      this.execute(sql);
55      while (result != null && !((postgresql.ResultSet)result).reallyResultSet())
56        result = ((postgresql.ResultSet)result).getNext();
57      if (result == null)
58        throw new PSQLException("postgresql.stat.noresult");
59      return result;
60    }
61  
62    /**
63     * Execute a SQL INSERT, UPDATE or DELETE statement.  In addition
64     * SQL statements that return nothing such as SQL DDL statements
65     * can be executed
66     *
67     * @param sql a SQL statement
68     * @return either a row count, or 0 for SQL commands
69     * @exception SQLException if a database access error occurs
70     */
71    public int executeUpdate(String sql) throws SQLException
72    {
73      this.execute(sql);
74      if (((postgresql.ResultSet)result).reallyResultSet())
75        throw new PSQLException("postgresql.stat.result");
76      return this.getUpdateCount();
77    }
78  
79    /**
80     * In many cases, it is desirable to immediately release a
81     * Statement's database and JDBC resources instead of waiting
82     * for this to happen when it is automatically closed.  The
83     * close method provides this immediate release.
84     *
85     * <p><B>Note:</B> A Statement is automatically closed when it is 
86     * garbage collected.  When a Statement is closed, its current 
87     * ResultSet, if one exists, is also closed.
88     *
89     * @exception SQLException if a database access error occurs (why?)
90     */
91    public void close() throws SQLException
92    {
93      result = null;
94    }
95  
96    /**
97     * The maxFieldSize limit (in bytes) is the maximum amount of
98     * data returned for any column value; it only applies to
99     * BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR and LONGVARCHAR
100    * columns.  If the limit is exceeded, the excess data is silently
101    * discarded.
102    *
103    * @return the current max column size limit; zero means unlimited
104    * @exception SQLException if a database access error occurs
105    */
106   public int getMaxFieldSize() throws SQLException
107   {
108     return 8192;    // We cannot change this
109   }
110 
111   /**
112    * Sets the maxFieldSize - NOT! - We throw an SQLException just
113    * to inform them to stop doing this.
114    *
115    * @param max the new max column size limit; zero means unlimited
116    * @exception SQLException if a database access error occurs
117    */
118   public void setMaxFieldSize(int max) throws SQLException
119   {
120     throw new PSQLException("postgresql.stat.maxfieldsize");
121   }
122 
123   /**
124    * The maxRows limit is set to limit the number of rows that
125    * any ResultSet can contain.  If the limit is exceeded, the
126    * excess rows are silently dropped.
127    *
128    * @return the current maximum row limit; zero means unlimited
129    * @exception SQLException if a database access error occurs
130    */
131   public int getMaxRows() throws SQLException
132   {
133     return connection.maxrows;
134   }
135 
136   /**
137    * Set the maximum number of rows
138    *
139    * @param max the new max rows limit; zero means unlimited
140    * @exception SQLException if a database access error occurs
141    * @see getMaxRows
142    */
143   public void setMaxRows(int max) throws SQLException
144   {
145     connection.maxrows = max;
146   }
147 
148   /**
149    * If escape scanning is on (the default), the driver will do escape
150    * substitution before sending the SQL to the database.  
151    *
152    * @param enable true to enable; false to disable
153    * @exception SQLException if a database access error occurs
154    */
155   public void setEscapeProcessing(boolean enable) throws SQLException
156   {
157     escapeProcessing = enable;
158   }
159 
160   /**
161    * The queryTimeout limit is the number of seconds the driver
162    * will wait for a Statement to execute.  If the limit is
163    * exceeded, a SQLException is thrown.
164    *
165    * @return the current query timeout limit in seconds; 0 = unlimited
166    * @exception SQLException if a database access error occurs
167    */
168   public int getQueryTimeout() throws SQLException
169   {
170     return timeout;
171   }
172 
173   /**
174    * Sets the queryTimeout limit
175    *
176    * @param seconds - the new query timeout limit in seconds
177    * @exception SQLException if a database access error occurs
178    */
179   public void setQueryTimeout(int seconds) throws SQLException
180   {
181     timeout = seconds;
182   }
183 
184   /**
185    * Cancel can be used by one thread to cancel a statement that
186    * is being executed by another thread.  However, PostgreSQL is
187    * a sync. sort of thing, so this really has no meaning - we 
188    * define it as a no-op (i.e. you can't cancel, but there is no
189    * error if you try.)
190    *
191    * 6.4 introduced a cancel operation, but we have not implemented it
192    * yet. Sometime before 6.5, this method will be implemented.
193    *
194    * @exception SQLException only because thats the spec.
195    */
196   public void cancel() throws SQLException
197   {
198     // No-op
199   }
200 
201   /**
202    * The first warning reported by calls on this Statement is
203    * returned.  A Statement's execute methods clear its SQLWarning
204    * chain.  Subsequent Statement warnings will be chained to this
205    * SQLWarning.
206    *
207    * <p>The Warning chain is automatically cleared each time a statement
208    * is (re)executed.
209    *
210    * <p><B>Note:</B>  If you are processing a ResultSet then any warnings
211    * associated with ResultSet reads will be chained on the ResultSet
212    * object.
213    *
214    * @return the first SQLWarning on null
215    * @exception SQLException if a database access error occurs
216    */
217   public SQLWarning getWarnings() throws SQLException
218   {
219     return warnings;
220   }
221 
222   /**
223    * After this call, getWarnings returns null until a new warning
224    * is reported for this Statement.
225    *
226    * @exception SQLException if a database access error occurs (why?)
227    */
228   public void clearWarnings() throws SQLException
229   {
230     warnings = null;
231   }
232 
233   /**
234    * setCursorName defines the SQL cursor name that will be used by
235    * subsequent execute methods.  This name can then be used in SQL
236    * positioned update/delete statements to identify the current row
237    * in the ResultSet generated by this statement.  If a database
238    * doesn't support positioned update/delete, this method is a
239    * no-op.
240    *
241    * <p><B>Note:</B> By definition, positioned update/delete execution
242    * must be done by a different Statement than the one which
243    * generated the ResultSet being used for positioning.  Also, cursor
244    * names must be unique within a Connection.
245    *
246    * <p>We throw an additional constriction.  There can only be one
247    * cursor active at any one time.
248    *
249    * @param name the new cursor name
250    * @exception SQLException if a database access error occurs
251    */
252   public void setCursorName(String name) throws SQLException
253   {
254     connection.setCursorName(name);
255   }
256 
257   /**
258    * Execute a SQL statement that may return multiple results. We
259    * don't have to worry about this since we do not support multiple
260    * ResultSets.   You can use getResultSet or getUpdateCount to 
261    * retrieve the result.
262    *
263    * @param sql any SQL statement
264    * @return true if the next result is a ResulSet, false if it is
265    *   an update count or there are no more results
266    * @exception SQLException if a database access error occurs
267    */
268   public boolean execute(String sql) throws SQLException
269   {
270     result = connection.ExecSQL(sql);
271     return (result != null && ((postgresql.ResultSet)result).reallyResultSet());
272   }
273 
274   /**
275    * getResultSet returns the current result as a ResultSet.  It
276    * should only be called once per result.
277    *
278    * @return the current result set; null if there are no more
279    * @exception SQLException if a database access error occurs (why?)
280    */
281   public java.sql.ResultSet getResultSet() throws SQLException
282   {
283     return result;
284   }
285 
286   /**
287    * getUpdateCount returns the current result as an update count,
288    * if the result is a ResultSet or there are no more results, -1
289    * is returned.  It should only be called once per result.
290    *
291    * @return the current result as an update count.
292    * @exception SQLException if a database access error occurs
293    */
294   public int getUpdateCount() throws SQLException
295   {
296     if (result == null)     return -1;
297     if (((postgresql.ResultSet)result).reallyResultSet())  return -1;
298     return ((postgresql.ResultSet)result).getResultCount();
299   }
300 
301   /**
302    * getMoreResults moves to a Statement's next result.  If it returns
303    * true, this result is a ResulSet.
304    *
305    * @return true if the next ResultSet is valid
306    * @exception SQLException if a database access error occurs
307    */
308   public boolean getMoreResults() throws SQLException
309   {
310     result = ((postgresql.ResultSet)result).getNext();
311     return (result != null && ((postgresql.ResultSet)result).reallyResultSet());
312   }
313    
314    /**
315     * Returns the status message from the current Result.<p>
316     * This is used internally by the driver.
317     *
318     * @return status message from backend
319     */
320    public String getResultStatusString()
321    {
322      if(result == null)
323        return null;
324      return ((postgresql.ResultSet)result).getStatusString();
325    }
326     
327     // ** JDBC 2 Extensions **
328     
329     public void addBatch(String sql) throws SQLException
330     {
331   if(batch==null)
332       batch=new Vector();
333   batch.addElement(sql);
334     }
335     
336     public void clearBatch() throws SQLException
337     {
338   if(batch!=null)
339       batch.removeAllElements();
340     }
341     
342     public int[] executeBatch() throws SQLException
343     {
344   if(batch==null || batch.isEmpty())
345       throw new PSQLException("postgresql.stat.batch.empty");
346   
347   int size=batch.size();
348   int[] result=new int[size];
349   int i=0;
350   this.execute("begin"); // PTM: check this when autoCommit is false
351   try {
352       for(i=0;i<size;i++)
353     result[i]=this.executeUpdate((String)batch.elementAt(i));
354       this.execute("commit"); // PTM: check this
355   } catch(SQLException e) {
356       this.execute("abort"); // PTM: check this
357       throw new PSQLException("postgresql.stat.batch.error",new Integer(i),batch.elementAt(i));
358   }
359   return result;
360     }
361     
362     public java.sql.Connection getConnection() throws SQLException
363     {
364   return (java.sql.Connection)connection;
365     }
366     
367     public int getFetchDirection() throws SQLException
368     {
369   throw postgresql.Driver.notImplemented();
370     }
371     
372     public int getFetchSize() throws SQLException
373     {
374   throw postgresql.Driver.notImplemented();
375     }
376     
377     public int getKeysetSize() throws SQLException
378     {
379   throw postgresql.Driver.notImplemented();
380     }
381     
382     public int getResultSetConcurrency() throws SQLException
383     {
384   throw postgresql.Driver.notImplemented();
385     }
386     
387     public int getResultSetType() throws SQLException
388     {
389   throw postgresql.Driver.notImplemented();
390     }
391     
392     public void setFetchDirection(int direction) throws SQLException
393     {
394   throw postgresql.Driver.notImplemented();
395     }
396     
397     public void setFetchSize(int rows) throws SQLException
398     {
399   throw postgresql.Driver.notImplemented();
400     }
401     
402     public void setKeysetSize(int keys) throws SQLException
403     {
404   throw postgresql.Driver.notImplemented();
405     }
406     
407     public void setResultSetConcurrency(int value) throws SQLException
408     {
409   throw postgresql.Driver.notImplemented();
410     }
411     
412     public void setResultSetType(int value) throws SQLException
413     {
414   throw postgresql.Driver.notImplemented();
415     }
416     
417     
418 }