Source code: postgresql/jdbc1/Statement.java
1 package postgresql.jdbc1;
2
3 // IMPORTANT NOTE: This file implements the JDBC 1 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 2 class in the
6 // postgresql.jdbc2 package.
7
8 import java.sql.*;
9
10 import postgresql.util.PSQLException;
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
33 /**
34 * Constructor for a Statement. It simply sets the connection
35 * that created us.
36 *
37 * @param c the Connection instantation that creates us
38 */
39 public Statement (Connection c)
40 {
41 connection = c;
42 }
43
44 /**
45 * Execute a SQL statement that retruns a single ResultSet
46 *
47 * @param sql typically a static SQL SELECT statement
48 * @return a ResulSet that contains the data produced by the query
49 * @exception SQLException if a database access error occurs
50 */
51 public java.sql.ResultSet executeQuery(String sql) throws SQLException
52 {
53 this.execute(sql);
54 while (result != null && !((postgresql.ResultSet)result).reallyResultSet())
55 result = ((postgresql.ResultSet)result).getNext();
56 if (result == null)
57 throw new PSQLException("postgresql.stat.noresult");
58 return result;
59 }
60
61 /**
62 * Execute a SQL INSERT, UPDATE or DELETE statement. In addition
63 * SQL statements that return nothing such as SQL DDL statements
64 * can be executed
65 *
66 * @param sql a SQL statement
67 * @return either a row count, or 0 for SQL commands
68 * @exception SQLException if a database access error occurs
69 */
70 public int executeUpdate(String sql) throws SQLException
71 {
72 this.execute(sql);
73 if (((postgresql.ResultSet)result).reallyResultSet())
74 throw new PSQLException("postgresql.stat.result");
75 return this.getUpdateCount();
76 }
77
78 /**
79 * In many cases, it is desirable to immediately release a
80 * Statement's database and JDBC resources instead of waiting
81 * for this to happen when it is automatically closed. The
82 * close method provides this immediate release.
83 *
84 * <p><B>Note:</B> A Statement is automatically closed when it is
85 * garbage collected. When a Statement is closed, its current
86 * ResultSet, if one exists, is also closed.
87 *
88 * @exception SQLException if a database access error occurs (why?)
89 */
90 public void close() throws SQLException
91 {
92 result = null;
93 }
94
95 /**
96 * The maxFieldSize limit (in bytes) is the maximum amount of
97 * data returned for any column value; it only applies to
98 * BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR and LONGVARCHAR
99 * columns. If the limit is exceeded, the excess data is silently
100 * discarded.
101 *
102 * @return the current max column size limit; zero means unlimited
103 * @exception SQLException if a database access error occurs
104 */
105 public int getMaxFieldSize() throws SQLException
106 {
107 return 8192; // We cannot change this
108 }
109
110 /**
111 * Sets the maxFieldSize - NOT! - We throw an SQLException just
112 * to inform them to stop doing this.
113 *
114 * @param max the new max column size limit; zero means unlimited
115 * @exception SQLException if a database access error occurs
116 */
117 public void setMaxFieldSize(int max) throws SQLException
118 {
119 throw new PSQLException("postgresql.stat.maxfieldsize");
120 }
121
122 /**
123 * The maxRows limit is set to limit the number of rows that
124 * any ResultSet can contain. If the limit is exceeded, the
125 * excess rows are silently dropped.
126 *
127 * @return the current maximum row limit; zero means unlimited
128 * @exception SQLException if a database access error occurs
129 */
130 public int getMaxRows() throws SQLException
131 {
132 return connection.maxrows;
133 }
134
135 /**
136 * Set the maximum number of rows
137 *
138 * @param max the new max rows limit; zero means unlimited
139 * @exception SQLException if a database access error occurs
140 * @see getMaxRows
141 */
142 public void setMaxRows(int max) throws SQLException
143 {
144 connection.maxrows = max;
145 }
146
147 /**
148 * If escape scanning is on (the default), the driver will do escape
149 * substitution before sending the SQL to the database.
150 *
151 * @param enable true to enable; false to disable
152 * @exception SQLException if a database access error occurs
153 */
154 public void setEscapeProcessing(boolean enable) throws SQLException
155 {
156 escapeProcessing = enable;
157 }
158
159 /**
160 * The queryTimeout limit is the number of seconds the driver
161 * will wait for a Statement to execute. If the limit is
162 * exceeded, a SQLException is thrown.
163 *
164 * @return the current query timeout limit in seconds; 0 = unlimited
165 * @exception SQLException if a database access error occurs
166 */
167 public int getQueryTimeout() throws SQLException
168 {
169 return timeout;
170 }
171
172 /**
173 * Sets the queryTimeout limit
174 *
175 * @param seconds - the new query timeout limit in seconds
176 * @exception SQLException if a database access error occurs
177 */
178 public void setQueryTimeout(int seconds) throws SQLException
179 {
180 timeout = seconds;
181 }
182
183 /**
184 * Cancel can be used by one thread to cancel a statement that
185 * is being executed by another thread. However, PostgreSQL is
186 * a sync. sort of thing, so this really has no meaning - we
187 * define it as a no-op (i.e. you can't cancel, but there is no
188 * error if you try.)
189 *
190 * 6.4 introduced a cancel operation, but we have not implemented it
191 * yet. Sometime before 6.5, this method will be implemented.
192 *
193 * @exception SQLException only because thats the spec.
194 */
195 public void cancel() throws SQLException
196 {
197 // No-op
198 }
199
200 /**
201 * The first warning reported by calls on this Statement is
202 * returned. A Statement's execute methods clear its SQLWarning
203 * chain. Subsequent Statement warnings will be chained to this
204 * SQLWarning.
205 *
206 * <p>The Warning chain is automatically cleared each time a statement
207 * is (re)executed.
208 *
209 * <p><B>Note:</B> If you are processing a ResultSet then any warnings
210 * associated with ResultSet reads will be chained on the ResultSet
211 * object.
212 *
213 * @return the first SQLWarning on null
214 * @exception SQLException if a database access error occurs
215 */
216 public SQLWarning getWarnings() throws SQLException
217 {
218 return warnings;
219 }
220
221 /**
222 * After this call, getWarnings returns null until a new warning
223 * is reported for this Statement.
224 *
225 * @exception SQLException if a database access error occurs (why?)
226 */
227 public void clearWarnings() throws SQLException
228 {
229 warnings = null;
230 }
231
232 /**
233 * setCursorName defines the SQL cursor name that will be used by
234 * subsequent execute methods. This name can then be used in SQL
235 * positioned update/delete statements to identify the current row
236 * in the ResultSet generated by this statement. If a database
237 * doesn't support positioned update/delete, this method is a
238 * no-op.
239 *
240 * <p><B>Note:</B> By definition, positioned update/delete execution
241 * must be done by a different Statement than the one which
242 * generated the ResultSet being used for positioning. Also, cursor
243 * names must be unique within a Connection.
244 *
245 * <p>We throw an additional constriction. There can only be one
246 * cursor active at any one time.
247 *
248 * @param name the new cursor name
249 * @exception SQLException if a database access error occurs
250 */
251 public void setCursorName(String name) throws SQLException
252 {
253 connection.setCursorName(name);
254 }
255
256 /**
257 * Execute a SQL statement that may return multiple results. We
258 * don't have to worry about this since we do not support multiple
259 * ResultSets. You can use getResultSet or getUpdateCount to
260 * retrieve the result.
261 *
262 * @param sql any SQL statement
263 * @return true if the next result is a ResulSet, false if it is
264 * an update count or there are no more results
265 * @exception SQLException if a database access error occurs
266 */
267 public boolean execute(String sql) throws SQLException
268 {
269 result = connection.ExecSQL(sql);
270 return (result != null && ((postgresql.ResultSet)result).reallyResultSet());
271 }
272
273 /**
274 * getResultSet returns the current result as a ResultSet. It
275 * should only be called once per result.
276 *
277 * @return the current result set; null if there are no more
278 * @exception SQLException if a database access error occurs (why?)
279 */
280 public java.sql.ResultSet getResultSet() throws SQLException
281 {
282 return result;
283 }
284
285 /**
286 * getUpdateCount returns the current result as an update count,
287 * if the result is a ResultSet or there are no more results, -1
288 * is returned. It should only be called once per result.
289 *
290 * @return the current result as an update count.
291 * @exception SQLException if a database access error occurs
292 */
293 public int getUpdateCount() throws SQLException
294 {
295 if (result == null) return -1;
296 if (((postgresql.ResultSet)result).reallyResultSet()) return -1;
297 return ((postgresql.ResultSet)result).getResultCount();
298 }
299
300 /**
301 * getMoreResults moves to a Statement's next result. If it returns
302 * true, this result is a ResulSet.
303 *
304 * @return true if the next ResultSet is valid
305 * @exception SQLException if a database access error occurs
306 */
307 public boolean getMoreResults() throws SQLException
308 {
309 result = ((postgresql.ResultSet)result).getNext();
310 return (result != null && ((postgresql.ResultSet)result).reallyResultSet());
311 }
312
313 /**
314 * Returns the status message from the current Result.<p>
315 * This is used internally by the driver.
316 *
317 * @return status message from backend
318 */
319 public String getResultStatusString()
320 {
321 if(result == null)
322 return null;
323 return ((postgresql.ResultSet)result).getStatusString();
324 }
325 }