• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package SQLite.JDBC2z;
2 
3 import java.sql.*;
4 import java.util.*;
5 
6 public class JDBCStatement implements java.sql.Statement {
7 
8     protected JDBCConnection conn;
9     protected JDBCResultSet rs;
10     protected int updcnt;
11     protected int maxrows = 0;
12     private ArrayList<String> batch;
13 
JDBCStatement(JDBCConnection conn)14     public JDBCStatement(JDBCConnection conn) {
15 	this.conn = conn;
16 	this.updcnt = 0;
17 	this.rs = null;
18 	this.batch = null;
19     }
20 
setFetchSize(int fetchSize)21     public void setFetchSize(int fetchSize) throws SQLException {
22 	if (fetchSize != 1) {
23 	    throw new SQLException("fetch size not 1");
24 	}
25     }
26 
getFetchSize()27     public int getFetchSize() throws SQLException {
28 	return 1;
29     }
30 
getMaxRows()31     public int getMaxRows() throws SQLException {
32 	return maxrows;
33     }
34 
setMaxRows(int max)35     public void setMaxRows(int max) throws SQLException {
36 	if (max < 0) {
37 	    throw new SQLException("max must be >= 0 (was " + max + ")");
38 	}
39 	maxrows = max;
40     }
41 
setFetchDirection(int fetchDirection)42     public void setFetchDirection(int fetchDirection) throws SQLException {
43 	throw new SQLException("not supported");
44     }
45 
getFetchDirection()46     public int getFetchDirection() throws SQLException {
47 	return ResultSet.FETCH_UNKNOWN;
48     }
49 
getResultSetConcurrency()50     public int getResultSetConcurrency() throws SQLException {
51 	return ResultSet.CONCUR_READ_ONLY;
52     }
53 
getResultSetType()54     public int getResultSetType() throws SQLException {
55 	return ResultSet.TYPE_SCROLL_INSENSITIVE;
56     }
57 
setQueryTimeout(int seconds)58     public void setQueryTimeout(int seconds) throws SQLException {
59 	// BEGIN android-changed: more closely follow specification:
60 	// "[throws SQLException if] this method is called on a closed Statement or the condition
61 	// seconds >= 0 is not satisfied"
62 	// (http://java.sun.com/javase/6/docs/api/java/sql/Statement.html#setQueryTimeout(int))
63 	if (isClosed()) {
64 	    throw new SQLException("can't set a query timeout on a closed statement");
65 	} else if (seconds < 0) {
66 	    throw new SQLException("can't set a query timeout of less than 0 seconds");
67 	} else if (seconds == 0) {
68 	    // An argument of 0 seconds should set an unlimited timeout. However, since this was not
69 	    // done previously, I assume it isn't implemented and use the same implementation.
70 	    conn.timeout = 5000;
71 	} else {
72 	    conn.timeout = seconds * 1000;
73 	}
74 	// END android-changed
75     }
76 
getQueryTimeout()77     public int getQueryTimeout() throws SQLException {
78 	return conn.timeout / 1000; // android-changed: should return seconds
79     }
80 
getResultSet()81     public ResultSet getResultSet() throws SQLException {
82 	return rs;
83     }
84 
executeQuery(String sql, String args[], boolean updonly)85     ResultSet executeQuery(String sql, String args[], boolean updonly)
86 	throws SQLException {
87 	SQLite.TableResult tr = null;
88 	if (rs != null) {
89 	    rs.close();
90 	    rs = null;
91 	}
92 	updcnt = -1;
93 	if (conn == null || conn.db == null) {
94 	    throw new SQLException("stale connection");
95 	}
96 	int busy = 0;
97 	boolean starttrans = !conn.autocommit && !conn.intrans;
98 	while (true) {
99 	    try {
100 		if (starttrans) {
101 		    conn.db.exec("BEGIN TRANSACTION", null);
102 		    conn.intrans = true;
103 		}
104 		if (args == null) {
105 		    if (updonly) {
106 			conn.db.exec(sql, null);
107 		    } else {
108 			tr = conn.db.get_table(sql, maxrows);
109 		    }
110 		} else {
111 		    if (updonly) {
112 			conn.db.exec(sql, null, args);
113 		    } else {
114 			tr = conn.db.get_table(sql, maxrows, args);
115 		    }
116 		}
117 		updcnt = (int) conn.db.changes();
118 	    } catch (SQLite.Exception e) {
119 		if (conn.db.is3() &&
120 		    conn.db.last_error() == SQLite.Constants.SQLITE_BUSY &&
121 		    conn.busy3(conn.db, ++busy)) {
122 		    try {
123 			if (starttrans && conn.intrans) {
124 			    conn.db.exec("ROLLBACK", null);
125 			    conn.intrans = false;
126 			}
127 		    } catch (SQLite.Exception ee) {
128 		    }
129 		    try {
130 			int ms = 20 + busy * 10;
131 			if (ms > 1000) {
132 			    ms = 1000;
133 			}
134 			synchronized (this) {
135 			    this.wait(ms);
136 			}
137 		    } catch (java.lang.Exception eee) {
138 		    }
139 		    continue;
140 		}
141 		throw new SQLException(e.toString());
142 	    }
143 	    break;
144 	}
145 	if (!updonly && tr == null) {
146 	    throw new SQLException("no result set produced");
147 	}
148 	if (!updonly && tr != null) {
149 	    rs = new JDBCResultSet(new TableResultX(tr), this);
150 	}
151 	return rs;
152     }
153 
executeQuery(String sql)154     public ResultSet executeQuery(String sql) throws SQLException {
155 	return executeQuery(sql, null, false);
156     }
157 
execute(String sql)158     public boolean execute(String sql) throws SQLException {
159 	return executeQuery(sql) != null;
160     }
161 
cancel()162     public void cancel() throws SQLException {
163 	if (conn == null || conn.db == null) {
164 	    throw new SQLException("stale connection");
165 	}
166 	conn.db.interrupt();
167     }
168 
clearWarnings()169     public void clearWarnings() throws SQLException {
170     }
171 
getConnection()172     public Connection getConnection() throws SQLException {
173 	return conn;
174     }
175 
addBatch(String sql)176     public void addBatch(String sql) throws SQLException {
177 	if (batch == null) {
178 	    batch = new ArrayList<String>(1);
179 	}
180 	batch.add(sql);
181     }
182 
executeBatch()183     public int[] executeBatch() throws SQLException {
184 	if (batch == null) {
185 	    return new int[0];
186 	}
187 	int[] ret = new int[batch.size()];
188 	for (int i = 0; i < ret.length; i++) {
189 	    ret[i] = EXECUTE_FAILED;
190 	}
191 	int errs = 0;
192 	for (int i = 0; i < ret.length; i++) {
193 	    try {
194 		execute((String) batch.get(i));
195 		ret[i] = updcnt;
196 	    } catch (SQLException e) {
197 		++errs;
198 	    }
199 	}
200 	if (errs > 0) {
201 	    throw new BatchUpdateException("batch failed", ret);
202 	}
203 	return ret;
204     }
205 
clearBatch()206     public void clearBatch() throws SQLException {
207 	if (batch != null) {
208 	    batch.clear();
209 	    batch = null;
210 	}
211     }
212 
close()213     public void close() throws SQLException {
214 	clearBatch();
215 	conn = null;
216     }
217 
executeUpdate(String sql)218     public int executeUpdate(String sql) throws SQLException {
219 	executeQuery(sql, null, true);
220 	return updcnt;
221     }
222 
getMaxFieldSize()223     public int getMaxFieldSize() throws SQLException {
224 	return 0;
225     }
226 
getMoreResults()227     public boolean getMoreResults() throws SQLException {
228 	if (rs != null) {
229 	    rs.close();
230 	    rs = null;
231 	}
232 	return false;
233     }
234 
getUpdateCount()235     public int getUpdateCount() throws SQLException {
236 	return updcnt;
237     }
238 
getWarnings()239     public SQLWarning getWarnings() throws SQLException {
240 	return null;
241     }
242 
setCursorName(String name)243     public void setCursorName(String name) throws SQLException {
244 	throw new SQLFeatureNotSupportedException();
245     }
246 
setEscapeProcessing(boolean enable)247     public void setEscapeProcessing(boolean enable) throws SQLException {
248 	throw new SQLException("not supported");
249     }
250 
setMaxFieldSize(int max)251     public void setMaxFieldSize(int max) throws SQLException {
252 	throw new SQLException("not supported");
253     }
254 
getMoreResults(int x)255     public boolean getMoreResults(int x) throws SQLException {
256 	throw new SQLFeatureNotSupportedException();
257     }
258 
getGeneratedKeys()259     public ResultSet getGeneratedKeys() throws SQLException {
260 	throw new SQLFeatureNotSupportedException();
261     }
262 
executeUpdate(String sql, int autokeys)263     public int executeUpdate(String sql, int autokeys)
264 	throws SQLException {
265 	if (autokeys != Statement.NO_GENERATED_KEYS) {
266 	    throw new SQLFeatureNotSupportedException("generated keys not supported");
267 	}
268 	return executeUpdate(sql);
269     }
270 
executeUpdate(String sql, int colIndexes[])271     public int executeUpdate(String sql, int colIndexes[])
272 	throws SQLException {
273 	throw new SQLFeatureNotSupportedException();
274     }
275 
executeUpdate(String sql, String colIndexes[])276     public int executeUpdate(String sql, String colIndexes[])
277 	throws SQLException {
278 	throw new SQLFeatureNotSupportedException();
279     }
280 
execute(String sql, int autokeys)281     public boolean execute(String sql, int autokeys)
282 	throws SQLException {
283 	if (autokeys != Statement.NO_GENERATED_KEYS) {
284 	    throw new SQLFeatureNotSupportedException("autogenerated keys not supported");
285 	}
286 	return execute(sql);
287     }
288 
execute(String sql, int colIndexes[])289     public boolean execute(String sql, int colIndexes[])
290 	throws SQLException {
291 	throw new SQLFeatureNotSupportedException();
292     }
293 
execute(String sql, String colIndexes[])294     public boolean execute(String sql, String colIndexes[])
295 	throws SQLException {
296 	throw new SQLFeatureNotSupportedException();
297     }
298 
getResultSetHoldability()299     public int getResultSetHoldability() throws SQLException {
300 	return ResultSet.HOLD_CURSORS_OVER_COMMIT;
301     }
302 
isClosed()303     public boolean isClosed() throws SQLException {
304 	return conn == null; // android-changed: pretty sure this is correct, since it matches what's done in close()
305     }
306 
setPoolable(boolean yes)307     public void setPoolable(boolean yes) throws SQLException {
308 	if (yes) {
309 	    throw new SQLException("poolable statements not supported");
310 	}
311     }
312 
isPoolable()313     public boolean isPoolable() throws SQLException {
314 	return false;
315     }
316 
unwrap(java.lang.Class<T> iface)317     public <T> T unwrap(java.lang.Class<T> iface) throws SQLException {
318 	throw new SQLException("unsupported");
319     }
320 
isWrapperFor(java.lang.Class iface)321     public boolean isWrapperFor(java.lang.Class iface) throws SQLException {
322 	return false;
323     }
324 
325 }
326