6 public class JDBCConnection
7 implements java.sql.Connection, SQLite.BusyHandler {
12 protected DatabaseX db;
25 * SQLite 3 VFS to use.
30 * Autocommit flag, true means autocommit.
32 protected boolean autocommit = true;
35 * In-transaction flag.
36 * Can be true only when autocommit false.
38 protected boolean intrans = false;
41 * Timeout for Database.exec()
43 protected int timeout = 1000000;
46 * Use double/julian date representation.
48 protected boolean useJulian = false;
51 * File name of database.
53 private String dbfile = null;
56 * Reference to meta data or null.
58 private JDBCDatabaseMetaData meta = null;
61 * Base time value for timeout handling.
66 * Database in readonly mode.
68 private boolean readonly = false;
71 * Transaction isolation mode.
73 private int trmode = TRANSACTION_SERIALIZABLE;
75 private boolean busy0(DatabaseX db, int count) {
77 t0 = System.currentTimeMillis();
80 long t1 = System.currentTimeMillis();
81 if (t1 - t0 > timeout) {
90 public boolean busy(String table, int count) {
91 return busy0(db, count);
94 protected boolean busy3(DatabaseX db, int count) {
96 t0 = System.currentTimeMillis();
99 long t1 = System.currentTimeMillis();
100 if (t1 - t0 > timeout) {
108 private DatabaseX open(boolean readonly) throws SQLException {
109 DatabaseX dbx = null;
111 dbx = new DatabaseX();
112 dbx.open(dbfile, readonly ? SQLite.Constants.SQLITE_OPEN_READONLY :
113 (SQLite.Constants.SQLITE_OPEN_READWRITE |
114 SQLite.Constants.SQLITE_OPEN_CREATE), vfs);
115 dbx.set_encoding(enc);
116 } catch (SQLite.Exception e) {
117 throw new SQLException(e.toString());
122 dbx.exec("PRAGMA short_column_names = off;", null);
123 dbx.exec("PRAGMA full_column_names = on;", null);
124 dbx.exec("PRAGMA empty_result_callbacks = on;", null);
125 if (SQLite.Database.version().compareTo("2.6.0") >= 0) {
126 dbx.exec("PRAGMA show_datatypes = on;", null);
128 } catch (SQLite.Exception e) {
129 if (dbx.last_error() != SQLite.Constants.SQLITE_BUSY ||
130 !busy0(dbx, ++loop)) {
133 } catch (SQLite.Exception ee) {
135 throw new SQLException(e.toString());
144 public JDBCConnection(String url, String enc, String pwd, String drep,
146 throws SQLException {
147 if (url.startsWith("sqlite:/")) {
148 dbfile = url.substring(8);
149 } else if (url.startsWith("jdbc:sqlite:/")) {
150 dbfile = url.substring(13);
152 throw new SQLException("unsupported url");
160 if (pwd != null && pwd.length() > 0) {
163 } catch (SQLite.Exception se) {
164 throw new SQLException("error while setting key");
166 db.busy_handler(this);
167 } catch (SQLException e) {
171 } catch (SQLite.Exception ee) {
176 useJulian = drep != null &&
177 (drep.startsWith("j") || drep.startsWith("J"));
181 public SQLite.Database getSQLiteDatabase() {
182 return (SQLite.Database) db;
185 public Statement createStatement() {
186 JDBCStatement s = new JDBCStatement(this);
190 public Statement createStatement(int resultSetType,
191 int resultSetConcurrency)
192 throws SQLException {
193 if (resultSetType != ResultSet.TYPE_FORWARD_ONLY &&
194 resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE &&
195 resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
196 throw new SQLFeatureNotSupportedException("unsupported result set type");
198 if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY &&
199 resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
200 throw new SQLFeatureNotSupportedException("unsupported result set concurrency");
202 JDBCStatement s = new JDBCStatement(this);
206 public DatabaseMetaData getMetaData() throws SQLException {
208 meta = new JDBCDatabaseMetaData(this);
213 public void close() throws SQLException {
216 } catch (SQLException e) {
224 } catch (SQLite.Exception e) {
225 throw new SQLException(e.toString());
230 public boolean isClosed() throws SQLException {
234 public boolean isReadOnly() throws SQLException {
238 public void clearWarnings() throws SQLException {
241 public void commit() throws SQLException {
243 throw new SQLException("stale connection");
249 db.exec("COMMIT", null);
251 } catch (SQLite.Exception e) {
252 throw new SQLException(e.toString());
256 public boolean getAutoCommit() throws SQLException {
260 public String getCatalog() throws SQLException {
264 public int getTransactionIsolation() throws SQLException {
268 public SQLWarning getWarnings() throws SQLException {
272 public String nativeSQL(String sql) throws SQLException {
273 throw new SQLException("not supported");
276 public CallableStatement prepareCall(String sql) throws SQLException {
277 throw new SQLException("not supported");
280 public CallableStatement prepareCall(String sql, int x, int y)
281 throws SQLException {
282 throw new SQLFeatureNotSupportedException();
285 public PreparedStatement prepareStatement(String sql) throws SQLException {
286 JDBCPreparedStatement s = new JDBCPreparedStatement(this, sql);
290 public PreparedStatement prepareStatement(String sql, int resultSetType,
291 int resultSetConcurrency)
292 throws SQLException {
293 if (resultSetType != ResultSet.TYPE_FORWARD_ONLY &&
294 resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE &&
295 resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) {
296 throw new SQLFeatureNotSupportedException("unsupported result set type");
298 if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY &&
299 resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) {
300 throw new SQLFeatureNotSupportedException("unsupported result set concurrency");
302 JDBCPreparedStatement s = new JDBCPreparedStatement(this, sql);
306 public void rollback() throws SQLException {
308 throw new SQLException("stale connection");
314 db.exec("ROLLBACK", null);
316 } catch (SQLite.Exception e) {
317 throw new SQLException(e.toString());
321 public void setAutoCommit(boolean ac) throws SQLException {
322 if (ac && intrans && db != null) {
324 db.exec("ROLLBACK", null);
325 } catch (SQLite.Exception e) {
326 throw new SQLException(e.toString());
334 public void setCatalog(String catalog) throws SQLException {
337 public void setReadOnly(boolean ro) throws SQLException {
339 throw new SQLException("incomplete transaction");
341 if (ro != readonly) {
342 DatabaseX dbx = null;
349 } catch (SQLException e) {
351 } catch (SQLite.Exception ee) {
355 } catch (SQLite.Exception eee) {
358 throw new SQLException(ee.toString());
363 public void setTransactionIsolation(int level) throws SQLException {
364 if (db.is3() && SQLite.JDBCDriver.sharedCache) {
366 if (level == TRANSACTION_READ_UNCOMMITTED &&
367 trmode != TRANSACTION_READ_UNCOMMITTED) {
369 } else if (level == TRANSACTION_SERIALIZABLE &&
370 trmode != TRANSACTION_SERIALIZABLE) {
375 db.exec("PRAGMA read_uncommitted = " + flag + ";", null);
377 } catch (java.lang.Exception e) {
381 if (level != trmode) {
382 throw new SQLException("not supported");
386 public java.util.Map<String, Class<?>> getTypeMap() throws SQLException {
387 throw new SQLFeatureNotSupportedException();
390 public void setTypeMap(java.util.Map map) throws SQLException {
391 throw new SQLFeatureNotSupportedException();
394 public int getHoldability() throws SQLException {
395 return ResultSet.HOLD_CURSORS_OVER_COMMIT;
398 public void setHoldability(int holdability) throws SQLException {
399 if (holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT) {
402 throw new SQLFeatureNotSupportedException("unsupported holdability");
405 public Savepoint setSavepoint() throws SQLException {
406 throw new SQLFeatureNotSupportedException();
409 public Savepoint setSavepoint(String name) throws SQLException {
410 throw new SQLFeatureNotSupportedException();
413 public void rollback(Savepoint x) throws SQLException {
414 throw new SQLFeatureNotSupportedException();
417 public void releaseSavepoint(Savepoint x) throws SQLException {
418 throw new SQLFeatureNotSupportedException();
421 public Statement createStatement(int resultSetType,
422 int resultSetConcurrency,
423 int resultSetHoldability)
424 throws SQLException {
425 if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
426 throw new SQLFeatureNotSupportedException("unsupported holdability");
428 return createStatement(resultSetType, resultSetConcurrency);
431 public PreparedStatement prepareStatement(String sql, int resultSetType,
432 int resultSetConcurrency,
433 int resultSetHoldability)
434 throws SQLException {
435 if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
436 throw new SQLFeatureNotSupportedException("unsupported holdability");
438 return prepareStatement(sql, resultSetType, resultSetConcurrency);
441 public CallableStatement prepareCall(String sql, int x, int y, int z)
442 throws SQLException {
443 throw new SQLFeatureNotSupportedException();
446 public PreparedStatement prepareStatement(String sql, int autokeys)
447 throws SQLException {
448 if (autokeys != Statement.NO_GENERATED_KEYS) {
449 throw new SQLFeatureNotSupportedException("generated keys not supported");
451 return prepareStatement(sql);
454 public PreparedStatement prepareStatement(String sql, int colIndexes[])
455 throws SQLException {
456 throw new SQLFeatureNotSupportedException();
459 public PreparedStatement prepareStatement(String sql, String columns[])
460 throws SQLException {
461 throw new SQLFeatureNotSupportedException();
464 public Clob createClob() throws SQLException {
465 throw new SQLFeatureNotSupportedException();
468 public Blob createBlob() throws SQLException {
469 throw new SQLFeatureNotSupportedException();
472 public NClob createNClob() throws SQLException {
473 throw new SQLFeatureNotSupportedException();
476 public SQLXML createSQLXML() throws SQLException {
477 throw new SQLFeatureNotSupportedException();
480 public boolean isValid(int timeout) throws SQLException {
484 public void setClientInfo(String name, String value)
485 throws SQLClientInfoException {
486 throw new SQLClientInfoException();
489 public void setClientInfo(Properties prop) throws SQLClientInfoException {
490 throw new SQLClientInfoException();
493 public String getClientInfo(String name) throws SQLException {
494 throw new SQLException("unsupported");
497 public Properties getClientInfo() throws SQLException {
498 return new Properties();
501 public Array createArrayOf(String type, Object[] elems)
502 throws SQLException {
503 throw new SQLFeatureNotSupportedException();
506 public Struct createStruct(String type, Object[] attrs)
507 throws SQLException {
508 throw new SQLFeatureNotSupportedException();
511 public <T> T unwrap(java.lang.Class<T> iface) throws SQLException {
512 throw new SQLException("unsupported");
515 public boolean isWrapperFor(java.lang.Class iface) throws SQLException {
521 class DatabaseX extends SQLite.Database {
523 static Object lock = new Object();
531 synchronized (lock) {
534 } catch (java.lang.Exception e) {
538 public void exec(String sql, SQLite.Callback cb)
539 throws SQLite.Exception {
541 synchronized (lock) {
546 public void exec(String sql, SQLite.Callback cb, String args[])
547 throws SQLite.Exception {
548 super.exec(sql, cb, args);
549 synchronized (lock) {
554 public SQLite.TableResult get_table(String sql, String args[])
555 throws SQLite.Exception {
556 SQLite.TableResult ret = super.get_table(sql, args);
557 synchronized (lock) {
563 public void get_table(String sql, String args[], SQLite.TableResult tbl)
564 throws SQLite.Exception {
565 super.get_table(sql, args, tbl);
566 synchronized (lock) {