001: /*
002: * $Id: AxionStatement.java,v 1.34 2007/11/13 19:04:01 rwald Exp $
003: * =======================================================================
004: * Copyright (c) 2002-2005 Axion Development Team. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above
011: * copyright notice, this list of conditions and the following
012: * disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The names "Tigris", "Axion", nor the names of its contributors may
020: * not be used to endorse or promote products derived from this
021: * software without specific prior written permission.
022: *
023: * 4. Products derived from this software may not be called "Axion", nor
024: * may "Tigris" or "Axion" appear in their names without specific prior
025: * written permission.
026: *
027: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
028: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
029: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
030: * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
031: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
032: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
033: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
034: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
035: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
036: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
037: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
038: * =======================================================================
039: */
040:
041: package org.axiondb.jdbc;
042:
043: import java.sql.BatchUpdateException;
044: import java.sql.ResultSet;
045: import java.sql.SQLException;
046: import java.sql.SQLWarning;
047: import java.sql.Statement;
048: import java.util.Iterator;
049:
050: import org.axiondb.AxionCommand;
051: import org.axiondb.AxionException;
052: import org.axiondb.util.ExceptionConverter;
053:
054: /**
055: * A {@link Statement} implementation.
056: *
057: * @version $Revision: 1.34 $ $Date: 2007/11/13 19:04:01 $
058: * @author Chuck Burdick
059: * @author Rodney Waldhoff
060: * @author Jonathan Giron
061: * @author Ahimanikya Satapathy
062: */
063: public class AxionStatement extends BaseAxionStatement implements
064: Statement {
065:
066: protected AxionStatement(AxionConnection conn) throws SQLException {
067: super (conn);
068: }
069:
070: protected AxionStatement(AxionConnection conn, int resultSetType,
071: int resultSetConcurrency) throws SQLException {
072: super (conn);
073: _type = resultSetType;
074: _concurrency = resultSetConcurrency;
075: }
076:
077: public void addBatch(String sql) throws SQLException {
078: if (getBatchCount() == 0) {
079: clearCurrentResult();
080: }
081: addToBatchContext(parseCommand(sql));
082: }
083:
084: public void cancel() throws SQLException {
085: throw new SQLException("cancel is not supported");
086: }
087:
088: public void clearBatch() throws SQLException {
089: _batchContext.clear();
090: _batchContext.trimToSize();
091: }
092:
093: public void clearWarnings() throws SQLException {
094: _warning = null;
095: }
096:
097: public int[] executeBatch() throws SQLException {
098: SQLException exception = null;
099: int[] results = new int[getBatchCount()];
100: int i = 0;
101: for (Iterator iter = getBatchContext(); iter.hasNext(); i++) {
102: AxionCommand cmd = (AxionCommand) iter.next();
103: try {
104: results[i] = executeUpdate(cmd);
105: } catch (SQLWarning w) {
106: addWarning(w);
107: } catch (SQLException e) {
108: exception = e;
109: results[i] = EXECUTE_FAILED;
110: }
111: }
112: clearBatchContext();
113: if (null != exception) {
114: throw new BatchUpdateException(exception.getMessage(),
115: results);
116: }
117: return results;
118: }
119:
120: /**
121: * Adds the given SQLWarning to the current chain of SQLWarnings, or sets it as the first
122: * in the chain.
123: *
124: * @param w SQLWarning to be added to the warning chain
125: */
126: protected synchronized void addWarning(SQLWarning newWarning) {
127: if (_warning != null) {
128: _warning.setNextWarning(newWarning);
129: } else {
130: _warning = newWarning;
131: }
132: }
133:
134: public boolean execute(String sql) throws SQLException {
135: clearCurrentResult();
136: return execute(parseCommand(sql));
137: }
138:
139: public ResultSet executeQuery(String sql) throws SQLException {
140: clearCurrentResult();
141: return executeQuery(parseCommand(sql));
142: }
143:
144: public int executeUpdate(String sql) throws SQLException {
145: clearCurrentResult();
146: return executeUpdate(parseCommand(sql));
147: }
148:
149: public int getFetchDirection() throws SQLException {
150: return ResultSet.FETCH_FORWARD;
151: }
152:
153: public int getFetchSize() throws SQLException {
154: return 0;
155: }
156:
157: public int getMaxFieldSize() throws SQLException {
158: return 0;
159: }
160:
161: public boolean getMoreResults() throws SQLException {
162: closeCurrentResultSet();
163: return false;
164: }
165:
166: public int getQueryTimeout() throws SQLException {
167: return 0;
168: }
169:
170: public ResultSet getResultSet() throws SQLException {
171: ResultSet rs = getCurrentResultSet();
172: if (rs != null) {
173: if (_concurrency == ResultSet.CONCUR_READ_ONLY) {
174: rs = new UnmodifiableResultSet(rs);
175: }
176:
177: if (_type == ResultSet.TYPE_FORWARD_ONLY) {
178: rs = new ForwardOnlyResultSet(rs);
179: }
180: }
181:
182: return rs;
183: }
184:
185: public int getResultSetConcurrency() throws SQLException {
186: return _concurrency;
187: }
188:
189: public int getResultSetType() throws SQLException {
190: return _type;
191: }
192:
193: void setResultSetConcurrency(int concurrency) throws SQLException {
194: _concurrency = concurrency;
195: }
196:
197: void setResultSetType(int type) throws SQLException {
198: _type = type;
199: }
200:
201: public int getUpdateCount() throws SQLException {
202: return clearCurrentUpdateCount();
203: }
204:
205: public SQLWarning getWarnings() throws SQLException {
206: return _warning;
207: }
208:
209: public void setCursorName(String name) throws SQLException {
210: // "If the database doesn't suport positioned update/delete, this method is a
211: // noop."
212: }
213:
214: public void setEscapeProcessing(boolean enable) throws SQLException {
215: if (!enable) {
216: throw new SQLException("Unsupported");
217: }
218: }
219:
220: public void setFetchDirection(int direction) throws SQLException {
221: // setFetchDirection is only a hint anyway
222: switch (direction) {
223: case ResultSet.FETCH_FORWARD:
224: case ResultSet.FETCH_UNKNOWN:
225: case ResultSet.FETCH_REVERSE:
226: break;
227: default:
228: throw new SQLException("Unrecognized fetch direction: "
229: + direction + ".");
230: }
231: }
232:
233: public void setFetchSize(int rows) throws SQLException {
234: // setFecthSize is only a hint
235: if (rows < 0) {
236: throw new SQLException("FetchSize should be non-negative");
237: }
238: }
239:
240: public void setMaxFieldSize(int size) throws SQLException {
241: if (size < 0) {
242: throw new SQLException(
243: "MaxFieldSize should be non-negative");
244: } else if (size != 0) {
245: throw new SQLException("MaxFieldSize " + size
246: + " is not supported.");
247: }
248: }
249:
250: public void setQueryTimeout(int seconds) throws SQLException {
251: if (seconds < 0) {
252: throw new SQLException(
253: "QueryTimeout should be non-negative");
254: } else if (seconds != 0) {
255: throw new SQLException("QueryTimeout " + seconds
256: + " is not supported.");
257: }
258: }
259:
260: public ResultSet getGeneratedKeys() throws SQLException {
261: return AxionResultSet.createEmptyResultSet(this );
262: }
263:
264: /** Currently unsupported when autoGeneratedKeys is not Statement.NO_GENERATED_KEYS. */
265: public boolean execute(String sql, int autoGeneratedKeys)
266: throws SQLException {
267: if (Statement.NO_GENERATED_KEYS == autoGeneratedKeys) {
268: return execute(sql);
269: }
270: throw new SQLException("autoGeneratedKeys are not supported");
271: }
272:
273: /** Currently unsupported. */
274: public boolean execute(String sql, int columnIndexes[])
275: throws SQLException {
276: throw new SQLException(
277: "execute(String,int[]) is currently not supported");
278: }
279:
280: /** Currently unsupported. */
281: public boolean execute(String sql, String columnNames[])
282: throws SQLException {
283: throw new SQLException(
284: "execute(String,String[]) is currently not supported");
285: }
286:
287: /** Currently unsupported when auotGeneratedKeys is not Statement.NO_GENERATED_KEYS. */
288: public int executeUpdate(String sql, int autoGeneratedKeys)
289: throws SQLException {
290: if (Statement.NO_GENERATED_KEYS == autoGeneratedKeys) {
291: return executeUpdate(sql);
292: }
293: throw new SQLException("autoGeneratedKeys are not supported");
294: }
295:
296: /** Currently unsupported. */
297: public int executeUpdate(String arg0, int[] arg1)
298: throws SQLException {
299: throw new SQLException(
300: "executeUpdate(String,int[]) is currently not supported");
301: }
302:
303: /** Currently unsupported. */
304: public int executeUpdate(String arg0, String[] arg1)
305: throws SQLException {
306: throw new SQLException(
307: "executeUpdate(String,String[]) is currently not supported");
308: }
309:
310: /**
311: * Currently unsupported when current is not Statement.CLOSE_CURRENT_RESULT or
312: * Statement.CLOSE_ALL_RESULTS.
313: */
314: public boolean getMoreResults(int current) throws SQLException {
315: if (Statement.CLOSE_CURRENT_RESULT == current
316: || Statement.CLOSE_ALL_RESULTS == current) {
317: return getMoreResults();
318: }
319: throw new SQLException("getMoreResults(" + current
320: + ") is currently not supported");
321: }
322:
323: /** Supported. */
324: public int getResultSetHoldability() throws SQLException {
325: return ResultSet.CLOSE_CURSORS_AT_COMMIT;
326: }
327:
328: protected final boolean execute(AxionCommand cmd)
329: throws SQLException {
330: boolean result = false;
331: try {
332: result = cmd.execute(getDatabase());
333: } catch (AxionException e) {
334: throw ExceptionConverter.convert(e);
335: } catch (RuntimeException e) {
336: throw ExceptionConverter.convert(e);
337: }
338: setCurrentResult(result, cmd);
339: getAxionConnection().commitIfAuto();
340: return result;
341: }
342:
343: protected final ResultSet executeQuery(AxionCommand cmd)
344: throws SQLException {
345: try {
346: setCurrentResultSet(cmd.executeQuery(getDatabase(),
347: ResultSet.CONCUR_READ_ONLY == _concurrency));
348: } catch (AxionException e) {
349: throw ExceptionConverter.convert(e);
350: } catch (RuntimeException e) {
351: throw ExceptionConverter.convert(e);
352: }
353:
354: if (getAxionConnection().getAutoCommit()) {
355: getCurrentResultSet().setTransaction(
356: getAxionConnection().getDatabase()
357: .getTransactionManager(),
358: getAxionConnection().forgetCurrentTransaction());
359: }
360:
361: return getResultSet();
362: }
363:
364: protected final int executeUpdate(AxionCommand cmd)
365: throws SQLException {
366: try {
367: setCurrentUpdateCount(cmd.executeUpdate(getDatabase()));
368: } catch (AxionException e) {
369: throw ExceptionConverter.convert(e);
370: } catch (RuntimeException e) {
371: throw ExceptionConverter.convert(e);
372: }
373: getAxionConnection().commitIfAuto();
374: return getCurrentUpdateCount();
375: }
376:
377: private int _type = ResultSet.TYPE_FORWARD_ONLY;
378: private int _concurrency = ResultSet.CONCUR_READ_ONLY;
379:
380: @Override
381: public boolean isClosed() throws SQLException {
382: throw new SQLException("Not supported");
383: }
384:
385: @Override
386: public boolean isPoolable() throws SQLException {
387: throw new SQLException("Not supported");
388: }
389:
390: @Override
391: public void setPoolable(boolean arg0) throws SQLException {
392: throw new SQLException("Not supported");
393: }
394:
395: @Override
396: public boolean isWrapperFor(Class<?> arg0) throws SQLException {
397: throw new SQLException("Not supported");
398: }
399:
400: @Override
401: public <T> T unwrap(Class<T> arg0) throws SQLException {
402: throw new SQLException("Not supported");
403: }
404: }
|