diff options
31 files changed, 5023 insertions, 4030 deletions
diff --git a/sql/src/test/java/tests/SQLite/AllTests.java b/sql/src/test/java/tests/SQLite/AllTests.java index e2aa55c..ea8b841 100644 --- a/sql/src/test/java/tests/SQLite/AllTests.java +++ b/sql/src/test/java/tests/SQLite/AllTests.java @@ -28,7 +28,6 @@ public class AllTests { suite.addTestSuite(DatabaseTest.class); suite.addTestSuite(JDBCDriverFunctionalTest.class); suite.addTestSuite(JDBCDriverTest.class); - suite.addTestSuite(ConstantsTest.class); suite.addTestSuite(BlobTest.class); suite.addTestSuite(StmtTest.class); suite.addTestSuite(ExceptionTest.class); diff --git a/sql/src/test/java/tests/SQLite/ConstantsTest.java b/sql/src/test/java/tests/SQLite/ConstantsTest.java deleted file mode 100644 index 2a4961f..0000000 --- a/sql/src/test/java/tests/SQLite/ConstantsTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package tests.SQLite; - -import SQLite.Constants; -import dalvik.annotation.TestTargets; -import dalvik.annotation.TestLevel; -import dalvik.annotation.TestTargetNew; -import dalvik.annotation.TestTargetClass; - -import junit.framework.TestCase; - -@TestTargetClass(Constants.class) -public class ConstantsTest extends TestCase { - - /** - * @tests Constants#Constants() - */ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "constructor test", - method = "Constants", - args = {} - ) - public void testConstants() { - Constants c = new Constants(); - - assertNotNull(c); - assertEquals(c.SQLITE_OK, 0); - assertEquals(c.SQLITE_ERROR, 1); - assertEquals(c.SQLITE_INTERNAL, 2); - assertEquals(c.SQLITE_PERM, 3); - assertEquals(c.SQLITE_ABORT, 4); - assertEquals(c.SQLITE_BUSY, 5); - assertEquals(c.SQLITE_LOCKED, 6); - assertEquals(c.SQLITE_NOMEM, 7); - assertEquals(c.SQLITE_READONLY, 8); - assertEquals(c.SQLITE_INTERRUPT, 9); - assertEquals(c.SQLITE_IOERR, 10); - assertEquals(c.SQLITE_CORRUPT, 11); - assertEquals(c.SQLITE_NOTFOUND, 12); - assertEquals(c.SQLITE_FULL, 13); - assertEquals(c.SQLITE_CANTOPEN, 14); - assertEquals(c.SQLITE_PROTOCOL, 15); - assertEquals(c.SQLITE_EMPTY, 16); - assertEquals(c.SQLITE_SCHEMA, 17); - assertEquals(c.SQLITE_TOOBIG, 18); - assertEquals(c.SQLITE_CONSTRAINT, 19); - assertEquals(c.SQLITE_MISMATCH, 20); - assertEquals(c.SQLITE_MISUSE, 21); - assertEquals(c.SQLITE_NOLFS, 22); - assertEquals(c.SQLITE_AUTH, 23); - assertEquals(c.SQLITE_FORMAT, 24); - assertEquals(c.SQLITE_RANGE, 25); - assertEquals(c.SQLITE_NOTADB, 26); - assertEquals(c.SQLITE_ROW, 100); - assertEquals(c.SQLITE_DONE, 101); - assertEquals(c.SQLITE_INTEGER, 1); - assertEquals(c.SQLITE_FLOAT, 2); - assertEquals(c.SQLITE_BLOB, 4); - assertEquals(c.SQLITE_NULL, 5); - assertEquals(c.SQLITE3_TEXT, 3); - assertEquals(c.SQLITE_NUMERIC, -1); - assertEquals(c.SQLITE_TEXT, 3); - assertEquals(c.SQLITE2_TEXT, -2); - assertEquals(c.SQLITE_ARGS, -3); - assertEquals(c.SQLITE_COPY, 0); - assertEquals(c.SQLITE_CREATE_INDEX, 1); - assertEquals(c.SQLITE_CREATE_TABLE, 2); - assertEquals(c.SQLITE_CREATE_TEMP_INDEX, 3); - assertEquals(c.SQLITE_CREATE_TEMP_TABLE, 4); - assertEquals(c.SQLITE_CREATE_TEMP_TRIGGER, 5); - assertEquals(c.SQLITE_CREATE_TEMP_VIEW, 6); - assertEquals(c.SQLITE_CREATE_TRIGGER, 7); - assertEquals(c.SQLITE_CREATE_VIEW, 8); - assertEquals(c.SQLITE_DELETE, 9); - assertEquals(c.SQLITE_DROP_INDEX, 10); - assertEquals(c.SQLITE_DROP_TABLE, 11); - assertEquals(c.SQLITE_DROP_TEMP_INDEX, 12); - assertEquals(c.SQLITE_DROP_TEMP_TABLE, 13); - assertEquals(c.SQLITE_DROP_TEMP_TRIGGER, 14); - assertEquals(c.SQLITE_DROP_TEMP_VIEW, 15); - assertEquals(c.SQLITE_DROP_TRIGGER, 16); - assertEquals(c.SQLITE_DROP_VIEW, 17); - assertEquals(c.SQLITE_INSERT, 18); - assertEquals(c.SQLITE_PRAGMA, 19); - assertEquals(c.SQLITE_READ, 20); - assertEquals(c.SQLITE_SELECT, 21); - assertEquals(c.SQLITE_TRANSACTION, 22); - assertEquals(c.SQLITE_UPDATE, 23); - assertEquals(c.SQLITE_ATTACH, 24); - assertEquals(c.SQLITE_DETACH, 25); - assertEquals(c.SQLITE_DENY, 1); - assertEquals(c.SQLITE_IGNORE, 2); - } -} diff --git a/sql/src/test/java/tests/SQLite/DatabaseTest.java b/sql/src/test/java/tests/SQLite/DatabaseTest.java index 95ce7c8..12a556d 100644 --- a/sql/src/test/java/tests/SQLite/DatabaseTest.java +++ b/sql/src/test/java/tests/SQLite/DatabaseTest.java @@ -1069,7 +1069,7 @@ public class DatabaseTest extends SQLiteTest { db.exec("insert into TEST values(4, 'Fiona', 'Apple'); ", null); db.trace((Trace) t); db.create_aggregate("myaggfunc", 1, aggFunction); - db.function_type("myaggfunc", Constants.SQLITE_TEXT); + db.function_type("myaggfunc", Constants.SQLITE3_TEXT); db.exec("PRAGMA show_datatypes = on", null); assertFalse(aggFunction.functionCalled); @@ -1125,7 +1125,7 @@ public class DatabaseTest extends SQLiteTest { null); db.create_function("sin", 1, sinFunc); - db.function_type("sin", Constants.SQLITE_NUMERIC); + db.function_type("sin", Constants.SQLITE_FLOAT); res = db.get_table("select sin(res) from TEST WHERE res = " + Double.toString(input)); @@ -2036,4 +2036,3 @@ public class DatabaseTest extends SQLiteTest { } } - diff --git a/sql/src/test/java/tests/SQLite/StmtTest.java b/sql/src/test/java/tests/SQLite/StmtTest.java index cb71243..7a37154 100644 --- a/sql/src/test/java/tests/SQLite/StmtTest.java +++ b/sql/src/test/java/tests/SQLite/StmtTest.java @@ -982,17 +982,6 @@ public class StmtTest extends SQLiteTest { } } - /** - * @throws Exception - * @tests {@link Stmt#column_type(int)} - */ - @TestTargetNew( - level = TestLevel.SUFFICIENT, - notes = "method test", - method = "column_type", - args = {int.class} - ) - @KnownFailure("For numeric, float and blob wrong type is returned") public void testColumn_type() throws Exception { db.exec(createAllTypes, null); db.exec(insertAllTypes, null); @@ -1033,10 +1022,8 @@ public class StmtTest extends SQLiteTest { assertEquals(Constants.SQLITE_NULL, st.column_type(29)); // Failing tests - assertTrue("NUMERIC".equalsIgnoreCase(st.column_decltype(12))); - assertEquals(Constants.SQLITE_NUMERIC, st.column_type(12)); // NUMERIC - // -> got - // INTEGER + assertTrue("INTEGER".equalsIgnoreCase(st.column_decltype(12))); + assertEquals(Constants.SQLITE_INTEGER, st.column_type(12)); assertTrue("FLOAT".equalsIgnoreCase(st.column_decltype(11))); assertEquals(Constants.SQLITE_FLOAT, st.column_type(11)); // FLOAT -> diff --git a/sql/src/test/java/tests/java/sql/DatabaseMetaDataNotSupportedTest.java b/sql/src/test/java/tests/java/sql/DatabaseMetaDataNotSupportedTest.java index b09b779..c03bd6f 100644 --- a/sql/src/test/java/tests/java/sql/DatabaseMetaDataNotSupportedTest.java +++ b/sql/src/test/java/tests/java/sql/DatabaseMetaDataNotSupportedTest.java @@ -941,23 +941,14 @@ public class DatabaseMetaDataNotSupportedTest extends TestCase { meta.ownInsertsAreVisible(100)); } - /** - * @tests {@link java.sql.DatabaseMetaData#ownUpdatesAreVisible(int)} - */ - @TestTargetNew( - level = TestLevel.NOT_FEASIBLE, - notes = "not supported. Verification with invalid parameters missed.", - method = "ownUpdatesAreVisible", - args = {int.class} - ) public void test_ownUpdatesAreVisibleI() throws SQLException { - assertFalse( + assertTrue( "result set's own updates are visible for TYPE_FORWARD_ONLY type", meta.ownUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY)); - assertFalse( + assertTrue( "result set's own updates are visible for TYPE_SCROLL_INSENSITIVE type", meta.ownUpdatesAreVisible(ResultSet.TYPE_SCROLL_INSENSITIVE)); - assertFalse( + assertTrue( "result set's own updates are visible for TYPE_SCROLL_SENSITIVE type", meta.ownUpdatesAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE)); assertFalse("result set's own updates are visible for unknown type", @@ -1090,18 +1081,8 @@ public class DatabaseMetaDataNotSupportedTest extends TestCase { } - /** - * @tests java.sql.DatabaseMetaData#supportsBatchUpdates() - */ - @TestTargetNew( - level = TestLevel.NOT_FEASIBLE, - notes = "not supported", - method = "supportsBatchUpdates", - args = {} - ) public void test_supportsBatchUpdates() throws SQLException { - // NOT_FEASIBLE: SQLITE does not implement this functionality - assertFalse(meta.supportsBatchUpdates()); + assertTrue(meta.supportsBatchUpdates()); } /** @@ -1792,32 +1773,12 @@ public class DatabaseMetaDataNotSupportedTest extends TestCase { assertFalse(meta.supportsTransactions()); } - /** - * @tests java.sql.DatabaseMetaData#supportsUnion() - */ - @TestTargetNew( - level = TestLevel.NOT_FEASIBLE, - notes = "not supported", - method = "supportsUnion", - args = {} - ) public void test_supportsUnion() throws SQLException { - // NOT_FEASIBLE: SQLITE does not implement this functionality - assertFalse(meta.supportsUnion()); + assertTrue(meta.supportsUnion()); } - /** - * @tests java.sql.DatabaseMetaData#supportsUnionAll() - */ - @TestTargetNew( - level = TestLevel.NOT_FEASIBLE, - notes = "not supported", - method = "supportsUnionAll", - args = {} - ) public void test_supportsUnionAll() throws SQLException { - // NOT_FEASIBLE: SQLITE does not implement this functionality - assertFalse(meta.supportsUnionAll()); + assertTrue(meta.supportsUnionAll()); } /** diff --git a/sql/src/test/java/tests/sql/PreparedStatementTest.java b/sql/src/test/java/tests/sql/PreparedStatementTest.java index 26147ed..1546d38 100755 --- a/sql/src/test/java/tests/sql/PreparedStatementTest.java +++ b/sql/src/test/java/tests/sql/PreparedStatementTest.java @@ -2981,16 +2981,6 @@ public class PreparedStatementTest extends SQLTest { } } - /** - * @test {@link java.sql.PreparedStatement#setCharacterStream(int, java.io.Reader, int)} - * - */ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "not supported", - method = "setCharacterStream", - args = {int.class, java.io.Reader.class, int.class} - ) public void testSetCharacterSteam() { ResultSet res = null; PreparedStatement ps = null; @@ -3002,9 +2992,6 @@ public class PreparedStatementTest extends SQLTest { assertNotNull("Error in test setup: file not found",file); Reader reader = new InputStreamReader(file); ps.setCharacterStream(1, reader, 100); - fail("Exception expected not supported"); - } catch (SQLException e) { - // ok } catch (Exception e) { fail("Error in test setup "+e.getMessage()); e.printStackTrace(); diff --git a/sql/src/test/java/tests/sql/ResultSetGetterTests.java b/sql/src/test/java/tests/sql/ResultSetGetterTests.java index 9b12fc1..fccfd94 100644 --- a/sql/src/test/java/tests/sql/ResultSetGetterTests.java +++ b/sql/src/test/java/tests/sql/ResultSetGetterTests.java @@ -299,7 +299,6 @@ public class ResultSetGetterTests extends SQLTest { method = "getBytes", args = {int.class} ) - @KnownFailure("last assertion fails: invalid conversion. Test passes on RI") public void testGetBytesIntVarbinary() throws SQLException { Statement st = null; @@ -347,7 +346,6 @@ public class ResultSetGetterTests extends SQLTest { method = "getBytes", args = {int.class} ) - @KnownFailure("last assertion fails: invalid conversion. Test passes on RI") public void testGetBytesIntBinary() throws SQLException { Statement st = null; @@ -511,18 +509,9 @@ public class ResultSetGetterTests extends SQLTest { } } - /** - * Test method for {@link java.sql.ResultSet#getConcurrency()}. - */ - @TestTargetNew( - level = TestLevel.SUFFICIENT, - notes = "Not fully supported: CONCUR_UPDATABLE not supported", - method = "getConcurrency", - args = {} - ) public void testGetConcurrency() { try { - assertEquals(ResultSet.CONCUR_READ_ONLY, res.getConcurrency()); + assertEquals(ResultSet.CONCUR_UPDATABLE, res.getConcurrency()); } catch (SQLException e) { fail("Unexpected exception: " + e.getMessage()); } diff --git a/sql/src/test/java/tests/sql/ResultSetTest.java b/sql/src/test/java/tests/sql/ResultSetTest.java index 796c6a4..5b6d74a 100644 --- a/sql/src/test/java/tests/sql/ResultSetTest.java +++ b/sql/src/test/java/tests/sql/ResultSetTest.java @@ -107,19 +107,6 @@ public class ResultSetTest extends SQLTest { } catch (SQLException e) { fail("Unexpected exception: " + e.getMessage()); } - - try { -// Go back in position with forward only cursor - assertEquals(ResultSet.TYPE_FORWARD_ONLY, target.getFetchDirection()); - target.absolute(2); - target.absolute(1); - fail("Should get SQLException"); - } catch (SQLException e) { - // ok - } - - - } /** @@ -598,42 +585,8 @@ public class ResultSetTest extends SQLTest { } - /** - * Test method for {@link java.sql.ResultSet#previous()}. - */ - @TestTargetNew( - level = TestLevel.PARTIAL_COMPLETE, - notes = "tests SQLException", - method = "previous", - args = {} - ) - public void testPrevious() { - + public void testPrevious() throws SQLException { try { - assertEquals(ResultSet.FETCH_FORWARD, target.getFetchDirection()); - target.last(); - target.previous(); - fail("Should get SQLException"); - } catch (SQLException e) { - // ok - } - } - - /** - * Test method for {@link java.sql.ResultSet#previous()}. - * @throws SQLException - */ - @TestTargetNew( - level = TestLevel.PARTIAL_COMPLETE, - notes = "not supported", - method = "previous", - args = {} - ) - @KnownFailure("not supported") - public void testPrevious2() throws SQLException { - try { - assertSame(ResultSet.TYPE_SCROLL_INSENSITIVE, scrollableTarget.getFetchDirection()); - target.first(); target.previous(); assertTrue(target.isBeforeFirst()); diff --git a/sql/src/test/java/tests/sql/StatementTest.java b/sql/src/test/java/tests/sql/StatementTest.java index f884782..55bd7ab 100755 --- a/sql/src/test/java/tests/sql/StatementTest.java +++ b/sql/src/test/java/tests/sql/StatementTest.java @@ -692,29 +692,28 @@ public class StatementTest extends SQLTest { } } - /** - * @test java.sql.Statement#setMaxRows(int max) - * TODO not supported - */ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "not supported", - method = "setMaxRows", - args = {int.class} - ) - public void testSetMaxRows() { + public void testMaxRows() { Statement st = null; try { st = conn.createStatement(); - st.execute("select * from zoo;"); - for (int i = 0; i < 300; i += 50) { + for (int i = 0; i < 300; i += 50) { try { st.setMaxRows(i); assertEquals(i, st.getMaxRows()); - fail("Revise test implemenation for feature impl. has changed"); + ResultSet r = st.executeQuery("select * from zoo;"); + int rowCount = 0; + while (r.next()) { + ++rowCount; + } + if (i == 0) { + // 0 means unlimited. + assertTrue("rowCount=" + rowCount + " i=" + i, rowCount > i); + } else { + assertTrue("rowCount=" + rowCount + " i=" + i, rowCount <= i); + } + r.close(); } catch (SQLException sqle) { - assertEquals("not supported", sqle.getMessage()); -// fail("SQLException is thrown: " + sqle.getMessage()); + fail("SQLException is thrown: " + sqle.getMessage()); } } try { @@ -735,41 +734,6 @@ public class StatementTest extends SQLTest { } /** - * @test java.sql.Statement#getMaxRows() - * TODO not supported - */ - @TestTargetNew( - level = TestLevel.COMPLETE, - notes = "not supported", - method = "getMaxRows", - args = {} - ) - public void testGetMaxRows() { - Statement st = null; - try { - st = conn.createStatement(); - for (int i = 200; i < 500; i += 50) { - try { - st.setMaxRows(i); - assertEquals(i, st.getMaxRows()); - fail("Revise test implemenation for feature impl. has changed"); - } catch (SQLException sqle) { - assertEquals("not supported", sqle.getMessage()); -// fail("SQLException is thrown: " + sqle.getMessage()); - } - } - } catch (SQLException e) { - fail("Can't create statement, SQLException is thrown: " - + e.getMessage()); - } finally { - try { - st.close(); - } catch (SQLException ee) { - } - } - } - - /** * @test java.sql.Statement#close() * not passed according to Java Docs: should release all resources * IMMEDIATELY diff --git a/sqlite-jdbc/VERSION b/sqlite-jdbc/VERSION new file mode 100644 index 0000000..23bd019 --- /dev/null +++ b/sqlite-jdbc/VERSION @@ -0,0 +1 @@ +20100131 diff --git a/sqlite-jdbc/src/main/java/SQLite/Authorizer.java b/sqlite-jdbc/src/main/java/SQLite/Authorizer.java index cdc321d..24fc459 100644 --- a/sqlite-jdbc/src/main/java/SQLite/Authorizer.java +++ b/sqlite-jdbc/src/main/java/SQLite/Authorizer.java @@ -20,6 +20,6 @@ public interface Authorizer { */ public int authorize(int what, String arg1, String arg2, String arg3, - String arg4); + String arg4); } diff --git a/sqlite-jdbc/src/main/java/SQLite/Blob.java b/sqlite-jdbc/src/main/java/SQLite/Blob.java index 3de9f8a..3e28225 100644 --- a/sqlite-jdbc/src/main/java/SQLite/Blob.java +++ b/sqlite-jdbc/src/main/java/SQLite/Blob.java @@ -26,8 +26,8 @@ class BlobR extends InputStream { */ BlobR(Blob blob) { - this.blob = blob; - this.pos = 0; + this.blob = blob; + this.pos = 0; } /** @@ -36,8 +36,8 @@ class BlobR extends InputStream { */ public int available() throws IOException { - int ret = blob.size - pos; - return (ret < 0) ? 0 : ret; + int ret = blob.size - pos; + return (ret < 0) ? 0 : ret; } /** @@ -60,7 +60,7 @@ class BlobR extends InputStream { */ public boolean markSupported() { - return false; + return false; } /** @@ -69,8 +69,8 @@ class BlobR extends InputStream { public void close() throws IOException { blob.close(); - blob = null; - pos = 0; + blob = null; + pos = 0; } /** @@ -78,17 +78,17 @@ class BlobR extends InputStream { */ public long skip(long n) throws IOException { - long ret = pos + n; - if (ret < 0) { - ret = 0; - pos = 0; - } else if (ret > blob.size) { - ret = blob.size; - pos = blob.size; - } else { - pos = (int) ret; - } - return ret; + long ret = pos + n; + if (ret < 0) { + ret = 0; + pos = 0; + } else if (ret > blob.size) { + ret = blob.size; + pos = blob.size; + } else { + pos = (int) ret; + } + return ret; } /** @@ -97,13 +97,13 @@ class BlobR extends InputStream { */ public int read() throws IOException { - byte b[] = new byte[1]; - int n = blob.read(b, 0, pos, b.length); - if (n > 0) { - pos += n; - return b[0]; - } - return -1; + byte b[] = new byte[1]; + int n = blob.read(b, 0, pos, b.length); + if (n > 0) { + pos += n; + return b[0]; + } + return -1; } /** @@ -113,12 +113,12 @@ class BlobR extends InputStream { */ public int read(byte b[]) throws IOException { - int n = blob.read(b, 0, pos, b.length); - if (n > 0) { - pos += n; - return n; - } - return -1; + int n = blob.read(b, 0, pos, b.length); + if (n > 0) { + pos += n; + return n; + } + return -1; } /** @@ -130,21 +130,21 @@ class BlobR extends InputStream { */ public int read(byte b[], int off, int len) throws IOException { - if (off + len > b.length) { - len = b.length - off; - } - if (len < 0) { - return -1; - } - if (len == 0) { - return 0; - } - int n = blob.read(b, off, pos, len); - if (n > 0) { - pos += n; - return n; - } - return -1; + if (off + len > b.length) { + len = b.length - off; + } + if (len < 0) { + return -1; + } + if (len == 0) { + return 0; + } + int n = blob.read(b, off, pos, len); + if (n > 0) { + pos += n; + return n; + } + return -1; } } @@ -172,8 +172,8 @@ class BlobW extends OutputStream { */ BlobW(Blob blob) { - this.blob = blob; - this.pos = 0; + this.blob = blob; + this.pos = 0; } /** @@ -189,8 +189,8 @@ class BlobW extends OutputStream { public void close() throws IOException { blob.close(); - blob = null; - pos = 0; + blob = null; + pos = 0; } /** @@ -199,9 +199,9 @@ class BlobW extends OutputStream { */ public void write(int v) throws IOException { - byte b[] = new byte[1]; - b[0] = (byte) v; - pos += blob.write(b, 0, pos, 1); + byte b[] = new byte[1]; + b[0] = (byte) v; + pos += blob.write(b, 0, pos, 1); } /** @@ -210,9 +210,9 @@ class BlobW extends OutputStream { */ public void write(byte[] b) throws IOException { - if (b != null && b.length > 0) { - pos += blob.write(b, 0, pos, b.length); - } + if (b != null && b.length > 0) { + pos += blob.write(b, 0, pos, b.length); + } } /** @@ -223,15 +223,15 @@ class BlobW extends OutputStream { */ public void write(byte[] b, int off, int len) throws IOException { - if (b != null) { - if (off + len > b.length) { - len = b.length - off; - } - if (len <= 0) { - return; - } - pos += blob.write(b, off, pos, len); - } + if (b != null) { + if (off + len > b.length) { + len = b.length - off; + } + if (len <= 0) { + return; + } + pos += blob.write(b, off, pos, len); + } } } @@ -265,7 +265,7 @@ public class Blob { */ public InputStream getInputStream() { - return (InputStream) new BlobR(this); + return (InputStream) new BlobR(this); } /** @@ -274,7 +274,7 @@ public class Blob { */ public OutputStream getOutputStream() { - return (OutputStream) new BlobW(this); + return (OutputStream) new BlobW(this); } /** @@ -318,6 +318,6 @@ public class Blob { private static native void internal_init(); static { - internal_init(); + internal_init(); } } diff --git a/sqlite-jdbc/src/main/java/SQLite/Constants.java b/sqlite-jdbc/src/main/java/SQLite/Constants.java index 4e636b9..017c49c 100644 --- a/sqlite-jdbc/src/main/java/SQLite/Constants.java +++ b/sqlite-jdbc/src/main/java/SQLite/Constants.java @@ -4,154 +4,198 @@ package SQLite; /** * Container for SQLite constants. + * + * Usually generated by "native/mkconst.c". For Android, I pasted in the output of this one-liner: + * + * perl -ne '$_ =~ s/#define\s+(SQLITE\S+)\s+([0-9x]+)/ public static final int $1 = $2;/ && print $_;' external/sqlite/dist/sqlite3.h */ - public final class Constants { - /* - * Error code: 0 - */ - public static final int SQLITE_OK = 0; - /* - * Error code: 1 - */ - public static final int SQLITE_ERROR = 1; - /* - * Error code: 2 - */ - public static final int SQLITE_INTERNAL = 2; - /* - * Error code: 3 - */ - public static final int SQLITE_PERM = 3; - /* - * Error code: 4 - */ - public static final int SQLITE_ABORT = 4; - /* - * Error code: 5 - */ - public static final int SQLITE_BUSY = 5; - /* - * Error code: 6 - */ - public static final int SQLITE_LOCKED = 6; - /* - * Error code: 7 - */ - public static final int SQLITE_NOMEM = 7; - /* - * Error code: 8 - */ - public static final int SQLITE_READONLY = 8; - /* - * Error code: 9 - */ - public static final int SQLITE_INTERRUPT = 9; - /* - * Error code: 10 - */ - public static final int SQLITE_IOERR = 10; - /* - * Error code: 11 - */ - public static final int SQLITE_CORRUPT = 11; - /* - * Error code: 12 - */ - public static final int SQLITE_NOTFOUND = 12; - /* - * Error code: 13 - */ - public static final int SQLITE_FULL = 13; - /* - * Error code: 14 - */ - public static final int SQLITE_CANTOPEN = 14; - /* - * Error code: 15 - */ - public static final int SQLITE_PROTOCOL = 15; - /* - * Error code: 16 - */ - public static final int SQLITE_EMPTY = 16; - /* - * Error code: 17 - */ - public static final int SQLITE_SCHEMA = 17; - /* - * Error code: 18 - */ - public static final int SQLITE_TOOBIG = 18; - /* - * Error code: 19 - */ - public static final int SQLITE_CONSTRAINT = 19; - /* - * Error code: 20 - */ - public static final int SQLITE_MISMATCH = 20; - /* - * Error code: 21 - */ - public static final int SQLITE_MISUSE = 21; - /* - * Error code: 22 - */ - public static final int SQLITE_NOLFS = 22; - /* - * Error code: 23 - */ - public static final int SQLITE_AUTH = 23; - /* - * Error code: 24 - */ - public static final int SQLITE_FORMAT = 24; - /* - * Error code: 25 - */ - public static final int SQLITE_RANGE = 25; - /* - * Error code: 26 - */ - public static final int SQLITE_NOTADB = 26; - public static final int SQLITE_ROW = 100; - public static final int SQLITE_DONE = 101; + // Copied from VERSION. + public static final int drv_minor = 20100131; + // Generated by the one-liner above. + public static final int SQLITE_VERSION_NUMBER = 3006022; + public static final int SQLITE_OK = 0; /* Successful result */ + public static final int SQLITE_ERROR = 1; /* SQL error or missing database */ + public static final int SQLITE_INTERNAL = 2; /* Internal logic error in SQLite */ + public static final int SQLITE_PERM = 3; /* Access permission denied */ + public static final int SQLITE_ABORT = 4; /* Callback routine requested an abort */ + public static final int SQLITE_BUSY = 5; /* The database file is locked */ + public static final int SQLITE_LOCKED = 6; /* A table in the database is locked */ + public static final int SQLITE_NOMEM = 7; /* A malloc() failed */ + public static final int SQLITE_READONLY = 8; /* Attempt to write a readonly database */ + public static final int SQLITE_INTERRUPT = 9; /* Operation terminated by sqlite3_interrupt()*/ + public static final int SQLITE_IOERR = 10; /* Some kind of disk I/O error occurred */ + public static final int SQLITE_CORRUPT = 11; /* The database disk image is malformed */ + public static final int SQLITE_NOTFOUND = 12; /* NOT USED. Table or record not found */ + public static final int SQLITE_FULL = 13; /* Insertion failed because database is full */ + public static final int SQLITE_CANTOPEN = 14; /* Unable to open the database file */ + public static final int SQLITE_PROTOCOL = 15; /* NOT USED. Database lock protocol error */ + public static final int SQLITE_EMPTY = 16; /* Database is empty */ + public static final int SQLITE_SCHEMA = 17; /* The database schema changed */ + public static final int SQLITE_TOOBIG = 18; /* String or BLOB exceeds size limit */ + public static final int SQLITE_CONSTRAINT = 19; /* Abort due to constraint violation */ + public static final int SQLITE_MISMATCH = 20; /* Data type mismatch */ + public static final int SQLITE_MISUSE = 21; /* Library used incorrectly */ + public static final int SQLITE_NOLFS = 22; /* Uses OS features not supported on host */ + public static final int SQLITE_AUTH = 23; /* Authorization denied */ + public static final int SQLITE_FORMAT = 24; /* Auxiliary database format error */ + public static final int SQLITE_RANGE = 25; /* 2nd parameter to sqlite3_bind out of range */ + public static final int SQLITE_NOTADB = 26; /* File opened that is not a database file */ + public static final int SQLITE_ROW = 100; /* sqlite3_step() has another row ready */ + public static final int SQLITE_DONE = 101; /* sqlite3_step() has finished executing */ + public static final int SQLITE_OPEN_READONLY = 0x00000001; /* Ok for sqlite3_open_v2() */ + public static final int SQLITE_OPEN_READWRITE = 0x00000002; /* Ok for sqlite3_open_v2() */ + public static final int SQLITE_OPEN_CREATE = 0x00000004; /* Ok for sqlite3_open_v2() */ + public static final int SQLITE_OPEN_DELETEONCLOSE = 0x00000008; /* VFS only */ + public static final int SQLITE_OPEN_EXCLUSIVE = 0x00000010; /* VFS only */ + public static final int SQLITE_OPEN_MAIN_DB = 0x00000100; /* VFS only */ + public static final int SQLITE_OPEN_TEMP_DB = 0x00000200; /* VFS only */ + public static final int SQLITE_OPEN_TRANSIENT_DB = 0x00000400; /* VFS only */ + public static final int SQLITE_OPEN_MAIN_JOURNAL = 0x00000800; /* VFS only */ + public static final int SQLITE_OPEN_TEMP_JOURNAL = 0x00001000; /* VFS only */ + public static final int SQLITE_OPEN_SUBJOURNAL = 0x00002000; /* VFS only */ + public static final int SQLITE_OPEN_MASTER_JOURNAL = 0x00004000; /* VFS only */ + public static final int SQLITE_OPEN_NOMUTEX = 0x00008000; /* Ok for sqlite3_open_v2() */ + public static final int SQLITE_OPEN_FULLMUTEX = 0x00010000; /* Ok for sqlite3_open_v2() */ + public static final int SQLITE_OPEN_SHAREDCACHE = 0x00020000; /* Ok for sqlite3_open_v2() */ + public static final int SQLITE_OPEN_PRIVATECACHE = 0x00040000; /* Ok for sqlite3_open_v2() */ + public static final int SQLITE_IOCAP_ATOMIC = 0x00000001; + public static final int SQLITE_IOCAP_ATOMIC512 = 0x00000002; + public static final int SQLITE_IOCAP_ATOMIC1K = 0x00000004; + public static final int SQLITE_IOCAP_ATOMIC2K = 0x00000008; + public static final int SQLITE_IOCAP_ATOMIC4K = 0x00000010; + public static final int SQLITE_IOCAP_ATOMIC8K = 0x00000020; + public static final int SQLITE_IOCAP_ATOMIC16K = 0x00000040; + public static final int SQLITE_IOCAP_ATOMIC32K = 0x00000080; + public static final int SQLITE_IOCAP_ATOMIC64K = 0x00000100; + public static final int SQLITE_IOCAP_SAFE_APPEND = 0x00000200; + public static final int SQLITE_IOCAP_SEQUENTIAL = 0x00000400; + public static final int SQLITE_LOCK_NONE = 0; + public static final int SQLITE_LOCK_SHARED = 1; + public static final int SQLITE_LOCK_RESERVED = 2; + public static final int SQLITE_LOCK_PENDING = 3; + public static final int SQLITE_LOCK_EXCLUSIVE = 4; + public static final int SQLITE_SYNC_NORMAL = 0x00002; + public static final int SQLITE_SYNC_FULL = 0x00003; + public static final int SQLITE_SYNC_DATAONLY = 0x00010; + public static final int SQLITE_FCNTL_LOCKSTATE = 1; + public static final int SQLITE_GET_LOCKPROXYFILE = 2; + public static final int SQLITE_SET_LOCKPROXYFILE = 3; + public static final int SQLITE_LAST_ERRNO = 4; + public static final int SQLITE_ACCESS_EXISTS = 0; + public static final int SQLITE_ACCESS_READWRITE = 1; + public static final int SQLITE_ACCESS_READ = 2; + public static final int SQLITE_CONFIG_SINGLETHREAD = 1; /* nil */ + public static final int SQLITE_CONFIG_MULTITHREAD = 2; /* nil */ + public static final int SQLITE_CONFIG_SERIALIZED = 3; /* nil */ + public static final int SQLITE_CONFIG_MALLOC = 4; /* sqlite3_mem_methods* */ + public static final int SQLITE_CONFIG_GETMALLOC = 5; /* sqlite3_mem_methods* */ + public static final int SQLITE_CONFIG_SCRATCH = 6; /* void*, int sz, int N */ + public static final int SQLITE_CONFIG_PAGECACHE = 7; /* void*, int sz, int N */ + public static final int SQLITE_CONFIG_HEAP = 8; /* void*, int nByte, int min */ + public static final int SQLITE_CONFIG_MEMSTATUS = 9; /* boolean */ + public static final int SQLITE_CONFIG_MUTEX = 10; /* sqlite3_mutex_methods* */ + public static final int SQLITE_CONFIG_GETMUTEX = 11; /* sqlite3_mutex_methods* */ + public static final int SQLITE_CONFIG_LOOKASIDE = 13; /* int int */ + public static final int SQLITE_CONFIG_PCACHE = 14; /* sqlite3_pcache_methods* */ + public static final int SQLITE_CONFIG_GETPCACHE = 15; /* sqlite3_pcache_methods* */ + public static final int SQLITE_DBCONFIG_LOOKASIDE = 1001; /* void* int int */ + public static final int SQLITE_DENY = 1; /* Abort the SQL statement with an error */ + public static final int SQLITE_IGNORE = 2; /* Don't allow access, but don't generate an error */ + public static final int SQLITE_CREATE_INDEX = 1; /* Index Name Table Name */ + public static final int SQLITE_CREATE_TABLE = 2; /* Table Name NULL */ + public static final int SQLITE_CREATE_TEMP_INDEX = 3; /* Index Name Table Name */ + public static final int SQLITE_CREATE_TEMP_TABLE = 4; /* Table Name NULL */ + public static final int SQLITE_CREATE_TEMP_TRIGGER = 5; /* Trigger Name Table Name */ + public static final int SQLITE_CREATE_TEMP_VIEW = 6; /* View Name NULL */ + public static final int SQLITE_CREATE_TRIGGER = 7; /* Trigger Name Table Name */ + public static final int SQLITE_CREATE_VIEW = 8; /* View Name NULL */ + public static final int SQLITE_DELETE = 9; /* Table Name NULL */ + public static final int SQLITE_DROP_INDEX = 10; /* Index Name Table Name */ + public static final int SQLITE_DROP_TABLE = 11; /* Table Name NULL */ + public static final int SQLITE_DROP_TEMP_INDEX = 12; /* Index Name Table Name */ + public static final int SQLITE_DROP_TEMP_TABLE = 13; /* Table Name NULL */ + public static final int SQLITE_DROP_TEMP_TRIGGER = 14; /* Trigger Name Table Name */ + public static final int SQLITE_DROP_TEMP_VIEW = 15; /* View Name NULL */ + public static final int SQLITE_DROP_TRIGGER = 16; /* Trigger Name Table Name */ + public static final int SQLITE_DROP_VIEW = 17; /* View Name NULL */ + public static final int SQLITE_INSERT = 18; /* Table Name NULL */ + public static final int SQLITE_PRAGMA = 19; /* Pragma Name 1st arg or NULL */ + public static final int SQLITE_READ = 20; /* Table Name Column Name */ + public static final int SQLITE_SELECT = 21; /* NULL NULL */ + public static final int SQLITE_TRANSACTION = 22; /* Operation NULL */ + public static final int SQLITE_UPDATE = 23; /* Table Name Column Name */ + public static final int SQLITE_ATTACH = 24; /* Filename NULL */ + public static final int SQLITE_DETACH = 25; /* Database Name NULL */ + public static final int SQLITE_ALTER_TABLE = 26; /* Database Name Table Name */ + public static final int SQLITE_REINDEX = 27; /* Index Name NULL */ + public static final int SQLITE_ANALYZE = 28; /* Table Name NULL */ + public static final int SQLITE_CREATE_VTABLE = 29; /* Table Name Module Name */ + public static final int SQLITE_DROP_VTABLE = 30; /* Table Name Module Name */ + public static final int SQLITE_FUNCTION = 31; /* NULL Function Name */ + public static final int SQLITE_SAVEPOINT = 32; /* Operation Savepoint Name */ + public static final int SQLITE_COPY = 0; /* No longer used */ + public static final int SQLITE_LIMIT_LENGTH = 0; + public static final int SQLITE_LIMIT_SQL_LENGTH = 1; + public static final int SQLITE_LIMIT_COLUMN = 2; + public static final int SQLITE_LIMIT_EXPR_DEPTH = 3; + public static final int SQLITE_LIMIT_COMPOUND_SELECT = 4; + public static final int SQLITE_LIMIT_VDBE_OP = 5; + public static final int SQLITE_LIMIT_FUNCTION_ARG = 6; + public static final int SQLITE_LIMIT_ATTACHED = 7; + public static final int SQLITE_LIMIT_LIKE_PATTERN_LENGTH = 8; + public static final int SQLITE_LIMIT_VARIABLE_NUMBER = 9; + public static final int SQLITE_LIMIT_TRIGGER_DEPTH = 10; public static final int SQLITE_INTEGER = 1; public static final int SQLITE_FLOAT = 2; public static final int SQLITE_BLOB = 4; public static final int SQLITE_NULL = 5; public static final int SQLITE3_TEXT = 3; - public static final int SQLITE_NUMERIC = -1; - public static final int SQLITE_TEXT = 3; - public static final int SQLITE2_TEXT = -2; - public static final int SQLITE_ARGS = -3; - public static final int SQLITE_COPY = 0; - public static final int SQLITE_CREATE_INDEX = 1; - public static final int SQLITE_CREATE_TABLE = 2; - public static final int SQLITE_CREATE_TEMP_INDEX = 3; - public static final int SQLITE_CREATE_TEMP_TABLE = 4; - public static final int SQLITE_CREATE_TEMP_TRIGGER = 5; - public static final int SQLITE_CREATE_TEMP_VIEW = 6; - public static final int SQLITE_CREATE_TRIGGER = 7; - public static final int SQLITE_CREATE_VIEW = 8; - public static final int SQLITE_DELETE = 9; - public static final int SQLITE_DROP_INDEX = 10; - public static final int SQLITE_DROP_TABLE = 11; - public static final int SQLITE_DROP_TEMP_INDEX = 12; - public static final int SQLITE_DROP_TEMP_TABLE = 13; - public static final int SQLITE_DROP_TEMP_TRIGGER = 14; - public static final int SQLITE_DROP_TEMP_VIEW = 15; - public static final int SQLITE_DROP_TRIGGER = 16; - public static final int SQLITE_DROP_VIEW = 17; - public static final int SQLITE_INSERT = 18; - public static final int SQLITE_PRAGMA = 19; - public static final int SQLITE_READ = 20; - public static final int SQLITE_SELECT = 21; - public static final int SQLITE_TRANSACTION = 22; - public static final int SQLITE_UPDATE = 23; - public static final int SQLITE_ATTACH = 24; - public static final int SQLITE_DETACH = 25; - public static final int SQLITE_DENY = 1; - public static final int SQLITE_IGNORE = 2; + public static final int SQLITE_UTF8 = 1; + public static final int SQLITE_UTF16LE = 2; + public static final int SQLITE_UTF16BE = 3; + public static final int SQLITE_UTF16 = 4; /* Use native byte order */ + public static final int SQLITE_ANY = 5; /* sqlite3_create_function only */ + public static final int SQLITE_UTF16_ALIGNED = 8; /* sqlite3_create_collation only */ + public static final int SQLITE_INDEX_CONSTRAINT_EQ = 2; + public static final int SQLITE_INDEX_CONSTRAINT_GT = 4; + public static final int SQLITE_INDEX_CONSTRAINT_LE = 8; + public static final int SQLITE_INDEX_CONSTRAINT_LT = 16; + public static final int SQLITE_INDEX_CONSTRAINT_GE = 32; + public static final int SQLITE_INDEX_CONSTRAINT_MATCH = 64; + public static final int SQLITE_MUTEX_FAST = 0; + public static final int SQLITE_MUTEX_RECURSIVE = 1; + public static final int SQLITE_MUTEX_STATIC_MASTER = 2; + public static final int SQLITE_MUTEX_STATIC_MEM = 3; /* sqlite3_malloc() */ + public static final int SQLITE_MUTEX_STATIC_MEM2 = 4; /* NOT USED */ + public static final int SQLITE_MUTEX_STATIC_OPEN = 4; /* sqlite3BtreeOpen() */ + public static final int SQLITE_MUTEX_STATIC_PRNG = 5; /* sqlite3_random() */ + public static final int SQLITE_MUTEX_STATIC_LRU = 6; /* lru page list */ + public static final int SQLITE_MUTEX_STATIC_LRU2 = 7; /* lru page list */ + public static final int SQLITE_TESTCTRL_FIRST = 5; + public static final int SQLITE_TESTCTRL_PRNG_SAVE = 5; + public static final int SQLITE_TESTCTRL_PRNG_RESTORE = 6; + public static final int SQLITE_TESTCTRL_PRNG_RESET = 7; + public static final int SQLITE_TESTCTRL_BITVEC_TEST = 8; + public static final int SQLITE_TESTCTRL_FAULT_INSTALL = 9; + public static final int SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS = 10; + public static final int SQLITE_TESTCTRL_PENDING_BYTE = 11; + public static final int SQLITE_TESTCTRL_ASSERT = 12; + public static final int SQLITE_TESTCTRL_ALWAYS = 13; + public static final int SQLITE_TESTCTRL_RESERVE = 14; + public static final int SQLITE_TESTCTRL_OPTIMIZATIONS = 15; + public static final int SQLITE_TESTCTRL_ISKEYWORD = 16; + public static final int SQLITE_TESTCTRL_LAST = 16; + public static final int SQLITE_STATUS_MEMORY_USED = 0; + public static final int SQLITE_STATUS_PAGECACHE_USED = 1; + public static final int SQLITE_STATUS_PAGECACHE_OVERFLOW = 2; + public static final int SQLITE_STATUS_SCRATCH_USED = 3; + public static final int SQLITE_STATUS_SCRATCH_OVERFLOW = 4; + public static final int SQLITE_STATUS_MALLOC_SIZE = 5; + public static final int SQLITE_STATUS_PARSER_STACK = 6; + public static final int SQLITE_STATUS_PAGECACHE_SIZE = 7; + public static final int SQLITE_STATUS_SCRATCH_SIZE = 8; + public static final int SQLITE_DBSTATUS_LOOKASIDE_USED = 0; + public static final int SQLITE_STMTSTATUS_FULLSCAN_STEP = 1; + public static final int SQLITE_STMTSTATUS_SORT = 2; } diff --git a/sqlite-jdbc/src/main/java/SQLite/Database.java b/sqlite-jdbc/src/main/java/SQLite/Database.java index fbb5d29..8178836 100644 --- a/sqlite-jdbc/src/main/java/SQLite/Database.java +++ b/sqlite-jdbc/src/main/java/SQLite/Database.java @@ -22,17 +22,102 @@ public class Database { * Open an SQLite database file. * * @param filename the name of the database file - * @param mode open mode, currently ignored + * @param mode open mode (e.g. SQLITE_OPEN_READONLY) */ public void open(String filename, int mode) throws SQLite.Exception { - synchronized(this) { - _open(filename, mode); + if ((mode & 0200) != 0) { + mode = SQLite.Constants.SQLITE_OPEN_READWRITE | + SQLite.Constants.SQLITE_OPEN_CREATE; + } else if ((mode & 0400) != 0) { + mode = SQLite.Constants.SQLITE_OPEN_READONLY; + } + synchronized(this) { + try { + _open4(filename, mode, null, false); + } catch (SQLite.Exception se) { + throw se; + } catch (java.lang.OutOfMemoryError me) { + throw me; + } catch (Throwable t) { + _open(filename, mode); + } + } } + + /** + * Open an SQLite database file. + * + * @param filename the name of the database file + * @param mode open mode (e.g. SQLITE_OPEN_READONLY) + * @param vfs VFS name (for SQLite >= 3.5) + */ + + public void open(String filename, int mode, String vfs) + throws SQLite.Exception { + if ((mode & 0200) != 0) { + mode = SQLite.Constants.SQLITE_OPEN_READWRITE | + SQLite.Constants.SQLITE_OPEN_CREATE; + } else if ((mode & 0400) != 0) { + mode = SQLite.Constants.SQLITE_OPEN_READONLY; + } + synchronized(this) { + try { + _open4(filename, mode, vfs, false); + } catch (SQLite.Exception se) { + throw se; + } catch (java.lang.OutOfMemoryError me) { + throw me; + } catch (Throwable t) { + _open(filename, mode); + } + } } + /** + * Open an SQLite database file. + * + * @param filename the name of the database file + * @param mode open mode (e.g. SQLITE_OPEN_READONLY) + * @param vfs VFS name (for SQLite >= 3.5) + * @param ver2 flag to force version on create (false = SQLite3, true = SQLite2) + */ + + public void open(String filename, int mode, String vfs, boolean ver2) + throws SQLite.Exception { + if ((mode & 0200) != 0) { + mode = SQLite.Constants.SQLITE_OPEN_READWRITE | + SQLite.Constants.SQLITE_OPEN_CREATE; + } else if ((mode & 0400) != 0) { + mode = SQLite.Constants.SQLITE_OPEN_READONLY; + } + synchronized(this) { + try { + _open4(filename, mode, vfs, ver2); + } catch (SQLite.Exception se) { + throw se; + } catch (java.lang.OutOfMemoryError me) { + throw me; + } catch (Throwable t) { + _open(filename, mode); + } + } + } + + /* + * For backward compatibility to older sqlite.jar, sqlite_jni + */ + private native void _open(String filename, int mode) - throws SQLite.Exception; + throws SQLite.Exception; + + /* + * Newer full interface + */ + + private native void _open4(String filename, int mode, String vfs, + boolean ver2) + throws SQLite.Exception; /** * Open SQLite auxiliary database file for temporary @@ -42,22 +127,22 @@ public class Database { */ public void open_aux_file(String filename) throws SQLite.Exception { - synchronized(this) { - _open_aux_file(filename); - } + synchronized(this) { + _open_aux_file(filename); + } } private native void _open_aux_file(String filename) - throws SQLite.Exception; + throws SQLite.Exception; /** * Destructor for object. */ protected void finalize() { - synchronized(this) { - _finalize(); - } + synchronized(this) { + _finalize(); + } } private native void _finalize(); @@ -66,14 +151,14 @@ public class Database { * Close the underlying SQLite database file. */ - public void close() throws SQLite.Exception { - synchronized(this) { - _close(); - } + public void close() throws SQLite.Exception { + synchronized(this) { + _close(); + } } private native void _close() - throws SQLite.Exception; + throws SQLite.Exception; /** * Execute an SQL statement and invoke callback methods @@ -88,13 +173,13 @@ public class Database { */ public void exec(String sql, SQLite.Callback cb) throws SQLite.Exception { - synchronized(this) { - _exec(sql, cb); - } + synchronized(this) { + _exec(sql, cb); + } } private native void _exec(String sql, SQLite.Callback cb) - throws SQLite.Exception; + throws SQLite.Exception; /** * Execute an SQL statement and invoke callback methods @@ -120,14 +205,14 @@ public class Database { */ public void exec(String sql, SQLite.Callback cb, - String args[]) throws SQLite.Exception { - synchronized(this) { - _exec(sql, cb, args); - } + String args[]) throws SQLite.Exception { + synchronized(this) { + _exec(sql, cb, args); + } } private native void _exec(String sql, SQLite.Callback cb, String args[]) - throws SQLite.Exception; + throws SQLite.Exception; /** * Return the row identifier of the last inserted @@ -135,9 +220,9 @@ public class Database { */ public long last_insert_rowid() { - synchronized(this) { - return _last_insert_rowid(); - } + synchronized(this) { + return _last_insert_rowid(); + } } private native long _last_insert_rowid(); @@ -147,9 +232,9 @@ public class Database { */ public void interrupt() { - synchronized(this) { - _interrupt(); - } + synchronized(this) { + _interrupt(); + } } private native void _interrupt(); @@ -159,9 +244,9 @@ public class Database { */ public long changes() { - synchronized(this) { - return _changes(); - } + synchronized(this) { + return _changes(); + } } private native long _changes(); @@ -174,9 +259,9 @@ public class Database { */ public void busy_handler(SQLite.BusyHandler bh) { - synchronized(this) { - _busy_handler(bh); - } + synchronized(this) { + _busy_handler(bh); + } } private native void _busy_handler(SQLite.BusyHandler bh); @@ -189,9 +274,9 @@ public class Database { */ public void busy_timeout(int ms) { - synchronized(this) { - _busy_timeout(ms); - } + synchronized(this) { + _busy_timeout(ms); + } } private native void _busy_timeout(int ms); @@ -201,25 +286,92 @@ public class Database { * set into memory. * * @param sql the SQL statement to be executed + * @param maxrows the max. number of rows to retrieve + * @return result set + */ + + public TableResult get_table(String sql, int maxrows) + throws SQLite.Exception { + TableResult ret = new TableResult(maxrows); + if (!is3()) { + try { + exec(sql, ret); + } catch (SQLite.Exception e) { + if (maxrows <= 0 || !ret.atmaxrows) { + throw e; + } + } + } else { + synchronized(this) { + /* only one statement !!! */ + Vm vm = compile(sql); + set_last_error(vm.error_code); + if (ret.maxrows > 0) { + while (ret.nrows < ret.maxrows && vm.step(ret)) { + set_last_error(vm.error_code); + } + } else { + while (vm.step(ret)) { + set_last_error(vm.error_code); + } + } + vm.finalize(); + } + } + return ret; + } + + /** + * Convenience method to retrieve an entire result + * set into memory. + * + * @param sql the SQL statement to be executed * @return result set */ public TableResult get_table(String sql) throws SQLite.Exception { - TableResult ret = new TableResult(); - if (!is3()) { - exec(sql, ret); - } else { - synchronized(this) { - /* only one statement !!! */ - Vm vm = compile(sql); - set_last_error(vm.error_code); - while (vm.step(ret)) { - set_last_error(vm.error_code); - } - vm.finalize(); - } + return get_table(sql, 0); } - return ret; + + /** + * Convenience method to retrieve an entire result + * set into memory. + * + * @param sql the SQL statement to be executed + * @param maxrows the max. number of rows to retrieve + * @param args arguments for the SQL statement, '%q' substitution + * @return result set + */ + + public TableResult get_table(String sql, int maxrows, String args[]) + throws SQLite.Exception { + TableResult ret = new TableResult(maxrows); + if (!is3()) { + try { + exec(sql, ret, args); + } catch (SQLite.Exception e) { + if (maxrows <= 0 || !ret.atmaxrows) { + throw e; + } + } + } else { + synchronized(this) { + /* only one statement !!! */ + Vm vm = compile(sql, args); + set_last_error(vm.error_code); + if (ret.maxrows > 0) { + while (ret.nrows < ret.maxrows && vm.step(ret)) { + set_last_error(vm.error_code); + } + } else { + while (vm.step(ret)) { + set_last_error(vm.error_code); + } + } + vm.finalize(); + } + } + return ret; } /** @@ -232,22 +384,8 @@ public class Database { */ public TableResult get_table(String sql, String args[]) - throws SQLite.Exception { - TableResult ret = new TableResult(); - if (!is3()) { - exec(sql, ret, args); - } else { - synchronized(this) { - /* only one statement !!! */ - Vm vm = compile(sql, args); - set_last_error(vm.error_code); - while (vm.step(ret)) { - set_last_error(vm.error_code); - } - vm.finalize(); - } - } - return ret; + throws SQLite.Exception { + return get_table(sql, 0, args); } /** @@ -261,19 +399,32 @@ public class Database { */ public void get_table(String sql, String args[], TableResult tbl) - throws SQLite.Exception { - tbl.clear(); - if (!is3()) { - exec(sql, tbl, args); - } else { - synchronized(this) { - /* only one statement !!! */ - Vm vm = compile(sql, args); - while (vm.step(tbl)) { - } - vm.finalize(); - } - } + throws SQLite.Exception { + tbl.clear(); + if (!is3()) { + try { + exec(sql, tbl, args); + } catch (SQLite.Exception e) { + if (tbl.maxrows <= 0 || !tbl.atmaxrows) { + throw e; + } + } + } else { + synchronized(this) { + /* only one statement !!! */ + Vm vm = compile(sql, args); + if (tbl.maxrows > 0) { + while (tbl.nrows < tbl.maxrows && vm.step(tbl)) { + set_last_error(vm.error_code); + } + } else { + while (vm.step(tbl)) { + set_last_error(vm.error_code); + } + } + vm.finalize(); + } + } } /** @@ -285,7 +436,7 @@ public class Database { */ public synchronized static boolean complete(String sql) { - return _complete(sql); + return _complete(sql); } private native static boolean _complete(String sql); @@ -314,9 +465,9 @@ public class Database { */ public void create_function(String name, int nargs, Function f) { - synchronized(this) { - _create_function(name, nargs, f); - } + synchronized(this) { + _create_function(name, nargs, f); + } } private native void _create_function(String name, int nargs, Function f); @@ -330,9 +481,9 @@ public class Database { */ public void create_aggregate(String name, int nargs, Function f) { - synchronized(this) { - _create_aggregate(name, nargs, f); - } + synchronized(this) { + _create_aggregate(name, nargs, f); + } } private native void _create_aggregate(String name, int nargs, Function f); @@ -346,9 +497,9 @@ public class Database { */ public void function_type(String name, int type) { - synchronized(this) { - _function_type(name, type); - } + synchronized(this) { + _function_type(name, type); + } } private native void _function_type(String name, int type); @@ -364,7 +515,7 @@ public class Database { */ public int last_error() { - return error_code; + return error_code; } /** @@ -373,7 +524,7 @@ public class Database { */ protected void set_last_error(int error_code) { - this.error_code = error_code; + this.error_code = error_code; } /** @@ -383,9 +534,9 @@ public class Database { */ public String error_message() { - synchronized(this) { - return _errmsg(); - } + synchronized(this) { + return _errmsg(); + } } private native String _errmsg(); @@ -405,13 +556,13 @@ public class Database { */ public void set_encoding(String enc) throws SQLite.Exception { - synchronized(this) { - _set_encoding(enc); - } + synchronized(this) { + _set_encoding(enc); + } } private native void _set_encoding(String enc) - throws SQLite.Exception; + throws SQLite.Exception; /** * Set authorizer function. Only available in SQLite 2.7.6 and @@ -421,9 +572,9 @@ public class Database { */ public void set_authorizer(Authorizer auth) { - synchronized(this) { - _set_authorizer(auth); - } + synchronized(this) { + _set_authorizer(auth); + } } private native void _set_authorizer(Authorizer auth); @@ -436,9 +587,9 @@ public class Database { */ public void trace(Trace tr) { - synchronized(this) { - _trace(tr); - } + synchronized(this) { + _trace(tr); + } } private native void _trace(Trace tr); @@ -452,11 +603,11 @@ public class Database { */ public Vm compile(String sql) throws SQLite.Exception { - synchronized(this) { - Vm vm = new Vm(); - vm_compile(sql, vm); - return vm; - } + synchronized(this) { + Vm vm = new Vm(); + vm_compile(sql, vm); + return vm; + } } /** @@ -469,11 +620,11 @@ public class Database { */ public Vm compile(String sql, String args[]) throws SQLite.Exception { - synchronized(this) { - Vm vm = new Vm(); - vm_compile_args(sql, vm, args); - return vm; - } + synchronized(this) { + Vm vm = new Vm(); + vm_compile_args(sql, vm, args); + return vm; + } } /** @@ -485,11 +636,11 @@ public class Database { */ public Stmt prepare(String sql) throws SQLite.Exception { - synchronized(this) { - Stmt stmt = new Stmt(); - stmt_prepare(sql, stmt); - return stmt; - } + synchronized(this) { + Stmt stmt = new Stmt(); + stmt_prepare(sql, stmt); + return stmt; + } } /** @@ -503,12 +654,12 @@ public class Database { */ public Blob open_blob(String db, String table, String column, - long row, boolean rw) throws SQLite.Exception { - synchronized(this) { - Blob blob = new Blob(); - _open_blob(db, table, column, row, rw, blob); - return blob; - } + long row, boolean rw) throws SQLite.Exception { + synchronized(this) { + Blob blob = new Blob(); + _open_blob(db, table, column, row, rw, blob); + return blob; + } } /** @@ -525,7 +676,7 @@ public class Database { */ private native void vm_compile(String sql, Vm vm) - throws SQLite.Exception; + throws SQLite.Exception; /** * Internal compile method, SQLite 3.0 only. @@ -535,7 +686,7 @@ public class Database { */ private native void vm_compile_args(String sql, Vm vm, String args[]) - throws SQLite.Exception; + throws SQLite.Exception; /** * Internal SQLite3 prepare method. @@ -544,7 +695,7 @@ public class Database { */ private native void stmt_prepare(String sql, Stmt stmt) - throws SQLite.Exception; + throws SQLite.Exception; /** * Internal SQLite open blob method. @@ -557,8 +708,8 @@ public class Database { */ private native void _open_blob(String db, String table, String column, - long row, boolean rw, Blob blob) - throws SQLite.Exception; + long row, boolean rw, Blob blob) + throws SQLite.Exception; /** * Establish a progress callback method which gets called after @@ -569,47 +720,186 @@ public class Database { */ public void progress_handler(int n, SQLite.ProgressHandler p) { - synchronized(this) { - _progress_handler(n, p); - } + synchronized(this) { + _progress_handler(n, p); + } } private native void _progress_handler(int n, SQLite.ProgressHandler p); /** + * Specify key for encrypted database. To be called + * right after open() on SQLite3 databases. + * Not available in public releases of SQLite. + * + * @param ekey the key as byte array + */ + + public void key(byte[] ekey) throws SQLite.Exception { + synchronized(this) { + _key(ekey); + } + } + + /** + * Specify key for encrypted database. To be called + * right after open() on SQLite3 databases. + * Not available in public releases of SQLite. + * + * @param skey the key as String + */ + + public void key(String skey) throws SQLite.Exception { + synchronized(this) { + byte ekey[] = null; + if (skey != null && skey.length() > 0) { + ekey = new byte[skey.length()]; + for (int i = 0; i< skey.length(); i++) { + char c = skey.charAt(i); + ekey[i] = (byte) ((c & 0xff) ^ (c >> 8)); + } + } + _key(ekey); + } + } + + private native void _key(byte[] ekey); + + /** + * Change the key of a encrypted database. The + * SQLite3 database must have been open()ed. + * Not available in public releases of SQLite. + * + * @param ekey the key as byte array + */ + + public void rekey(byte[] ekey) throws SQLite.Exception { + synchronized(this) { + _rekey(ekey); + } + } + + /** + * Change the key of a encrypted database. The + * SQLite3 database must have been open()ed. + * Not available in public releases of SQLite. + * + * @param skey the key as String + */ + + public void rekey(String skey) throws SQLite.Exception { + synchronized(this) { + byte ekey[] = null; + if (skey != null && skey.length() > 0) { + ekey = new byte[skey.length()]; + for (int i = 0; i< skey.length(); i++) { + char c = skey.charAt(i); + ekey[i] = (byte) ((c & 0xff) ^ (c >> 8)); + } + } + _rekey(ekey); + } + } + + private native void _rekey(byte[] ekey); + + /** + * Enable/disable shared cache mode (SQLite 3.x only). + * + * @param onoff boolean to enable or disable shared cache + * @return boolean when true, function supported/succeeded + */ + + protected static native boolean _enable_shared_cache(boolean onoff); + + /** * Internal native initializer. */ private static native void internal_init(); /** + * Make long value from julian date for java.lang.Date + * + * @param d double value (julian date in SQLite3 format) + * @return long + */ + + public static long long_from_julian(double d) { + d -= 2440587.5; + d *= 86400000.0; + return (long) d; + } + + /** + * Make long value from julian date for java.lang.Date + * + * @param s string (double value) (julian date in SQLite3 format) + * @return long + */ + + public static long long_from_julian(String s) throws SQLite.Exception { + try { + double d = Double.valueOf(s).doubleValue(); + return long_from_julian(d); + } catch (java.lang.Exception ee) { + throw new SQLite.Exception("not a julian date"); + } + } + + /** + * Make julian date value from java.lang.Date + * + * @param ms millisecond value of java.lang.Date + * @return double + */ + + public static double julian_from_long(long ms) { + double adj = (ms < 0) ? 0 : 0.5; + double d = (ms + adj) / 86400000.0 + 2440587.5; + return d; + } + + /** * Static initializer to load the native part. */ static { - try { - String path = System.getProperty("SQLite.library.path"); - if (path == null || path.length() == 0){ - System.loadLibrary("sqlite_jni"); - } else { - try { - java.lang.reflect.Method mapLibraryName; - Class param[] = new Class[1]; - param[0] = String.class; - mapLibraryName = System.class.getMethod("mapLibraryName", - param); - Object args[] = new Object[1]; - args[0] = "sqlite_jni"; - String mapped = (String) mapLibraryName.invoke(null, args); - System.load(path + java.io.File.separator + mapped); - } catch (Throwable t) { - System.loadLibrary("sqlite_jni"); - } - } - internal_init(); - } catch (Throwable t) { - System.err.println("Unable to load sqlite: " + t); - } + try { + String path = System.getProperty("SQLite.library.path"); + if (path == null || path.length() == 0) { + System.loadLibrary("sqlite_jni"); + } else { + try { + java.lang.reflect.Method mapLibraryName; + Class param[] = new Class[1]; + param[0] = String.class; + mapLibraryName = System.class.getMethod("mapLibraryName", + param); + Object args[] = new Object[1]; + args[0] = "sqlite_jni"; + String mapped = (String) mapLibraryName.invoke(null, args); + System.load(path + java.io.File.separator + mapped); + } catch (Throwable t) { + System.err.println("Unable to load sqlite_jni from" + + "SQLite.library.path=" + path + + ", trying system default: " + t); + System.loadLibrary("sqlite_jni"); + } + } + } catch (Throwable t) { + System.err.println("Unable to load sqlite_jni: " + t); + } + /* + * Call native initializer functions now, since the + * native part could have been linked statically, i.e. + * the try/catch above would have failed in that case. + */ + try { + internal_init(); + new FunctionContext(); + } catch (java.lang.Exception e) { + } } } diff --git a/sqlite-jdbc/src/main/java/SQLite/Exception.java b/sqlite-jdbc/src/main/java/SQLite/Exception.java index cc26b99..589fa4b 100644 --- a/sqlite-jdbc/src/main/java/SQLite/Exception.java +++ b/sqlite-jdbc/src/main/java/SQLite/Exception.java @@ -13,6 +13,6 @@ public class Exception extends java.lang.Exception { */ public Exception(String string) { - super(string); + super(string); } } diff --git a/sqlite-jdbc/src/main/java/SQLite/FunctionContext.java b/sqlite-jdbc/src/main/java/SQLite/FunctionContext.java index d0b5182..8509b4d 100644 --- a/sqlite-jdbc/src/main/java/SQLite/FunctionContext.java +++ b/sqlite-jdbc/src/main/java/SQLite/FunctionContext.java @@ -77,6 +77,6 @@ public class FunctionContext { private static native void internal_init(); static { - internal_init(); + internal_init(); } } diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCConnection.java b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCConnection.java index 20c98e3..67e95da 100644 --- a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCConnection.java +++ b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCConnection.java @@ -22,6 +22,11 @@ public class JDBCConnection protected String enc; /** + * SQLite 3 VFS to use. + */ + protected String vfs; + + /** * Autocommit flag, true means autocommit. */ protected boolean autocommit = true; @@ -38,6 +43,11 @@ public class JDBCConnection protected int timeout = 1000000; /** + * Use double/julian date representation. + */ + protected boolean useJulian = false; + + /** * File name of database. */ private String dbfile = null; @@ -57,344 +67,398 @@ public class JDBCConnection */ private boolean readonly = false; + /** + * Transaction isolation mode. + */ + private int trmode = TRANSACTION_SERIALIZABLE; private boolean busy0(DatabaseX db, int count) { - if (count <= 1) { - t0 = System.currentTimeMillis(); - } - if (db != null) { - long t1 = System.currentTimeMillis(); - if (t1 - t0 > timeout) { - return false; - } - db.wait(100); - return true; - } - return false; + if (count <= 1) { + t0 = System.currentTimeMillis(); + } + if (db != null) { + long t1 = System.currentTimeMillis(); + if (t1 - t0 > timeout) { + return false; + } + db.wait(100); + return true; + } + return false; } public boolean busy(String table, int count) { - return busy0(db, count); + return busy0(db, count); } protected boolean busy3(DatabaseX db, int count) { - if (count <= 1) { - t0 = System.currentTimeMillis(); - } - if (db != null) { - long t1 = System.currentTimeMillis(); - if (t1 - t0 > timeout) { - return false; - } - return true; - } - return false; + if (count <= 1) { + t0 = System.currentTimeMillis(); + } + if (db != null) { + long t1 = System.currentTimeMillis(); + if (t1 - t0 > timeout) { + return false; + } + return true; + } + return false; } private DatabaseX open(boolean readonly) throws SQLException { - DatabaseX db = null; - try { - db = new DatabaseX(); - db.open(dbfile, readonly ? 0444 : 0644); - db.set_encoding(enc); - } catch (SQLite.Exception e) { - throw new SQLException(e.toString()); - } - int loop = 0; - while (true) { - try { - db.exec("PRAGMA short_column_names = off;", null); - db.exec("PRAGMA full_column_names = on;", null); - db.exec("PRAGMA empty_result_callbacks = on;", null); - if (SQLite.Database.version().compareTo("2.6.0") >= 0) { - db.exec("PRAGMA show_datatypes = on;", null); - } - } catch (SQLite.Exception e) { - if (db.last_error() != SQLite.Constants.SQLITE_BUSY || - !busy0(db, ++loop)) { - try { - db.close(); - } catch (SQLite.Exception ee) { - } - throw new SQLException(e.toString()); - } - continue; - } - break; - } - return db; - } - - public JDBCConnection(String url, String enc) throws SQLException { - if (url.startsWith("sqlite:/")) { - dbfile = url.substring(8); - } else if (url.startsWith("jdbc:sqlite:/")) { - dbfile = url.substring(13); - } else { - throw new SQLException("unsupported url"); - } - this.url = url; - this.enc = enc; - try { - db = open(readonly); - db.busy_handler(this); - } catch (SQLException e) { - if (db != null) { - try { - db.close(); - } catch (SQLite.Exception ee) { - } - } - throw e; - } + DatabaseX dbx = null; + try { + dbx = new DatabaseX(); + dbx.open(dbfile, readonly ? SQLite.Constants.SQLITE_OPEN_READONLY : + (SQLite.Constants.SQLITE_OPEN_READWRITE | + SQLite.Constants.SQLITE_OPEN_CREATE), vfs); + dbx.set_encoding(enc); + } catch (SQLite.Exception e) { + throw new SQLException(e.toString()); + } + int loop = 0; + while (true) { + try { + dbx.exec("PRAGMA short_column_names = off;", null); + dbx.exec("PRAGMA full_column_names = on;", null); + dbx.exec("PRAGMA empty_result_callbacks = on;", null); + if (SQLite.Database.version().compareTo("2.6.0") >= 0) { + dbx.exec("PRAGMA show_datatypes = on;", null); + } + } catch (SQLite.Exception e) { + if (dbx.last_error() != SQLite.Constants.SQLITE_BUSY || + !busy0(dbx, ++loop)) { + try { + dbx.close(); + } catch (SQLite.Exception ee) { + } + throw new SQLException(e.toString()); + } + continue; + } + break; + } + return dbx; + } + + public JDBCConnection(String url, String enc, String pwd, String drep, + String vfs) + throws SQLException { + if (url.startsWith("sqlite:/")) { + dbfile = url.substring(8); + } else if (url.startsWith("jdbc:sqlite:/")) { + dbfile = url.substring(13); + } else { + throw new SQLException("unsupported url"); + } + this.url = url; + this.enc = enc; + this.vfs = vfs; + try { + db = open(readonly); + try { + if (pwd != null && pwd.length() > 0) { + db.key(pwd); + } + } catch (SQLite.Exception se) { + throw new SQLException("error while setting key"); + } + db.busy_handler(this); + } catch (SQLException e) { + if (db != null) { + try { + db.close(); + } catch (SQLite.Exception ee) { + } + } + throw e; + } + useJulian = drep != null && + (drep.startsWith("j") || drep.startsWith("J")); } /* non-standard */ public SQLite.Database getSQLiteDatabase() { - return (SQLite.Database) db; + return (SQLite.Database) db; } public Statement createStatement() { - JDBCStatement s = new JDBCStatement(this); - return s; + JDBCStatement s = new JDBCStatement(this); + return s; } - + public Statement createStatement(int resultSetType, - int resultSetConcurrency) - throws SQLException { - JDBCStatement s = new JDBCStatement(this); - return s; - } - + int resultSetConcurrency) + throws SQLException { + if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && + resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE && + resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) { + throw new SQLException("unsupported result set type"); + } + if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && + resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) { + throw new SQLException("unsupported result set concurrency"); + } + JDBCStatement s = new JDBCStatement(this); + return s; + } + public DatabaseMetaData getMetaData() throws SQLException { - if (meta == null) { - meta = new JDBCDatabaseMetaData(this); - } - return meta; + if (meta == null) { + meta = new JDBCDatabaseMetaData(this); + } + return meta; } public void close() throws SQLException { - try { - rollback(); - } catch (SQLException e) { - /* ignored */ - } - intrans = false; - if (db != null) { - try { - db.close(); - db = null; - } catch (SQLite.Exception e) { - throw new SQLException(e.toString()); - } - } + try { + rollback(); + } catch (SQLException e) { + /* ignored */ + } + intrans = false; + if (db != null) { + try { + db.close(); + db = null; + } catch (SQLite.Exception e) { + throw new SQLException(e.toString()); + } + } } public boolean isClosed() throws SQLException { - return db == null; + return db == null; } public boolean isReadOnly() throws SQLException { - return readonly; + return readonly; } public void clearWarnings() throws SQLException { } public void commit() throws SQLException { - if (db == null) { - throw new SQLException("stale connection"); - } - if (!intrans) { - return; - } - try { - db.exec("COMMIT", null); - intrans = false; - } catch (SQLite.Exception e) { - throw new SQLException(e.toString()); - } + if (db == null) { + throw new SQLException("stale connection"); + } + if (!intrans) { + return; + } + try { + db.exec("COMMIT", null); + intrans = false; + } catch (SQLite.Exception e) { + throw new SQLException(e.toString()); + } } public boolean getAutoCommit() throws SQLException { - return autocommit; + return autocommit; } public String getCatalog() throws SQLException { - return null; + return null; } public int getTransactionIsolation() throws SQLException { - return TRANSACTION_SERIALIZABLE; + return trmode; } public SQLWarning getWarnings() throws SQLException { - return null; + return null; } public String nativeSQL(String sql) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public CallableStatement prepareCall(String sql) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public CallableStatement prepareCall(String sql, int x, int y) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public PreparedStatement prepareStatement(String sql) throws SQLException { - JDBCPreparedStatement s = new JDBCPreparedStatement(this, sql); - return s; + JDBCPreparedStatement s = new JDBCPreparedStatement(this, sql); + return s; } public PreparedStatement prepareStatement(String sql, int resultSetType, - int resultSetConcurrency) - throws SQLException { - JDBCPreparedStatement s = new JDBCPreparedStatement(this, sql); - return s; + int resultSetConcurrency) + throws SQLException { + if (resultSetType != ResultSet.TYPE_FORWARD_ONLY && + resultSetType != ResultSet.TYPE_SCROLL_INSENSITIVE && + resultSetType != ResultSet.TYPE_SCROLL_SENSITIVE) { + throw new SQLException("unsupported result set type"); + } + if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY && + resultSetConcurrency != ResultSet.CONCUR_UPDATABLE) { + throw new SQLException("unsupported result set concurrency"); + } + JDBCPreparedStatement s = new JDBCPreparedStatement(this, sql); + return s; } public void rollback() throws SQLException { - if (db == null) { - throw new SQLException("stale connection"); - } - if (!intrans) { - return; - } - try { - db.exec("ROLLBACK", null); - intrans = false; - } catch (SQLite.Exception e) { - throw new SQLException(e.toString()); - } + if (db == null) { + throw new SQLException("stale connection"); + } + if (!intrans) { + return; + } + try { + db.exec("ROLLBACK", null); + intrans = false; + } catch (SQLite.Exception e) { + throw new SQLException(e.toString()); + } } public void setAutoCommit(boolean ac) throws SQLException { - if (ac && intrans && db != null) { - try { - db.exec("ROLLBACK", null); - } catch (SQLite.Exception e) { - throw new SQLException(e.toString()); - } - } - intrans = false; - autocommit = ac; + if (ac && intrans && db != null) { + try { + db.exec("ROLLBACK", null); + } catch (SQLite.Exception e) { + throw new SQLException(e.toString()); + } finally { + intrans = false; + } + } + autocommit = ac; } public void setCatalog(String catalog) throws SQLException { } public void setReadOnly(boolean ro) throws SQLException { - if (intrans) { - throw new SQLException("incomplete transaction"); - } - if (ro != readonly) { - DatabaseX db = null; - try { - db = open(ro); - this.db.close(); - this.db = db; - db = null; - readonly = ro; - } catch (SQLException e) { - throw e; - } catch (SQLite.Exception ee) { - if (db != null) { - try { - db.close(); - } catch (SQLite.Exception eee) { - } - } - throw new SQLException(ee.toString()); - } - } + if (intrans) { + throw new SQLException("incomplete transaction"); + } + if (ro != readonly) { + DatabaseX dbx = null; + try { + dbx = open(ro); + db.close(); + db = dbx; + dbx = null; + readonly = ro; + } catch (SQLException e) { + throw e; + } catch (SQLite.Exception ee) { + if (dbx != null) { + try { + dbx.close(); + } catch (SQLite.Exception eee) { + } + } + throw new SQLException(ee.toString()); + } + } } public void setTransactionIsolation(int level) throws SQLException { - if (level != TRANSACTION_SERIALIZABLE) { - throw new SQLException("not supported"); - } + if (db.is3() && SQLite.JDBCDriver.sharedCache) { + String flag = null; + if (level == TRANSACTION_READ_UNCOMMITTED && + trmode != TRANSACTION_READ_UNCOMMITTED) { + flag = "on"; + } else if (level == TRANSACTION_SERIALIZABLE && + trmode != TRANSACTION_SERIALIZABLE) { + flag = "off"; + } + if (flag != null) { + try { + db.exec("PRAGMA read_uncommitted = " + flag + ";", null); + trmode = level; + } catch (java.lang.Exception e) { + } + } + } + if (level != trmode) { + throw new SQLException("not supported"); + } } public java.util.Map<String, Class<?>> getTypeMap() throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public void setTypeMap(java.util.Map map) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public int getHoldability() throws SQLException { - return ResultSet.HOLD_CURSORS_OVER_COMMIT; + return ResultSet.HOLD_CURSORS_OVER_COMMIT; } public void setHoldability(int holdability) throws SQLException { - if (holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT) { - return; - } - throw new SQLException("not supported"); + if (holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT) { + return; + } + throw new SQLException("not supported"); } public Savepoint setSavepoint() throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public Savepoint setSavepoint(String name) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public void rollback(Savepoint x) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public void releaseSavepoint(Savepoint x) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public Statement createStatement(int resultSetType, - int resultSetConcurrency, - int resultSetHoldability) - throws SQLException { - if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) { - throw new SQLException("not supported"); - } - return createStatement(resultSetType, resultSetConcurrency); + int resultSetConcurrency, + int resultSetHoldability) + throws SQLException { + if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) { + throw new SQLException("not supported"); + } + return createStatement(resultSetType, resultSetConcurrency); } public PreparedStatement prepareStatement(String sql, int resultSetType, - int resultSetConcurrency, - int resultSetHoldability) - throws SQLException { - if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) { - throw new SQLException("not supported"); - } - return prepareStatement(sql, resultSetType, resultSetConcurrency); + int resultSetConcurrency, + int resultSetHoldability) + throws SQLException { + if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) { + throw new SQLException("not supported"); + } + return prepareStatement(sql, resultSetType, resultSetConcurrency); } public CallableStatement prepareCall(String sql, int x, int y, int z) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public PreparedStatement prepareStatement(String sql, int autokeys) - throws SQLException { - if (autokeys != Statement.NO_GENERATED_KEYS) { - throw new SQLException("not supported"); - } - return prepareStatement(sql); + throws SQLException { + if (autokeys != Statement.NO_GENERATED_KEYS) { + throw new SQLException("not supported"); + } + return prepareStatement(sql); } public PreparedStatement prepareStatement(String sql, int colIndexes[]) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public PreparedStatement prepareStatement(String sql, String columns[]) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } } @@ -404,49 +468,49 @@ class DatabaseX extends SQLite.Database { static Object lock = new Object(); public DatabaseX() { - super(); + super(); } void wait(int ms) { - try { - synchronized (lock) { - lock.wait(ms); - } - } catch (java.lang.Exception e) { - } + try { + synchronized (lock) { + lock.wait(ms); + } + } catch (java.lang.Exception e) { + } } public void exec(String sql, SQLite.Callback cb) - throws SQLite.Exception { - super.exec(sql, cb); - synchronized (lock) { - lock.notifyAll(); - } + throws SQLite.Exception { + super.exec(sql, cb); + synchronized (lock) { + lock.notifyAll(); + } } public void exec(String sql, SQLite.Callback cb, String args[]) - throws SQLite.Exception { - super.exec(sql, cb, args); - synchronized (lock) { - lock.notifyAll(); - } + throws SQLite.Exception { + super.exec(sql, cb, args); + synchronized (lock) { + lock.notifyAll(); + } } public SQLite.TableResult get_table(String sql, String args[]) - throws SQLite.Exception { - SQLite.TableResult ret = super.get_table(sql, args); - synchronized (lock) { - lock.notifyAll(); - } - return ret; + throws SQLite.Exception { + SQLite.TableResult ret = super.get_table(sql, args); + synchronized (lock) { + lock.notifyAll(); + } + return ret; } public void get_table(String sql, String args[], SQLite.TableResult tbl) - throws SQLite.Exception { - super.get_table(sql, args, tbl); - synchronized (lock) { - lock.notifyAll(); - } + throws SQLite.Exception { + super.get_table(sql, args, tbl); + synchronized (lock) { + lock.notifyAll(); + } } } diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCDatabaseMetaData.java b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCDatabaseMetaData.java index 8c14d1d..878e06e 100644 --- a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCDatabaseMetaData.java +++ b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCDatabaseMetaData.java @@ -8,1571 +8,1640 @@ public class JDBCDatabaseMetaData implements DatabaseMetaData { private JDBCConnection conn; public JDBCDatabaseMetaData(JDBCConnection conn) { - this.conn = conn; + this.conn = conn; } public boolean allProceduresAreCallable() throws SQLException { - return false; + return false; } public boolean allTablesAreSelectable() throws SQLException { - return true; + return true; } public String getURL() throws SQLException { - return conn.url; + return conn.url; } public String getUserName() throws SQLException { - return ""; + return ""; } public boolean isReadOnly() throws SQLException { - return false; + return false; } public boolean nullsAreSortedHigh() throws SQLException { - return false; + return false; } public boolean nullsAreSortedLow() throws SQLException { - return false; + return false; } public boolean nullsAreSortedAtStart() throws SQLException { - return false; + return false; } public boolean nullsAreSortedAtEnd() throws SQLException { - return false; + return false; } public String getDatabaseProductName() throws SQLException { - return "SQLite"; + return "SQLite"; } public String getDatabaseProductVersion() throws SQLException { - return SQLite.Database.version(); + return SQLite.Database.version(); } public String getDriverName() throws SQLException { - return "SQLite/JDBC"; + return "SQLite/JDBC"; } public String getDriverVersion() throws SQLException { - return "" + SQLite.JDBCDriver.MAJORVERSION + "." + - SQLite.JDBCDriver.MINORVERSION; + return "" + SQLite.JDBCDriver.MAJORVERSION + "." + + SQLite.Constants.drv_minor; } public int getDriverMajorVersion() { - return SQLite.JDBCDriver.MAJORVERSION; + return SQLite.JDBCDriver.MAJORVERSION; } public int getDriverMinorVersion() { - return SQLite.JDBCDriver.MINORVERSION; + return SQLite.Constants.drv_minor; } public boolean usesLocalFiles() throws SQLException { - return true; + return true; } public boolean usesLocalFilePerTable() throws SQLException { - return false; + return false; } public boolean supportsMixedCaseIdentifiers() throws SQLException { - return false; + return false; } public boolean storesUpperCaseIdentifiers() throws SQLException { - return false; + return false; } public boolean storesLowerCaseIdentifiers() throws SQLException { - return false; + return false; } public boolean storesMixedCaseIdentifiers() throws SQLException { - return true; + return true; } public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException { - return false; + return false; } public boolean storesUpperCaseQuotedIdentifiers() throws SQLException { - return false; + return false; } public boolean storesLowerCaseQuotedIdentifiers() throws SQLException { - return false; + return false; } public boolean storesMixedCaseQuotedIdentifiers() throws SQLException { - return true; + return true; } public String getIdentifierQuoteString() throws SQLException { - return "\""; + return "\""; } public String getSQLKeywords() throws SQLException { - return "SELECT,UPDATE,CREATE,TABLE,VIEW,DELETE,FROM,WHERE" + - ",COMMIT,ROLLBACK,TRIGGER"; + return "SELECT,UPDATE,CREATE,TABLE,VIEW,DELETE,FROM,WHERE" + + ",COMMIT,ROLLBACK,TRIGGER"; } public String getNumericFunctions() throws SQLException { - return ""; + return ""; } public String getStringFunctions() throws SQLException { - return ""; + return ""; } public String getSystemFunctions() throws SQLException { - return ""; + return ""; } public String getTimeDateFunctions() throws SQLException { - return ""; + return ""; } public String getSearchStringEscape() throws SQLException { - return "\\"; + return "\\"; } public String getExtraNameCharacters() throws SQLException { - return ""; + return ""; } public boolean supportsAlterTableWithAddColumn() throws SQLException { - return false; + return false; } public boolean supportsAlterTableWithDropColumn() throws SQLException { - return false; + return false; } public boolean supportsColumnAliasing() throws SQLException { - return true; + return true; } public boolean nullPlusNonNullIsNull() throws SQLException { - return false; + return false; } public boolean supportsConvert() throws SQLException { - return false; + return false; } public boolean supportsConvert(int fromType, int toType) - throws SQLException { - return false; + throws SQLException { + return false; } public boolean supportsTableCorrelationNames() throws SQLException { - return true; + return true; } public boolean supportsDifferentTableCorrelationNames() - throws SQLException { - return false; + throws SQLException { + return false; } public boolean supportsExpressionsInOrderBy() throws SQLException { - return true; + return true; } public boolean supportsOrderByUnrelated() throws SQLException { - return true; + return true; } public boolean supportsGroupBy() throws SQLException { - return true; + return true; } public boolean supportsGroupByUnrelated() throws SQLException { - return true; + return true; } public boolean supportsGroupByBeyondSelect() throws SQLException { - return false; + return false; } public boolean supportsLikeEscapeClause() throws SQLException { - return false; + return false; } public boolean supportsMultipleResultSets() throws SQLException { - return false; + return false; } public boolean supportsMultipleTransactions() throws SQLException { - return false; + return false; } public boolean supportsNonNullableColumns() throws SQLException { - return true; + return true; } public boolean supportsMinimumSQLGrammar() throws SQLException { - return true; + return true; } public boolean supportsCoreSQLGrammar() throws SQLException { - return false; + return false; } public boolean supportsExtendedSQLGrammar() throws SQLException { - return false; + return false; } public boolean supportsANSI92EntryLevelSQL() throws SQLException { - return true; + return true; } public boolean supportsANSI92IntermediateSQL() throws SQLException { - return false; + return false; } public boolean supportsANSI92FullSQL() throws SQLException { - return false; + return false; } public boolean supportsIntegrityEnhancementFacility() - throws SQLException { - return false; + throws SQLException { + return false; } public boolean supportsOuterJoins() throws SQLException { - return false; + return false; } public boolean supportsFullOuterJoins() throws SQLException { - return false; + return false; } public boolean supportsLimitedOuterJoins() throws SQLException { - return false; + return false; } public String getSchemaTerm() throws SQLException { - return ""; + return ""; } public String getProcedureTerm() throws SQLException { - return ""; + return ""; } public String getCatalogTerm() throws SQLException { - return ""; + return ""; } public boolean isCatalogAtStart() throws SQLException { - return false; + return false; } public String getCatalogSeparator() throws SQLException { - return ""; + return ""; } public boolean supportsSchemasInDataManipulation() throws SQLException { - return false; + return false; } public boolean supportsSchemasInProcedureCalls() throws SQLException { - return false; + return false; } public boolean supportsSchemasInTableDefinitions() throws SQLException { - return false; + return false; } public boolean supportsSchemasInIndexDefinitions() throws SQLException { - return false; + return false; } public boolean supportsSchemasInPrivilegeDefinitions() - throws SQLException { - return false; + throws SQLException { + return false; } public boolean supportsCatalogsInDataManipulation() throws SQLException { - return false; + return false; } public boolean supportsCatalogsInProcedureCalls() throws SQLException { - return false; + return false; } public boolean supportsCatalogsInTableDefinitions() throws SQLException { - return false; + return false; } public boolean supportsCatalogsInIndexDefinitions() throws SQLException { - return false; + return false; } public boolean supportsCatalogsInPrivilegeDefinitions() - throws SQLException { - return false; + throws SQLException { + return false; } public boolean supportsPositionedDelete() throws SQLException { - return false; + return false; } public boolean supportsPositionedUpdate() throws SQLException { - return false; + return false; } public boolean supportsSelectForUpdate() throws SQLException { - return true; + return false; } public boolean supportsStoredProcedures() throws SQLException { - return false; + return false; } public boolean supportsSubqueriesInComparisons() throws SQLException { - return true; + return true; } public boolean supportsSubqueriesInExists() throws SQLException { - return true; + return true; } public boolean supportsSubqueriesInIns() throws SQLException { - return true; + return true; } public boolean supportsSubqueriesInQuantifieds() throws SQLException { - return false; + return false; } public boolean supportsCorrelatedSubqueries() throws SQLException { - return false; + return false; } public boolean supportsUnion() throws SQLException { - return false; + return true; } public boolean supportsUnionAll() throws SQLException { - return false; + return true; } public boolean supportsOpenCursorsAcrossCommit() throws SQLException { - return false; + return false; } public boolean supportsOpenCursorsAcrossRollback() throws SQLException { - return false; + return false; } public boolean supportsOpenStatementsAcrossCommit() throws SQLException { - return false; + return false; } public boolean supportsOpenStatementsAcrossRollback() throws SQLException { - return false; + return false; } public int getMaxBinaryLiteralLength() throws SQLException { - return 0; + return 0; } public int getMaxCharLiteralLength() throws SQLException { - return 0; + return 0; } public int getMaxColumnNameLength() throws SQLException { - return 0; + return 0; } public int getMaxColumnsInGroupBy() throws SQLException { - return 0; + return 0; } public int getMaxColumnsInIndex() throws SQLException { - return 0; + return 0; } public int getMaxColumnsInOrderBy() throws SQLException { - return 0; + return 0; } public int getMaxColumnsInSelect() throws SQLException { - return 0; + return 0; } public int getMaxColumnsInTable() throws SQLException { - return 0; + return 0; } public int getMaxConnections() throws SQLException { - return 0; + return 0; } public int getMaxCursorNameLength() throws SQLException { - return 8; + return 8; } public int getMaxIndexLength() throws SQLException { - return 0; + return 0; } public int getMaxSchemaNameLength() throws SQLException { - return 0; + return 0; } public int getMaxProcedureNameLength() throws SQLException { - return 0; + return 0; } public int getMaxCatalogNameLength() throws SQLException { - return 0; + return 0; } public int getMaxRowSize() throws SQLException { - return 0; + return 0; } public boolean doesMaxRowSizeIncludeBlobs() throws SQLException { - return true; + return true; } public int getMaxStatementLength() throws SQLException { - return 0; + return 0; } public int getMaxStatements() throws SQLException { - return 0; + return 0; } public int getMaxTableNameLength() throws SQLException { - return 0; + return 0; } public int getMaxTablesInSelect() throws SQLException { - return 0; + return 0; } public int getMaxUserNameLength() throws SQLException { - return 0; + return 0; } public int getDefaultTransactionIsolation() throws SQLException { - return Connection.TRANSACTION_SERIALIZABLE; + return Connection.TRANSACTION_SERIALIZABLE; } public boolean supportsTransactions() throws SQLException { - return true; + return true; } public boolean supportsTransactionIsolationLevel(int level) - throws SQLException { - return level == Connection.TRANSACTION_SERIALIZABLE; + throws SQLException { + return level == Connection.TRANSACTION_SERIALIZABLE; } public boolean supportsDataDefinitionAndDataManipulationTransactions() - throws SQLException { - return true; + throws SQLException { + return true; } public boolean supportsDataManipulationTransactionsOnly() - throws SQLException { - return false; + throws SQLException { + return false; } public boolean dataDefinitionCausesTransactionCommit() - throws SQLException { - return false; + throws SQLException { + return false; } public boolean dataDefinitionIgnoredInTransactions() throws SQLException { - return false; + return false; } public ResultSet getProcedures(String catalog, String schemaPattern, - String procedureNamePattern) - throws SQLException { - return null; + String procedureNamePattern) + throws SQLException { + return null; } public ResultSet getProcedureColumns(String catalog, - String schemaPattern, - String procedureNamePattern, - String columnNamePattern) - throws SQLException { - return null; + String schemaPattern, + String procedureNamePattern, + String columnNamePattern) + throws SQLException { + return null; } public ResultSet getTables(String catalog, String schemaPattern, - String tableNamePattern, String types[]) - throws SQLException { - JDBCStatement s = new JDBCStatement(conn); - StringBuffer sb = new StringBuffer(); - sb.append("SELECT '' AS 'TABLE_CAT', " + - "'' AS 'TABLE_SCHEM', " + - "tbl_name AS 'TABLE_NAME', " + - "upper(type) AS 'TABLE_TYPE', " + - "'' AS REMARKS FROM sqlite_master " + - "WHERE tbl_name like "); - if (tableNamePattern != null) { - sb.append(SQLite.Shell.sql_quote(tableNamePattern)); - } else { - sb.append("'%'"); - } - sb.append(" AND "); - if (types == null || types.length == 0) { - sb.append("(type = 'table' or type = 'view')"); - } else { - sb.append("("); - String sep = ""; - for (int i = 0; i < types.length; i++) { - sb.append(sep); - sb.append("type = "); - sb.append(SQLite.Shell.sql_quote(types[i].toLowerCase())); - sep = " or "; - } - sb.append(")"); - } - ResultSet rs = null; - try { - rs = s.executeQuery(sb.toString()); - s.close(); - } catch (SQLException e) { - throw e; - } finally { - s.close(); - } - return rs; + String tableNamePattern, String types[]) + throws SQLException { + JDBCStatement s = new JDBCStatement(conn); + StringBuffer sb = new StringBuffer(); + sb.append("SELECT '' AS 'TABLE_CAT', " + + "'' AS 'TABLE_SCHEM', " + + "tbl_name AS 'TABLE_NAME', " + + "upper(type) AS 'TABLE_TYPE', " + + "'' AS REMARKS FROM sqlite_master " + + "WHERE tbl_name like "); + if (tableNamePattern != null) { + sb.append(SQLite.Shell.sql_quote(tableNamePattern)); + } else { + sb.append("'%'"); + } + sb.append(" AND "); + if (types == null || types.length == 0) { + sb.append("(type = 'table' or type = 'view')"); + } else { + sb.append("("); + String sep = ""; + for (int i = 0; i < types.length; i++) { + sb.append(sep); + sb.append("type = "); + sb.append(SQLite.Shell.sql_quote(types[i].toLowerCase())); + sep = " or "; + } + sb.append(")"); + } + ResultSet rs = null; + try { + rs = s.executeQuery(sb.toString()); + s.close(); + } catch (SQLException e) { + throw e; + } finally { + s.close(); + } + return rs; } public ResultSet getSchemas() throws SQLException { - String cols[] = { "TABLE_SCHEM" }; - SQLite.TableResult tr = new SQLite.TableResult(); - tr.columns(cols); - String row[] = { "" }; - tr.newrow(row); - JDBCResultSet rs = new JDBCResultSet(tr, null); - return (ResultSet) rs; + String cols[] = { "TABLE_SCHEM" }; + SQLite.TableResult tr = new SQLite.TableResult(); + tr.columns(cols); + String row[] = { "" }; + tr.newrow(row); + JDBCResultSet rs = new JDBCResultSet(tr, null); + return (ResultSet) rs; } public ResultSet getCatalogs() throws SQLException { - String cols[] = { "TABLE_CAT" }; - SQLite.TableResult tr = new SQLite.TableResult(); - tr.columns(cols); - String row[] = { "" }; - tr.newrow(row); - JDBCResultSet rs = new JDBCResultSet(tr, null); - return (ResultSet) rs; + String cols[] = { "TABLE_CAT" }; + SQLite.TableResult tr = new SQLite.TableResult(); + tr.columns(cols); + String row[] = { "" }; + tr.newrow(row); + JDBCResultSet rs = new JDBCResultSet(tr, null); + return (ResultSet) rs; } public ResultSet getTableTypes() throws SQLException { - String cols[] = { "TABLE_TYPE" }; - SQLite.TableResult tr = new SQLite.TableResult(); - tr.columns(cols); - String row[] = new String[1]; - row[0] = "TABLE"; - tr.newrow(row); - row = new String[1]; - row[0] = "VIEW"; - tr.newrow(row); - JDBCResultSet rs = new JDBCResultSet(tr, null); - return (ResultSet) rs; + String cols[] = { "TABLE_TYPE" }; + SQLite.TableResult tr = new SQLite.TableResult(); + tr.columns(cols); + String row[] = new String[1]; + row[0] = "TABLE"; + tr.newrow(row); + row = new String[1]; + row[0] = "VIEW"; + tr.newrow(row); + JDBCResultSet rs = new JDBCResultSet(tr, null); + return (ResultSet) rs; } public ResultSet getColumns(String catalog, String schemaPattern, - String tableNamePattern, - String columnNamePattern) - throws SQLException { - JDBCStatement s = new JDBCStatement(conn); - JDBCResultSet rs0 = null; - try { - rs0 = (JDBCResultSet) - (s.executeQuery("PRAGMA table_info(" + - SQLite.Shell.sql_quote(tableNamePattern) + - ")")); - s.close(); - } catch (SQLException e) { - throw e; - } finally { - s.close(); - } - String cols[] = { - "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", - "COLUMN_NAME", "DATA_TYPE", "TYPE_NAME", - "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_POINTS", - "NUM_PREC_RADIX", "NULLABLE", "REMARKS", - "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", - "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", "IS_NULLABLE" - }; - int types[] = { - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.SMALLINT, Types.VARCHAR, - Types.INTEGER, Types.INTEGER, Types.INTEGER, - Types.INTEGER, Types.INTEGER, Types.VARCHAR, - Types.VARCHAR, Types.INTEGER, Types.INTEGER, - Types.INTEGER, Types.INTEGER, Types.VARCHAR - }; - TableResultX tr = new TableResultX(); - tr.columns(cols); - tr.sql_types(types); - JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); - if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { - Hashtable<String, Integer> h = new Hashtable<String, Integer>(); - for (int i = 0; i < rs0.tr.ncolumns; i++) { - h.put(rs0.tr.column[i], new Integer(i)); - } - if (columnNamePattern != null && - columnNamePattern.charAt(0) == '%') { - columnNamePattern = null; - } - for (int i = 0; i < rs0.tr.nrows; i++) { - String r0[] = (String [])(rs0.tr.rows.elementAt(i)); - int col = ((Integer) h.get("name")).intValue(); - if (columnNamePattern != null) { - if (r0[col].compareTo(columnNamePattern) != 0) { - continue; - } - } - String row[] = new String[cols.length]; - row[0] = ""; - row[1] = ""; - row[2] = tableNamePattern; - row[3] = r0[col]; - col = ((Integer) h.get("type")).intValue(); - String typeStr = r0[col]; - int type = mapSqlType(typeStr); - row[4] = "" + type; - row[5] = mapTypeName(type); - row[6] = "" + getD(typeStr, type); - row[7] = "" + getM(typeStr, type); - row[8] = "10"; - row[9] = "0"; - row[11] = null; - col = ((Integer) h.get("dflt_value")).intValue(); - row[12] = r0[col]; - row[13] = "0"; - row[14] = "0"; - row[15] = "65536"; - col = ((Integer) h.get("cid")).intValue(); - Integer cid = new Integer(r0[col]); - row[16] = "" + (cid.intValue() + 1); - col = ((Integer) h.get("notnull")).intValue(); - row[17] = (r0[col].charAt(0) == '0') ? "YES" : "NO"; - row[10] = (r0[col].charAt(0) == '0') ? "" + columnNullable : - "" + columnNoNulls; - tr.newrow(row); - } - } - return rs; + String tableNamePattern, + String columnNamePattern) + throws SQLException { + if (conn.db == null) { + throw new SQLException("connection closed"); + } + JDBCStatement s = new JDBCStatement(conn); + JDBCResultSet rs0 = null; + try { + try { + conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null); + } catch (SQLite.Exception se) { + throw new SQLException("schema reload failed"); + } + rs0 = (JDBCResultSet) + (s.executeQuery("PRAGMA table_info(" + + SQLite.Shell.sql_quote(tableNamePattern) + + ")")); + s.close(); + } catch (SQLException e) { + throw e; + } finally { + s.close(); + } + if (rs0.tr.nrows < 1) { + throw new SQLException("no such table: " + tableNamePattern); + } + String cols[] = { + "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", + "COLUMN_NAME", "DATA_TYPE", "TYPE_NAME", + "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_DIGITS", + "NUM_PREC_RADIX", "NULLABLE", "REMARKS", + "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", + "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", "IS_NULLABLE" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.SMALLINT, Types.VARCHAR, + Types.INTEGER, Types.INTEGER, Types.INTEGER, + Types.INTEGER, Types.INTEGER, Types.VARCHAR, + Types.VARCHAR, Types.INTEGER, Types.INTEGER, + Types.INTEGER, Types.INTEGER, Types.VARCHAR + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); + if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { + Hashtable<String, Integer> h = new Hashtable<String, Integer>(); + for (int i = 0; i < rs0.tr.ncolumns; i++) { + h.put(rs0.tr.column[i], new Integer(i)); + } + if (columnNamePattern != null && + columnNamePattern.charAt(0) == '%') { + columnNamePattern = null; + } + for (int i = 0; i < rs0.tr.nrows; i++) { + String r0[] = (String [])(rs0.tr.rows.elementAt(i)); + int col = ((Integer) h.get("name")).intValue(); + if (columnNamePattern != null) { + if (r0[col].compareTo(columnNamePattern) != 0) { + continue; + } + } + String row[] = new String[cols.length]; + row[0] = ""; + row[1] = ""; + row[2] = tableNamePattern; + row[3] = r0[col]; + col = ((Integer) h.get("type")).intValue(); + String typeStr = r0[col]; + int type = mapSqlType(typeStr); + row[4] = "" + type; + row[5] = mapTypeName(type); + row[6] = "" + getD(typeStr, type); + row[7] = "" + getM(typeStr, type); + row[8] = "10"; + row[9] = "0"; + row[11] = null; + col = ((Integer) h.get("dflt_value")).intValue(); + row[12] = r0[col]; + row[13] = "0"; + row[14] = "0"; + row[15] = "65536"; + col = ((Integer) h.get("cid")).intValue(); + Integer cid = new Integer(r0[col]); + row[16] = "" + (cid.intValue() + 1); + col = ((Integer) h.get("notnull")).intValue(); + row[17] = (r0[col].charAt(0) == '0') ? "YES" : "NO"; + row[10] = (r0[col].charAt(0) == '0') ? "" + columnNullable : + "" + columnNoNulls; + tr.newrow(row); + } + } + return rs; } public ResultSet getColumnPrivileges(String catalog, String schema, - String table, - String columnNamePattern) - throws SQLException { - String cols[] = { - "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", - "COLUMN_NAME", "GRANTOR", "GRANTEE", - "PRIVILEGE", "IS_GRANTABLE" - }; - int types[] = { - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR - }; - TableResultX tr = new TableResultX(); - tr.columns(cols); - tr.sql_types(types); - JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); - return rs; + String table, + String columnNamePattern) + throws SQLException { + String cols[] = { + "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", + "COLUMN_NAME", "GRANTOR", "GRANTEE", + "PRIVILEGE", "IS_GRANTABLE" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); + return rs; } public ResultSet getTablePrivileges(String catalog, String schemaPattern, - String tableNamePattern) - throws SQLException { - String cols[] = { - "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", - "COLUMN_NAME", "GRANTOR", "GRANTEE", - "PRIVILEGE", "IS_GRANTABLE" - }; - int types[] = { - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR - }; - TableResultX tr = new TableResultX(); - tr.columns(cols); - tr.sql_types(types); - JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); - return rs; + String tableNamePattern) + throws SQLException { + String cols[] = { + "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", + "COLUMN_NAME", "GRANTOR", "GRANTEE", + "PRIVILEGE", "IS_GRANTABLE" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); + return rs; } public ResultSet getBestRowIdentifier(String catalog, String schema, - String table, int scope, - boolean nullable) - throws SQLException { - JDBCStatement s0 = new JDBCStatement(conn); - JDBCResultSet rs0 = null; - JDBCStatement s1 = new JDBCStatement(conn); - JDBCResultSet rs1 = null; - try { - rs0 = (JDBCResultSet) - (s0.executeQuery("PRAGMA index_list(" + - SQLite.Shell.sql_quote(table) + ")")); - rs1 = (JDBCResultSet) - (s1.executeQuery("PRAGMA table_info(" + - SQLite.Shell.sql_quote(table) + ")")); - } catch (SQLException e) { - throw e; - } finally { - s0.close(); - s1.close(); - } - String cols[] = { - "SCOPE", "COLUMN_NAME", "DATA_TYPE", - "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", - "DECIMAL_DIGITS", "PSEUDO_COLUMN" - }; - int types[] = { - Types.SMALLINT, Types.VARCHAR, Types.SMALLINT, - Types.VARCHAR, Types.INTEGER, Types.INTEGER, - Types.SMALLINT, Types.SMALLINT - }; - TableResultX tr = new TableResultX(); - tr.columns(cols); - tr.sql_types(types); - JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); - if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0 && - rs1 != null && rs1.tr != null && rs1.tr.nrows > 0) { - Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); - for (int i = 0; i < rs0.tr.ncolumns; i++) { - h0.put(rs0.tr.column[i], new Integer(i)); - } - Hashtable<String, Integer> h1 = new Hashtable<String, Integer>(); - for (int i = 0; i < rs1.tr.ncolumns; i++) { - h1.put(rs1.tr.column[i], new Integer(i)); - } - for (int i = 0; i < rs0.tr.nrows; i++) { - String r0[] = (String [])(rs0.tr.rows.elementAt(i)); - int col = ((Integer) h0.get("unique")).intValue(); - String uniq = r0[col]; - col = ((Integer) h0.get("name")).intValue(); - String iname = r0[col]; - if (uniq.charAt(0) == '0') { - continue; - } - JDBCStatement s2 = new JDBCStatement(conn); - JDBCResultSet rs2 = null; - try { - rs2 = (JDBCResultSet) - (s2.executeQuery("PRAGMA index_info(" + - SQLite.Shell.sql_quote(iname) + ")")); - } catch (SQLException e) { - } finally { - s2.close(); - } - if (rs2 == null || rs2.tr == null || rs2.tr.nrows <= 0) { - continue; - } - Hashtable<String, Integer> h2 = - new Hashtable<String, Integer>(); - for (int k = 0; k < rs2.tr.ncolumns; k++) { - h2.put(rs2.tr.column[k], new Integer(k)); - } - for (int k = 0; k < rs2.tr.nrows; k++) { - String r2[] = (String [])(rs2.tr.rows.elementAt(k)); - col = ((Integer) h2.get("name")).intValue(); - String cname = r2[col]; - for (int m = 0; m < rs1.tr.nrows; m++) { - String r1[] = (String [])(rs1.tr.rows.elementAt(m)); - col = ((Integer) h1.get("name")).intValue(); - if (cname.compareTo(r1[col]) == 0) { - String row[] = new String[cols.length]; - row[0] = "" + scope; - row[1] = cname; - row[2] = "" + Types.VARCHAR; - row[3] = "VARCHAR"; - row[4] = "65536"; - row[5] = "0"; - row[6] = "0"; - row[7] = "" + bestRowNotPseudo; - tr.newrow(row); - } - } - } - } - } - if (tr.nrows <= 0) { - String row[] = new String[cols.length]; - row[0] = "" + scope; - row[1] = "_ROWID_"; - row[2] = "" + Types.INTEGER; - row[3] = "INTEGER"; - row[4] = "10"; - row[5] = "0"; - row[6] = "0"; - row[7] = "" + bestRowPseudo; - tr.newrow(row); - } - return rs; + String table, int scope, + boolean nullable) + throws SQLException { + JDBCStatement s0 = new JDBCStatement(conn); + JDBCResultSet rs0 = null; + JDBCStatement s1 = new JDBCStatement(conn); + JDBCResultSet rs1 = null; + try { + try { + conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null); + } catch (SQLite.Exception se) { + throw new SQLException("schema reload failed"); + } + rs0 = (JDBCResultSet) + (s0.executeQuery("PRAGMA index_list(" + + SQLite.Shell.sql_quote(table) + ")")); + rs1 = (JDBCResultSet) + (s1.executeQuery("PRAGMA table_info(" + + SQLite.Shell.sql_quote(table) + ")")); + } catch (SQLException e) { + throw e; + } finally { + s0.close(); + s1.close(); + } + String cols[] = { + "SCOPE", "COLUMN_NAME", "DATA_TYPE", + "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", + "DECIMAL_DIGITS", "PSEUDO_COLUMN" + }; + int types[] = { + Types.SMALLINT, Types.VARCHAR, Types.SMALLINT, + Types.VARCHAR, Types.INTEGER, Types.INTEGER, + Types.SMALLINT, Types.SMALLINT + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); + if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0 && + rs1 != null && rs1.tr != null && rs1.tr.nrows > 0) { + Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); + for (int i = 0; i < rs0.tr.ncolumns; i++) { + h0.put(rs0.tr.column[i], new Integer(i)); + } + Hashtable<String, Integer> h1 = new Hashtable<String, Integer>(); + for (int i = 0; i < rs1.tr.ncolumns; i++) { + h1.put(rs1.tr.column[i], new Integer(i)); + } + for (int i = 0; i < rs0.tr.nrows; i++) { + String r0[] = (String [])(rs0.tr.rows.elementAt(i)); + int col = ((Integer) h0.get("unique")).intValue(); + String uniq = r0[col]; + col = ((Integer) h0.get("name")).intValue(); + String iname = r0[col]; + if (uniq.charAt(0) == '0') { + continue; + } + JDBCStatement s2 = new JDBCStatement(conn); + JDBCResultSet rs2 = null; + try { + rs2 = (JDBCResultSet) + (s2.executeQuery("PRAGMA index_info(" + + SQLite.Shell.sql_quote(iname) + ")")); + } catch (SQLException e) { + } finally { + s2.close(); + } + if (rs2 == null || rs2.tr == null || rs2.tr.nrows <= 0) { + continue; + } + Hashtable<String, Integer> h2 = + new Hashtable<String, Integer>(); + for (int k = 0; k < rs2.tr.ncolumns; k++) { + h2.put(rs2.tr.column[k], new Integer(k)); + } + for (int k = 0; k < rs2.tr.nrows; k++) { + String r2[] = (String [])(rs2.tr.rows.elementAt(k)); + col = ((Integer) h2.get("name")).intValue(); + String cname = r2[col]; + for (int m = 0; m < rs1.tr.nrows; m++) { + String r1[] = (String [])(rs1.tr.rows.elementAt(m)); + col = ((Integer) h1.get("name")).intValue(); + if (cname.compareTo(r1[col]) == 0) { + String row[] = new String[cols.length]; + row[0] = "" + scope; + row[1] = cname; + row[2] = "" + Types.VARCHAR; + row[3] = "VARCHAR"; + row[4] = "65536"; + row[5] = "0"; + row[6] = "0"; + row[7] = "" + bestRowNotPseudo; + tr.newrow(row); + } + } + } + } + } + if (tr.nrows <= 0) { + String row[] = new String[cols.length]; + row[0] = "" + scope; + row[1] = "_ROWID_"; + row[2] = "" + Types.INTEGER; + row[3] = "INTEGER"; + row[4] = "10"; + row[5] = "0"; + row[6] = "0"; + row[7] = "" + bestRowPseudo; + tr.newrow(row); + } + return rs; } public ResultSet getVersionColumns(String catalog, String schema, - String table) throws SQLException { - String cols[] = { - "SCOPE", "COLUMN_NAME", "DATA_TYPE", - "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", - "DECIMAL_DIGITS", "PSEUDO_COLUMN" - }; - int types[] = { - Types.SMALLINT, Types.VARCHAR, Types.SMALLINT, - Types.VARCHAR, Types.INTEGER, Types.INTEGER, - Types.SMALLINT, Types.SMALLINT - }; - TableResultX tr = new TableResultX(); - tr.columns(cols); - tr.sql_types(types); - JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); - return rs; + String table) throws SQLException { + String cols[] = { + "SCOPE", "COLUMN_NAME", "DATA_TYPE", + "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", + "DECIMAL_DIGITS", "PSEUDO_COLUMN" + }; + int types[] = { + Types.SMALLINT, Types.VARCHAR, Types.SMALLINT, + Types.VARCHAR, Types.INTEGER, Types.INTEGER, + Types.SMALLINT, Types.SMALLINT + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); + return rs; } public ResultSet getPrimaryKeys(String catalog, String schema, - String table) throws SQLException { - JDBCStatement s0 = new JDBCStatement(conn); - JDBCResultSet rs0 = null; - try { - rs0 = (JDBCResultSet) - (s0.executeQuery("PRAGMA index_list(" + - SQLite.Shell.sql_quote(table) + ")")); - } catch (SQLException e) { - throw e; - } finally { - s0.close(); - } - String cols[] = { - "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", - "COLUMN_NAME", "KEY_SEQ", "PK_NAME" - }; - int types[] = { - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.SMALLINT, Types.VARCHAR - }; - TableResultX tr = new TableResultX(); - tr.columns(cols); - tr.sql_types(types); - JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); - if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { - Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); - for (int i = 0; i < rs0.tr.ncolumns; i++) { - h0.put(rs0.tr.column[i], new Integer(i)); - } - for (int i = 0; i < rs0.tr.nrows; i++) { - String r0[] = (String [])(rs0.tr.rows.elementAt(i)); - int col = ((Integer) h0.get("unique")).intValue(); - String uniq = r0[col]; - col = ((Integer) h0.get("name")).intValue(); - String iname = r0[col]; - if (uniq.charAt(0) == '0') { - continue; - } - JDBCStatement s1 = new JDBCStatement(conn); - JDBCResultSet rs1 = null; - try { - rs1 = (JDBCResultSet) - (s1.executeQuery("PRAGMA index_info(" + - SQLite.Shell.sql_quote(iname) + ")")); - } catch (SQLException e) { - } finally { - s1.close(); - } - if (rs1 == null || rs1.tr == null || rs1.tr.nrows <= 0) { - continue; - } - Hashtable<String, Integer> h1 = - new Hashtable<String, Integer>(); - for (int k = 0; k < rs1.tr.ncolumns; k++) { - h1.put(rs1.tr.column[k], new Integer(k)); - } - for (int k = 0; k < rs1.tr.nrows; k++) { - String r1[] = (String [])(rs1.tr.rows.elementAt(k)); - String row[] = new String[cols.length]; - row[0] = ""; - row[1] = ""; - row[2] = table; - col = ((Integer) h1.get("name")).intValue(); - row[3] = r1[col]; - col = ((Integer) h1.get("seqno")).intValue(); -// BEGIN android-changed - row[4] = "" + (Integer.parseInt(r1[col]) + 1); -// END android-changed - row[5] = iname; - tr.newrow(row); - } - } - } - JDBCStatement s1 = new JDBCStatement(conn); - try { - rs0 = (JDBCResultSet) - (s1.executeQuery("PRAGMA table_info(" + - SQLite.Shell.sql_quote(table) + ")")); - } catch (SQLException e) { - throw e; - } finally { - s1.close(); - } - if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { - Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); - for (int i = 0; i < rs0.tr.ncolumns; i++) { - h0.put(rs0.tr.column[i], new Integer(i)); - } - for (int i = 0; i < rs0.tr.nrows; i++) { - String r0[] = (String [])(rs0.tr.rows.elementAt(i)); - int col = ((Integer) h0.get("type")).intValue(); - String type = r0[col]; - if (!type.equalsIgnoreCase("integer")) { - continue; - } - col = ((Integer) h0.get("pk")).intValue(); - String pk = r0[col]; - if (pk.charAt(0) == '0') { - continue; - } - String row[] = new String[cols.length]; - row[0] = ""; - row[1] = ""; - row[2] = table; - col = ((Integer) h0.get("name")).intValue(); - row[3] = r0[col]; - col = ((Integer) h0.get("cid")).intValue(); -// BEGIN android-changed - row[4] = "" + (Integer.parseInt(r0[col]) + 1); -// END android-changed - row[5] = ""; - tr.newrow(row); - } - } - return rs; + String table) throws SQLException { + JDBCStatement s0 = new JDBCStatement(conn); + JDBCResultSet rs0 = null; + try { + try { + conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null); + } catch (SQLite.Exception se) { + throw new SQLException("schema reload failed"); + } + rs0 = (JDBCResultSet) + (s0.executeQuery("PRAGMA index_list(" + + SQLite.Shell.sql_quote(table) + ")")); + } catch (SQLException e) { + throw e; + } finally { + s0.close(); + } + String cols[] = { + "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", + "COLUMN_NAME", "KEY_SEQ", "PK_NAME" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.SMALLINT, Types.VARCHAR + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); + if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { + Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); + for (int i = 0; i < rs0.tr.ncolumns; i++) { + h0.put(rs0.tr.column[i], new Integer(i)); + } + for (int i = 0; i < rs0.tr.nrows; i++) { + String r0[] = (String [])(rs0.tr.rows.elementAt(i)); + int col = ((Integer) h0.get("unique")).intValue(); + String uniq = r0[col]; + col = ((Integer) h0.get("name")).intValue(); + String iname = r0[col]; + if (uniq.charAt(0) == '0') { + continue; + } + JDBCStatement s1 = new JDBCStatement(conn); + JDBCResultSet rs1 = null; + try { + rs1 = (JDBCResultSet) + (s1.executeQuery("PRAGMA index_info(" + + SQLite.Shell.sql_quote(iname) + ")")); + } catch (SQLException e) { + } finally { + s1.close(); + } + if (rs1 == null || rs1.tr == null || rs1.tr.nrows <= 0) { + continue; + } + Hashtable<String, Integer> h1 = + new Hashtable<String, Integer>(); + for (int k = 0; k < rs1.tr.ncolumns; k++) { + h1.put(rs1.tr.column[k], new Integer(k)); + } + for (int k = 0; k < rs1.tr.nrows; k++) { + String r1[] = (String [])(rs1.tr.rows.elementAt(k)); + String row[] = new String[cols.length]; + row[0] = ""; + row[1] = ""; + row[2] = table; + col = ((Integer) h1.get("name")).intValue(); + row[3] = r1[col]; + col = ((Integer) h1.get("seqno")).intValue(); + row[4] = "" + (Integer.valueOf(r1[col]).intValue() + 1); + row[5] = iname; + tr.newrow(row); + } + } + } + if (tr.nrows > 0) { + return rs; + } + JDBCStatement s1 = new JDBCStatement(conn); + try { + rs0 = (JDBCResultSet) + (s1.executeQuery("PRAGMA table_info(" + + SQLite.Shell.sql_quote(table) + ")")); + } catch (SQLException e) { + throw e; + } finally { + s1.close(); + } + if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { + Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); + for (int i = 0; i < rs0.tr.ncolumns; i++) { + h0.put(rs0.tr.column[i], new Integer(i)); + } + for (int i = 0; i < rs0.tr.nrows; i++) { + String r0[] = (String [])(rs0.tr.rows.elementAt(i)); + int col = ((Integer) h0.get("type")).intValue(); + String type = r0[col]; + if (!type.equalsIgnoreCase("integer")) { + continue; + } + col = ((Integer) h0.get("pk")).intValue(); + String pk = r0[col]; + if (pk.charAt(0) == '0') { + continue; + } + String row[] = new String[cols.length]; + row[0] = ""; + row[1] = ""; + row[2] = table; + col = ((Integer) h0.get("name")).intValue(); + row[3] = r0[col]; + col = ((Integer) h0.get("cid")).intValue(); + row[4] = "" + (Integer.valueOf(r0[col]).intValue() + 1); + row[5] = ""; + tr.newrow(row); + } + } + return rs; } private void internalImportedKeys(String table, String pktable, - JDBCResultSet in, TableResultX out) { - Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); - for (int i = 0; i < in.tr.ncolumns; i++) { - h0.put(in.tr.column[i], new Integer(i)); - } - for (int i = 0; i < in.tr.nrows; i++) { - String r0[] = (String [])(in.tr.rows.elementAt(i)); - int col = ((Integer) h0.get("table")).intValue(); - String pktab = r0[col]; - if (pktable != null && !pktable.equalsIgnoreCase(pktab)) { - continue; - } - col = ((Integer) h0.get("from")).intValue(); - String pkcol = r0[col]; - col = ((Integer) h0.get("to")).intValue(); - String fkcol = r0[col]; - col = ((Integer) h0.get("seq")).intValue(); - String seq = r0[col]; - String row[] = new String[out.ncolumns]; - row[0] = ""; - row[1] = ""; - row[2] = pktab; - row[3] = pkcol; - row[4] = ""; - row[5] = ""; - row[6] = table; - row[7] = fkcol == null ? pkcol : fkcol; -// BEGIN android-changed - row[8] = "" + ((Integer.parseInt(seq)) + 1); -// END android-changed - row[9] = - "" + java.sql.DatabaseMetaData.importedKeyNoAction; - row[10] = - "" + java.sql.DatabaseMetaData.importedKeyNoAction; - row[11] = null; - row[12] = null; - row[13] = - "" + java.sql.DatabaseMetaData.importedKeyNotDeferrable; - out.newrow(row); - } + JDBCResultSet in, TableResultX out) { + Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); + for (int i = 0; i < in.tr.ncolumns; i++) { + h0.put(in.tr.column[i], new Integer(i)); + } + for (int i = 0; i < in.tr.nrows; i++) { + String r0[] = (String [])(in.tr.rows.elementAt(i)); + int col = ((Integer) h0.get("table")).intValue(); + String pktab = r0[col]; + if (pktable != null && !pktable.equalsIgnoreCase(pktab)) { + continue; + } + col = ((Integer) h0.get("from")).intValue(); + String fkcol = r0[col]; + col = ((Integer) h0.get("to")).intValue(); + String pkcol = r0[col]; + col = ((Integer) h0.get("seq")).intValue(); + String seq = r0[col]; + String row[] = new String[out.ncolumns]; + row[0] = ""; + row[1] = ""; + row[2] = pktab; + row[3] = pkcol; + row[4] = ""; + row[5] = ""; + row[6] = table; + row[7] = fkcol == null ? pkcol : fkcol; + row[8] = "" + ((Integer.valueOf(seq)).intValue() + 1); + row[9] = + "" + java.sql.DatabaseMetaData.importedKeyNoAction; + row[10] = + "" + java.sql.DatabaseMetaData.importedKeyNoAction; + row[11] = null; + row[12] = null; + row[13] = + "" + java.sql.DatabaseMetaData.importedKeyNotDeferrable; + out.newrow(row); + } } public ResultSet getImportedKeys(String catalog, String schema, - String table) throws SQLException { - JDBCStatement s0 = new JDBCStatement(conn); - JDBCResultSet rs0 = null; - try { - rs0 = (JDBCResultSet) - (s0.executeQuery("PRAGMA foreign_key_list(" + - SQLite.Shell.sql_quote(table) + ")")); - } catch (SQLException e) { - throw e; - } finally { - s0.close(); - } - String cols[] = { - "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", - "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM", - "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", - "UPDATE_RULE", "DELETE_RULE", "FK_NAME", - "PK_NAME", "DEFERRABILITY" - }; - int types[] = { - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, - Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, - Types.VARCHAR, Types.SMALLINT - }; - TableResultX tr = new TableResultX(); - tr.columns(cols); - tr.sql_types(types); - JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); - if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { - internalImportedKeys(table, null, rs0, tr); - } - return rs; + String table) throws SQLException { + JDBCStatement s0 = new JDBCStatement(conn); + JDBCResultSet rs0 = null; + try { + try { + conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null); + } catch (SQLite.Exception se) { + throw new SQLException("schema reload failed"); + } + rs0 = (JDBCResultSet) + (s0.executeQuery("PRAGMA foreign_key_list(" + + SQLite.Shell.sql_quote(table) + ")")); + } catch (SQLException e) { + throw e; + } finally { + s0.close(); + } + String cols[] = { + "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", + "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM", + "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", + "UPDATE_RULE", "DELETE_RULE", "FK_NAME", + "PK_NAME", "DEFERRABILITY" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, + Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, + Types.VARCHAR, Types.SMALLINT + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); + if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { + internalImportedKeys(table, null, rs0, tr); + } + return rs; } public ResultSet getExportedKeys(String catalog, String schema, - String table) throws SQLException { - String cols[] = { - "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", - "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM", - "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", - "UPDATE_RULE", "DELETE_RULE", "FK_NAME", - "PK_NAME", "DEFERRABILITY" - }; - int types[] = { - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, - Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, - Types.VARCHAR, Types.SMALLINT - }; - TableResultX tr = new TableResultX(); - tr.columns(cols); - tr.sql_types(types); - JDBCResultSet rs = new JDBCResultSet(tr, null); - return rs; + String table) throws SQLException { + String cols[] = { + "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", + "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM", + "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", + "UPDATE_RULE", "DELETE_RULE", "FK_NAME", + "PK_NAME", "DEFERRABILITY" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, + Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, + Types.VARCHAR, Types.SMALLINT + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet(tr, null); + return rs; } public ResultSet getCrossReference(String primaryCatalog, - String primarySchema, - String primaryTable, - String foreignCatalog, - String foreignSchema, - String foreignTable) - throws SQLException { - JDBCResultSet rs0 = null; - if (foreignTable != null && foreignTable.charAt(0) != '%') { - JDBCStatement s0 = new JDBCStatement(conn); - try { - rs0 = (JDBCResultSet) - (s0.executeQuery("PRAGMA foreign_key_list(" + - SQLite.Shell.sql_quote(foreignTable) + ")")); - } catch (SQLException e) { - throw e; - } finally { - s0.close(); - } - } - String cols[] = { - "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", - "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM", - "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", - "UPDATE_RULE", "DELETE_RULE", "FK_NAME", - "PK_NAME", "DEFERRABILITY" - }; - int types[] = { - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, - Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, - Types.VARCHAR, Types.SMALLINT - }; - TableResultX tr = new TableResultX(); - tr.columns(cols); - tr.sql_types(types); - JDBCResultSet rs = new JDBCResultSet(tr, null); - if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { - String pktable = null; - if (primaryTable != null && primaryTable.charAt(0) != '%') { - pktable = primaryTable; - } - internalImportedKeys(foreignTable, pktable, rs0, tr); - } - return rs; + String primarySchema, + String primaryTable, + String foreignCatalog, + String foreignSchema, + String foreignTable) + throws SQLException { + JDBCResultSet rs0 = null; + if (foreignTable != null && foreignTable.charAt(0) != '%') { + JDBCStatement s0 = new JDBCStatement(conn); + try { + try { + conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null); + } catch (SQLite.Exception se) { + throw new SQLException("schema reload failed"); + } + rs0 = (JDBCResultSet) + (s0.executeQuery("PRAGMA foreign_key_list(" + + SQLite.Shell.sql_quote(foreignTable) + ")")); + } catch (SQLException e) { + throw e; + } finally { + s0.close(); + } + } + String cols[] = { + "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", + "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM", + "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", + "UPDATE_RULE", "DELETE_RULE", "FK_NAME", + "PK_NAME", "DEFERRABILITY" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, + Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, + Types.VARCHAR, Types.SMALLINT + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet(tr, null); + if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { + String pktable = null; + if (primaryTable != null && primaryTable.charAt(0) != '%') { + pktable = primaryTable; + } + internalImportedKeys(foreignTable, pktable, rs0, tr); + } + return rs; } public ResultSet getTypeInfo() throws SQLException { - String cols[] = { - "TYPE_NAME", "DATA_TYPE", "PRECISION", - "LITERAL_PREFIX", "LITERAL_SUFFIX", "CREATE_PARAMS", - "NULLABLE", "CASE_SENSITIVE", "SEARCHABLE", - "UNSIGNED_ATTRIBUTE", "FIXED_PREC_SCALE", "AUTO_INCREMENT", - "LOCAL_TYPE_NAME", "MINIMUM_SCALE", "MAXIMUM_SCALE", - "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "NUM_PREC_RADIX" - }; - int types[] = { - Types.VARCHAR, Types.SMALLINT, Types.INTEGER, - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.SMALLINT, Types.BIT, Types.SMALLINT, - Types.BIT, Types.BIT, Types.BIT, - Types.VARCHAR, Types.SMALLINT, Types.SMALLINT, - Types.INTEGER, Types.INTEGER, Types.INTEGER - }; - TableResultX tr = new TableResultX(); - tr.columns(cols); - tr.sql_types(types); - JDBCResultSet rs = new JDBCResultSet(tr, null); - String row1[] = { - "VARCHAR", "" + Types.VARCHAR, "65536", - "'", "'", null, - "" + typeNullable, "1", "" + typeSearchable, - "0", "0", "0", - null, "0", "0", - "0", "0", "0" - }; - tr.newrow(row1); - String row2[] = { - "INTEGER", "" + Types.INTEGER, "32", - null, null, null, - "" + typeNullable, "0", "" + typeSearchable, - "0", "0", "1", - null, "0", "0", - "0", "0", "2" - }; - tr.newrow(row2); - String row3[] = { - "DOUBLE", "" + Types.DOUBLE, "16", - null, null, null, - "" + typeNullable, "0", "" + typeSearchable, - "0", "0", "1", - null, "0", "0", - "0", "0", "10" - }; - tr.newrow(row3); - String row4[] = { - "FLOAT", "" + Types.FLOAT, "7", - null, null, null, - "" + typeNullable, "0", "" + typeSearchable, - "0", "0", "1", - null, "0", "0", - "0", "0", "10" - }; - tr.newrow(row4); - String row5[] = { - "SMALLINT", "" + Types.SMALLINT, "16", - null, null, null, - "" + typeNullable, "0", "" + typeSearchable, - "0", "0", "1", - null, "0", "0", - "0", "0", "2" - }; - tr.newrow(row5); - String row6[] = { - "BIT", "" + Types.BIT, "1", - null, null, null, - "" + typeNullable, "0", "" + typeSearchable, - "0", "0", "1", - null, "0", "0", - "0", "0", "2" - }; - tr.newrow(row6); - String row7[] = { - "TIMESTAMP", "" + Types.TIMESTAMP, "30", - null, null, null, - "" + typeNullable, "0", "" + typeSearchable, - "0", "0", "1", - null, "0", "0", - "0", "0", "0" - }; - tr.newrow(row7); - String row8[] = { - "DATE", "" + Types.DATE, "10", - null, null, null, - "" + typeNullable, "0", "" + typeSearchable, - "0", "0", "1", - null, "0", "0", - "0", "0", "0" - }; - tr.newrow(row8); - String row9[] = { - "TIME", "" + Types.TIME, "8", - null, null, null, - "" + typeNullable, "0", "" + typeSearchable, - "0", "0", "1", - null, "0", "0", - "0", "0", "0" - }; - tr.newrow(row9); - String row10[] = { - "BINARY", "" + Types.BINARY, "65536", - null, null, null, - "" + typeNullable, "0", "" + typeSearchable, - "0", "0", "1", - null, "0", "0", - "0", "0", "0" - }; - tr.newrow(row10); - String row11[] = { - "VARBINARY", "" + Types.VARBINARY, "65536", - null, null, null, - "" + typeNullable, "0", "" + typeSearchable, - "0", "0", "1", - null, "0", "0", - "0", "0", "0" - }; - tr.newrow(row11); - return rs; + String cols[] = { + "TYPE_NAME", "DATA_TYPE", "PRECISION", + "LITERAL_PREFIX", "LITERAL_SUFFIX", "CREATE_PARAMS", + "NULLABLE", "CASE_SENSITIVE", "SEARCHABLE", + "UNSIGNED_ATTRIBUTE", "FIXED_PREC_SCALE", "AUTO_INCREMENT", + "LOCAL_TYPE_NAME", "MINIMUM_SCALE", "MAXIMUM_SCALE", + "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "NUM_PREC_RADIX" + }; + int types[] = { + Types.VARCHAR, Types.SMALLINT, Types.INTEGER, + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.SMALLINT, Types.BIT, Types.SMALLINT, + Types.BIT, Types.BIT, Types.BIT, + Types.VARCHAR, Types.SMALLINT, Types.SMALLINT, + Types.INTEGER, Types.INTEGER, Types.INTEGER + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet(tr, null); + String row1[] = { + "VARCHAR", "" + Types.VARCHAR, "65536", + "'", "'", null, + "" + typeNullable, "1", "" + typeSearchable, + "0", "0", "0", + null, "0", "0", + "0", "0", "0" + }; + tr.newrow(row1); + String row2[] = { + "INTEGER", "" + Types.INTEGER, "32", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "2" + }; + tr.newrow(row2); + String row3[] = { + "DOUBLE", "" + Types.DOUBLE, "16", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "10" + }; + tr.newrow(row3); + String row4[] = { + "FLOAT", "" + Types.FLOAT, "7", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "10" + }; + tr.newrow(row4); + String row5[] = { + "SMALLINT", "" + Types.SMALLINT, "16", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "2" + }; + tr.newrow(row5); + String row6[] = { + "BIT", "" + Types.BIT, "1", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "2" + }; + tr.newrow(row6); + String row7[] = { + "TIMESTAMP", "" + Types.TIMESTAMP, "30", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "0" + }; + tr.newrow(row7); + String row8[] = { + "DATE", "" + Types.DATE, "10", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "0" + }; + tr.newrow(row8); + String row9[] = { + "TIME", "" + Types.TIME, "8", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "0" + }; + tr.newrow(row9); + String row10[] = { + "BINARY", "" + Types.BINARY, "65536", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "0" + }; + tr.newrow(row10); + String row11[] = { + "VARBINARY", "" + Types.VARBINARY, "65536", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "0" + }; + tr.newrow(row11); + String row12[] = { + "REAL", "" + Types.REAL, "16", + null, null, null, + "" + typeNullable, "0", "" + typeSearchable, + "0", "0", "1", + null, "0", "0", + "0", "0", "10" + }; + tr.newrow(row12); + return rs; } public ResultSet getIndexInfo(String catalog, String schema, String table, - boolean unique, boolean approximate) - throws SQLException { - JDBCStatement s0 = new JDBCStatement(conn); - JDBCResultSet rs0 = null; - try { - rs0 = (JDBCResultSet) - (s0.executeQuery("PRAGMA index_list(" + - SQLite.Shell.sql_quote(table) + ")")); - } catch (SQLException e) { - throw e; - } finally { - s0.close(); - } - String cols[] = { - "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", - "NON_UNIQUE", "INDEX_QUALIFIER", "INDEX_NAME", - "TYPE", "ORDINAL_POSITION", "COLUMN_NAME", - "ASC_OR_DESC", "CARDINALITY", "PAGES", - "FILTER_CONDITION" - }; - int types[] = { - Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, - Types.BIT, Types.VARCHAR, Types.VARCHAR, - Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, - Types.VARCHAR, Types.INTEGER, Types.INTEGER, - Types.VARCHAR - }; - TableResultX tr = new TableResultX(); - tr.columns(cols); - tr.sql_types(types); - JDBCResultSet rs = new JDBCResultSet(tr, null); - if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { - Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); - for (int i = 0; i < rs0.tr.ncolumns; i++) { - h0.put(rs0.tr.column[i], new Integer(i)); - } - for (int i = 0; i < rs0.tr.nrows; i++) { - String r0[] = (String [])(rs0.tr.rows.elementAt(i)); - int col = ((Integer) h0.get("unique")).intValue(); - String uniq = r0[col]; - col = ((Integer) h0.get("name")).intValue(); - String iname = r0[col]; - if (unique && uniq.charAt(0) == '0') { - continue; - } - JDBCStatement s1 = new JDBCStatement(conn); - JDBCResultSet rs1 = null; - try { - rs1 = (JDBCResultSet) - (s1.executeQuery("PRAGMA index_info(" + - SQLite.Shell.sql_quote(iname) + ")")); - } catch (SQLException e) { - } finally { - s1.close(); - } - if (rs1 == null || rs1.tr == null || rs1.tr.nrows <= 0) { - continue; - } - Hashtable<String, Integer> h1 = - new Hashtable<String, Integer>(); - for (int k = 0; k < rs1.tr.ncolumns; k++) { - h1.put(rs1.tr.column[k], new Integer(k)); - } - for (int k = 0; k < rs1.tr.nrows; k++) { - String r1[] = (String [])(rs1.tr.rows.elementAt(k)); - String row[] = new String[cols.length]; - row[0] = ""; - row[1] = ""; - row[2] = table; - row[3] = (uniq.charAt(0) != '0' || - (iname.charAt(0) == '(' && - iname.indexOf(" autoindex ") > 0)) ? "0" : "1"; - row[4] = ""; - row[5] = iname; - row[6] = "" + tableIndexOther; - col = ((Integer) h1.get("seqno")).intValue(); -// BEGIN android-changed - row[7] = "" + (Integer.parseInt(r1[col]) + 1); -// END android-changed - col = ((Integer) h1.get("name")).intValue(); - row[8] = r1[col]; - row[9] = "A"; - row[10] = "0"; - row[11] = "0"; - row[12] = null; - tr.newrow(row); - } - } - } - return rs; + boolean unique, boolean approximate) + throws SQLException { + JDBCStatement s0 = new JDBCStatement(conn); + JDBCResultSet rs0 = null; + try { + try { + conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null); + } catch (SQLite.Exception se) { + throw new SQLException("schema reload failed"); + } + rs0 = (JDBCResultSet) + (s0.executeQuery("PRAGMA index_list(" + + SQLite.Shell.sql_quote(table) + ")")); + } catch (SQLException e) { + throw e; + } finally { + s0.close(); + } + String cols[] = { + "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", + "NON_UNIQUE", "INDEX_QUALIFIER", "INDEX_NAME", + "TYPE", "ORDINAL_POSITION", "COLUMN_NAME", + "ASC_OR_DESC", "CARDINALITY", "PAGES", + "FILTER_CONDITION" + }; + int types[] = { + Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, + Types.BIT, Types.VARCHAR, Types.VARCHAR, + Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, + Types.VARCHAR, Types.INTEGER, Types.INTEGER, + Types.VARCHAR + }; + TableResultX tr = new TableResultX(); + tr.columns(cols); + tr.sql_types(types); + JDBCResultSet rs = new JDBCResultSet(tr, null); + if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { + Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); + for (int i = 0; i < rs0.tr.ncolumns; i++) { + h0.put(rs0.tr.column[i], new Integer(i)); + } + for (int i = 0; i < rs0.tr.nrows; i++) { + String r0[] = (String [])(rs0.tr.rows.elementAt(i)); + int col = ((Integer) h0.get("unique")).intValue(); + String uniq = r0[col]; + col = ((Integer) h0.get("name")).intValue(); + String iname = r0[col]; + if (unique && uniq.charAt(0) == '0') { + continue; + } + JDBCStatement s1 = new JDBCStatement(conn); + JDBCResultSet rs1 = null; + try { + rs1 = (JDBCResultSet) + (s1.executeQuery("PRAGMA index_info(" + + SQLite.Shell.sql_quote(iname) + ")")); + } catch (SQLException e) { + } finally { + s1.close(); + } + if (rs1 == null || rs1.tr == null || rs1.tr.nrows <= 0) { + continue; + } + Hashtable<String, Integer> h1 = + new Hashtable<String, Integer>(); + for (int k = 0; k < rs1.tr.ncolumns; k++) { + h1.put(rs1.tr.column[k], new Integer(k)); + } + for (int k = 0; k < rs1.tr.nrows; k++) { + String r1[] = (String [])(rs1.tr.rows.elementAt(k)); + String row[] = new String[cols.length]; + row[0] = ""; + row[1] = ""; + row[2] = table; + row[3] = (uniq.charAt(0) != '0' || + (iname.charAt(0) == '(' && + iname.indexOf(" autoindex ") > 0)) ? "0" : "1"; + row[4] = ""; + row[5] = iname; + row[6] = "" + tableIndexOther; + col = ((Integer) h1.get("seqno")).intValue(); + row[7] = "" + (Integer.valueOf(r1[col]).intValue() + 1); + col = ((Integer) h1.get("name")).intValue(); + row[8] = r1[col]; + row[9] = "A"; + row[10] = "0"; + row[11] = "0"; + row[12] = null; + tr.newrow(row); + } + } + } + return rs; } public boolean supportsResultSetType(int type) throws SQLException { - return type == ResultSet.CONCUR_READ_ONLY; + return type == ResultSet.TYPE_FORWARD_ONLY || + type == ResultSet.TYPE_SCROLL_INSENSITIVE || + type == ResultSet.TYPE_SCROLL_SENSITIVE; } public boolean supportsResultSetConcurrency(int type, int concurrency) - throws SQLException { - return false; + throws SQLException { + if (type == ResultSet.TYPE_FORWARD_ONLY || + type == ResultSet.TYPE_SCROLL_INSENSITIVE || + type == ResultSet.TYPE_SCROLL_SENSITIVE) { + return concurrency == ResultSet.CONCUR_READ_ONLY || + concurrency == ResultSet.CONCUR_UPDATABLE; + } + return false; } public boolean ownUpdatesAreVisible(int type) throws SQLException { - return false; + if (type == ResultSet.TYPE_FORWARD_ONLY || + type == ResultSet.TYPE_SCROLL_INSENSITIVE || + type == ResultSet.TYPE_SCROLL_SENSITIVE) { + return true; + } + return false; } public boolean ownDeletesAreVisible(int type) throws SQLException { - return false; + if (type == ResultSet.TYPE_FORWARD_ONLY || + type == ResultSet.TYPE_SCROLL_INSENSITIVE || + type == ResultSet.TYPE_SCROLL_SENSITIVE) { + return true; + } + return false; } public boolean ownInsertsAreVisible(int type) throws SQLException { - return false; + if (type == ResultSet.TYPE_FORWARD_ONLY || + type == ResultSet.TYPE_SCROLL_INSENSITIVE || + type == ResultSet.TYPE_SCROLL_SENSITIVE) { + return true; + } + return false; } public boolean othersUpdatesAreVisible(int type) throws SQLException { - return false; + return false; } public boolean othersDeletesAreVisible(int type) throws SQLException { - return false; + return false; } public boolean othersInsertsAreVisible(int type) throws SQLException { - return false; + return false; } public boolean updatesAreDetected(int type) throws SQLException { - return false; + return false; } public boolean deletesAreDetected(int type) throws SQLException { - return false; + return false; } public boolean insertsAreDetected(int type) throws SQLException { - return false; + return false; } public boolean supportsBatchUpdates() throws SQLException { - return false; + return true; } public ResultSet getUDTs(String catalog, String schemaPattern, - String typeNamePattern, int[] types) - throws SQLException { - return null; + String typeNamePattern, int[] types) + throws SQLException { + return null; } public Connection getConnection() throws SQLException { - return conn; + return conn; } static String mapTypeName(int type) { - switch (type) { - case Types.INTEGER: return "integer"; - case Types.SMALLINT: return "smallint"; - case Types.FLOAT: return "float"; - case Types.DOUBLE: return "double"; - case Types.TIMESTAMP: return "timestamp"; - case Types.DATE: return "date"; - case Types.TIME: return "time"; - case Types.BINARY: return "binary"; - case Types.VARBINARY: return "varbinary"; - } - return "varchar"; + switch (type) { + case Types.INTEGER: return "integer"; + case Types.SMALLINT: return "smallint"; + case Types.FLOAT: return "float"; + case Types.DOUBLE: return "double"; + case Types.TIMESTAMP: return "timestamp"; + case Types.DATE: return "date"; + case Types.TIME: return "time"; + case Types.BINARY: return "binary"; + case Types.VARBINARY: return "varbinary"; + case Types.REAL: return "real"; + } + return "varchar"; } static int mapSqlType(String type) { - if (type == null) { - return Types.VARCHAR; - } - type = type.toLowerCase(); - if (type.startsWith("inter")) { - return Types.VARCHAR; - } - if (type.startsWith("numeric") || - type.startsWith("int")) { - return Types.INTEGER; - } - if (type.startsWith("tinyint") || - type.startsWith("smallint")) { - return Types.SMALLINT; - } - if (type.startsWith("float")) { - return Types.FLOAT; - } - if (type.startsWith("double")) { - return Types.DOUBLE; - } - if (type.startsWith("datetime") || - type.startsWith("timestamp")) { - return Types.TIMESTAMP; - } - if (type.startsWith("date")) { - return Types.DATE; - } - if (type.startsWith("time")) { - return Types.TIME; - } - if (type.startsWith("blob")) { - return Types.BINARY; - } - if (type.startsWith("binary")) { - return Types.BINARY; - } - if (type.startsWith("varbinary")) { - return Types.VARBINARY; - } - return Types.VARCHAR; + if (type == null) { + return Types.VARCHAR; + } + type = type.toLowerCase(); + if (type.startsWith("inter")) { + return Types.VARCHAR; + } + if (type.startsWith("numeric") || + type.startsWith("int")) { + return Types.INTEGER; + } + if (type.startsWith("tinyint") || + type.startsWith("smallint")) { + return Types.SMALLINT; + } + if (type.startsWith("float")) { + return Types.FLOAT; + } + if (type.startsWith("double")) { + return Types.DOUBLE; + } + if (type.startsWith("datetime") || + type.startsWith("timestamp")) { + return Types.TIMESTAMP; + } + if (type.startsWith("date")) { + return Types.DATE; + } + if (type.startsWith("time")) { + return Types.TIME; + } + if (type.startsWith("blob")) { + return Types.BINARY; + } + if (type.startsWith("binary")) { + return Types.BINARY; + } + if (type.startsWith("varbinary")) { + return Types.VARBINARY; + } + if (type.startsWith("real")) { + return Types.REAL; + } + return Types.VARCHAR; } static int getM(String typeStr, int type) { - int m = 65536; - switch (type) { - case Types.INTEGER: m = 11; break; - case Types.SMALLINT: m = 6; break; - case Types.FLOAT: m = 25; break; - case Types.DOUBLE: m = 54; break; - case Types.TIMESTAMP: return 30; - case Types.DATE: return 10; - case Types.TIME: return 8; - } - typeStr = typeStr.toLowerCase(); - int i1 = typeStr.indexOf('('); - if (i1 > 0) { - ++i1; - int i2 = typeStr.indexOf(',', i1); - if (i2 < 0) { - i2 = typeStr.indexOf(')', i1); - } - if (i2 - i1 > 0) { - String num = typeStr.substring(i1, i2); - try { - m = java.lang.Integer.parseInt(num, 10); - } catch (NumberFormatException e) { - } - } - } - return m; + int m = 65536; + switch (type) { + case Types.INTEGER: m = 11; break; + case Types.SMALLINT: m = 6; break; + case Types.FLOAT: m = 25; break; + case Types.REAL: + case Types.DOUBLE: m = 54; break; + case Types.TIMESTAMP: return 30; + case Types.DATE: return 10; + case Types.TIME: return 8; + } + typeStr = typeStr.toLowerCase(); + int i1 = typeStr.indexOf('('); + if (i1 > 0) { + ++i1; + int i2 = typeStr.indexOf(',', i1); + if (i2 < 0) { + i2 = typeStr.indexOf(')', i1); + } + if (i2 - i1 > 0) { + String num = typeStr.substring(i1, i2); + try { + m = java.lang.Integer.parseInt(num, 10); + } catch (NumberFormatException e) { + } + } + } + return m; } static int getD(String typeStr, int type) { - int d = 0; - switch (type) { - case Types.INTEGER: d = 10; break; - case Types.SMALLINT: d = 5; break; - case Types.FLOAT: d = 24; break; - case Types.DOUBLE: d = 53; break; - default: return getM(typeStr, type); - } - typeStr = typeStr.toLowerCase(); - int i1 = typeStr.indexOf('('); - if (i1 > 0) { - ++i1; - int i2 = typeStr.indexOf(',', i1); - if (i2 < 0) { - return getM(typeStr, type); - } - i1 = i2; - i2 = typeStr.indexOf(')', i1); - if (i2 - i1 > 0) { - String num = typeStr.substring(i1, i2); - try { - d = java.lang.Integer.parseInt(num, 10); - } catch (NumberFormatException e) { - } - } - } - return d; + int d = 0; + switch (type) { + case Types.INTEGER: d = 10; break; + case Types.SMALLINT: d = 5; break; + case Types.FLOAT: d = 24; break; + case Types.REAL: + case Types.DOUBLE: d = 53; break; + default: return getM(typeStr, type); + } + typeStr = typeStr.toLowerCase(); + int i1 = typeStr.indexOf('('); + if (i1 > 0) { + ++i1; + int i2 = typeStr.indexOf(',', i1); + if (i2 < 0) { + return getM(typeStr, type); + } + i1 = i2; + i2 = typeStr.indexOf(')', i1); + if (i2 - i1 > 0) { + String num = typeStr.substring(i1, i2); + try { + d = java.lang.Integer.parseInt(num, 10); + } catch (NumberFormatException e) { + } + } + } + return d; } public boolean supportsSavepoints() { - return false; + return false; } public boolean supportsNamedParameters() { - return false; + return false; } public boolean supportsMultipleOpenResults() { - return false; + return false; } public boolean supportsGetGeneratedKeys() { - return false; + return false; } public boolean supportsResultSetHoldability(int x) { - return false; + return false; } public boolean supportsStatementPooling() { - return false; + return false; } public boolean locatorsUpdateCopy() throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public ResultSet getSuperTypes(String catalog, String schemaPattern, - String typeNamePattern) - throws SQLException { - throw new SQLException("not supported"); + String typeNamePattern) + throws SQLException { + throw new SQLException("not supported"); } public ResultSet getSuperTables(String catalog, String schemaPattern, - String tableNamePattern) - throws SQLException { - throw new SQLException("not supported"); + String tableNamePattern) + throws SQLException { + throw new SQLException("not supported"); } public ResultSet getAttributes(String catalog, String schemaPattern, - String typeNamePattern, - String attributeNamePattern) - throws SQLException { - throw new SQLException("not supported"); + String typeNamePattern, + String attributeNamePattern) + throws SQLException { + throw new SQLException("not supported"); } public int getResultSetHoldability() throws SQLException { - return ResultSet.HOLD_CURSORS_OVER_COMMIT; + return ResultSet.HOLD_CURSORS_OVER_COMMIT; } public int getDatabaseMajorVersion() { - return SQLite.JDBCDriver.MAJORVERSION; + return SQLite.JDBCDriver.MAJORVERSION; } public int getDatabaseMinorVersion() { - return SQLite.JDBCDriver.MINORVERSION; + return SQLite.Constants.drv_minor; } public int getJDBCMajorVersion() { - return 1; + return 1; } public int getJDBCMinorVersion() { - return 0; + return 0; } public int getSQLStateType() throws SQLException { - return sqlStateXOpen; + return sqlStateXOpen; } } diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCPreparedStatement.java b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCPreparedStatement.java index ab81867..3d5b045 100644 --- a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCPreparedStatement.java +++ b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCPreparedStatement.java @@ -9,12 +9,12 @@ class BatchArg { boolean blob; BatchArg(String arg, boolean blob) { - if (arg == null) { - this.arg = null; - } else { - this.arg = new String(arg); - } - this.blob = blob; + if (arg == null) { + this.arg = null; + } else { + this.arg = new String(arg); + } + this.blob = blob; } } @@ -26,727 +26,756 @@ public class JDBCPreparedStatement extends JDBCStatement private boolean blobs[]; private ArrayList<BatchArg> batch; private static final boolean nullrepl = - SQLite.Database.version().compareTo("2.5.0") < 0; + SQLite.Database.version().compareTo("2.5.0") < 0; public JDBCPreparedStatement(JDBCConnection conn, String sql) { - super(conn); - this.args = null; - this.blobs = null; - this.batch = null; - this.sql = fixup(sql); + super(conn); + this.args = null; + this.blobs = null; + this.batch = null; + this.sql = fixup(sql); } private String fixup(String sql) { - StringBuffer sb = new StringBuffer(); - boolean inq = false; - int nparm = 0; - for (int i = 0; i < sql.length(); i++) { - char c = sql.charAt(i); - if (c == '\'') { - if (inq) { + StringBuffer sb = new StringBuffer(); + boolean inq = false; + int nparm = 0; + for (int i = 0; i < sql.length(); i++) { + char c = sql.charAt(i); + if (c == '\'') { + if (inq) { char nextChar = 0; if(i + 1 < sql.length()) { nextChar = sql.charAt(i + 1); } - if (nextChar == '\'') { + if (nextChar == '\'') { sb.append(c); sb.append(nextChar); i++; } else { - inq = false; + inq = false; sb.append(c); } - } else { - inq = true; + } else { + inq = true; sb.append(c); - } - } else if (c == '?') { - if (inq) { - sb.append(c); - } else { - ++nparm; - sb.append(nullrepl ? "'%q'" : "%Q"); - } - } else if (c == ';') { - if (!inq) { - break; - } - sb.append(c); - } else if (c == '%') { - sb.append("%%"); - } else { - sb.append(c); - } - } - args = new String[nparm]; - blobs = new boolean[nparm]; - try { - clearParameters(); - } catch (SQLException e) { - } - return sb.toString(); + } + } else if (c == '?') { + if (inq) { + sb.append(c); + } else { + ++nparm; + sb.append(nullrepl ? "'%q'" : "%Q"); + } + } else if (c == ';') { + if (!inq) { + break; + } + sb.append(c); + } else if (c == '%') { + sb.append("%%"); + } else { + sb.append(c); + } + } + args = new String[nparm]; + blobs = new boolean[nparm]; + try { + clearParameters(); + } catch (SQLException e) { + } + return sb.toString(); } private String fixup2(String sql) { - if (!conn.db.is3()) { - return sql; - } - StringBuffer sb = new StringBuffer(); - int parm = -1; - for (int i = 0; i < sql.length(); i++) { - char c = sql.charAt(i); - if (c == '%') { - sb.append(c); - ++i; - c = sql.charAt(i); - if (c == 'Q') { - parm++; - if (blobs[parm]) { - c = 's'; - } - } - } - sb.append(c); - } - return sb.toString(); + if (!conn.db.is3()) { + return sql; + } + StringBuffer sb = new StringBuffer(); + int parm = -1; + for (int i = 0; i < sql.length(); i++) { + char c = sql.charAt(i); + if (c == '%') { + sb.append(c); + ++i; + c = sql.charAt(i); + if (c == 'Q') { + parm++; + if (blobs[parm]) { + c = 's'; + } + } + } + sb.append(c); + } + return sb.toString(); } public ResultSet executeQuery() throws SQLException { - return executeQuery(fixup2(sql), args, false); + return executeQuery(fixup2(sql), args, false); } public int executeUpdate() throws SQLException { - executeQuery(fixup2(sql), args, true); - return updcnt; + executeQuery(fixup2(sql), args, true); + return updcnt; } public void setNull(int parameterIndex, int sqlType) throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - args[parameterIndex - 1] = nullrepl ? "" : null; - blobs[parameterIndex - 1] = false; + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = nullrepl ? "" : null; + blobs[parameterIndex - 1] = false; } public void setBoolean(int parameterIndex, boolean x) - throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - args[parameterIndex - 1] = x ? "1" : "0"; - blobs[parameterIndex - 1] = false; + throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = x ? "1" : "0"; + blobs[parameterIndex - 1] = false; } public void setByte(int parameterIndex, byte x) throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - args[parameterIndex - 1] = "" + x; - blobs[parameterIndex - 1] = false; + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = "" + x; + blobs[parameterIndex - 1] = false; } public void setShort(int parameterIndex, short x) throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - args[parameterIndex - 1] = "" + x; - blobs[parameterIndex - 1] = false; + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = "" + x; + blobs[parameterIndex - 1] = false; } public void setInt(int parameterIndex, int x) throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - args[parameterIndex - 1] = "" + x; - blobs[parameterIndex - 1] = false; + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = "" + x; + blobs[parameterIndex - 1] = false; } public void setLong(int parameterIndex, long x) throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - args[parameterIndex - 1] = "" + x; - blobs[parameterIndex - 1] = false; + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = "" + x; + blobs[parameterIndex - 1] = false; } public void setFloat(int parameterIndex, float x) throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - args[parameterIndex - 1] = "" + x; - blobs[parameterIndex - 1] = false; + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = "" + x; + blobs[parameterIndex - 1] = false; } public void setDouble(int parameterIndex, double x) throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - args[parameterIndex - 1] = "" + x; - blobs[parameterIndex - 1] = false; + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + args[parameterIndex - 1] = "" + x; + blobs[parameterIndex - 1] = false; } public void setBigDecimal(int parameterIndex, BigDecimal x) - throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - if (x == null) { - args[parameterIndex - 1] = nullrepl ? "" : null; - } else { - args[parameterIndex - 1] = "" + x; - } - blobs[parameterIndex - 1] = false; + throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + args[parameterIndex - 1] = "" + x; + } + blobs[parameterIndex - 1] = false; } public void setString(int parameterIndex, String x) throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - if (x == null) { - args[parameterIndex - 1] = nullrepl ? "" : null; - } else { - args[parameterIndex - 1] = x; - } - blobs[parameterIndex - 1] = false; + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + args[parameterIndex - 1] = x; + } + blobs[parameterIndex - 1] = false; } public void setBytes(int parameterIndex, byte x[]) throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - blobs[parameterIndex - 1] = false; - if (x == null) { - args[parameterIndex - 1] = nullrepl ? "" : null; - } else { - if (conn.db.is3()) { - args[parameterIndex - 1] = SQLite.StringEncoder.encodeX(x); - blobs[parameterIndex - 1] = true; - } else { - args[parameterIndex - 1] = SQLite.StringEncoder.encode(x); - } - } + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + blobs[parameterIndex - 1] = false; + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + if (conn.db.is3()) { + args[parameterIndex - 1] = SQLite.StringEncoder.encodeX(x); + blobs[parameterIndex - 1] = true; + } else { + args[parameterIndex - 1] = SQLite.StringEncoder.encode(x); + } + } } public void setDate(int parameterIndex, java.sql.Date x) - throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - if (x == null) { - args[parameterIndex - 1] = nullrepl ? "" : null; - } else { - args[parameterIndex - 1] = x.toString(); - } - blobs[parameterIndex - 1] = false; + throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + if (conn.useJulian) { + args[parameterIndex - 1] = java.lang.Double.toString(SQLite.Database.julian_from_long(x.getTime())); + } else { + args[parameterIndex - 1] = x.toString(); + } + } + blobs[parameterIndex - 1] = false; } public void setTime(int parameterIndex, java.sql.Time x) - throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - if (x == null) { - args[parameterIndex - 1] = nullrepl ? "" : null; - } else { - args[parameterIndex - 1] = x.toString(); - } - blobs[parameterIndex - 1] = false; + throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + if (conn.useJulian) { + args[parameterIndex - 1] = java.lang.Double.toString(SQLite.Database.julian_from_long(x.getTime())); + } else { + args[parameterIndex - 1] = x.toString(); + } + } + blobs[parameterIndex - 1] = false; } public void setTimestamp(int parameterIndex, java.sql.Timestamp x) - throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - if (x == null) { - args[parameterIndex - 1] = nullrepl ? "" : null; - } else { - args[parameterIndex - 1] = x.toString(); - } - blobs[parameterIndex - 1] = false; + throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + if (conn.useJulian) { + args[parameterIndex - 1] = java.lang.Double.toString(SQLite.Database.julian_from_long(x.getTime())); + } else { + args[parameterIndex - 1] = x.toString(); + } + } + blobs[parameterIndex - 1] = false; } public void setAsciiStream(int parameterIndex, java.io.InputStream x, - int length) throws SQLException { - throw new SQLException("not supported"); + int length) throws SQLException { + throw new SQLException("not supported"); } @Deprecated public void setUnicodeStream(int parameterIndex, java.io.InputStream x, - int length) throws SQLException { - throw new SQLException("not supported"); + int length) throws SQLException { + throw new SQLException("not supported"); } public void setBinaryStream(int parameterIndex, java.io.InputStream x, - int length) throws SQLException { - throw new SQLException("not supported"); + int length) throws SQLException { + try { + byte[] data = new byte[length]; + x.read(data, 0, length); + setBytes(parameterIndex, data); + } catch (java.io.IOException e) { + throw new SQLException("I/O failed"); + } } public void clearParameters() throws SQLException { - for (int i = 0; i < args.length; i++) { - args[i] = nullrepl ? "" : null; - blobs[i] = false; - } + for (int i = 0; i < args.length; i++) { + args[i] = nullrepl ? "" : null; + blobs[i] = false; + } } public void setObject(int parameterIndex, Object x, int targetSqlType, - int scale) throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - if (x == null) { - args[parameterIndex - 1] = nullrepl ? "" : null; - } else { - if (x instanceof byte[]) { - byte[] bx = (byte[]) x; - if (conn.db.is3()) { - args[parameterIndex - 1] = - SQLite.StringEncoder.encodeX(bx); - blobs[parameterIndex - 1] = true; - return; - } - args[parameterIndex - 1] = SQLite.StringEncoder.encode(bx); - } else { - args[parameterIndex - 1] = x.toString(); - } - } - blobs[parameterIndex - 1] = false; + int scale) throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + if (x instanceof byte[]) { + byte[] bx = (byte[]) x; + if (conn.db.is3()) { + args[parameterIndex - 1] = + SQLite.StringEncoder.encodeX(bx); + blobs[parameterIndex - 1] = true; + return; + } + args[parameterIndex - 1] = SQLite.StringEncoder.encode(bx); + } else { + args[parameterIndex - 1] = x.toString(); + } + } + blobs[parameterIndex - 1] = false; } public void setObject(int parameterIndex, Object x, int targetSqlType) - throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - if (x == null) { - args[parameterIndex - 1] = nullrepl ? "" : null; - } else { - if (x instanceof byte[]) { - byte[] bx = (byte[]) x; - if (conn.db.is3()) { - args[parameterIndex - 1] = - SQLite.StringEncoder.encodeX(bx); - blobs[parameterIndex - 1] = true; - return; - } - args[parameterIndex - 1] = SQLite.StringEncoder.encode(bx); - } else { - args[parameterIndex - 1] = x.toString(); - } - } - blobs[parameterIndex - 1] = false; + throws SQLException { + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + if (x instanceof byte[]) { + byte[] bx = (byte[]) x; + if (conn.db.is3()) { + args[parameterIndex - 1] = + SQLite.StringEncoder.encodeX(bx); + blobs[parameterIndex - 1] = true; + return; + } + args[parameterIndex - 1] = SQLite.StringEncoder.encode(bx); + } else { + args[parameterIndex - 1] = x.toString(); + } + } + blobs[parameterIndex - 1] = false; } public void setObject(int parameterIndex, Object x) throws SQLException { - if (parameterIndex < 1 || parameterIndex > args.length) { - throw new SQLException("bad parameter index"); - } - if (x == null) { - args[parameterIndex - 1] = nullrepl ? "" : null; - } else { - if (x instanceof byte[]) { - byte[] bx = (byte[]) x; - if (conn.db.is3()) { - args[parameterIndex - 1] = - SQLite.StringEncoder.encodeX(bx); - blobs[parameterIndex - 1] = true; - return; - } - args[parameterIndex - 1] = SQLite.StringEncoder.encode(bx); - } else { - args[parameterIndex - 1] = x.toString(); - } - } - blobs[parameterIndex - 1] = false; + if (parameterIndex < 1 || parameterIndex > args.length) { + throw new SQLException("bad parameter index"); + } + if (x == null) { + args[parameterIndex - 1] = nullrepl ? "" : null; + } else { + if (x instanceof byte[]) { + byte[] bx = (byte[]) x; + if (conn.db.is3()) { + args[parameterIndex - 1] = + SQLite.StringEncoder.encodeX(bx); + blobs[parameterIndex - 1] = true; + return; + } + args[parameterIndex - 1] = SQLite.StringEncoder.encode(bx); + } else { + args[parameterIndex - 1] = x.toString(); + } + } + blobs[parameterIndex - 1] = false; } public boolean execute() throws SQLException { - return executeQuery(fixup2(sql), args, false) != null; + return executeQuery(fixup2(sql), args, false) != null; } public void addBatch() throws SQLException { - if (batch == null) { - batch = new ArrayList<BatchArg>(args.length); - } - for (int i = 0; i < args.length; i++) { - batch.add(new BatchArg(args[i], blobs[i])); - } + if (batch == null) { + batch = new ArrayList<BatchArg>(args.length); + } + for (int i = 0; i < args.length; i++) { + batch.add(new BatchArg(args[i], blobs[i])); + } } public int[] executeBatch() throws SQLException { - if (batch == null) { - return new int[0]; - } - int[] ret = new int[batch.size() / args.length]; - for (int i = 0; i < ret.length; i++) { - ret[i] = EXECUTE_FAILED; - } - int errs = 0; - int index = 0; - for (int i = 0; i < ret.length; i++) { - for (int k = 0; k < args.length; k++) { - BatchArg b = (BatchArg) batch.get(index++); - - args[i] = b.arg; - blobs[i] = b.blob; - } - try { - ret[i] = executeUpdate(); - } catch (SQLException e) { - ++errs; - } - } - if (errs > 0) { - throw new BatchUpdateException("batch failed", ret); - } - return ret; + if (batch == null) { + return new int[0]; + } + int[] ret = new int[batch.size() / args.length]; + for (int i = 0; i < ret.length; i++) { + ret[i] = EXECUTE_FAILED; + } + int errs = 0; + int index = 0; + for (int i = 0; i < ret.length; i++) { + for (int k = 0; k < args.length; k++) { + BatchArg b = (BatchArg) batch.get(index++); + + args[k] = b.arg; + blobs[k] = b.blob; + } + try { + ret[i] = executeUpdate(); + } catch (SQLException e) { + ++errs; + } + } + if (errs > 0) { + throw new BatchUpdateException("batch failed", ret); + } + return ret; } public void clearBatch() throws SQLException { - if (batch != null) { - batch.clear(); - batch = null; + if (batch != null) { + batch.clear(); + batch = null; + } } + + public void close() throws SQLException { + clearBatch(); + super.close(); } public void setCharacterStream(int parameterIndex, - java.io.Reader reader, - int length) throws SQLException { - throw new SQLException("not supported"); + java.io.Reader reader, + int length) throws SQLException { + try { + char[] data = new char[length]; + reader.read(data); + setString(parameterIndex, new String(data)); + } catch (java.io.IOException e) { + throw new SQLException("I/O failed"); + } } public void setRef(int i, Ref x) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public void setBlob(int i, Blob x) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public void setClob(int i, Clob x) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public void setArray(int i, Array x) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public ResultSetMetaData getMetaData() throws SQLException { - return rs.getMetaData(); + return rs.getMetaData(); } public void setDate(int parameterIndex, java.sql.Date x, Calendar cal) - throws SQLException { - setDate(parameterIndex, x); + throws SQLException { + setDate(parameterIndex, x); } public void setTime(int parameterIndex, java.sql.Time x, Calendar cal) - throws SQLException { - setTime(parameterIndex, x); + throws SQLException { + setTime(parameterIndex, x); } public void setTimestamp(int parameterIndex, java.sql.Timestamp x, - Calendar cal) throws SQLException { - setTimestamp(parameterIndex, x); + Calendar cal) throws SQLException { + setTimestamp(parameterIndex, x); } public void setNull(int parameterIndex, int sqlType, String typeName) - throws SQLException { - setNull(parameterIndex, sqlType); + throws SQLException { + setNull(parameterIndex, sqlType); } public ParameterMetaData getParameterMetaData() throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public void registerOutputParameter(String parameterName, int sqlType) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void registerOutputParameter(String parameterName, int sqlType, - int scale) - throws SQLException { - throw new SQLException("not supported"); + int scale) + throws SQLException { + throw new SQLException("not supported"); } public void registerOutputParameter(String parameterName, int sqlType, - String typeName) - throws SQLException { - throw new SQLException("not supported"); + String typeName) + throws SQLException { + throw new SQLException("not supported"); } public java.net.URL getURL(int parameterIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public void setURL(int parameterIndex, java.net.URL url) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setNull(String parameterName, int sqlType) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setBoolean(String parameterName, boolean val) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setByte(String parameterName, byte val) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setShort(String parameterName, short val) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setInt(String parameterName, int val) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setLong(String parameterName, long val) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setFloat(String parameterName, float val) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setDouble(String parameterName, double val) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setBigDecimal(String parameterName, BigDecimal val) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setString(String parameterName, String val) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setBytes(String parameterName, byte val[]) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setDate(String parameterName, java.sql.Date val) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setTime(String parameterName, java.sql.Time val) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setTimestamp(String parameterName, java.sql.Timestamp val) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setAsciiStream(String parameterName, - java.io.InputStream s, int length) - throws SQLException { - throw new SQLException("not supported"); + java.io.InputStream s, int length) + throws SQLException { + throw new SQLException("not supported"); } public void setBinaryStream(String parameterName, - java.io.InputStream s, int length) - throws SQLException { - throw new SQLException("not supported"); + java.io.InputStream s, int length) + throws SQLException { + throw new SQLException("not supported"); } public void setObject(String parameterName, Object val, int targetSqlType, - int scale) - throws SQLException { - throw new SQLException("not supported"); + int scale) + throws SQLException { + throw new SQLException("not supported"); } public void setObject(String parameterName, Object val, int targetSqlType) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setObject(String parameterName, Object val) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void setCharacterStream(String parameterName, - java.io.Reader r, int length) - throws SQLException { - throw new SQLException("not supported"); + java.io.Reader r, int length) + throws SQLException { + throw new SQLException("not supported"); } public void setDate(String parameterName, java.sql.Date val, - Calendar cal) - throws SQLException { - throw new SQLException("not supported"); + Calendar cal) + throws SQLException { + throw new SQLException("not supported"); } public void setTime(String parameterName, java.sql.Time val, - Calendar cal) - throws SQLException { - throw new SQLException("not supported"); + Calendar cal) + throws SQLException { + throw new SQLException("not supported"); } public void setTimestamp(String parameterName, java.sql.Timestamp val, - Calendar cal) - throws SQLException { - throw new SQLException("not supported"); + Calendar cal) + throws SQLException { + throw new SQLException("not supported"); } public void setNull(String parameterName, int sqlType, String typeName) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public String getString(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public boolean getBoolean(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public byte getByte(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public short getShort(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public int getInt(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public long getLong(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public float getFloat(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public double getDouble(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public byte[] getBytes(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public java.sql.Date getDate(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public java.sql.Time getTime(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public java.sql.Timestamp getTimestamp(String parameterName) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public Object getObject(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public Object getObject(int parameterIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public BigDecimal getBigDecimal(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public Object getObject(String parameterName, Map map) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public Object getObject(int parameterIndex, Map map) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public Ref getRef(int parameterIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public Ref getRef(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public Blob getBlob(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public Blob getBlob(int parameterIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public Clob getClob(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public Clob getClob(int parameterIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public Array getArray(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public Array getArray(int parameterIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public java.sql.Date getDate(String parameterName, Calendar cal) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public java.sql.Date getDate(int parameterIndex, Calendar cal) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public java.sql.Time getTime(String parameterName, Calendar cal) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public java.sql.Time getTime(int parameterIndex, Calendar cal) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public java.sql.Timestamp getTimestamp(String parameterName, Calendar cal) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public java.sql.Timestamp getTimestamp(int parameterIndex, Calendar cal) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public java.net.URL getURL(String parameterName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } } diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCResultSet.java b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCResultSet.java index 06384eb..1ecd846 100644 --- a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCResultSet.java +++ b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCResultSet.java @@ -23,910 +23,1292 @@ public class JDBCResultSet implements java.sql.ResultSet { /** * Meta data for result set or null. */ - private JDBCResultSetMetaData m; + private JDBCResultSetMetaData md; /** * Last result cell retrieved or null. */ private String lastg; + /** + * Updatability of this result set. + */ + private int updatable; + + /** + * When updatable this is the table name. + */ + private String uptable; + + /** + * When updatable these are the PK column names of uptable. + */ + private String pkcols[]; + + /** + * When updatable these are the PK column indices (0-based) of uptable. + */ + private int pkcoli[]; + + /* + * Constants to reflect updateability. + */ + private final static int UPD_UNKNOWN = -1; + private final static int UPD_NO = 0; + private final static int UPD_INS = 1; + private final static int UPD_INSUPDDEL = 2; + + /** + * Flag for cursor being (not) on insert row. + */ + private boolean oninsrow; + + /** + * Row buffer for insert/update row. + */ + private String rowbuf[]; + + private static final boolean nullrepl = + SQLite.Database.version().compareTo("2.5.0") < 0; public JDBCResultSet(SQLite.TableResult tr, JDBCStatement s) { - this.tr = tr; - this.s = s; - this.m = null; - this.lastg = null; - this.row = -1; + this.tr = tr; + this.s = s; + this.md = null; + this.lastg = null; + this.row = -1; + this.updatable = UPD_UNKNOWN; + this.oninsrow = false; + this.rowbuf = null; + } + + public boolean isUpdatable() throws SQLException { + if (updatable == UPD_UNKNOWN) { + try { + JDBCResultSetMetaData m = + (JDBCResultSetMetaData) getMetaData(); + java.util.HashSet<String> h = new java.util.HashSet<String>(); + String lastt = null; + for (int i = 1; i <= tr.ncolumns; i++) { + lastt = m.getTableName(i); + h.add(lastt); + } + if (h.size() > 1 || lastt == null) { + updatable = UPD_NO; + throw new SQLException("view or join"); + } + updatable = UPD_INS; + uptable = lastt; + JDBCResultSet pk = (JDBCResultSet) + s.conn.getMetaData().getPrimaryKeys(null, null, uptable); + if (pk.tr.nrows > 0) { + boolean colnotfound = false; + pkcols = new String[pk.tr.nrows]; + pkcoli = new int[pk.tr.nrows]; + for (int i = 0; i < pk.tr.nrows; i++) { + String rd[] = (String []) pk.tr.rows.elementAt(i); + pkcols[i] = rd[3]; + try { + pkcoli[i] = findColumn(pkcols[i]) - 1; + } catch (SQLException ee) { + colnotfound = true; + } + } + if (!colnotfound) { + updatable = UPD_INSUPDDEL; + } + } + pk.close(); + } catch (SQLException e) { + updatable = UPD_NO; + } + } + if (updatable < UPD_INS) { + throw new SQLException("result set not updatable"); + } + return true; + } + + public void fillRowbuf() throws SQLException { + if (rowbuf == null) { + if (row < 0) { + throw new SQLException("cursor outside of result set"); + } + rowbuf = new String[tr.ncolumns]; + System.arraycopy((String []) tr.rows.elementAt(row), 0, + rowbuf, 0, tr.ncolumns); + } } public boolean next() throws SQLException { - if (tr == null) { - return false; - } - row++; - return row < tr.nrows; + if (tr == null) { + return false; + } + row++; + return row < tr.nrows; } public int findColumn(String columnName) throws SQLException { - JDBCResultSetMetaData m = (JDBCResultSetMetaData) getMetaData(); - return m.findColByName(columnName); + JDBCResultSetMetaData m = (JDBCResultSetMetaData) getMetaData(); + return m.findColByName(columnName); } public int getRow() throws SQLException { - if (tr == null) { - throw new SQLException("no rows"); - } - return row + 1; + if (tr == null) { + throw new SQLException("no rows"); + } + return row + 1; } public boolean previous() throws SQLException { - if (tr == null) { - return false; - } - if (row >= 0) { - row--; - } - return row >= 0; + if (tr == null) { + // BEGIN android-changed: throw rather than return false. + throw new SQLException("ResultSet already closed"); + // END android-changed + } + if (row >= 0) { + row--; + } + return row >= 0; } public boolean absolute(int row) throws SQLException { - if (tr == null) { - return false; - } - if (row < 0) { - row = tr.nrows + 1 + row; - } - row--; - if (row < 0 || row > tr.nrows) { - return false; - } - this.row = row; - return true; + if (tr == null) { + return false; + } + if (row < 0) { + row = tr.nrows + 1 + row; + } + row--; + if (row < 0 || row > tr.nrows) { + return false; + } + this.row = row; + return true; } public boolean relative(int row) throws SQLException { - if (tr == null) { - return false; - } - if (this.row + row < 0 || this.row + row >= tr.nrows) { - return false; - } - this.row += row; - return true; + if (tr == null) { + return false; + } + if (this.row + row < 0 || this.row + row >= tr.nrows) { + return false; + } + this.row += row; + return true; } public void setFetchDirection(int dir) throws SQLException { - throw new SQLException("not supported"); + if (dir != ResultSet.FETCH_FORWARD) { + throw new SQLException("not supported"); + } } public int getFetchDirection() throws SQLException { - throw new SQLException("not supported"); + return ResultSet.FETCH_FORWARD; } public void setFetchSize(int fsize) throws SQLException { - throw new SQLException("not supported"); + if (fsize != 1) { + throw new SQLException("not supported"); + } } public int getFetchSize() throws SQLException { - throw new SQLException("not supported"); + return 1; } public String getString(int columnIndex) throws SQLException { - if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { - throw new SQLException("column " + columnIndex + " not found"); - } - String rd[] = (String []) tr.rows.elementAt(row); - lastg = rd[columnIndex - 1]; - return lastg; + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + return lastg; } public String getString(String columnName) throws SQLException { - int col = findColumn(columnName); - return getString(col); + int col = findColumn(columnName); + return getString(col); } public int getInt(int columnIndex) throws SQLException { - Integer i = internalGetInt(columnIndex); - if (i != null) { - return i.intValue(); - } - return 0; + Integer i = internalGetInt(columnIndex); + if (i != null) { + return i.intValue(); + } + return 0; } private Integer internalGetInt(int columnIndex) throws SQLException { - if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { - throw new SQLException("column " + columnIndex + " not found"); - } - String rd[] = (String []) tr.rows.elementAt(row); - lastg = rd[columnIndex - 1]; - try { - return Integer.valueOf(lastg); - } catch (java.lang.Exception e) { - lastg = null; - } - return null; + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + return Integer.valueOf(lastg); + } catch (java.lang.Exception e) { + lastg = null; + } + return null; } public int getInt(String columnName) throws SQLException { - int col = findColumn(columnName); - return getInt(col); + int col = findColumn(columnName); + return getInt(col); } public boolean getBoolean(int columnIndex) throws SQLException { - throw new SQLException("not supported"); + return getInt(columnIndex) == 1 || + Boolean.valueOf(getString(columnIndex)).booleanValue(); } public boolean getBoolean(String columnName) throws SQLException { - throw new SQLException("not supported"); + int col = findColumn(columnName); + return getBoolean(col); } public ResultSetMetaData getMetaData() throws SQLException { - if (m == null) { - m = new JDBCResultSetMetaData(this); - } - return m; + if (md == null) { + md = new JDBCResultSetMetaData(this); + } + return md; } public short getShort(int columnIndex) throws SQLException { - Short s = internalGetShort(columnIndex); - if (s != null) { - return s.shortValue(); - } - return 0; + Short sh = internalGetShort(columnIndex); + if (sh != null) { + return sh.shortValue(); + } + return 0; } private Short internalGetShort(int columnIndex) throws SQLException { - if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { - throw new SQLException("column " + columnIndex + " not found"); - } - String rd[] = (String []) tr.rows.elementAt(row); - lastg = rd[columnIndex - 1]; - try { - return Short.valueOf(lastg); - } catch (java.lang.Exception e) { - lastg = null; - } - return null; + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + return Short.valueOf(lastg); + } catch (java.lang.Exception e) { + lastg = null; + } + return null; } public short getShort(String columnName) throws SQLException { - int col = findColumn(columnName); - return getShort(col); + int col = findColumn(columnName); + return getShort(col); } public java.sql.Time getTime(int columnIndex) throws SQLException { - return internalGetTime(columnIndex, null); + return internalGetTime(columnIndex, null); } private java.sql.Time internalGetTime(int columnIndex, - java.util.Calendar cal) - throws SQLException { - if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { - throw new SQLException("column " + columnIndex + " not found"); - } - String rd[] = (String []) tr.rows.elementAt(row); - lastg = rd[columnIndex - 1]; - try { - return java.sql.Time.valueOf(lastg); - } catch (java.lang.Exception e) { - lastg = null; - } - return null; + java.util.Calendar cal) + throws SQLException { + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + if (s.conn.useJulian) { + try { + return new java.sql.Time(SQLite.Database.long_from_julian(lastg)); + } catch (java.lang.Exception ee) { + return java.sql.Time.valueOf(lastg); + } + } else { + try { + return java.sql.Time.valueOf(lastg); + } catch (java.lang.Exception ee) { + return new java.sql.Time(SQLite.Database.long_from_julian(lastg)); + } + } + } catch (java.lang.Exception e) { + lastg = null; + } + return null; } public java.sql.Time getTime(String columnName) throws SQLException { - int col = findColumn(columnName); - return getTime(col); + int col = findColumn(columnName); + return getTime(col); } public java.sql.Time getTime(int columnIndex, java.util.Calendar cal) - throws SQLException { - return internalGetTime(columnIndex, cal); + throws SQLException { + return internalGetTime(columnIndex, cal); } public java.sql.Time getTime(String columnName, java.util.Calendar cal) - throws SQLException{ - int col = findColumn(columnName); - return getTime(col, cal); + throws SQLException{ + int col = findColumn(columnName); + return getTime(col, cal); } public java.sql.Timestamp getTimestamp(int columnIndex) - throws SQLException{ - return internalGetTimestamp(columnIndex, null); + throws SQLException{ + return internalGetTimestamp(columnIndex, null); } private java.sql.Timestamp internalGetTimestamp(int columnIndex, - java.util.Calendar cal) - throws SQLException { - if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { - throw new SQLException("column " + columnIndex + " not found"); - } - String rd[] = (String []) tr.rows.elementAt(row); - lastg = rd[columnIndex - 1]; - try { - return java.sql.Timestamp.valueOf(lastg); - } catch (java.lang.Exception e) { - lastg = null; - } - return null; + java.util.Calendar cal) + throws SQLException { + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + if (s.conn.useJulian) { + try { + return new java.sql.Timestamp(SQLite.Database.long_from_julian(lastg)); + } catch (java.lang.Exception ee) { + return java.sql.Timestamp.valueOf(lastg); + } + } else { + try { + return java.sql.Timestamp.valueOf(lastg); + } catch (java.lang.Exception ee) { + return new java.sql.Timestamp(SQLite.Database.long_from_julian(lastg)); + } + } + } catch (java.lang.Exception e) { + lastg = null; + } + return null; } public java.sql.Timestamp getTimestamp(String columnName) - throws SQLException{ - int col = findColumn(columnName); - return getTimestamp(col); + throws SQLException{ + int col = findColumn(columnName); + return getTimestamp(col); } public java.sql.Timestamp getTimestamp(int columnIndex, - java.util.Calendar cal) - throws SQLException { - return internalGetTimestamp(columnIndex, cal); + java.util.Calendar cal) + throws SQLException { + return internalGetTimestamp(columnIndex, cal); } public java.sql.Timestamp getTimestamp(String columnName, - java.util.Calendar cal) - throws SQLException { - int col = findColumn(columnName); - return getTimestamp(col, cal); + java.util.Calendar cal) + throws SQLException { + int col = findColumn(columnName); + return getTimestamp(col, cal); } public java.sql.Date getDate(int columnIndex) throws SQLException { - return internalGetDate(columnIndex, null); + return internalGetDate(columnIndex, null); } private java.sql.Date internalGetDate(int columnIndex, - java.util.Calendar cal) - throws SQLException { - if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { - throw new SQLException("column " + columnIndex + " not found"); - } - String rd[] = (String []) tr.rows.elementAt(row); - lastg = rd[columnIndex - 1]; - try { - return java.sql.Date.valueOf(lastg); - } catch (java.lang.Exception e) { - lastg = null; - } - return null; + java.util.Calendar cal) + throws SQLException { + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + if (s.conn.useJulian) { + try { + return new java.sql.Date(SQLite.Database.long_from_julian(lastg)); + } catch (java.lang.Exception ee) { + return java.sql.Date.valueOf(lastg); + } + } else { + try { + return java.sql.Date.valueOf(lastg); + } catch (java.lang.Exception ee) { + return new java.sql.Date(SQLite.Database.long_from_julian(lastg)); + } + } + } catch (java.lang.Exception e) { + lastg = null; + } + return null; } public java.sql.Date getDate(String columnName) throws SQLException { - int col = findColumn(columnName); - return getDate(col); + int col = findColumn(columnName); + return getDate(col); } public java.sql.Date getDate(int columnIndex, java.util.Calendar cal) - throws SQLException{ - return internalGetDate(columnIndex, cal); + throws SQLException{ + return internalGetDate(columnIndex, cal); } public java.sql.Date getDate(String columnName, java.util.Calendar cal) - throws SQLException{ - int col = findColumn(columnName); - return getDate(col, cal); + throws SQLException{ + int col = findColumn(columnName); + return getDate(col, cal); } public double getDouble(int columnIndex) throws SQLException { - Double d = internalGetDouble(columnIndex); - if (d != null) { - return d.doubleValue(); - } - return 0; + Double d = internalGetDouble(columnIndex); + if (d != null) { + return d.doubleValue(); + } + return 0; } private Double internalGetDouble(int columnIndex) throws SQLException { - if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { - throw new SQLException("column " + columnIndex + " not found"); - } - String rd[] = (String []) tr.rows.elementAt(row); - lastg = rd[columnIndex - 1]; - try { - return Double.valueOf(lastg); - } catch (java.lang.Exception e) { - lastg = null; - } - return null; + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + return Double.valueOf(lastg); + } catch (java.lang.Exception e) { + lastg = null; + } + return null; } public double getDouble(String columnName) throws SQLException { - int col = findColumn(columnName); - return getDouble(col); + int col = findColumn(columnName); + return getDouble(col); } public float getFloat(int columnIndex) throws SQLException { - Float f = internalGetFloat(columnIndex); - if (f != null) { - return f.floatValue(); - } - return 0; + Float f = internalGetFloat(columnIndex); + if (f != null) { + return f.floatValue(); + } + return 0; } private Float internalGetFloat(int columnIndex) throws SQLException { - if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { - throw new SQLException("column " + columnIndex + " not found"); - } - String rd[] = (String []) tr.rows.elementAt(row); - lastg = rd[columnIndex - 1]; - try { - return Float.valueOf(lastg); - } catch (java.lang.Exception e) { - lastg = null; - } - return null; + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + return Float.valueOf(lastg); + } catch (java.lang.Exception e) { + lastg = null; + } + return null; } public float getFloat(String columnName) throws SQLException { - int col = findColumn(columnName); - return getFloat(col); + int col = findColumn(columnName); + return getFloat(col); } public long getLong(int columnIndex) throws SQLException { - Long l = internalGetLong(columnIndex); - if (l != null) { - return l.longValue(); - } - return 0; + Long l = internalGetLong(columnIndex); + if (l != null) { + return l.longValue(); + } + return 0; } private Long internalGetLong(int columnIndex) throws SQLException { - if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { - throw new SQLException("column " + columnIndex + " not found"); - } - String rd[] = (String []) tr.rows.elementAt(row); - lastg = rd[columnIndex - 1]; - try { - return Long.valueOf(lastg); - } catch (java.lang.Exception e) { - lastg = null; - } - return null; + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + try { + return Long.valueOf(lastg); + } catch (java.lang.Exception e) { + lastg = null; + } + return null; } public long getLong(String columnName) throws SQLException { - int col = findColumn(columnName); - return getLong(col); + int col = findColumn(columnName); + return getLong(col); } @Deprecated public java.io.InputStream getUnicodeStream(int columnIndex) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } @Deprecated public java.io.InputStream getUnicodeStream(String columnName) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public java.io.InputStream getAsciiStream(String columnName) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public java.io.InputStream getAsciiStream(int columnIndex) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public BigDecimal getBigDecimal(String columnName) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } @Deprecated public BigDecimal getBigDecimal(String columnName, int scale) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public BigDecimal getBigDecimal(int columnIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } @Deprecated public BigDecimal getBigDecimal(int columnIndex, int scale) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public java.io.InputStream getBinaryStream(int columnIndex) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + byte data[] = getBytes(columnIndex); + if (data != null) { + return new java.io.ByteArrayInputStream(data); + } + return null; } public java.io.InputStream getBinaryStream(String columnName) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + byte data[] = getBytes(columnName); + if (data != null) { + return new java.io.ByteArrayInputStream(data); + } + return null; } public byte getByte(int columnIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public byte getByte(String columnName) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public byte[] getBytes(int columnIndex) throws SQLException { - if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { - throw new SQLException("column " + columnIndex + " not found"); - } - byte ret[] = null; - String rd[] = (String []) tr.rows.elementAt(row); - lastg = rd[columnIndex - 1]; - if (lastg != null) { - ret = SQLite.StringEncoder.decode(lastg); - } - return ret; + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + byte ret[] = null; + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + if (lastg != null) { + ret = SQLite.StringEncoder.decode(lastg); + } + return ret; } public byte[] getBytes(String columnName) throws SQLException { - int col = findColumn(columnName); - return getBytes(col); + int col = findColumn(columnName); + return getBytes(col); } public String getCursorName() throws SQLException { - return null; + return null; } public Object getObject(int columnIndex) throws SQLException { - if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { - throw new SQLException("column " + columnIndex + " not found"); - } - String rd[] = (String []) tr.rows.elementAt(row); - lastg = rd[columnIndex - 1]; - Object ret = lastg; - if (tr instanceof TableResultX) { - switch (((TableResultX) tr).sql_type[columnIndex - 1]) { - case Types.SMALLINT: - ret = internalGetShort(columnIndex); - break; - case Types.INTEGER: - ret = internalGetInt(columnIndex); - break; - case Types.DOUBLE: - ret = internalGetDouble(columnIndex); - break; - case Types.FLOAT: - ret = internalGetFloat(columnIndex); - break; - case Types.BIGINT: - ret = internalGetLong(columnIndex); - break; - case Types.BINARY: - case Types.VARBINARY: - case Types.LONGVARBINARY: - ret = getBytes(columnIndex); - break; - case Types.NULL: - ret = null; - break; - /* defaults to String below */ - } - } - return ret; + if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) { + throw new SQLException("column " + columnIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[columnIndex - 1]; + Object ret = lastg; + if (tr instanceof TableResultX) { + switch (((TableResultX) tr).sql_type[columnIndex - 1]) { + case Types.SMALLINT: + ret = internalGetShort(columnIndex); + break; + case Types.INTEGER: + ret = internalGetInt(columnIndex); + break; + case Types.DOUBLE: + ret = internalGetDouble(columnIndex); + break; + case Types.FLOAT: + ret = internalGetFloat(columnIndex); + break; + case Types.BIGINT: + ret = internalGetLong(columnIndex); + break; + case Types.BINARY: + case Types.VARBINARY: + case Types.LONGVARBINARY: + ret = getBytes(columnIndex); + break; + case Types.NULL: + ret = null; + break; + /* defaults to String below */ + } + } + return ret; } public Object getObject(String columnName) throws SQLException { - int col = findColumn(columnName); - return getObject(col); + int col = findColumn(columnName); + return getObject(col); } public Object getObject(int columnIndex, java.util.Map map) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public Object getObject(String columnIndex, java.util.Map map) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public java.sql.Ref getRef(int columnIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public java.sql.Ref getRef(String columnIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public java.sql.Blob getBlob(int columnIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public java.sql.Blob getBlob(String columnIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public java.sql.Clob getClob(int columnIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public java.sql.Clob getClob(String columnIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public java.sql.Array getArray(int columnIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public java.sql.Array getArray(String columnIndex) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public java.io.Reader getCharacterStream(int columnIndex) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + String data = getString(columnIndex); + if (data != null) { + char[] cdata = data.toCharArray(); + return new java.io.CharArrayReader(cdata); + } + return null; } public java.io.Reader getCharacterStream(String columnName) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + String data = getString(columnName); + if (data != null) { + char[] cdata = data.toCharArray(); + return new java.io.CharArrayReader(cdata); + } + return null; } public SQLWarning getWarnings() throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public boolean wasNull() throws SQLException { - return lastg == null; + return lastg == null; } - + public void clearWarnings() throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public boolean isFirst() throws SQLException { - if (tr == null) { - return true; - } - return row == 0; + if (tr == null) { + return true; + } + return row == 0; } public boolean isBeforeFirst() throws SQLException { - if (tr == null || tr.nrows <= 0) { - return false; - } - return row < 0; + if (tr == null || tr.nrows <= 0) { + return false; + } + return row < 0; } public void beforeFirst() throws SQLException { - if (tr == null) { - return; - } - row = -1; + if (tr == null) { + return; + } + row = -1; } public boolean first() throws SQLException { - if (tr == null || tr.nrows <= 0) { - return false; - } - row = 0; - return true; + if (tr == null || tr.nrows <= 0) { + return false; + } + row = 0; + return true; } public boolean isAfterLast() throws SQLException { - if (tr == null || tr.nrows <= 0) { - return false; - } - return row >= tr.nrows; + if (tr == null || tr.nrows <= 0) { + return false; + } + return row >= tr.nrows; } public void afterLast() throws SQLException { - if (tr == null) { - return; - } - row = tr.nrows; + if (tr == null) { + return; + } + row = tr.nrows; } public boolean isLast() throws SQLException { - if (tr == null) { - return true; - } - return row == tr.nrows - 1; + if (tr == null) { + return true; + } + return row == tr.nrows - 1; } public boolean last() throws SQLException { - if (tr == null || tr.nrows <= 0) { - return false; - } - row = tr.nrows -1; - return true; + if (tr == null || tr.nrows <= 0) { + return false; + } + row = tr.nrows -1; + return true; } public int getType() throws SQLException { - return TYPE_SCROLL_INSENSITIVE; + return TYPE_SCROLL_SENSITIVE; } public int getConcurrency() throws SQLException { - return CONCUR_READ_ONLY; + return CONCUR_UPDATABLE; } public boolean rowUpdated() throws SQLException { - throw new SQLException("not supported"); + return false; } public boolean rowInserted() throws SQLException { - throw new SQLException("not supported"); + return false; } public boolean rowDeleted() throws SQLException { - throw new SQLException("not supported"); + return false; } public void insertRow() throws SQLException { - throw new SQLException("not supported"); + isUpdatable(); + if (!oninsrow || rowbuf == null) { + throw new SQLException("no insert data provided"); + } + JDBCResultSetMetaData m = (JDBCResultSetMetaData) getMetaData(); + StringBuffer sb = new StringBuffer(); + sb.append("INSERT INTO "); + sb.append(SQLite.Shell.sql_quote_dbl(uptable)); + sb.append("("); + for (int i = 0; i < tr.ncolumns; i++) { + sb.append(SQLite.Shell.sql_quote_dbl(m.getColumnName(i + 1))); + if (i < tr.ncolumns - 1) { + sb.append(","); + } + } + sb.append(") VALUES("); + for (int i = 0; i < tr.ncolumns; i++) { + sb.append(nullrepl ? "'%q'" : "%Q"); + if (i < tr.ncolumns - 1) { + sb.append(","); + } + } + sb.append(")"); + try { + this.s.conn.db.exec(sb.toString(), null, rowbuf); + } catch (SQLite.Exception e) { + throw new SQLException(e.getMessage()); + } + tr.newrow(rowbuf); + rowbuf = null; + oninsrow = false; + last(); } public void updateRow() throws SQLException { - throw new SQLException("not supported"); + isUpdatable(); + if (rowbuf == null) { + throw new SQLException("no update data provided"); + } + if (oninsrow) { + throw new SQLException("cursor on insert row"); + } + if (updatable < UPD_INSUPDDEL) { + throw new SQLException("no primary key on table defined"); + } + String rd[] = (String []) tr.rows.elementAt(row); + JDBCResultSetMetaData m = (JDBCResultSetMetaData) getMetaData(); + String args[] = new String[tr.ncolumns + pkcols.length]; + StringBuffer sb = new StringBuffer(); + sb.append("UPDATE "); + sb.append(SQLite.Shell.sql_quote_dbl(uptable)); + sb.append(" SET "); + int i; + for (i = 0; i < tr.ncolumns; i++) { + sb.append(SQLite.Shell.sql_quote_dbl(m.getColumnName(i + 1))); + sb.append(" = " + (nullrepl ? "'%q'" : "%Q")); + if (i < tr.ncolumns - 1) { + sb.append(","); + } + args[i] = rowbuf[i]; + } + sb. append(" WHERE "); + for (int k = 0; k < pkcols.length; k++, i++) { + sb.append(SQLite.Shell.sql_quote_dbl(pkcols[k])); + sb.append(" = " + (nullrepl ? "'%q'" : "%Q")); + if (k < pkcols.length - 1) { + sb.append(" AND "); + } + args[i] = rd[pkcoli[k]]; + } + try { + this.s.conn.db.exec(sb.toString(), null, args); + } catch (SQLite.Exception e) { + throw new SQLException(e.getMessage()); + } + System.arraycopy(rowbuf, 0, rd, 0, rowbuf.length); + rowbuf = null; } public void deleteRow() throws SQLException { - throw new SQLException("not supported"); + isUpdatable(); + if (oninsrow) { + throw new SQLException("cursor on insert row"); + } + if (updatable < UPD_INSUPDDEL) { + throw new SQLException("no primary key on table defined"); + } + fillRowbuf(); + StringBuffer sb = new StringBuffer(); + sb.append("DELETE FROM "); + sb.append(SQLite.Shell.sql_quote_dbl(uptable)); + sb.append(" WHERE "); + String args[] = new String[pkcols.length]; + for (int i = 0; i < pkcols.length; i++) { + sb.append(SQLite.Shell.sql_quote_dbl(pkcols[i])); + sb.append(" = " + (nullrepl ? "'%q'" : "%Q")); + if (i < pkcols.length - 1) { + sb.append(" AND "); + } + args[i] = rowbuf[pkcoli[i]]; + } + try { + this.s.conn.db.exec(sb.toString(), null, args); + } catch (SQLite.Exception e) { + throw new SQLException(e.getMessage()); + } + rowbuf = null; } public void refreshRow() throws SQLException { - throw new SQLException("not supported"); + isUpdatable(); + if (oninsrow) { + throw new SQLException("cursor on insert row"); + } + if (updatable < UPD_INSUPDDEL) { + throw new SQLException("no primary key on table defined"); + } + JDBCResultSetMetaData m = (JDBCResultSetMetaData) getMetaData(); + String rd[] = (String []) tr.rows.elementAt(row); + StringBuffer sb = new StringBuffer(); + sb.append("SELECT "); + for (int i = 0; i < tr.ncolumns; i++) { + sb.append(SQLite.Shell.sql_quote_dbl(m.getColumnName(i + 1))); + if (i < tr.ncolumns - 1) { + sb.append(","); + } + } + sb.append(" FROM "); + sb.append(SQLite.Shell.sql_quote_dbl(uptable)); + sb.append(" WHERE "); + String args[] = new String[pkcols.length]; + for (int i = 0; i < pkcols.length; i++) { + sb.append(SQLite.Shell.sql_quote_dbl(pkcols[i])); + sb.append(" = " + (nullrepl ? "'%q'" : "%Q")); + if (i < pkcols.length - 1) { + sb.append(" AND "); + } + args[i] = rd[pkcoli[i]]; + } + SQLite.TableResult trnew = null; + try { + trnew = this.s.conn.db.get_table(sb.toString(), args); + } catch (SQLite.Exception e) { + throw new SQLException(e.getMessage()); + } + if (trnew.nrows != 1) { + throw new SQLException("wrong size of result set"); + } + rowbuf = null; + tr.rows.setElementAt(trnew.rows.elementAt(0), row); } public void cancelRowUpdates() throws SQLException { - throw new SQLException("not supported"); + rowbuf = null; } public void moveToInsertRow() throws SQLException { - throw new SQLException("not supported"); + isUpdatable(); + if (!oninsrow) { + oninsrow = true; + rowbuf = new String[tr.nrows]; + } } public void moveToCurrentRow() throws SQLException { - throw new SQLException("not supported"); + if (oninsrow) { + oninsrow = false; + rowbuf = null; + } } public void updateNull(int colIndex) throws SQLException { - throw new SQLException("not supported"); + isUpdatable(); + if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) { + throw new SQLException("column " + colIndex + " not found"); + } + fillRowbuf(); + rowbuf[colIndex - 1] = null; } public void updateBoolean(int colIndex, boolean b) throws SQLException { - throw new SQLException("not supported"); + updateString(colIndex, b ? "1" : "0"); } public void updateByte(int colIndex, byte b) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public void updateShort(int colIndex, short b) throws SQLException { - throw new SQLException("not supported"); + isUpdatable(); + if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) { + throw new SQLException("column " + colIndex + " not found"); + } + fillRowbuf(); + rowbuf[colIndex - 1] = Short.toString(b); } public void updateInt(int colIndex, int b) throws SQLException { - throw new SQLException("not supported"); + isUpdatable(); + if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) { + throw new SQLException("column " + colIndex + " not found"); + } + fillRowbuf(); + rowbuf[colIndex - 1] = Integer.toString(b); } public void updateLong(int colIndex, long b) throws SQLException { - throw new SQLException("not supported"); + isUpdatable(); + if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) { + throw new SQLException("column " + colIndex + " not found"); + } + fillRowbuf(); + rowbuf[colIndex - 1] = Long.toString(b); } public void updateFloat(int colIndex, float f) throws SQLException { - throw new SQLException("not supported"); + isUpdatable(); + if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) { + throw new SQLException("column " + colIndex + " not found"); + } + fillRowbuf(); + rowbuf[colIndex - 1] = Float.toString(f); } public void updateDouble(int colIndex, double f) throws SQLException { - throw new SQLException("not supported"); + isUpdatable(); + if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) { + throw new SQLException("column " + colIndex + " not found"); + } + fillRowbuf(); + rowbuf[colIndex - 1] = Double.toString(f); } public void updateBigDecimal(int colIndex, BigDecimal f) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void updateString(int colIndex, String s) throws SQLException { - throw new SQLException("not supported"); + isUpdatable(); + if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) { + throw new SQLException("column " + colIndex + " not found"); + } + fillRowbuf(); + rowbuf[colIndex - 1] = s; } public void updateBytes(int colIndex, byte[] s) throws SQLException { - throw new SQLException("not supported"); + isUpdatable(); + if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) { + throw new SQLException("column " + colIndex + " not found"); + } + fillRowbuf(); + if (this.s.conn.db.is3()) { + rowbuf[colIndex - 1] = SQLite.StringEncoder.encodeX(s); + } else { + rowbuf[colIndex - 1] = SQLite.StringEncoder.encode(s); + } } public void updateDate(int colIndex, java.sql.Date d) throws SQLException { - throw new SQLException("not supported"); + isUpdatable(); + if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) { + throw new SQLException("column " + colIndex + " not found"); + } + fillRowbuf(); + rowbuf[colIndex - 1] = d.toString(); } public void updateTime(int colIndex, java.sql.Time t) throws SQLException { - throw new SQLException("not supported"); + isUpdatable(); + if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) { + throw new SQLException("column " + colIndex + " not found"); + } + fillRowbuf(); + rowbuf[colIndex - 1] = t.toString(); } public void updateTimestamp(int colIndex, java.sql.Timestamp t) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + isUpdatable(); + if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) { + throw new SQLException("column " + colIndex + " not found"); + } + fillRowbuf(); + rowbuf[colIndex - 1] = t.toString(); } public void updateAsciiStream(int colIndex, java.io.InputStream in, int s) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void updateBinaryStream(int colIndex, java.io.InputStream in, int s) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void updateCharacterStream(int colIndex, java.io.Reader in, int s) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public void updateObject(int colIndex, Object obj) throws SQLException { - throw new SQLException("not supported"); + updateString(colIndex, obj.toString()); } public void updateObject(int colIndex, Object obj, int s) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + updateString(colIndex, obj.toString()); } - public void updateNull(String colIndex) throws SQLException { - throw new SQLException("not supported"); + public void updateNull(String colName) throws SQLException { + int col = findColumn(colName); + updateNull(col); } - public void updateBoolean(String colIndex, boolean b) throws SQLException { - throw new SQLException("not supported"); + public void updateBoolean(String colName, boolean b) throws SQLException { + int col = findColumn(colName); + updateBoolean(col, b); } - public void updateByte(String colIndex, byte b) throws SQLException { - throw new SQLException("not supported"); + public void updateByte(String colName, byte b) throws SQLException { + throw new SQLException("not supported"); } - public void updateShort(String colIndex, short b) throws SQLException { - throw new SQLException("not supported"); + public void updateShort(String colName, short b) throws SQLException { + int col = findColumn(colName); + updateShort(col, b); } - public void updateInt(String colIndex, int b) throws SQLException { - throw new SQLException("not supported"); + public void updateInt(String colName, int b) throws SQLException { + int col = findColumn(colName); + updateInt(col, b); } - public void updateLong(String colIndex, long b) throws SQLException { - throw new SQLException("not supported"); + public void updateLong(String colName, long b) throws SQLException { + int col = findColumn(colName); + updateLong(col, b); } - public void updateFloat(String colIndex, float f) throws SQLException { - throw new SQLException("not supported"); + public void updateFloat(String colName, float f) throws SQLException { + int col = findColumn(colName); + updateFloat(col, f); } - public void updateDouble(String colIndex, double f) throws SQLException { - throw new SQLException("not supported"); + public void updateDouble(String colName, double f) throws SQLException { + int col = findColumn(colName); + updateDouble(col, f); } - public void updateBigDecimal(String colIndex, BigDecimal f) - throws SQLException { - throw new SQLException("not supported"); + public void updateBigDecimal(String colName, BigDecimal f) + throws SQLException { + throw new SQLException("not supported"); } - public void updateString(String colIndex, String s) throws SQLException { - throw new SQLException("not supported"); + public void updateString(String colName, String s) throws SQLException { + int col = findColumn(colName); + updateString(col, s); } - public void updateBytes(String colIndex, byte[] s) throws SQLException { - throw new SQLException("not supported"); + public void updateBytes(String colName, byte[] s) throws SQLException { + int col = findColumn(colName); + updateBytes(col, s); } - public void updateDate(String colIndex, java.sql.Date d) - throws SQLException { - throw new SQLException("not supported"); + public void updateDate(String colName, java.sql.Date d) + throws SQLException { + int col = findColumn(colName); + updateDate(col, d); } - public void updateTime(String colIndex, java.sql.Time t) - throws SQLException { - throw new SQLException("not supported"); + public void updateTime(String colName, java.sql.Time t) + throws SQLException { + int col = findColumn(colName); + updateTime(col, t); } - public void updateTimestamp(String colIndex, java.sql.Timestamp t) - throws SQLException { - throw new SQLException("not supported"); + public void updateTimestamp(String colName, java.sql.Timestamp t) + throws SQLException { + int col = findColumn(colName); + updateTimestamp(col, t); } - public void updateAsciiStream(String colIndex, java.io.InputStream in, - int s) - throws SQLException { - throw new SQLException("not supported"); + public void updateAsciiStream(String colName, java.io.InputStream in, + int s) + throws SQLException { + throw new SQLException("not supported"); } - public void updateBinaryStream(String colIndex, java.io.InputStream in, - int s) - throws SQLException { - throw new SQLException("not supported"); + public void updateBinaryStream(String colName, java.io.InputStream in, + int s) + throws SQLException { + throw new SQLException("not supported"); } - public void updateCharacterStream(String colIndex, java.io.Reader in, - int s) - throws SQLException { - throw new SQLException("not supported"); + public void updateCharacterStream(String colName, java.io.Reader in, + int s) + throws SQLException { + throw new SQLException("not supported"); } - public void updateObject(String colIndex, Object obj) - throws SQLException { - throw new SQLException("not supported"); + public void updateObject(String colName, Object obj) + throws SQLException { + int col = findColumn(colName); + updateObject(col, obj); } - public void updateObject(String colIndex, Object obj, int s) - throws SQLException { - throw new SQLException("not supported"); + public void updateObject(String colName, Object obj, int s) + throws SQLException { + int col = findColumn(colName); + updateObject(col, obj, s); } public Statement getStatement() throws SQLException { - if (s == null) { - throw new SQLException("stale result set"); - } - return s; + if (s == null) { + throw new SQLException("stale result set"); + } + return s; } public void close() throws SQLException { - s = null; - tr = null; - lastg = null; - row = -1; + s = null; + tr = null; + lastg = null; + oninsrow = false; + rowbuf = null; + row = -1; } public java.net.URL getURL(int colIndex) throws SQLException { - if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) { - throw new SQLException("column " + colIndex + " not found"); - } - String rd[] = (String []) tr.rows.elementAt(row); - lastg = rd[colIndex - 1]; - java.net.URL url = null; - if (lastg == null) { - return url; - } - try { - url = new java.net.URL(lastg); - } catch (java.lang.Exception e) { - url = null; - } - return url; - } - - public java.net.URL getURL(String colIndex) throws SQLException { - int col = findColumn(colIndex); - return getURL(col); + if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) { + throw new SQLException("column " + colIndex + " not found"); + } + String rd[] = (String []) tr.rows.elementAt(row); + lastg = rd[colIndex - 1]; + java.net.URL url = null; + if (lastg == null) { + return url; + } + try { + url = new java.net.URL(lastg); + } catch (java.lang.Exception e) { + url = null; + } + return url; + } + + public java.net.URL getURL(String colName) throws SQLException { + int col = findColumn(colName); + return getURL(col); } public void updateRef(int colIndex, java.sql.Ref x) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } - public void updateRef(String colIndex, java.sql.Ref x) - throws SQLException { - throw new SQLException("not supported"); + public void updateRef(String colName, java.sql.Ref x) + throws SQLException { + throw new SQLException("not supported"); } public void updateBlob(int colIndex, java.sql.Blob x) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } - public void updateBlob(String colIndex, java.sql.Blob x) - throws SQLException { - throw new SQLException("not supported"); + public void updateBlob(String colName, java.sql.Blob x) + throws SQLException { + throw new SQLException("not supported"); } public void updateClob(int colIndex, java.sql.Clob x) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } - public void updateClob(String colIndex, java.sql.Clob x) - throws SQLException { - throw new SQLException("not supported"); + public void updateClob(String colName, java.sql.Clob x) + throws SQLException { + throw new SQLException("not supported"); } public void updateArray(int colIndex, java.sql.Array x) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } - public void updateArray(String colIndex, java.sql.Array x) - throws SQLException { - throw new SQLException("not supported"); + public void updateArray(String colName, java.sql.Array x) + throws SQLException { + throw new SQLException("not supported"); } } diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCResultSetMetaData.java b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCResultSetMetaData.java index 934ca78..40be126 100644 --- a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCResultSetMetaData.java +++ b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCResultSetMetaData.java @@ -5,208 +5,210 @@ import java.sql.*; public class JDBCResultSetMetaData implements java.sql.ResultSetMetaData { private JDBCResultSet r; - + public JDBCResultSetMetaData(JDBCResultSet r) { - this.r = r; + this.r = r; } public String getCatalogName(int column) throws java.sql.SQLException { - return null; + return null; } public String getColumnClassName(int column) throws java.sql.SQLException { - column--; - if (r != null && r.tr != null) { - if (column < 0 || column >= r.tr.ncolumns) { - return null; - } - if (r.tr instanceof TableResultX) { - switch (((TableResultX) r.tr).sql_type[column]) { - case Types.SMALLINT: return "java.lang.Short"; - case Types.INTEGER: return "java.lang.Integer"; - case Types.DOUBLE: return "java.lang.Double"; - case Types.FLOAT: return "java.lang.Float"; - case Types.BIGINT: return "java.lang.Long"; - case Types.DATE: return "java.sql.Date"; - case Types.TIME: return "java.sql.Time"; - case Types.TIMESTAMP: return "java.sql.Timestamp"; - case Types.BINARY: - case Types.VARBINARY: return "[B"; - /* defaults to varchar below */ - } - } - return "java.lang.String"; - } - return null; + column--; + if (r != null && r.tr != null) { + if (column < 0 || column >= r.tr.ncolumns) { + return null; + } + if (r.tr instanceof TableResultX) { + switch (((TableResultX) r.tr).sql_type[column]) { + case Types.SMALLINT: return "java.lang.Short"; + case Types.INTEGER: return "java.lang.Integer"; + case Types.REAL: + case Types.DOUBLE: return "java.lang.Double"; + case Types.FLOAT: return "java.lang.Float"; + case Types.BIGINT: return "java.lang.Long"; + case Types.DATE: return "java.sql.Date"; + case Types.TIME: return "java.sql.Time"; + case Types.TIMESTAMP: return "java.sql.Timestamp"; + case Types.BINARY: + case Types.VARBINARY: return "[B"; + /* defaults to varchar below */ + } + } + return "java.lang.String"; + } + return null; } public int getColumnCount() throws java.sql.SQLException { - if (r != null && r.tr != null) { - return r.tr.ncolumns; - } - return 0; + if (r != null && r.tr != null) { + return r.tr.ncolumns; + } + return 0; } public int getColumnDisplaySize(int column) throws java.sql.SQLException { - return 0; + return 0; } public String getColumnLabel(int column) throws java.sql.SQLException { - column--; - String c = null; - if (r != null && r.tr != null) { - if (column < 0 || column >= r.tr.ncolumns) { - return c; - } - c = r.tr.column[column]; - } - return c; + column--; + String c = null; + if (r != null && r.tr != null) { + if (column < 0 || column >= r.tr.ncolumns) { + return c; + } + c = r.tr.column[column]; + } + return c; } public String getColumnName(int column) throws java.sql.SQLException { - column--; - String c = null; - if (r != null && r.tr != null) { - if (column < 0 || column >= r.tr.ncolumns) { - return c; - } - c = r.tr.column[column]; - if (c != null) { - int i = c.indexOf('.'); - if (i > 0) { - return c.substring(i + 1); - } - } - } - return c; + column--; + String c = null; + if (r != null && r.tr != null) { + if (column < 0 || column >= r.tr.ncolumns) { + return c; + } + c = r.tr.column[column]; + if (c != null) { + int i = c.indexOf('.'); + if (i > 0) { + return c.substring(i + 1); + } + } + } + return c; } public int getColumnType(int column) throws java.sql.SQLException { - column--; - if (r != null && r.tr != null) { - if (column >= 0 && column < r.tr.ncolumns) { - if (r.tr instanceof TableResultX) { - return ((TableResultX) r.tr).sql_type[column]; - } - return Types.VARCHAR; - } - } - throw new SQLException("bad column index"); + column--; + if (r != null && r.tr != null) { + if (column >= 0 && column < r.tr.ncolumns) { + if (r.tr instanceof TableResultX) { + return ((TableResultX) r.tr).sql_type[column]; + } + return Types.VARCHAR; + } + } + throw new SQLException("bad column index"); } public String getColumnTypeName(int column) throws java.sql.SQLException { - column--; - if (r != null && r.tr != null) { - if (column >= 0 && column < r.tr.ncolumns) { - if (r.tr instanceof TableResultX) { - switch (((TableResultX) r.tr).sql_type[column]) { - case Types.SMALLINT: return "smallint"; - case Types.INTEGER: return "integer"; - case Types.DOUBLE: return "double"; - case Types.FLOAT: return "float"; - case Types.BIGINT: return "bigint"; - case Types.DATE: return "date"; - case Types.TIME: return "time"; - case Types.TIMESTAMP: return "timestamp"; - case Types.BINARY: return "binary"; - case Types.VARBINARY: return "varbinary"; - /* defaults to varchar below */ - } - } - return "varchar"; - } - } - throw new SQLException("bad column index"); + column--; + if (r != null && r.tr != null) { + if (column >= 0 && column < r.tr.ncolumns) { + if (r.tr instanceof TableResultX) { + switch (((TableResultX) r.tr).sql_type[column]) { + case Types.SMALLINT: return "smallint"; + case Types.INTEGER: return "integer"; + case Types.DOUBLE: return "double"; + case Types.FLOAT: return "float"; + case Types.BIGINT: return "bigint"; + case Types.DATE: return "date"; + case Types.TIME: return "time"; + case Types.TIMESTAMP: return "timestamp"; + case Types.BINARY: return "binary"; + case Types.VARBINARY: return "varbinary"; + case Types.REAL: return "real"; + /* defaults to varchar below */ + } + } + return "varchar"; + } + } + throw new SQLException("bad column index"); } public int getPrecision(int column) throws java.sql.SQLException { - return 0; + return 0; } public int getScale(int column) throws java.sql.SQLException { - return 0; + return 0; } public String getSchemaName(int column) throws java.sql.SQLException { - return null; + return null; } public String getTableName(int column) throws java.sql.SQLException { - column--; - String c = null; - if (r != null && r.tr != null) { - if (column < 0 || column >= r.tr.ncolumns) { - return c; - } - c = r.tr.column[column]; - if (c != null) { - int i = c.indexOf('.'); - if (i > 0) { - return c.substring(0, i); - } - c = null; - } - } - return c; + column--; + String c = null; + if (r != null && r.tr != null) { + if (column < 0 || column >= r.tr.ncolumns) { + return c; + } + c = r.tr.column[column]; + if (c != null) { + int i = c.indexOf('.'); + if (i > 0) { + return c.substring(0, i); + } + c = null; + } + } + return c; } public boolean isAutoIncrement(int column) throws java.sql.SQLException { - return false; + return false; } public boolean isCaseSensitive(int column) throws java.sql.SQLException { - return false; + return false; } public boolean isCurrency(int column) throws java.sql.SQLException { - return false; + return false; } public boolean isDefinitelyWritable(int column) - throws java.sql.SQLException { - return true; + throws java.sql.SQLException { + return true; } public int isNullable(int column) throws java.sql.SQLException { - return columnNullableUnknown; + return columnNullableUnknown; } public boolean isReadOnly(int column) throws java.sql.SQLException { - return false; + return false; } public boolean isSearchable(int column) throws java.sql.SQLException { - return true; + return true; } public boolean isSigned(int column) throws java.sql.SQLException { - return false; + return false; } public boolean isWritable(int column) throws java.sql.SQLException { - return true; + return true; } int findColByName(String columnName) throws java.sql.SQLException { - String c = null; - if (r != null && r.tr != null) { - for (int i = 0; i < r.tr.ncolumns; i++) { - c = r.tr.column[i]; - if (c != null) { - if (c.compareToIgnoreCase(columnName) == 0) { - return i + 1; - } - int k = c.indexOf('.'); - if (k > 0) { - c = c.substring(k + 1); - if (c.compareToIgnoreCase(columnName) == 0) { - return i + 1; - } - } - } - c = null; - } - } - throw new SQLException("column " + columnName + " not found"); + String c = null; + if (r != null && r.tr != null) { + for (int i = 0; i < r.tr.ncolumns; i++) { + c = r.tr.column[i]; + if (c != null) { + if (c.compareToIgnoreCase(columnName) == 0) { + return i + 1; + } + int k = c.indexOf('.'); + if (k > 0) { + c = c.substring(k + 1); + if (c.compareToIgnoreCase(columnName) == 0) { + return i + 1; + } + } + } + c = null; + } + } + throw new SQLException("column " + columnName + " not found"); } } diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCStatement.java b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCStatement.java index 99d12d3..48efa08 100644 --- a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCStatement.java +++ b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/JDBCStatement.java @@ -8,280 +8,286 @@ public class JDBCStatement implements java.sql.Statement { protected JDBCConnection conn; protected JDBCResultSet rs; protected int updcnt; + protected int maxrows = 0; private ArrayList<String> batch; public JDBCStatement(JDBCConnection conn) { - this.conn = conn; - this.updcnt = 0; - this.rs = null; - this.batch = null; + this.conn = conn; + this.updcnt = 0; + this.rs = null; + this.batch = null; } public void setFetchSize(int fetchSize) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public int getFetchSize() throws SQLException { - return 1; + return 1; } public int getMaxRows() throws SQLException { - return 0; + return maxrows; } public void setMaxRows(int max) throws SQLException { - throw new SQLException("not supported"); + // BEGIN android-added: + if (max < 0) { + throw new SQLException("max must be >= 0 (was " + max + ")"); + } + // END android-added + maxrows = max; } public void setFetchDirection(int fetchDirection) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public int getFetchDirection() throws SQLException { - return ResultSet.FETCH_UNKNOWN; + return ResultSet.FETCH_UNKNOWN; } public int getResultSetConcurrency() throws SQLException { - return ResultSet.CONCUR_READ_ONLY; + return ResultSet.CONCUR_READ_ONLY; } public int getResultSetType() throws SQLException { - return ResultSet.TYPE_SCROLL_INSENSITIVE; + return ResultSet.TYPE_SCROLL_INSENSITIVE; } public void setQueryTimeout(int seconds) throws SQLException { - conn.timeout = seconds * 1000; - if (conn.timeout < 0) { - conn.timeout = 120000; - } else if (conn.timeout < 1000) { - conn.timeout = 5000; - } + conn.timeout = seconds * 1000; + if (conn.timeout < 0) { + conn.timeout = 120000; + } else if (conn.timeout < 1000) { + conn.timeout = 5000; + } } public int getQueryTimeout() throws SQLException { - return conn.timeout; + return conn.timeout; } public ResultSet getResultSet() throws SQLException { - return rs; + return rs; } ResultSet executeQuery(String sql, String args[], boolean updonly) - throws SQLException { - SQLite.TableResult tr = null; - if (rs != null) { - rs.close(); - rs = null; - } - updcnt = -1; - if (conn == null || conn.db == null) { - throw new SQLException("stale connection"); - } - int busy = 0; - boolean starttrans = !conn.autocommit && !conn.intrans; - while (true) { - try { - if (starttrans) { - conn.db.exec("BEGIN TRANSACTION", null); - conn.intrans = true; - } - if (args == null) { - if (updonly) { - conn.db.exec(sql, null); - } else { - tr = conn.db.get_table(sql); - } - } else { - if (updonly) { - conn.db.exec(sql, null, args); - } else { - tr = conn.db.get_table(sql, args); - } - } - updcnt = (int) conn.db.changes(); - } catch (SQLite.Exception e) { - if (conn.db.is3() && - conn.db.last_error() == SQLite.Constants.SQLITE_BUSY && - conn.busy3(conn.db, ++busy)) { - try { - if (starttrans && conn.intrans) { - conn.db.exec("ROLLBACK", null); - conn.intrans = false; - } - } catch (SQLite.Exception ee) { - } - try { - int ms = 20 + busy * 10; - if (ms > 1000) { - ms = 1000; - } - synchronized (this) { - this.wait(ms); - } - } catch (java.lang.Exception eee) { - } - continue; - } - throw new SQLException(e.toString()); - } - break; - } - if (!updonly && tr == null) { - throw new SQLException("no result set produced"); - } - if (!updonly && tr != null) { - rs = new JDBCResultSet(new TableResultX(tr), this); - } - return rs; + throws SQLException { + SQLite.TableResult tr = null; + if (rs != null) { + rs.close(); + rs = null; + } + updcnt = -1; + if (conn == null || conn.db == null) { + throw new SQLException("stale connection"); + } + int busy = 0; + boolean starttrans = !conn.autocommit && !conn.intrans; + while (true) { + try { + if (starttrans) { + conn.db.exec("BEGIN TRANSACTION", null); + conn.intrans = true; + } + if (args == null) { + if (updonly) { + conn.db.exec(sql, null); + } else { + tr = conn.db.get_table(sql, maxrows); + } + } else { + if (updonly) { + conn.db.exec(sql, null, args); + } else { + tr = conn.db.get_table(sql, maxrows, args); + } + } + updcnt = (int) conn.db.changes(); + } catch (SQLite.Exception e) { + if (conn.db.is3() && + conn.db.last_error() == SQLite.Constants.SQLITE_BUSY && + conn.busy3(conn.db, ++busy)) { + try { + if (starttrans && conn.intrans) { + conn.db.exec("ROLLBACK", null); + conn.intrans = false; + } + } catch (SQLite.Exception ee) { + } + try { + int ms = 20 + busy * 10; + if (ms > 1000) { + ms = 1000; + } + synchronized (this) { + this.wait(ms); + } + } catch (java.lang.Exception eee) { + } + continue; + } + throw new SQLException(e.toString()); + } + break; + } + if (!updonly && tr == null) { + throw new SQLException("no result set produced"); + } + if (!updonly && tr != null) { + rs = new JDBCResultSet(new TableResultX(tr), this); + } + return rs; } public ResultSet executeQuery(String sql) throws SQLException { - return executeQuery(sql, null, false); + return executeQuery(sql, null, false); } public boolean execute(String sql) throws SQLException { - return executeQuery(sql) != null; + return executeQuery(sql) != null; } public void cancel() throws SQLException { - if (conn == null || conn.db == null) { - throw new SQLException("stale connection"); - } - conn.db.interrupt(); + if (conn == null || conn.db == null) { + throw new SQLException("stale connection"); + } + conn.db.interrupt(); } public void clearWarnings() throws SQLException { } public Connection getConnection() throws SQLException { - return conn; + return conn; } public void addBatch(String sql) throws SQLException { - if (batch == null) { - batch = new ArrayList<String>(1); - } - batch.add(sql); + if (batch == null) { + batch = new ArrayList<String>(1); + } + batch.add(sql); } public int[] executeBatch() throws SQLException { - if (batch == null) { - return new int[0]; - } - int[] ret = new int[batch.size()]; - for (int i = 0; i < ret.length; i++) { - ret[i] = EXECUTE_FAILED; - } - int errs = 0; - for (int i = 0; i < ret.length; i++) { - try { - execute((String) batch.get(i)); - ret[i] = updcnt; - } catch (SQLException e) { - ++errs; - } - } - if (errs > 0) { - throw new BatchUpdateException("batch failed", ret); - } - return ret; + if (batch == null) { + return new int[0]; + } + int[] ret = new int[batch.size()]; + for (int i = 0; i < ret.length; i++) { + ret[i] = EXECUTE_FAILED; + } + int errs = 0; + for (int i = 0; i < ret.length; i++) { + try { + execute((String) batch.get(i)); + ret[i] = updcnt; + } catch (SQLException e) { + ++errs; + } + } + if (errs > 0) { + throw new BatchUpdateException("batch failed", ret); + } + return ret; } public void clearBatch() throws SQLException { - if (batch != null) { - batch.clear(); - batch = null; - } + if (batch != null) { + batch.clear(); + batch = null; + } } public void close() throws SQLException { - clearBatch(); - conn = null; + clearBatch(); + conn = null; } public int executeUpdate(String sql) throws SQLException { - executeQuery(sql, null, true); - return updcnt; + executeQuery(sql, null, true); + return updcnt; } public int getMaxFieldSize() throws SQLException { - return 0; + return 0; } public boolean getMoreResults() throws SQLException { - if (rs != null) { - rs.close(); - rs = null; - } - return false; + if (rs != null) { + rs.close(); + rs = null; + } + return false; } public int getUpdateCount() throws SQLException { - return updcnt; + return updcnt; } public SQLWarning getWarnings() throws SQLException { - return null; + return null; } public void setCursorName(String name) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public void setEscapeProcessing(boolean enable) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public void setMaxFieldSize(int max) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public boolean getMoreResults(int x) throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public ResultSet getGeneratedKeys() throws SQLException { - throw new SQLException("not supported"); + throw new SQLException("not supported"); } public int executeUpdate(String sql, int autokeys) - throws SQLException { - if (autokeys != Statement.NO_GENERATED_KEYS) { - throw new SQLException("not supported"); - } - return executeUpdate(sql); + throws SQLException { + if (autokeys != Statement.NO_GENERATED_KEYS) { + throw new SQLException("not supported"); + } + return executeUpdate(sql); } public int executeUpdate(String sql, int colIndexes[]) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public int executeUpdate(String sql, String colIndexes[]) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public boolean execute(String sql, int autokeys) - throws SQLException { - if (autokeys != Statement.NO_GENERATED_KEYS) { - throw new SQLException("not supported"); - } - return execute(sql); + throws SQLException { + if (autokeys != Statement.NO_GENERATED_KEYS) { + throw new SQLException("not supported"); + } + return execute(sql); } public boolean execute(String sql, int colIndexes[]) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public boolean execute(String sql, String colIndexes[]) - throws SQLException { - throw new SQLException("not supported"); + throws SQLException { + throw new SQLException("not supported"); } public int getResultSetHoldability() throws SQLException { - return ResultSet.HOLD_CURSORS_OVER_COMMIT; + return ResultSet.HOLD_CURSORS_OVER_COMMIT; } } diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/TableResultX.java b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/TableResultX.java index 205372f..1414fc0 100644 --- a/sqlite-jdbc/src/main/java/SQLite/JDBC2y/TableResultX.java +++ b/sqlite-jdbc/src/main/java/SQLite/JDBC2y/TableResultX.java @@ -7,31 +7,40 @@ public class TableResultX extends SQLite.TableResult { public int sql_type[]; public TableResultX() { - super(); - sql_type = new int[this.ncolumns]; - for (int i = 0; i < this.ncolumns; i++) { - sql_type[i] = Types.VARCHAR; + super(); + sql_type = new int[this.ncolumns]; + for (int i = 0; i < this.ncolumns; i++) { + sql_type[i] = Types.VARCHAR; + } } + + public TableResultX(int maxrows) { + super(maxrows); + sql_type = new int[this.ncolumns]; + for (int i = 0; i < this.ncolumns; i++) { + sql_type[i] = Types.VARCHAR; + } } public TableResultX(SQLite.TableResult tr) { - this.column = tr.column; - this.rows = tr.rows; - this.ncolumns = tr.ncolumns; - this.nrows = tr.nrows; - this.types = tr.types; - sql_type = new int[tr.ncolumns]; - for (int i = 0; i < this.ncolumns; i++) { - sql_type[i] = Types.VARCHAR; - } - if (tr.types != null) { - for (int i = 0; i < tr.types.length; i++) { - sql_type[i] = JDBCDatabaseMetaData.mapSqlType(tr.types[i]); - } - } + this.column = tr.column; + this.rows = tr.rows; + this.ncolumns = tr.ncolumns; + this.nrows = tr.nrows; + this.types = tr.types; + this.maxrows = tr.maxrows; + sql_type = new int[tr.ncolumns]; + for (int i = 0; i < this.ncolumns; i++) { + sql_type[i] = Types.VARCHAR; + } + if (tr.types != null) { + for (int i = 0; i < tr.types.length; i++) { + sql_type[i] = JDBCDatabaseMetaData.mapSqlType(tr.types[i]); + } + } } void sql_types(int types[]) { - sql_type = types; + sql_type = types; } } diff --git a/sqlite-jdbc/src/main/java/SQLite/JDBCDriver.java b/sqlite-jdbc/src/main/java/SQLite/JDBCDriver.java index 63b95ee..c90035d 100644 --- a/sqlite-jdbc/src/main/java/SQLite/JDBCDriver.java +++ b/sqlite-jdbc/src/main/java/SQLite/JDBCDriver.java @@ -6,104 +6,139 @@ import java.util.Properties; public class JDBCDriver implements java.sql.Driver { public static final int MAJORVERSION = 1; - public static final int MINORVERSION = 2; + + public static boolean sharedCache = false; + + public static String vfs = null; private static java.lang.reflect.Constructor makeConn = null; protected Connection conn; static { - try { - Class connClass = null; - Class args[] = new Class[2]; - args[0] = Class.forName("java.lang.String"); - args[1] = args[0]; - String jvers = java.lang.System.getProperty("java.version"); - String cvers; - if (jvers == null || jvers.startsWith("1.0")) { - throw new java.lang.Exception("unsupported java version"); - } else if (jvers.startsWith("1.1")) { - cvers = "SQLite.JDBC1.JDBCConnection"; - } else if (jvers.startsWith("1.2") || jvers.startsWith("1.3")) { - cvers = "SQLite.JDBC2.JDBCConnection"; - } else if (jvers.startsWith("1.4")) { - cvers = "SQLite.JDBC2x.JDBCConnection"; - } else if (jvers.startsWith("1.5")) { - cvers = "SQLite.JDBC2y.JDBCConnection"; - try { - Class.forName(cvers); - } catch (java.lang.Exception e) { - cvers = "SQLite.JDBC2x.JDBCConnection"; - } - } else { - cvers = "SQLite.JDBC2z.JDBCConnection"; - try { - Class.forName(cvers); - } catch (java.lang.Exception e) { - cvers = "SQLite.JDBC2y.JDBCConnection"; - try { - Class.forName(cvers); - } catch (java.lang.Exception ee) { - cvers = "SQLite.JDBC2x.JDBCConnection"; - } - } - } - connClass = Class.forName(cvers); - makeConn = connClass.getConstructor(args); - java.sql.DriverManager.registerDriver(new JDBCDriver()); - } catch (java.lang.Exception e) { - System.err.println(e); - } + try { + Class connClass = null; + Class args[] = new Class[5]; + args[0] = Class.forName("java.lang.String"); + args[1] = args[0]; + args[2] = args[0]; + args[3] = args[0]; + args[4] = args[0]; + String jvers = java.lang.System.getProperty("java.version"); + String cvers; + if (jvers == null || jvers.startsWith("1.0")) { + throw new java.lang.Exception("unsupported java version"); + } else if (jvers.startsWith("1.1")) { + cvers = "SQLite.JDBC1.JDBCConnection"; + } else if (jvers.startsWith("1.2") || jvers.startsWith("1.3")) { + cvers = "SQLite.JDBC2.JDBCConnection"; + } else if (jvers.startsWith("1.4")) { + cvers = "SQLite.JDBC2x.JDBCConnection"; + } else if (jvers.startsWith("1.5")) { + cvers = "SQLite.JDBC2y.JDBCConnection"; + try { + Class.forName(cvers); + } catch (java.lang.Exception e) { + cvers = "SQLite.JDBC2x.JDBCConnection"; + } + } else { + cvers = "SQLite.JDBC2z.JDBCConnection"; + try { + Class.forName(cvers); + } catch (java.lang.Exception e) { + cvers = "SQLite.JDBC2y.JDBCConnection"; + try { + Class.forName(cvers); + } catch (java.lang.Exception ee) { + cvers = "SQLite.JDBC2x.JDBCConnection"; + } + } + } + connClass = Class.forName(cvers); + makeConn = connClass.getConstructor(args); + java.sql.DriverManager.registerDriver(new JDBCDriver()); + try { + String shcache = + java.lang.System.getProperty("SQLite.sharedcache"); + if (shcache != null && + (shcache.startsWith("y") || shcache.startsWith("Y"))) { + sharedCache = SQLite.Database._enable_shared_cache(true); + } + } catch (java.lang.Exception e) { + } + try { + String tvfs = + java.lang.System.getProperty("SQLite.vfs"); + if (tvfs != null) { + vfs = tvfs; + } + } catch (java.lang.Exception e) { + } + } catch (java.lang.Exception e) { + System.err.println(e); + } } public JDBCDriver() { } - + public boolean acceptsURL(String url) throws SQLException { - return url.startsWith("sqlite:/") || - url.startsWith("jdbc:sqlite:/"); + return url.startsWith("sqlite:/") || + url.startsWith("jdbc:sqlite:/"); } public Connection connect(String url, Properties info) - throws SQLException { - if (!acceptsURL(url)) { - return null; - } - Object args[] = new Object[2]; - args[0] = url; - if (info != null) { - args[1] = info.getProperty("encoding"); - } - if (args[1] == null) { - args[1] = java.lang.System.getProperty("SQLite.encoding"); - } - try { - conn = (Connection) makeConn.newInstance(args); - } catch (java.lang.reflect.InvocationTargetException ie) { - throw new SQLException(ie.getTargetException().toString()); - } catch (java.lang.Exception e) { - throw new SQLException(e.toString()); - } - return conn; + throws SQLException { + if (!acceptsURL(url)) { + return null; + } + Object args[] = new Object[5]; + args[0] = url; + if (info != null) { + args[1] = info.getProperty("encoding"); + args[2] = info.getProperty("password"); + args[3] = info.getProperty("daterepr"); + args[4] = info.getProperty("vfs"); + } + if (args[1] == null) { + args[1] = java.lang.System.getProperty("SQLite.encoding"); + } + if (args[4] == null) { + args[4] = vfs; + } + try { + conn = (Connection) makeConn.newInstance(args); + } catch (java.lang.reflect.InvocationTargetException ie) { + throw new SQLException(ie.getTargetException().toString()); + } catch (java.lang.Exception e) { + throw new SQLException(e.toString()); + } + return conn; } public int getMajorVersion() { - return MAJORVERSION; + return MAJORVERSION; } public int getMinorVersion() { - return MINORVERSION; + return Constants.drv_minor; } public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) - throws SQLException { - DriverPropertyInfo p[] = new DriverPropertyInfo[1]; - DriverPropertyInfo pp = new DriverPropertyInfo("encoding", ""); - p[0] = pp; - return p; + throws SQLException { + DriverPropertyInfo p[] = new DriverPropertyInfo[4]; + DriverPropertyInfo pp = new DriverPropertyInfo("encoding", ""); + p[0] = pp; + pp = new DriverPropertyInfo("password", ""); + p[1] = pp; + pp = new DriverPropertyInfo("daterepr", "normal"); + p[2] = pp; + pp = new DriverPropertyInfo("vfs", vfs); + p[3] = pp; + return p; } public boolean jdbcCompliant() { - return false; + return false; } } diff --git a/sqlite-jdbc/src/main/java/SQLite/Shell.java b/sqlite-jdbc/src/main/java/SQLite/Shell.java index 78d37a1..b25e8ca 100644 --- a/sqlite-jdbc/src/main/java/SQLite/Shell.java +++ b/sqlite-jdbc/src/main/java/SQLite/Shell.java @@ -38,537 +38,562 @@ public class Shell implements Callback { static final int MODE_Insert2 = 6; public Shell(PrintWriter pw, PrintWriter err) { - this.pw = pw; - this.err = err; + this.pw = pw; + this.err = err; } public Shell(PrintStream ps, PrintStream errs) { - pw = new PrintWriter(ps); - err = new PrintWriter(errs); + pw = new PrintWriter(ps); + err = new PrintWriter(errs); } protected Object clone() { Shell s = new Shell(this.pw, this.err); - s.db = db; - s.echo = echo; - s.mode = mode; - s.count = 0; - s.showHeader = showHeader; - s.tableName = tableName; - s.sep = sep; - s.colwidth = colwidth; - return s; + s.db = db; + s.echo = echo; + s.mode = mode; + s.count = 0; + s.showHeader = showHeader; + s.tableName = tableName; + s.sep = sep; + s.colwidth = colwidth; + return s; } static public String sql_quote_dbl(String str) { - if (str == null) { - return "NULL"; - } - int i, single = 0, dbl = 0; - for (i = 0; i < str.length(); i++) { - if (str.charAt(i) == '\'') { - single++; - } else if (str.charAt(i) == '"') { - dbl++; - } - } - if (dbl == 0) { - return "\"" + str + "\""; - } - StringBuffer sb = new StringBuffer("\""); - for (i = 0; i < str.length(); i++) { - char c = str.charAt(i); - if (c == '"') { - sb.append("\"\""); - } else { - sb.append(c); - } - } - return sb.toString(); + if (str == null) { + return "NULL"; + } + int i, single = 0, dbl = 0; + for (i = 0; i < str.length(); i++) { + if (str.charAt(i) == '\'') { + single++; + } else if (str.charAt(i) == '"') { + dbl++; + } + } + if (dbl == 0) { + return "\"" + str + "\""; + } + StringBuffer sb = new StringBuffer("\""); + for (i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (c == '"') { + sb.append("\"\""); + } else { + sb.append(c); + } + } + return sb.toString(); } static public String sql_quote(String str) { - if (str == null) { - return "NULL"; - } - int i, single = 0, dbl = 0; - for (i = 0; i < str.length(); i++) { - if (str.charAt(i) == '\'') { - single++; - } else if (str.charAt(i) == '"') { - dbl++; - } - } - if (single == 0) { - return "'" + str + "'"; - } - if (dbl == 0) { - return "\"" + str + "\""; - } - StringBuffer sb = new StringBuffer("'"); - for (i = 0; i < str.length(); i++) { - char c = str.charAt(i); - if (c == '\'') { - sb.append("''"); - } else { - sb.append(c); - } - } - return sb.toString(); + if (str == null) { + return "NULL"; + } + int i, single = 0, dbl = 0; + for (i = 0; i < str.length(); i++) { + if (str.charAt(i) == '\'') { + single++; + } else if (str.charAt(i) == '"') { + dbl++; + } + } + if (single == 0) { + return "'" + str + "'"; + } + if (dbl == 0) { + return "\"" + str + "\""; + } + StringBuffer sb = new StringBuffer("'"); + for (i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (c == '\'') { + sb.append("''"); + } else { + sb.append(c); + } + } + return sb.toString(); } static String html_quote(String str) { - if (str == null) { - return "NULL"; - } - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < str.length(); i++) { - char c = str.charAt(i); - if (c == '<') { - sb.append("<"); - } else if (c == '>') { - sb.append(">"); - } else if (c == '&') { - sb.append("&"); - } else { - int x = c; - if (x < 32 || x > 127) { - sb.append("&#" + x + ";"); - } else { - sb.append(c); - } - } - } - return sb.toString(); + if (str == null) { + return "NULL"; + } + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (c == '<') { + sb.append("<"); + } else if (c == '>') { + sb.append(">"); + } else if (c == '&') { + sb.append("&"); + } else { + int x = c; + if (x < 32 || x > 127) { + sb.append("&#" + x + ";"); + } else { + sb.append(c); + } + } + } + return sb.toString(); } static boolean is_numeric(String str) { - try { - Double d = Double.valueOf(str); - } catch (java.lang.Exception e) { - return false; - } - return true; + try { + Double d = Double.valueOf(str); + } catch (java.lang.Exception e) { + return false; + } + return true; } void set_table_name(String str) { - if (str == null) { - tableName = ""; - return; - } - tableName = Shell.sql_quote(str); + if (str == null) { + tableName = ""; + return; + } + if (db.is3()) { + tableName = Shell.sql_quote_dbl(str); + } else { + tableName = Shell.sql_quote(str); + } } public void columns(String args[]) { - cols = args; + cols = args; } public void types(String args[]) { - /* Empty body to satisfy SQLite.Callback interface. */ + /* Empty body to satisfy SQLite.Callback interface. */ } public boolean newrow(String args[]) { - int i; - String tname; - switch (mode) { - case Shell.MODE_Line: - if (args.length == 0) { - break; - } - if (count++ > 0) { - pw.println(""); - } - for (i = 0; i < args.length; i++) { - pw.println(cols[i] + " = " + - args[i] == null ? "NULL" : args[i]); - } - break; - case Shell.MODE_Column: - String csep = ""; - if (count++ == 0) { - colwidth = new int[args.length]; - for (i = 0; i < args.length; i++) { - int w, n; - w = cols[i].length(); - if (w < 10) { - w = 10; - } - colwidth[i] = w; - if (showHeader) { - pw.print(csep + cols[i]); - csep = " "; - } - } - if (showHeader) { - pw.println(""); - } - } - if (args.length == 0) { - break; - } - csep = ""; - for (i = 0; i < args.length; i++) { - pw.print(csep + (args[i] == null ? "NULL" : args[i])); - csep = " "; - } - pw.println(""); - break; - case Shell.MODE_Semi: - case Shell.MODE_List: - if (count++ == 0 && showHeader) { - for (i = 0; i < args.length; i++) { - pw.print(cols[i] + - (i == args.length - 1 ? "\n" : sep)); - } - } - if (args.length == 0) { - break; - } - for (i = 0; i < args.length; i++) { - pw.print(args[i] == null ? "NULL" : args[i]); - if (mode == Shell.MODE_Semi) { - pw.print(";"); - } else if (i < args.length - 1) { - pw.print(sep); - } - } - pw.println(""); - break; - case MODE_Html: - if (count++ == 0 && showHeader) { - pw.print("<TR>"); - for (i = 0; i < args.length; i++) { - pw.print("<TH>" + html_quote(cols[i]) + "</TH>"); - } - pw.println("</TR>"); - } - if (args.length == 0) { - break; - } - pw.print("<TR>"); - for (i = 0; i < args.length; i++) { - pw.print("<TD>" + html_quote(args[i]) + "</TD>"); - } - pw.println("</TR>"); - break; - case MODE_Insert: - if (args.length == 0) { - break; - } - tname = tableName; - if (destTable != null) { - tname = destTable; - } - pw.print("INSERT INTO " + tname + " VALUES("); - for (i = 0; i < args.length; i++) { - String tsep = i > 0 ? "," : ""; - if (args[i] == null) { - pw.print(tsep + "NULL"); - } else if (is_numeric(args[i])) { - pw.print(tsep + args[i]); - } else { - pw.print(tsep + sql_quote(args[i])); - } - } - pw.println(");"); - break; - case MODE_Insert2: - if (args.length == 0) { - break; - } - tname = tableName; - if (destTable != null) { - tname = destTable; - } - pw.print("INSERT INTO " + tname + " VALUES("); - for (i = 0; i < args.length; i++) { - String tsep = i > 0 ? "," : ""; - pw.print(tsep + args[i]); - } - pw.println(");"); - break; - } - return false; + int i; + String tname; + switch (mode) { + case Shell.MODE_Line: + if (args.length == 0) { + break; + } + if (count++ > 0) { + pw.println(""); + } + for (i = 0; i < args.length; i++) { + pw.println(cols[i] + " = " + + args[i] == null ? "NULL" : args[i]); + } + break; + case Shell.MODE_Column: + String csep = ""; + if (count++ == 0) { + colwidth = new int[args.length]; + for (i = 0; i < args.length; i++) { + int w, n; + w = cols[i].length(); + if (w < 10) { + w = 10; + } + colwidth[i] = w; + if (showHeader) { + pw.print(csep + cols[i]); + csep = " "; + } + } + if (showHeader) { + pw.println(""); + } + } + if (args.length == 0) { + break; + } + csep = ""; + for (i = 0; i < args.length; i++) { + pw.print(csep + (args[i] == null ? "NULL" : args[i])); + csep = " "; + } + pw.println(""); + break; + case Shell.MODE_Semi: + case Shell.MODE_List: + if (count++ == 0 && showHeader) { + for (i = 0; i < args.length; i++) { + pw.print(cols[i] + + (i == args.length - 1 ? "\n" : sep)); + } + } + if (args.length == 0) { + break; + } + for (i = 0; i < args.length; i++) { + pw.print(args[i] == null ? "NULL" : args[i]); + if (mode == Shell.MODE_Semi) { + pw.print(";"); + } else if (i < args.length - 1) { + pw.print(sep); + } + } + pw.println(""); + break; + case MODE_Html: + if (count++ == 0 && showHeader) { + pw.print("<TR>"); + for (i = 0; i < args.length; i++) { + pw.print("<TH>" + html_quote(cols[i]) + "</TH>"); + } + pw.println("</TR>"); + } + if (args.length == 0) { + break; + } + pw.print("<TR>"); + for (i = 0; i < args.length; i++) { + pw.print("<TD>" + html_quote(args[i]) + "</TD>"); + } + pw.println("</TR>"); + break; + case MODE_Insert: + if (args.length == 0) { + break; + } + tname = tableName; + if (destTable != null) { + tname = destTable; + } + pw.print("INSERT INTO " + tname + " VALUES("); + for (i = 0; i < args.length; i++) { + String tsep = i > 0 ? "," : ""; + if (args[i] == null) { + pw.print(tsep + "NULL"); + } else if (is_numeric(args[i])) { + pw.print(tsep + args[i]); + } else { + pw.print(tsep + sql_quote(args[i])); + } + } + pw.println(");"); + break; + case MODE_Insert2: + if (args.length == 0) { + break; + } + tname = tableName; + if (destTable != null) { + tname = destTable; + } + pw.print("INSERT INTO " + tname + " VALUES("); + for (i = 0; i < args.length; i++) { + String tsep = i > 0 ? "," : ""; + pw.print(tsep + args[i]); + } + pw.println(");"); + break; + } + return false; } void do_meta(String line) { StringTokenizer st = new StringTokenizer(line.toLowerCase()); - int n = st.countTokens(); - if (n <= 0) { - return; - } - String cmd = st.nextToken(); - String args[] = new String[n - 1]; - int i = 0; - while (st.hasMoreTokens()) { - args[i] = st.nextToken(); - ++i; - } - if (cmd.compareTo(".dump") == 0) { - new DBDump(this, args); - return; - } - if (cmd.compareTo(".echo") == 0) { - if (args.length > 0 && - (args[0].startsWith("y") || args[0].startsWith("on"))) { - echo = true; - } - return; - } - if (cmd.compareTo(".exit") == 0) { - try { - db.close(); - } catch (Exception e) { - } - System.exit(0); - } - if (cmd.compareTo(".header") == 0) { - if (args.length > 0 && - (args[0].startsWith("y") || args[0].startsWith("on"))) { - showHeader = true; - } - return; - } - if (cmd.compareTo(".help") == 0) { - pw.println(".dump ?TABLE? ... Dump database in text fmt"); - pw.println(".echo ON|OFF Command echo on or off"); - pw.println(".enc ?NAME? Change encoding"); - pw.println(".exit Exit program"); - pw.println(".header ON|OFF Display headers on or off"); - pw.println(".help This message"); - pw.println(".mode MODE Set output mode to\n" + - " line, column, insert\n" + - " list, or html"); - pw.println(".mode insert TABLE Generate SQL insert stmts"); - pw.println(".schema ?PATTERN? List table schema"); - pw.println(".separator STRING Set separator string"); - pw.println(".tables ?PATTERN? List table names"); - return; - } - if (cmd.compareTo(".mode") == 0) { - if (args.length > 0) { - if (args[0].compareTo("line") == 0) { - mode = Shell.MODE_Line; - } else if (args[0].compareTo("column") == 0) { - mode = Shell.MODE_Column; - } else if (args[0].compareTo("list") == 0) { - mode = Shell.MODE_List; - } else if (args[0].compareTo("html") == 0) { - mode = Shell.MODE_Html; - } else if (args[0].compareTo("insert") == 0) { - mode = Shell.MODE_Insert; - if (args.length > 1) { - destTable = args[1]; - } - } - } - return; - } - if (cmd.compareTo(".separator") == 0) { - if (args.length > 0) { - sep = args[0]; - } - return; - } - if (cmd.compareTo(".tables") == 0) { - TableResult t = null; - if (args.length > 0) { - try { - String qarg[] = new String[1]; - qarg[0] = args[0]; - t = db.get_table("SELECT name FROM sqlite_master " + - "WHERE type='table' AND " + - "name LIKE '%%%q%%' " + - "ORDER BY name", qarg); - } catch (Exception e) { - err.println("SQL Error: " + e); - err.flush(); - } - } else { - try { - t = db.get_table("SELECT name FROM sqlite_master " + - "WHERE type='table' ORDER BY name"); - } catch (Exception e) { - err.println("SQL Error: " + e); - err.flush(); - } - } - if (t != null) { - for (i = 0; i < t.nrows; i++) { - String tab = ((String[]) t.rows.elementAt(i))[0]; - if (tab != null) { - pw.println(tab); - } - } - } - return; - } - if (cmd.compareTo(".schema") == 0) { - if (args.length > 0) { - try { - String qarg[] = new String[1]; - qarg[0] = args[0]; - db.exec("SELECT sql FROM sqlite_master " + - "WHERE type!='meta' AND " + - "name LIKE '%%%q%%' AND " + - "sql NOTNULL " + - "ORDER BY type DESC, name", - this, qarg); - } catch (Exception e) { - err.println("SQL Error: " + e); - err.flush(); - } - } else { - try { - db.exec("SELECT sql FROM sqlite_master " + - "WHERE type!='meta' AND " + - "sql NOTNULL " + - "ORDER BY tbl_name, type DESC, name", - this); - } catch (Exception e) { - err.println("SQL Error: " + e); - err.flush(); - } - } - return; - } - if (cmd.compareTo(".enc") == 0) { - try { - db.set_encoding(args.length > 0 ? args[0] : null); - } catch (Exception e) { - err.println("" + e); - err.flush(); - } - return; - } - err.println("Unknown command '" + cmd + "'"); - err.flush(); + int n = st.countTokens(); + if (n <= 0) { + return; + } + String cmd = st.nextToken(); + String args[] = new String[n - 1]; + int i = 0; + while (st.hasMoreTokens()) { + args[i] = st.nextToken(); + ++i; + } + if (cmd.compareTo(".dump") == 0) { + new DBDump(this, args); + return; + } + if (cmd.compareTo(".echo") == 0) { + if (args.length > 0 && + (args[0].startsWith("y") || args[0].startsWith("on"))) { + echo = true; + } + return; + } + if (cmd.compareTo(".exit") == 0) { + try { + db.close(); + } catch (Exception e) { + } + System.exit(0); + } + if (cmd.compareTo(".header") == 0) { + if (args.length > 0 && + (args[0].startsWith("y") || args[0].startsWith("on"))) { + showHeader = true; + } + return; + } + if (cmd.compareTo(".help") == 0) { + pw.println(".dump ?TABLE? ... Dump database in text fmt"); + pw.println(".echo ON|OFF Command echo on or off"); + pw.println(".enc ?NAME? Change encoding"); + pw.println(".exit Exit program"); + pw.println(".header ON|OFF Display headers on or off"); + pw.println(".help This message"); + pw.println(".mode MODE Set output mode to\n" + + " line, column, insert\n" + + " list, or html"); + pw.println(".mode insert TABLE Generate SQL insert stmts"); + pw.println(".schema ?PATTERN? List table schema"); + pw.println(".separator STRING Set separator string"); + pw.println(".tables ?PATTERN? List table names"); + return; + } + if (cmd.compareTo(".mode") == 0) { + if (args.length > 0) { + if (args[0].compareTo("line") == 0) { + mode = Shell.MODE_Line; + } else if (args[0].compareTo("column") == 0) { + mode = Shell.MODE_Column; + } else if (args[0].compareTo("list") == 0) { + mode = Shell.MODE_List; + } else if (args[0].compareTo("html") == 0) { + mode = Shell.MODE_Html; + } else if (args[0].compareTo("insert") == 0) { + mode = Shell.MODE_Insert; + if (args.length > 1) { + destTable = args[1]; + } + } + } + return; + } + if (cmd.compareTo(".separator") == 0) { + if (args.length > 0) { + sep = args[0]; + } + return; + } + if (cmd.compareTo(".tables") == 0) { + TableResult t = null; + if (args.length > 0) { + try { + String qarg[] = new String[1]; + qarg[0] = args[0]; + t = db.get_table("SELECT name FROM sqlite_master " + + "WHERE type='table' AND " + + "name LIKE '%%%q%%' " + + "ORDER BY name", qarg); + } catch (Exception e) { + err.println("SQL Error: " + e); + err.flush(); + } + } else { + try { + t = db.get_table("SELECT name FROM sqlite_master " + + "WHERE type='table' ORDER BY name"); + } catch (Exception e) { + err.println("SQL Error: " + e); + err.flush(); + } + } + if (t != null) { + for (i = 0; i < t.nrows; i++) { + String tab = ((String[]) t.rows.elementAt(i))[0]; + if (tab != null) { + pw.println(tab); + } + } + } + return; + } + if (cmd.compareTo(".schema") == 0) { + if (args.length > 0) { + try { + String qarg[] = new String[1]; + qarg[0] = args[0]; + db.exec("SELECT sql FROM sqlite_master " + + "WHERE type!='meta' AND " + + "name LIKE '%%%q%%' AND " + + "sql NOTNULL " + + "ORDER BY type DESC, name", + this, qarg); + } catch (Exception e) { + err.println("SQL Error: " + e); + err.flush(); + } + } else { + try { + db.exec("SELECT sql FROM sqlite_master " + + "WHERE type!='meta' AND " + + "sql NOTNULL " + + "ORDER BY tbl_name, type DESC, name", + this); + } catch (Exception e) { + err.println("SQL Error: " + e); + err.flush(); + } + } + return; + } + if (cmd.compareTo(".enc") == 0) { + try { + db.set_encoding(args.length > 0 ? args[0] : null); + } catch (Exception e) { + err.println("" + e); + err.flush(); + } + return; + } + if (cmd.compareTo(".rekey") == 0) { + try { + db.rekey(args.length > 0 ? args[0] : null); + } catch (Exception e) { + err.println("" + e); + err.flush(); + } + return; + } + err.println("Unknown command '" + cmd + "'"); + err.flush(); } String read_line(BufferedReader is, String prompt) { - try { - if (prompt != null) { - pw.print(prompt); - pw.flush(); - } - String line = is.readLine(); - return line; - } catch (IOException e) { - return null; - } + try { + if (prompt != null) { + pw.print(prompt); + pw.flush(); + } + String line = is.readLine(); + return line; + } catch (IOException e) { + return null; + } } void do_input(BufferedReader is) { - String line, sql = null; - String prompt = "SQLITE> "; - while ((line = read_line(is, prompt)) != null) { - if (echo) { - pw.println(line); - } - if (line.length() > 0 && line.charAt(0) == '.') { - do_meta(line); - } else { - if (sql == null) { - sql = line; - } else { - sql = sql + " " + line; - } - if (Database.complete(sql)) { - try { - db.exec(sql, this); - } catch (Exception e) { - if (!echo) { - err.println(sql); - } - err.println("SQL Error: " + e); - err.flush(); - } - sql = null; - prompt = "SQLITE> "; - } else { - prompt = "SQLITE? "; - } - } - pw.flush(); - } - if (sql != null) { - err.println("Incomplete SQL: " + sql); - err.flush(); - } + String line, sql = null; + String prompt = "SQLITE> "; + while ((line = read_line(is, prompt)) != null) { + if (echo) { + pw.println(line); + } + if (line.length() > 0 && line.charAt(0) == '.') { + do_meta(line); + } else { + if (sql == null) { + sql = line; + } else { + sql = sql + " " + line; + } + if (Database.complete(sql)) { + try { + db.exec(sql, this); + } catch (Exception e) { + if (!echo) { + err.println(sql); + } + err.println("SQL Error: " + e); + err.flush(); + } + sql = null; + prompt = "SQLITE> "; + } else { + prompt = "SQLITE? "; + } + } + pw.flush(); + } + if (sql != null) { + err.println("Incomplete SQL: " + sql); + err.flush(); + } } void do_cmd(String sql) { if (db == null) { - return; - } + return; + } if (sql.length() > 0 && sql.charAt(0) == '.') { - do_meta(sql); - } else { - try { - db.exec(sql, this); - } catch (Exception e) { - err.println("SQL Error: " + e); - err.flush(); - } - } + do_meta(sql); + } else { + try { + db.exec(sql, this); + } catch (Exception e) { + err.println("SQL Error: " + e); + err.flush(); + } + } } public static void main(String args[]) { - Shell s = new Shell(System.out, System.err); - s.mode = Shell.MODE_List; - s.sep = "|"; - s.showHeader = false; - s.db = new Database(); - String dbname = null, sql = null; - for (int i = 0; i < args.length; i++) { - if(args[i].compareTo("-html") ==0) { - s.mode = Shell.MODE_Html; - } else if (args[i].compareTo("-list") == 0) { - s.mode = Shell.MODE_List; - } else if (args[i].compareTo("-line") == 0) { - s.mode = Shell.MODE_Line; - } else if (i < args.length - 1 && - args[i].compareTo("-separator") == 0) { - ++i; - s.sep = args[i]; - } else if (args[i].compareTo("-header") == 0) { - s.showHeader = true; - } else if (args[i].compareTo("-noheader") == 0) { - s.showHeader = false; - } else if (args[i].compareTo("-echo") == 0) { - s.echo = true; - } else if (dbname == null) { - dbname = args[i]; - } else if (sql == null) { - sql = args[i]; - } else { - System.err.println("Arguments: ?OPTIONS? FILENAME ?SQL?"); - System.exit(1); - } - } - if (dbname == null) { - System.err.println("No database file given"); - System.exit(1); - } - try { - s.db.open(dbname, 0); - } catch (Exception e) { - System.err.println("Unable to open database: " + e); - System.exit(1); - } - if (sql != null) { - s.do_cmd(sql); - } else { - // BEGIN android-modified - BufferedReader is = - new BufferedReader(new InputStreamReader(System.in), 8192); - // END android-modified - s.do_input(is); - } - try { - s.db.close(); - } catch (Exception ee) { - } + String key = null; + Shell s = new Shell(System.out, System.err); + s.mode = Shell.MODE_List; + s.sep = "|"; + s.showHeader = false; + s.db = new Database(); + String dbname = null, sql = null; + for (int i = 0; i < args.length; i++) { + if(args[i].compareTo("-html") ==0) { + s.mode = Shell.MODE_Html; + } else if (args[i].compareTo("-list") == 0) { + s.mode = Shell.MODE_List; + } else if (args[i].compareTo("-line") == 0) { + s.mode = Shell.MODE_Line; + } else if (i < args.length - 1 && + args[i].compareTo("-separator") == 0) { + ++i; + s.sep = args[i]; + } else if (args[i].compareTo("-header") == 0) { + s.showHeader = true; + } else if (args[i].compareTo("-noheader") == 0) { + s.showHeader = false; + } else if (args[i].compareTo("-echo") == 0) { + s.echo = true; + } else if (args[i].compareTo("-key") == 0) { + ++i; + key = args[i]; + } else if (dbname == null) { + dbname = args[i]; + } else if (sql == null) { + sql = args[i]; + } else { + System.err.println("Arguments: ?OPTIONS? FILENAME ?SQL?"); + System.exit(1); + } + } + if (dbname == null) { + System.err.println("No database file given"); + System.exit(1); + } + try { + s.db.open(dbname, 0); + } catch (Exception e) { + System.err.println("Unable to open database: " + e); + System.exit(1); + } + if (key != null) { + try { + s.db.key(key); + } catch (Exception e) { + System.err.println("Unable to set key: " + e); + System.exit(1); + } + } + if (sql != null) { + s.do_cmd(sql); + s.pw.flush(); + } else { + BufferedReader is = + new BufferedReader(new InputStreamReader(System.in)); + s.do_input(is); + s.pw.flush(); + } + try { + s.db.close(); + } catch (Exception ee) { + } } } @@ -584,86 +609,86 @@ class DBDump implements Callback { DBDump(Shell s, String tables[]) { this.s = s; - s.pw.println("BEGIN TRANSACTION;"); + s.pw.println("BEGIN TRANSACTION;"); if (tables == null || tables.length == 0) { - try { - s.db.exec("SELECT name, type, sql FROM sqlite_master " + - "WHERE type!='meta' AND sql NOT NULL " + - "ORDER BY substr(type,2,1), name", this); - } catch (Exception e) { - s.err.println("SQL Error: " + e); - s.err.flush(); - } - } else { - String arg[] = new String[1]; - for (int i = 0; i < tables.length; i++) { - arg[0] = tables[i]; - try { - s.db.exec("SELECT name, type, sql FROM sqlite_master " + - "WHERE tbl_name LIKE '%q' AND type!='meta' " + - " AND sql NOT NULL " + - " ORDER BY substr(type,2,1), name", - this, arg); - } catch (Exception e) { - s.err.println("SQL Error: " + e); - s.err.flush(); - } - } - } - s.pw.println("COMMIT;"); + try { + s.db.exec("SELECT name, type, sql FROM sqlite_master " + + "WHERE type!='meta' AND sql NOT NULL " + + "ORDER BY substr(type,2,1), name", this); + } catch (Exception e) { + s.err.println("SQL Error: " + e); + s.err.flush(); + } + } else { + String arg[] = new String[1]; + for (int i = 0; i < tables.length; i++) { + arg[0] = tables[i]; + try { + s.db.exec("SELECT name, type, sql FROM sqlite_master " + + "WHERE tbl_name LIKE '%q' AND type!='meta' " + + " AND sql NOT NULL " + + " ORDER BY substr(type,2,1), name", + this, arg); + } catch (Exception e) { + s.err.println("SQL Error: " + e); + s.err.flush(); + } + } + } + s.pw.println("COMMIT;"); } public void columns(String col[]) { - /* Empty body to satisfy SQLite.Callback interface. */ + /* Empty body to satisfy SQLite.Callback interface. */ } public void types(String args[]) { - /* Empty body to satisfy SQLite.Callback interface. */ + /* Empty body to satisfy SQLite.Callback interface. */ } public boolean newrow(String args[]) { if (args.length != 3) { - return true; - } - s.pw.println(args[2] + ";"); - if (args[1].compareTo("table") == 0) { - Shell s2 = (Shell) s.clone(); - s2.mode = Shell.MODE_Insert; - s2.set_table_name(args[0]); - String qargs[] = new String[1]; - qargs[0] = args[0]; - try { - if (s2.db.is3()) { - TableResult t = null; - t = s2.db.get_table("PRAGMA table_info('%q')", qargs); - String query; - if (t != null) { - StringBuffer sb = new StringBuffer(); - String sep = ""; + return true; + } + s.pw.println(args[2] + ";"); + if (args[1].compareTo("table") == 0) { + Shell s2 = (Shell) s.clone(); + s2.mode = Shell.MODE_Insert; + s2.set_table_name(args[0]); + String qargs[] = new String[1]; + qargs[0] = args[0]; + try { + if (s2.db.is3()) { + TableResult t = null; + t = s2.db.get_table("PRAGMA table_info('%q')", qargs); + String query; + if (t != null) { + StringBuffer sb = new StringBuffer(); + String sep = ""; - sb.append("SELECT "); - for (int i = 0; i < t.nrows; i++) { - String col = ((String[]) t.rows.elementAt(i))[1]; - sb.append(sep + "quote(" + - Shell.sql_quote_dbl(col) + ")"); - sep = ","; - } - sb.append(" from '%q'"); - query = sb.toString(); - s2.mode = Shell.MODE_Insert2; - } else { - query = "SELECT * from '%q'"; - } - s2.db.exec(query, s2, qargs); - } else { - s2.db.exec("SELECT * from '%q'", s2, qargs); - } - } catch (Exception e) { - s.err.println("SQL Error: " + e); - s.err.flush(); - return true; - } - } - return false; + sb.append("SELECT "); + for (int i = 0; i < t.nrows; i++) { + String col = ((String[]) t.rows.elementAt(i))[1]; + sb.append(sep + "quote(" + + Shell.sql_quote_dbl(col) + ")"); + sep = ","; + } + sb.append(" from '%q'"); + query = sb.toString(); + s2.mode = Shell.MODE_Insert2; + } else { + query = "SELECT * from '%q'"; + } + s2.db.exec(query, s2, qargs); + } else { + s2.db.exec("SELECT * from '%q'", s2, qargs); + } + } catch (Exception e) { + s.err.println("SQL Error: " + e); + s.err.flush(); + return true; + } + } + return false; } } diff --git a/sqlite-jdbc/src/main/java/SQLite/Stmt.java b/sqlite-jdbc/src/main/java/SQLite/Stmt.java index c4f72ed..d60e6b0 100644 --- a/sqlite-jdbc/src/main/java/SQLite/Stmt.java +++ b/sqlite-jdbc/src/main/java/SQLite/Stmt.java @@ -141,7 +141,7 @@ public class Stmt { */ public native void bind_zeroblob(int pos, int length) - throws SQLite.Exception; + throws SQLite.Exception; /** * Return number of parameters in compiled SQLite3 statement. @@ -165,7 +165,7 @@ public class Stmt { */ public native int bind_parameter_index(String name) - throws SQLite.Exception; + throws SQLite.Exception; /** @@ -226,16 +226,16 @@ public class Stmt { public Object column(int col) throws SQLite.Exception { switch (column_type(col)) { - case Constants.SQLITE_INTEGER: - return new Long(column_long(col)); - case Constants.SQLITE_FLOAT: - return new Double(column_double(col)); - case Constants.SQLITE_BLOB: - return column_bytes(col); - case Constants.SQLITE3_TEXT: - return column_string(col); - } - return null; + case Constants.SQLITE_INTEGER: + return new Long(column_long(col)); + case Constants.SQLITE_FLOAT: + return new Double(column_double(col)); + case Constants.SQLITE_BLOB: + return column_bytes(col); + case Constants.SQLITE3_TEXT: + return column_string(col); + } + return null; } /** @@ -283,6 +283,6 @@ public class Stmt { private static native void internal_init(); static { - internal_init(); + internal_init(); } } diff --git a/sqlite-jdbc/src/main/java/SQLite/StringEncoder.java b/sqlite-jdbc/src/main/java/SQLite/StringEncoder.java index c2f20ad..f02e77b 100644 --- a/sqlite-jdbc/src/main/java/SQLite/StringEncoder.java +++ b/sqlite-jdbc/src/main/java/SQLite/StringEncoder.java @@ -40,55 +40,55 @@ public class StringEncoder { */ public static String encode(byte[] a) { - // check input - if (a == null || a.length == 0) { - // bogus shift, no data - return "x"; - } - // determine count - int[] cnt = new int[256]; - for (int i = 0 ; i < a.length; i++) { - cnt[a[i] & 0xff]++; - } - // determine shift for minimum number of escapes - int shift = 1; - int nEscapes = a.length; - for (int i = 1; i < 256; i++) { - if (i == '\'') { - continue; - } - int sum = cnt[i] + cnt[(i + 1) & 0xff] + cnt[(i + '\'') & 0xff]; - if (sum < nEscapes) { - nEscapes = sum; - shift = i; - if (nEscapes == 0) { - // cannot become smaller - break; - } - } - } - // construct encoded output - int outLen = a.length + nEscapes + 1; - StringBuffer out = new StringBuffer(outLen); - out.append((char)shift); - for (int i = 0; i < a.length; i++) { - // apply shift - char c = (char)((a[i] - shift)&0xff); - // insert escapes - if (c == 0) { // forbidden - out.append((char)1); - out.append((char)1); - } else if (c == 1) { // escape character - out.append((char)1); - out.append((char)2); - } else if (c == '\'') { // forbidden - out.append((char)1); - out.append((char)3); - } else { - out.append(c); - } - } - return out.toString(); + // check input + if (a == null || a.length == 0) { + // bogus shift, no data + return "x"; + } + // determine count + int[] cnt = new int[256]; + for (int i = 0 ; i < a.length; i++) { + cnt[a[i] & 0xff]++; + } + // determine shift for minimum number of escapes + int shift = 1; + int nEscapes = a.length; + for (int i = 1; i < 256; i++) { + if (i == '\'') { + continue; + } + int sum = cnt[i] + cnt[(i + 1) & 0xff] + cnt[(i + '\'') & 0xff]; + if (sum < nEscapes) { + nEscapes = sum; + shift = i; + if (nEscapes == 0) { + // cannot become smaller + break; + } + } + } + // construct encoded output + int outLen = a.length + nEscapes + 1; + StringBuffer out = new StringBuffer(outLen); + out.append((char)shift); + for (int i = 0; i < a.length; i++) { + // apply shift + char c = (char)((a[i] - shift)&0xff); + // insert escapes + if (c == 0) { // forbidden + out.append((char)1); + out.append((char)1); + } else if (c == 1) { // escape character + out.append((char)1); + out.append((char)2); + } else if (c == '\'') { // forbidden + out.append((char)1); + out.append((char)3); + } else { + out.append(c); + } + } + return out.toString(); } /** @@ -102,53 +102,96 @@ public class StringEncoder { */ public static byte[] decode(String s) { - char[] a = s.toCharArray(); - if (a.length > 2 && a[0] == 'X' && - a[1] == '\'' && a[a.length-1] == '\'') { - // SQLite3 BLOB syntax - byte[] result = new byte[(a.length-3)/2]; - for (int i = 2, k = 0; i < a.length - 1; i += 2, k++) { - byte tmp = (byte) (a[i] - '0'); - if (tmp > 15) { - tmp -= 0x20; - } - result[k] = (byte) (tmp << 4); - tmp = (byte) (a[i+1] - '0'); - if (tmp > 15) { - tmp -= 0x20; - } - result[k] |= tmp; - } - return result; - } - // first element is the shift - byte[] result = new byte[a.length-1]; - int i = 0; - int shift = s.charAt(i++); - int j = 0; - while (i < s.length()) { - int c; - if ((c = s.charAt(i++)) == 1) { // escape character found - if ((c = s.charAt(i++)) == 1) { - c = 0; - } else if (c == 2) { - c = 1; - } else if (c == 3) { - c = '\''; - } else { - throw new IllegalArgumentException( - "invalid string passed to decoder: " + j); - } - } - // do shift - result[j++] = (byte)((c + shift) & 0xff); - } - int outLen = j; - // provide array of correct length - if (result.length != outLen) { - result = byteCopy(result, 0, outLen, new byte[outLen]); - } - return result; + char[] a = s.toCharArray(); + if (a.length > 2 && a[0] == 'X' && + a[1] == '\'' && a[a.length-1] == '\'') { + // SQLite3 BLOB syntax + byte[] result = new byte[(a.length-3)/2]; + for (int i = 2, k = 0; i < a.length - 1; i += 2, k++) { + byte tmp; + switch (a[i]) { + case '0': tmp = 0; break; + case '1': tmp = 1; break; + case '2': tmp = 2; break; + case '3': tmp = 3; break; + case '4': tmp = 4; break; + case '5': tmp = 5; break; + case '6': tmp = 6; break; + case '7': tmp = 7; break; + case '8': tmp = 8; break; + case '9': tmp = 9; break; + case 'A': + case 'a': tmp = 10; break; + case 'B': + case 'b': tmp = 11; break; + case 'C': + case 'c': tmp = 12; break; + case 'D': + case 'd': tmp = 13; break; + case 'E': + case 'e': tmp = 14; break; + case 'F': + case 'f': tmp = 15; break; + default: tmp = 0; break; + } + result[k] = (byte) (tmp << 4); + switch (a[i+1]) { + case '0': tmp = 0; break; + case '1': tmp = 1; break; + case '2': tmp = 2; break; + case '3': tmp = 3; break; + case '4': tmp = 4; break; + case '5': tmp = 5; break; + case '6': tmp = 6; break; + case '7': tmp = 7; break; + case '8': tmp = 8; break; + case '9': tmp = 9; break; + case 'A': + case 'a': tmp = 10; break; + case 'B': + case 'b': tmp = 11; break; + case 'C': + case 'c': tmp = 12; break; + case 'D': + case 'd': tmp = 13; break; + case 'E': + case 'e': tmp = 14; break; + case 'F': + case 'f': tmp = 15; break; + default: tmp = 0; break; + } + result[k] |= tmp; + } + return result; + } + // first element is the shift + byte[] result = new byte[a.length-1]; + int i = 0; + int shift = s.charAt(i++); + int j = 0; + while (i < s.length()) { + int c; + if ((c = s.charAt(i++)) == 1) { // escape character found + if ((c = s.charAt(i++)) == 1) { + c = 0; + } else if (c == 2) { + c = 1; + } else if (c == 3) { + c = '\''; + } else { + throw new IllegalArgumentException( + "invalid string passed to decoder: " + j); + } + } + // do shift + result[j++] = (byte)((c + shift) & 0xff); + } + int outLen = j; + // provide array of correct length + if (result.length != outLen) { + result = byteCopy(result, 0, outLen, new byte[outLen]); + } + return result; } /** @@ -162,17 +205,17 @@ public class StringEncoder { */ private static byte[] byteCopy(byte[] source, int offset, - int count, byte[] target) { - for (int i = offset, j = 0; i < offset + count; i++, j++) { - target[j] = source[i]; - } - return target; + int count, byte[] target) { + for (int i = offset, j = 0; i < offset + count; i++, j++) { + target[j] = source[i]; + } + return target; } static final char[] xdigits = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /** @@ -183,19 +226,19 @@ public class StringEncoder { */ public static String encodeX(byte[] a) { - // check input - if (a == null || a.length == 0) { - return "X''"; - } - int outLen = a.length + 3; - StringBuffer out = new StringBuffer(outLen); - out.append('X'); - out.append('\''); - for (int i = 0; i < a.length; i++) { - out.append(xdigits[a[i] >> 4]); - out.append(xdigits[a[i] & 0x0F]); - } - out.append('\''); - return out.toString(); + // check input + if (a == null || a.length == 0) { + return "X''"; + } + int outLen = a.length * 2 + 3; + StringBuffer out = new StringBuffer(outLen); + out.append('X'); + out.append('\''); + for (int i = 0; i < a.length; i++) { + out.append(xdigits[(a[i] >> 4) & 0x0F]); + out.append(xdigits[a[i] & 0x0F]); + } + out.append('\''); + return out.toString(); } } diff --git a/sqlite-jdbc/src/main/java/SQLite/TableResult.java b/sqlite-jdbc/src/main/java/SQLite/TableResult.java index 1a7fb57..14337aa 100644 --- a/sqlite-jdbc/src/main/java/SQLite/TableResult.java +++ b/sqlite-jdbc/src/main/java/SQLite/TableResult.java @@ -60,11 +60,32 @@ public class TableResult implements Callback { public Vector rows; /** + * Maximum number of rows to hold in the table. + */ + + public int maxrows = 0; + + /** + * Flag to indicate Maximum number of rows condition. + */ + + public boolean atmaxrows; + + /** * Create an empty result set. */ public TableResult() { - clear(); + clear(); + } + + /** + * Create an empty result set with maximum number of rows. + */ + + public TableResult(int maxrows) { + this.maxrows = maxrows; + clear(); } /** @@ -72,10 +93,11 @@ public class TableResult implements Callback { */ public void clear() { - column = new String[0]; - types = null; - rows = new Vector(); - ncolumns = nrows = 0; + column = new String[0]; + types = null; + rows = new Vector(); + ncolumns = nrows = 0; + atmaxrows = false; } /** @@ -83,8 +105,8 @@ public class TableResult implements Callback { */ public void columns(String coldata[]) { - column = coldata; - ncolumns = column.length; + column = coldata; + ncolumns = column.length; } /** @@ -92,7 +114,7 @@ public class TableResult implements Callback { */ public void types(String types[]) { - this.types = types; + this.types = types; } /** @@ -100,11 +122,15 @@ public class TableResult implements Callback { */ public boolean newrow(String rowdata[]) { - if (rowdata != null) { - rows.addElement(rowdata); - nrows++; - } - return false; + if (rowdata != null) { + if (maxrows > 0 && nrows >= maxrows) { + atmaxrows = true; + return true; + } + rows.addElement(rowdata); + nrows++; + } + return false; } /** @@ -112,22 +138,22 @@ public class TableResult implements Callback { */ public String toString() { - StringBuffer sb = new StringBuffer(); - int i; - for (i = 0; i < ncolumns; i++) { - sb.append(column[i] == null ? "NULL" : column[i]); - sb.append('|'); - } - sb.append('\n'); - for (i = 0; i < nrows; i++) { - int k; - String row[] = (String[]) rows.elementAt(i); - for (k = 0; k < ncolumns; k++) { - sb.append(row[k] == null ? "NULL" : row[k]); - sb.append('|'); - } - sb.append('\n'); - } - return sb.toString(); + StringBuffer sb = new StringBuffer(); + int i; + for (i = 0; i < ncolumns; i++) { + sb.append(column[i] == null ? "NULL" : column[i]); + sb.append('|'); + } + sb.append('\n'); + for (i = 0; i < nrows; i++) { + int k; + String row[] = (String[]) rows.elementAt(i); + for (k = 0; k < ncolumns; k++) { + sb.append(row[k] == null ? "NULL" : row[k]); + sb.append('|'); + } + sb.append('\n'); + } + return sb.toString(); } } diff --git a/sqlite-jdbc/src/main/java/SQLite/Vm.java b/sqlite-jdbc/src/main/java/SQLite/Vm.java index 9856ed0..f47e12f 100644 --- a/sqlite-jdbc/src/main/java/SQLite/Vm.java +++ b/sqlite-jdbc/src/main/java/SQLite/Vm.java @@ -73,6 +73,6 @@ public class Vm { private static native void internal_init(); static { - internal_init(); + internal_init(); } } diff --git a/sqlite-jdbc/src/main/native/sqlite_jni.c b/sqlite-jdbc/src/main/native/sqlite_jni.c index 1333d24..bb5e2da 100644 --- a/sqlite-jdbc/src/main/native/sqlite_jni.c +++ b/sqlite-jdbc/src/main/native/sqlite_jni.c @@ -30,7 +30,9 @@ #define HAVE_BOTH_SQLITE 1 #endif -#define CANT_PASS_VALIST_AS_CHARPTR +#ifndef HAVE_SQLITE3_SHARED_CACHE +#define HAVE_SQLITE3_SHARED_CACHE 0 +#endif #include "sqlite_jni.h" @@ -181,7 +183,7 @@ jstrlen(const jchar *jstr) int len = 0; if (jstr) { - while (*jstr++) { + while (*jstr++) { len++; } } @@ -332,6 +334,7 @@ trans2iso(JNIEnv *env, int haveutf, jstring enc, jstring src, dest->result = 0; dest->tofree = 0; if (haveutf) { + // BEGIN android-changed: leak/error reporting/simplification/performance. const jsize utfLength = (*env)->GetStringUTFLength(env, src); dest->result = dest->tofree = malloc(utfLength + 1); if (!dest->tofree) { @@ -340,6 +343,7 @@ trans2iso(JNIEnv *env, int haveutf, jstring enc, jstring src, } (*env)->GetStringUTFRegion(env, src, 0, utfLength, dest->result); return dest->result; + // END android-changed } if (enc) { bytes = (*env)->CallObjectMethod(env, src, @@ -417,7 +421,7 @@ busyhandler(void *udata, const char *table, int count) "(Ljava/lang/String;I)Z"); if (mid == 0) { - (*env)->DeleteLocalRef(env, cls); + (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak return ret; } trans2utf(env, h->haveutf, h->enc, table, &tabstr); @@ -425,7 +429,7 @@ busyhandler(void *udata, const char *table, int count) (jint) count) != JNI_FALSE; (*env)->DeleteLocalRef(env, tabstr.jstr); - (*env)->DeleteLocalRef(env, cls); + (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak } return ret; } @@ -445,12 +449,12 @@ busyhandler3(void *udata, int count) "(Ljava/lang/String;I)Z"); if (mid == 0) { - (*env)->DeleteLocalRef(env, cls); + (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak return ret; } ret = (*env)->CallBooleanMethod(env, h->bh, mid, 0, (jint) count) != JNI_FALSE; - (*env)->DeleteLocalRef(env, cls); + (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak } return ret; } @@ -468,11 +472,11 @@ progresshandler(void *udata) jmethodID mid = (*env)->GetMethodID(env, cls, "progress", "()Z"); if (mid == 0) { - (*env)->DeleteLocalRef(env, cls); + (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak return ret; } ret = (*env)->CallBooleanMethod(env, h->ph, mid) != JNI_TRUE; - (*env)->DeleteLocalRef(env, cls); + (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak } return ret; } @@ -690,41 +694,39 @@ callback(void *udata, int ncol, char **data, char **cols) #endif #endif } - mid = (*env)->GetMethodID(env, cls, "newrow", - "([Ljava/lang/String;)Z"); - if (mid) { - jboolean rc; + if (data) { + mid = (*env)->GetMethodID(env, cls, "newrow", + "([Ljava/lang/String;)Z"); + if (mid) { + jboolean rc; - if (data) { arr = (*env)->NewObjectArray(env, ncol, C_java_lang_String, 0); - } else { - arr = 0; - } - for (i = 0; arr && i < ncol; i++) { - if (data[i]) { - transstr dats; + for (i = 0; arr && i < ncol; i++) { + if (data[i]) { + transstr dats; - trans2utf(env, h->haveutf, h->enc, data[i], &dats); - (*env)->SetObjectArrayElement(env, arr, i, dats.jstr); - exc = (*env)->ExceptionOccurred(env); - if (exc) { - (*env)->DeleteLocalRef(env, exc); - return 1; + trans2utf(env, h->haveutf, h->enc, data[i], &dats); + (*env)->SetObjectArrayElement(env, arr, i, dats.jstr); + exc = (*env)->ExceptionOccurred(env); + if (exc) { + (*env)->DeleteLocalRef(env, exc); + return 1; + } + (*env)->DeleteLocalRef(env, dats.jstr); } - (*env)->DeleteLocalRef(env, dats.jstr); } + rc = (*env)->CallBooleanMethod(env, h->cb, mid, arr); + exc = (*env)->ExceptionOccurred(env); + if (exc) { + (*env)->DeleteLocalRef(env, exc); + return 1; + } + if (arr) { + (*env)->DeleteLocalRef(env, arr); + } + (*env)->DeleteLocalRef(env, cls); + return rc != JNI_FALSE; } - rc = (*env)->CallBooleanMethod(env, h->cb, mid, arr); - exc = (*env)->ExceptionOccurred(env); - if (exc) { - (*env)->DeleteLocalRef(env, exc); - return 1; - } - if (arr) { - (*env)->DeleteLocalRef(env, arr); - } - (*env)->DeleteLocalRef(env, cls); - return rc != JNI_FALSE; } } return 0; @@ -803,7 +805,7 @@ doclose(JNIEnv *env, jobject obj, int final) bl->next = 0; bl->h = 0; if (bl->blob) { - sqlite3_blob_close(bl->blob); + sqlite3_blob_close(bl->blob); } bl->blob = 0; } @@ -996,13 +998,21 @@ Java_SQLite_Database__1interrupt(JNIEnv *env, jobject obj) } JNIEXPORT void JNICALL -Java_SQLite_Database__1open(JNIEnv *env, jobject obj, jstring file, jint mode) +Java_SQLite_Database__1open4(JNIEnv *env, jobject obj, jstring file, jint mode, + jstring vfs, jboolean ver2) { handle *h = gethandle(env, obj); jthrowable exc; char *err = 0; transstr filename; int maj, min, lev; +#if HAVE_SQLITE3_OPEN_V2 + transstr vfsname; + + vfsname.result = 0; + vfsname.tofree = 0; + vfsname.jstr = 0; +#endif if (h) { if (h->sqlite) { @@ -1066,6 +1076,17 @@ Java_SQLite_Database__1open(JNIEnv *env, jobject obj, jstring file, jint mode) (*env)->DeleteLocalRef(env, exc); return; } +#if HAVE_SQLITE3_OPEN_V2 + if (vfs) { + trans2iso(env, 1, h->enc, vfs, &vfsname); + exc = (*env)->ExceptionOccurred(env); + if (exc) { + transfree(&filename); + (*env)->DeleteLocalRef(env, exc); + return; + } + } +#endif #if HAVE_BOTH_SQLITE { FILE *f = fopen(filename.result, "rb"); @@ -1075,8 +1096,13 @@ Java_SQLite_Database__1open(JNIEnv *env, jobject obj, jstring file, jint mode) c_0 = fgetc(f); fclose(f); } - if (c_0 != '*') { + if (c_0 != '*' && ver2 == JNI_FALSE) { +#if HAVE_SQLITE3_OPEN_V2 + int rc = sqlite3_open_v2(filename.result, (sqlite3 **) &h->sqlite, + (int) mode, vfsname.result); +#else int rc = sqlite3_open(filename.result, (sqlite3 **) &h->sqlite); +#endif if (rc == SQLITE_OK) { h->is3 = 1; @@ -1094,7 +1120,13 @@ Java_SQLite_Database__1open(JNIEnv *env, jobject obj, jstring file, jint mode) h->sqlite = (void *) sqlite_open(filename.result, (int) mode, &err); #endif #if HAVE_SQLITE3 - if (sqlite3_open(filename.result, (sqlite3 **) &h->sqlite) != SQLITE_OK) { +#if HAVE_SQLITE3_OPEN_V2 + if (sqlite3_open_v2(filename.result, (sqlite3 **) &h->sqlite, + (int) mode, vfsname.result) != SQLITE_OK) +#else + if (sqlite3_open(filename.result, (sqlite3 **) &h->sqlite) != SQLITE_OK) +#endif + { if (h->sqlite) { sqlite3_close((sqlite3 *) h->sqlite); h->sqlite = 0; @@ -1103,6 +1135,9 @@ Java_SQLite_Database__1open(JNIEnv *env, jobject obj, jstring file, jint mode) #endif #endif transfree(&filename); +#if HAVE_SQLITE3_OPEN_V2 + transfree(&vfsname); +#endif exc = (*env)->ExceptionOccurred(env); if (exc) { (*env)->DeleteLocalRef(env, exc); @@ -1145,6 +1180,9 @@ Java_SQLite_Database__1open(JNIEnv *env, jobject obj, jstring file, jint mode) #if HAVE_BOTH_SQLITE if (h->is3) { sscanf(sqlite3_libversion(), "%d.%d.%d", &maj, &min, &lev); +#if HAVE_SQLITE3_LOAD_EXTENSION + sqlite3_enable_load_extension((sqlite3 *) h->sqlite, 1); +#endif } else { sscanf(sqlite_libversion(), "%d.%d.%d", &maj, &min, &lev); } @@ -1154,6 +1192,9 @@ Java_SQLite_Database__1open(JNIEnv *env, jobject obj, jstring file, jint mode) #endif #if HAVE_SQLITE3 sscanf(sqlite3_libversion(), "%d.%d.%d", &maj, &min, &lev); +#if HAVE_SQLITE3_LOAD_EXTENSION + sqlite3_enable_load_extension((sqlite3 *) h->sqlite, 1); +#endif #endif #endif h->ver = ((maj & 0xFF) << 16) | ((min & 0xFF) << 8) | (lev & 0xFF); @@ -1168,6 +1209,12 @@ Java_SQLite_Database__1open(JNIEnv *env, jobject obj, jstring file, jint mode) } JNIEXPORT void JNICALL +Java_SQLite_Database__1open(JNIEnv *env, jobject obj, jstring file, jint mode) +{ + Java_SQLite_Database__1open4(env, obj, file, mode, 0, 0); +} + +JNIEXPORT void JNICALL Java_SQLite_Database__1open_1aux_1file(JNIEnv *env, jobject obj, jstring file) { handle *h = gethandle(env, obj); @@ -1339,7 +1386,7 @@ Java_SQLite_Database__1exec__Ljava_lang_String_2LSQLite_Callback_2_3Ljava_lang_S jthrowable exc; int rc = SQLITE_ERROR, nargs, i; char *err = 0, *p; - const char *str = (*env)->GetStringUTFChars(env, sql, NULL); + const char *str = (*env)->GetStringUTFChars(env, sql, NULL); // android-changed: unused variable transstr sqlstr; struct args { char *arg; @@ -1615,7 +1662,7 @@ call_common(sqlite_func *sf, int isstep, int nargs, const char **args) int i; if (mid == 0) { - (*env)->DeleteLocalRef(env, cls); + (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak return; } arr = (*env)->NewObjectArray(env, nargs, C_java_lang_String, 0); @@ -1664,7 +1711,7 @@ call_final(sqlite_func *sf) jmethodID mid = (*env)->GetMethodID(env, cls, "last_step", "(LSQLite/FunctionContext;)V"); if (mid == 0) { - (*env)->DeleteLocalRef(env, cls); + (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak return; } f->sf = sf; @@ -1691,7 +1738,7 @@ call3_common(sqlite3_context *sf, int isstep, int nargs, sqlite3_value **args) int i; if (mid == 0) { - (*env)->DeleteLocalRef(env, cls); + (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak return; } arr = (*env)->NewObjectArray(env, nargs, C_java_lang_String, 0); @@ -1741,7 +1788,7 @@ call3_final(sqlite3_context *sf) jmethodID mid = (*env)->GetMethodID(env, cls, "last_step", "(LSQLite/FunctionContext;)V"); if (mid == 0) { - (*env)->DeleteLocalRef(env, cls); + (*env)->DeleteLocalRef(env, cls); // android-changed: plug leak return; } f->sf = sf; @@ -2520,7 +2567,8 @@ Java_SQLite_Vm_step(JNIEnv *env, jobject obj, jobject cb) if (v && v->vm && v->h) { jthrowable exc; - int ret, ncol = 0; + int ret, tmp; + long ncol = 0; #if HAVE_SQLITE3 freemem *freeproc = 0; const char **blob = 0; @@ -2531,7 +2579,29 @@ Java_SQLite_Vm_step(JNIEnv *env, jobject obj, jobject cb) #if HAVE_BOTH_SQLITE if (v->is3) { ret = sqlite3_step((sqlite3_stmt *) v->vm); - if (ret == SQLITE_ROW) { + if (ret == SQLITE_DONE && v->hh.row1) { + ncol = sqlite3_column_count((sqlite3_stmt *) v->vm); + if (ncol > 0) { + data = calloc(ncol * 3 + 3 + 1, sizeof (char *)); + if (data) { + data[0] = (const char *) ncol; + ++data; + cols = data + ncol + 1; + blob = cols + ncol + 1; + freeproc = free_tab; + } else { + ret = SQLITE_NOMEM; + } + } + if (ret != SQLITE_NOMEM) { + int i; + + for (i = 0; i < ncol; i++) { + cols[i] = + sqlite3_column_name((sqlite3_stmt *) v->vm, i); + } + } + } else if (ret == SQLITE_ROW) { ncol = sqlite3_data_count((sqlite3_stmt *) v->vm); if (ncol > 0) { data = calloc(ncol * 3 + 3 + 1, sizeof (char *)); @@ -2584,15 +2654,41 @@ Java_SQLite_Vm_step(JNIEnv *env, jobject obj, jobject cb) } } } else { - ret = sqlite_step((sqlite_vm *) v->vm, &ncol, &data, &cols); + tmp = 0; + ret = sqlite_step((sqlite_vm *) v->vm, &tmp, &data, &cols); + ncol = tmp; } #else #if HAVE_SQLITE2 - ret = sqlite_step((sqlite_vm *) v->vm, &ncol, &data, &cols); + tmp = 0; + ret = sqlite_step((sqlite_vm *) v->vm, &tmp, &data, &cols); + ncol = tmp; #endif #if HAVE_SQLITE3 ret = sqlite3_step((sqlite3_stmt *) v->vm); - if (ret == SQLITE_ROW) { + if (ret == SQLITE_DONE && v->hh.row1) { + ncol = sqlite3_column_count((sqlite3_stmt *) v->vm); + if (ncol > 0) { + data = calloc(ncol * 3 + 3 + 1, sizeof (char *)); + if (data) { + data[0] = (const char *) ncol; + ++data; + cols = data + ncol + 1; + blob = cols + ncol + 1; + freeproc = free_tab; + } else { + ret = SQLITE_NOMEM; + } + } + if (ret != SQLITE_NOMEM) { + int i; + + for (i = 0; i < ncol; i++) { + cols[i] = + sqlite3_column_name((sqlite3_stmt *) v->vm, i); + } + } + } else if (ret == SQLITE_ROW) { ncol = sqlite3_data_count((sqlite3_stmt *) v->vm); if (ncol > 0) { data = calloc(ncol * 3 + 3 + 1, sizeof (char *)); @@ -2670,6 +2766,29 @@ Java_SQLite_Vm_step(JNIEnv *env, jobject obj, jobject cb) return JNI_TRUE; } else if (ret == SQLITE_DONE) { dofin: + if (v->hh.row1 && cols) { + v->hh.cb = cb; + v->hh.env = env; +#if HAVE_BOTH_SQLITE + if (v->is3) { + v->hh.stmt = (sqlite3_stmt *) v->vm; + } +#else +#if HAVE_SQLITE3 + v->hh.stmt = (sqlite3_stmt *) v->vm; +#endif +#endif + callback((void *) &v->hh, ncol, (char **) 0, (char **) cols); +#if HAVE_SQLITE3 + if (data && freeproc) { + freeproc((void *) data); + } +#endif + exc = (*env)->ExceptionOccurred(env); + if (exc) { + (*env)->DeleteLocalRef(env, exc); + } + } #if HAVE_BOTH_SQLITE if (v->is3) { sqlite3_finalize((sqlite3_stmt *) v->vm); @@ -2720,6 +2839,9 @@ Java_SQLite_Vm_compile(JNIEnv *env, jobject obj) hvm *v = gethvm(env, obj); void *svm = 0; char *err = 0; +#ifdef HAVE_SQLITE2 + char *errfr = 0; +#endif const char *tail; int ret; @@ -2759,11 +2881,13 @@ Java_SQLite_Vm_compile(JNIEnv *env, jobject obj) sqlite3_finalize((sqlite3_stmt *) svm); svm = 0; } + err = (char *) sqlite3_errmsg((sqlite3 *) v->h->sqlite); } } else { ret = sqlite_compile((sqlite *) v->h->sqlite, v->tail, - &tail, (sqlite_vm **) &svm, &err); + &tail, (sqlite_vm **) &svm, &errfr); if (ret != SQLITE_OK) { + err = errfr; if (svm) { sqlite_finalize((sqlite_vm *) svm, 0); svm = 0; @@ -2773,8 +2897,9 @@ Java_SQLite_Vm_compile(JNIEnv *env, jobject obj) #else #if HAVE_SQLITE2 ret = sqlite_compile((sqlite *) v->h->sqlite, v->tail, - &tail, (sqlite_vm **) &svm, &err); + &tail, (sqlite_vm **) &svm, &errfr); if (ret != SQLITE_OK) { + err = errfr; if (svm) { sqlite_finalize((sqlite_vm *) svm, 0); svm = 0; @@ -2794,6 +2919,7 @@ Java_SQLite_Vm_compile(JNIEnv *env, jobject obj) sqlite3_finalize((sqlite3_stmt *) svm); svm = 0; } + err = (char *) sqlite3_errmsg((sqlite3 *) v->h->sqlite); } #endif #endif @@ -2802,15 +2928,15 @@ Java_SQLite_Vm_compile(JNIEnv *env, jobject obj) v->tail = 0; throwex(env, err ? err : "error in compile/prepare"); #if HAVE_SQLITE2 - if (err) { - sqlite_freemem(err); + if (errfr) { + sqlite_freemem(errfr); } #endif return JNI_FALSE; } #if HAVE_SQLITE2 - if (err) { - sqlite_freemem(err); + if (errfr) { + sqlite_freemem(errfr); } #endif if (!svm) { @@ -2838,6 +2964,9 @@ Java_SQLite_Database_vm_1compile(JNIEnv *env, jobject obj, jstring sql, void *svm = 0; hvm *v; char *err = 0; +#if HAVE_SQLITE2 + char *errfr = 0; +#endif const char *tail; transstr tr; jvalue vv; @@ -2877,11 +3006,13 @@ Java_SQLite_Database_vm_1compile(JNIEnv *env, jobject obj, jstring sql, sqlite3_finalize((sqlite3_stmt *) svm); svm = 0; } + err = (char *) sqlite3_errmsg((sqlite3 *) h->sqlite); } } else { ret = sqlite_compile((sqlite *) h->sqlite, tr.result, &tail, - (sqlite_vm **) &svm, &err); + (sqlite_vm **) &svm, &errfr); if (ret != SQLITE_OK) { + err = errfr; if (svm) { sqlite_finalize((sqlite_vm *) svm, 0); } @@ -2890,8 +3021,9 @@ Java_SQLite_Database_vm_1compile(JNIEnv *env, jobject obj, jstring sql, #else #if HAVE_SQLITE2 ret = sqlite_compile((sqlite *) h->sqlite, tr.result, &tail, - (sqlite_vm **) &svm, &err); + (sqlite_vm **) &svm, &errfr); if (ret != SQLITE_OK) { + err = errfr; if (svm) { sqlite_finalize((sqlite_vm *) svm, 0); svm = 0; @@ -2911,6 +3043,7 @@ Java_SQLite_Database_vm_1compile(JNIEnv *env, jobject obj, jstring sql, sqlite3_finalize((sqlite3_stmt *) svm); svm = 0; } + err = (char *) sqlite3_errmsg((sqlite3 *) h->sqlite); } #endif #endif @@ -2919,15 +3052,15 @@ Java_SQLite_Database_vm_1compile(JNIEnv *env, jobject obj, jstring sql, setvmerr(env, vm, ret); throwex(env, err ? err : "error in prepare/compile"); #if HAVE_SQLITE2 - if (err) { - sqlite_freemem(err); + if (errfr) { + sqlite_freemem(errfr); } #endif return; } #if HAVE_SQLITE2 - if (err) { - sqlite_freemem(err); + if (errfr) { + sqlite_freemem(errfr); } #endif if (!svm) { @@ -3019,7 +3152,7 @@ Java_SQLite_Database_vm_1compile_1args(JNIEnv *env, jthrowable exc; int rc = SQLITE_ERROR, nargs, i; char *p; - const char *str = (*env)->GetStringUTFChars(env, sql, NULL); + const char *str = (*env)->GetStringUTFChars(env, sql, NULL); // android-changed: unused variable const char *tail; transstr sqlstr; struct args { @@ -3408,7 +3541,7 @@ Java_SQLite_Database_stmt_1prepare(JNIEnv *env, jobject obj, jstring sql, return; } len16 = len16 + sizeof (jchar) - ((char *) tail - (char *) sql16); - if (len16 < (jsize) sizeof (jchar)) { + if (len16 < (jsize) sizeof (jchar)) { // android-changed: signed/unsigned comparison len16 = sizeof (jchar); } v = malloc(sizeof (hvm) + len16); @@ -3681,6 +3814,7 @@ Java_SQLite_Stmt_bind__ILjava_lang_String_2(JNIEnv *env, jobject obj, return; } if (val) { + // BEGIN android-changed: simplification/performance. const jsize charCount = (*env)->GetStringLength(env, val); len = charCount * sizeof(jchar); if (len > 0) { @@ -3697,6 +3831,7 @@ Java_SQLite_Stmt_bind__ILjava_lang_String_2(JNIEnv *env, jobject obj, ret = sqlite3_bind_text16((sqlite3_stmt *) v->vm, pos, "", 0, SQLITE_STATIC); } + // END android-changed } else { ret = sqlite3_bind_null((sqlite3_stmt *) v->vm, pos); } @@ -4312,6 +4447,108 @@ Java_SQLite_Blob_finalize(JNIEnv *env, jobject obj) #endif } +JNIEXPORT void +JNICALL Java_SQLite_Database__1key(JNIEnv *env, jobject obj, jbyteArray key) +{ + jsize len; + jbyte *data; +#if HAVE_SQLITE3_KEY + handle *h = gethandle(env, obj); +#endif + + len = (*env)->GetArrayLength(env, key); + data = (*env)->GetByteArrayElements(env, key, 0); + if (len == 0) { + data = 0; + } + if (!data) { + len = 0; + } +#if HAVE_SQLITE3_KEY + if (h && h->sqlite) { +#if HAVE_BOTH_SQLITE + if (!h->is3) { + if (data) { + memset(data, 0, len); + } + throwex(env, "unsupported"); + } +#endif + sqlite3_key((sqlite3 *) h->sqlite, data, len); + if (data) { + memset(data, 0, len); + } + } else { + if (data) { + memset(data, 0, len); + } + throwclosed(env); + } +#else + if (data) { + memset(data, 0, len); + } + /* no error */ +#endif +} + +JNIEXPORT void JNICALL +Java_SQLite_Database__1rekey(JNIEnv *env, jobject obj, jbyteArray key) +{ + jsize len; + jbyte *data; +#if HAVE_SQLITE3_KEY + handle *h = gethandle(env, obj); +#endif + + len = (*env)->GetArrayLength(env, key); + data = (*env)->GetByteArrayElements(env, key, 0); + if (len == 0) { + data = 0; + } + if (!data) { + len = 0; + } +#if HAVE_SQLITE3_KEY + if (h && h->sqlite) { +#if HAVE_BOTH_SQLITE + if (!h->is3) { + if (data) { + memset(data, 0, len); + } + throwex(env, "unsupported"); + } +#endif + sqlite3_rekey((sqlite3 *) h->sqlite, data, len); + if (data) { + memset(data, 0, len); + } + } else { + if (data) { + memset(data, 0, len); + } + throwclosed(env); + } +#else + if (data) { + memset(data, 0, len); + } + throwex(env, "unsupported"); +#endif +} + +JNIEXPORT jboolean JNICALL +Java_SQLite_Database__1enable_1shared_1cache(JNIEnv *env, jclass cls, + jboolean onoff) +{ +#if HAVE_SQLITE3_SHARED_CACHE + return (sqlite3_enable_shared_cache(onoff == JNI_TRUE) == SQLITE_OK) ? + JNI_TRUE : JNI_FALSE; +#else + return JNI_FALSE; +#endif +} + JNIEXPORT void JNICALL Java_SQLite_Stmt_internal_1init(JNIEnv *env, jclass cls) { @@ -4342,11 +4579,13 @@ Java_SQLite_Blob_internal_1init(JNIEnv *env, jclass cls) JNIEXPORT void JNICALL Java_SQLite_Database_internal_1init(JNIEnv *env, jclass cls) { -//#ifndef JNI_VERSION_1_2 - jclass jls = (*env)->FindClass(env, "java/lang/String"); +#if defined(DONT_USE_JNI_ONLOAD) || !defined(JNI_VERSION_1_2) + while (C_java_lang_String == 0) { + jclass jls = (*env)->FindClass(env, "java/lang/String"); - C_java_lang_String = (*env)->NewGlobalRef(env, jls); -//#endif + C_java_lang_String = (*env)->NewGlobalRef(env, jls); + } +#endif F_SQLite_Database_handle = (*env)->GetFieldID(env, cls, "handle", "J"); F_SQLite_Database_error_code = @@ -4363,7 +4602,7 @@ Java_SQLite_Database_internal_1init(JNIEnv *env, jclass cls) "([BLjava/lang/String;)V"); } -#ifdef JNI_VERSION_1_2 +#if !defined(DONT_USE_JNI_ONLOAD) && defined(JNI_VERSION_1_2) JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { @@ -4384,7 +4623,7 @@ JNI_OnLoad(JavaVM *vm, void *reserved) if (!cls) { return JNI_ERR; } - C_java_lang_String = (*env)->NewWeakGlobalRef(env, cls); + C_java_lang_String = (*env)->NewGlobalRef(env, cls); // android-changed: bug return JNI_VERSION_1_2; } @@ -4397,7 +4636,7 @@ JNI_OnUnload(JavaVM *vm, void *reserved) return; } if (C_java_lang_String) { - (*env)->DeleteWeakGlobalRef(env, C_java_lang_String); + (*env)->DeleteGlobalRef(env, C_java_lang_String); // android-changed: bug C_java_lang_String = 0; } } diff --git a/sqlite-jdbc/src/main/native/sqlite_jni_defs.h b/sqlite-jdbc/src/main/native/sqlite_jni_defs.h index 91b2378..d21bf16 100644 --- a/sqlite-jdbc/src/main/native/sqlite_jni_defs.h +++ b/sqlite-jdbc/src/main/native/sqlite_jni_defs.h @@ -36,4 +36,4 @@ #define HAVE_SQLITE3_RESULT_ZEROBLOB 0 #define HAVE_SQLITE3_INCRBLOBIO 0 - +#define CANT_PASS_VALIST_AS_CHARPTR |