5 import java.sql.CallableStatement;
7 import java.sql.DatabaseMetaData;
8 import java.sql.PreparedStatement;
9 import java.sql.ResultSet;
10 import java.sql.SQLException;
11 import java.sql.SQLWarning;
12 import java.sql.Savepoint;
13 import java.sql.Statement;
14 import java.sql.Struct;
15 import java.util.Properties;
17 public class JDBCConnection
18 implements java.sql.Connection, SQLite.BusyHandler {
23 protected DatabaseX db;
36 * SQLite 3 VFS to use.
41 * Autocommit flag, true means autocommit.
43 protected boolean autocommit = true;
46 * In-transaction flag.
47 * Can be true only when autocommit false.
49 protected boolean intrans = false;
52 * Timeout for Database.exec()
54 protected int timeout = 1000000;
57 * Use double/julian date representation.
59 protected boolean useJulian = false;
62 * File name of database.
64 private String dbfile = null;
67 * Reference to meta data or null.
69 private JDBCDatabaseMetaData meta = null;
72 * Base time value for timeout handling.
77 * Database in readonly mode.
79 private boolean readonly = false;
82 * Transaction isolation mode.
84 private int trmode = TRANSACTION_SERIALIZABLE;
86 private boolean busy0(DatabaseX db, int count) {
88 t0 = System.currentTimeMillis();
91 long t1 = System.currentTimeMillis();
92 if (t1 - t0 > timeout) {
101 public boolean busy(String table, int count) {
102 return busy0(db, count);
105 protected boolean busy3(DatabaseX db, int count) {
107 t0 = System.currentTimeMillis();
110 long t1 = System.currentTimeMillis();
111 if (t1 - t0 > timeout) {
119 private DatabaseX open(boolean readonly) throws SQLException {
120 DatabaseX dbx = null;
122 dbx = new DatabaseX();
123 dbx.open(dbfile, readonly ? SQLite.Constants.SQLITE_OPEN_READONLY :
124 (SQLite.Constants.SQLITE_OPEN_READWRITE |
125 SQLite.Constants.SQLITE_OPEN_CREATE), vfs);
126 dbx.set_encoding(enc);
127 } catch (SQLite.Exception e) {
128 throw new SQLException(e.toString());
133 dbx.exec("PRAGMA short_column_names = off;", null);
134 dbx.exec("PRAGMA full_column_names = on;", null);
135 dbx.exec("PRAGMA empty_result_callbacks = on;", null);
136 if (SQLite.Database.version().compareTo("2.6.0") >= 0) {
137 dbx.exec("PRAGMA show_datatypes = on;", null);
139 } catch (SQLite.Exception e) {
140 if (dbx.last_error() != SQLite.Constants.SQLITE_BUSY ||
141 !busy0(dbx, ++loop)) {
144 } catch (SQLite.Exception ee) {
146 throw new SQLException(e.toString());
155 public JDBCConnection(String url, String enc, String pwd, String drep,
157 throws SQLException {
158 if (url.startsWith("sqlite:/")) {
159 dbfile = url.substring(8);
160 } else if (url.startsWith("jdbc:sqlite:/")) {
161 dbfile = url.substring(13);
163 throw new SQLException("unsupported url");
171 if (pwd != null && pwd.length() > 0) {
174 } catch (SQLite.Exception se) {
176 SQLException("error while setting key: " + se.toString());
178 db.busy_handler(this);
179 } catch (SQLException e) {
183 } catch (SQLite.Exception ee) {
188 useJulian = drep != null &&
189 (drep.startsWith("j") || drep.startsWith("J"));
193 public SQLite.Database getSQLiteDatabase() {
197 public Statement createStatement() {
198 JDBCStatement s = new JDBCStatement(this);
202 public Statement createStatement(int resultSetType,
203 int resultSetConcurrency)
204 throws SQLException {
205 if (resultSetType != ResultSet.TYPE_FORWARD_ONLY &&
206 resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE &&
207 resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
208 throw new SQLException("unsupported result set type");
210 if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY &&
211 resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
212 throw new SQLException("unsupported result set concurrency");
214 JDBCStatement s = new JDBCStatement(this);
218 public DatabaseMetaData getMetaData() throws SQLException {
220 meta = new JDBCDatabaseMetaData(this);
225 public void close() throws SQLException {
228 } catch (SQLException e) {
236 } catch (SQLite.Exception e) {
237 throw new SQLException(e.toString());
242 public boolean isClosed() throws SQLException {
246 public boolean isReadOnly() throws SQLException {
250 public void clearWarnings() throws SQLException {
253 public void commit() throws SQLException {
255 throw new SQLException("stale connection");
261 db.exec("COMMIT", null);
263 } catch (SQLite.Exception e) {
264 throw new SQLException(e.toString());
268 public boolean getAutoCommit() throws SQLException {
272 public String getCatalog() throws SQLException {
276 public int getTransactionIsolation() throws SQLException {
280 public SQLWarning getWarnings() throws SQLException {
284 public String nativeSQL(String sql) throws SQLException {
285 throw new SQLException("not supported");
288 public CallableStatement prepareCall(String sql) throws SQLException {
289 throw new SQLException("not supported");
292 public CallableStatement prepareCall(String sql, int x, int y)
293 throws SQLException {
294 throw new SQLException("not supported");
297 public PreparedStatement prepareStatement(String sql) throws SQLException {
298 JDBCPreparedStatement s = new JDBCPreparedStatement(this, sql);
302 public PreparedStatement prepareStatement(String sql, int resultSetType,
303 int resultSetConcurrency)
304 throws SQLException {
305 if (resultSetType != ResultSet.TYPE_FORWARD_ONLY &&
306 resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE &&
307 resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
308 throw new SQLException("unsupported result set type");
310 if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY &&
311 resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
312 throw new SQLException("unsupported result set concurrency");
314 JDBCPreparedStatement s = new JDBCPreparedStatement(this, sql);
318 public void rollback() throws SQLException {
320 throw new SQLException("stale connection");
326 db.exec("ROLLBACK", null);
328 } catch (SQLite.Exception e) {
329 throw new SQLException(e.toString());
333 public void setAutoCommit(boolean ac) throws SQLException {
334 if (ac && intrans && db != null) {
336 db.exec("ROLLBACK", null);
337 } catch (SQLite.Exception e) {
338 throw new SQLException(e.toString());
346 public void setCatalog(String catalog) throws SQLException {
349 public void setReadOnly(boolean ro) throws SQLException {
351 throw new SQLException("incomplete transaction");
353 if (ro != readonly) {
354 DatabaseX dbx = null;
361 } catch (SQLException e) {
363 } catch (SQLite.Exception ee) {
367 } catch (SQLite.Exception eee) {
370 throw new SQLException(ee.toString());
375 public void setTransactionIsolation(int level) throws SQLException {
376 if (db.is3() && SQLite.JDBC.sharedCache) {
378 if (level == TRANSACTION_READ_UNCOMMITTED &&
379 trmode != TRANSACTION_READ_UNCOMMITTED) {
381 } else if (level == TRANSACTION_SERIALIZABLE &&
382 trmode != TRANSACTION_SERIALIZABLE) {
387 db.exec("PRAGMA read_uncommitted = " + flag + ";", null);
389 } catch (java.lang.Exception e) {
393 if (level != trmode) {
394 throw new SQLException("not supported");
398 public java.util.Map<String, Class<?>> getTypeMap() throws SQLException {
399 throw new SQLException("not supported");
402 public void setTypeMap(java.util.Map map) throws SQLException {
403 throw new SQLException("not supported");
406 public int getHoldability() throws SQLException {
407 return ResultSet.HOLD_CURSORS_OVER_COMMIT;
410 public void setHoldability(int holdability) throws SQLException {
411 if (holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT) {
414 throw new SQLException("not supported");
417 public Savepoint setSavepoint() throws SQLException {
418 throw new SQLException("not supported");
421 public Savepoint setSavepoint(String name) throws SQLException {
422 throw new SQLException("not supported");
425 public void rollback(Savepoint x) throws SQLException {
426 throw new SQLException("not supported");
429 public void releaseSavepoint(Savepoint x) throws SQLException {
430 throw new SQLException("not supported");
433 public Statement createStatement(int resultSetType,
434 int resultSetConcurrency,
435 int resultSetHoldability)
436 throws SQLException {
437 if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
438 throw new SQLException("not supported");
440 return createStatement(resultSetType, resultSetConcurrency);
443 public PreparedStatement prepareStatement(String sql, int resultSetType,
444 int resultSetConcurrency,
445 int resultSetHoldability)
446 throws SQLException {
447 if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
448 throw new SQLException("not supported");
450 return prepareStatement(sql, resultSetType, resultSetConcurrency);
453 public CallableStatement prepareCall(String sql, int x, int y, int z)
454 throws SQLException {
455 throw new SQLException("not supported");
458 public PreparedStatement prepareStatement(String sql, int autokeys)
459 throws SQLException {
460 if (autokeys != Statement.NO_GENERATED_KEYS) {
461 throw new SQLException("not supported");
463 return prepareStatement(sql);
466 public PreparedStatement prepareStatement(String sql, int colIndexes[])
467 throws SQLException {
468 throw new SQLException("not supported");
471 public PreparedStatement prepareStatement(String sql, String columns[])
472 throws SQLException {
473 throw new SQLException("not supported");
478 class DatabaseX extends SQLite.Database {
480 static Object lock = new Object();
488 synchronized (lock) {
491 } catch (java.lang.Exception e) {
495 public void exec(String sql, SQLite.Callback cb)
496 throws SQLite.Exception {
498 synchronized (lock) {
503 public void exec(String sql, SQLite.Callback cb, String args[])
504 throws SQLite.Exception {
505 super.exec(sql, cb, args);
506 synchronized (lock) {
511 public SQLite.TableResult get_table(String sql, String args[])
512 throws SQLite.Exception {
513 SQLite.TableResult ret = super.get_table(sql, args);
514 synchronized (lock) {
520 public void get_table(String sql, String args[], SQLite.TableResult tbl)
521 throws SQLite.Exception {
522 super.get_table(sql, args, tbl);
523 synchronized (lock) {