├── .gitignore ├── Android-SQLiteConnectorTest ├── AndroidManifest.xml ├── ant.properties ├── build.xml ├── libs │ └── .gitignore ├── local.properties ├── proguard-project.txt ├── project.properties ├── res │ ├── layout │ │ └── main.xml │ └── values │ │ └── strings.xml └── src │ └── com │ └── test │ └── SQLiteConnectorTest.java ├── Makefile ├── README.md ├── UN-LICENSE └── src └── io └── liteglue ├── SQLCode.java ├── SQLColumnType.java ├── SQLDatabaseHandle.java ├── SQLGDatabaseHandle.java ├── SQLStatementHandle.java ├── SQLiteConnection.java ├── SQLiteConnectionFactory.java ├── SQLiteConnector.java ├── SQLiteGlueConnection.java ├── SQLiteNative.java ├── SQLiteOpenFlags.java └── SQLiteStatement.java /.gitignore: -------------------------------------------------------------------------------- 1 | .*.swp 2 | *.swp 3 | *.java.old 4 | *.jar 5 | Android-SQLiteConnectorTest/bin 6 | Android-SQLiteConnectorTest/gen 7 | build 8 | -------------------------------------------------------------------------------- /Android-SQLiteConnectorTest/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Android-SQLiteConnectorTest/ant.properties: -------------------------------------------------------------------------------- 1 | # This file is used to override default values used by the Ant build system. 2 | # 3 | # This file must be checked into Version Control Systems, as it is 4 | # integral to the build system of your project. 5 | 6 | # This file is only used by the Ant script. 7 | 8 | # You can use this to override default values such as 9 | # 'source.dir' for the location of your java source folder and 10 | # 'out.dir' for the location of your output folder. 11 | 12 | # You can also use it define how the release builds are signed by declaring 13 | # the following properties: 14 | # 'key.store' for the location of your keystore and 15 | # 'key.alias' for the name of the key to use. 16 | # The password will be asked during the build when you use the 'release' target. 17 | 18 | -------------------------------------------------------------------------------- /Android-SQLiteConnectorTest/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 49 | 50 | 51 | 52 | 56 | 57 | 69 | 70 | 71 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /Android-SQLiteConnectorTest/libs/.gitignore: -------------------------------------------------------------------------------- 1 | *.so 2 | -------------------------------------------------------------------------------- /Android-SQLiteConnectorTest/local.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must *NOT* be checked into Version Control Systems, 5 | # as it contains information specific to your local configuration. 6 | 7 | # location of the SDK. This is only used by Ant 8 | # For customization when using a Version Control System, please read the 9 | # header note. 10 | sdk.dir=/usr/local/Cellar/android-sdk/24.1.2 11 | -------------------------------------------------------------------------------- /Android-SQLiteConnectorTest/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /Android-SQLiteConnectorTest/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-19 15 | -------------------------------------------------------------------------------- /Android-SQLiteConnectorTest/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 12 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Android-SQLiteConnectorTest/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | SQLiteConnectorTest 4 | 5 | -------------------------------------------------------------------------------- /Android-SQLiteConnectorTest/src/com/test/SQLiteConnectorTest.java: -------------------------------------------------------------------------------- 1 | package com.test; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | 6 | import android.widget.ArrayAdapter; 7 | import android.widget.ListView; 8 | 9 | import io.liteglue.*; 10 | 11 | import java.io.File; 12 | 13 | import java.sql.SQLException; 14 | 15 | public class SQLiteConnectorTest extends Activity 16 | { 17 | ArrayAdapter resultsAdapter; 18 | 19 | int errorCount = 0; 20 | 21 | /* package */ void logErrorItem(String result) { 22 | android.util.Log.e("SQLiteGlueTest", result); 23 | resultsAdapter.add(result); 24 | } 25 | 26 | /* package */ void checkBooleanResult(String label, boolean actual, boolean expected) { 27 | if (expected == actual) { 28 | logResult(label + " - OK"); 29 | } else { 30 | ++errorCount; 31 | logErrorItem("FAILED CHECK: " + label); 32 | logErrorItem("expected: " + expected); 33 | logErrorItem("actual: " + actual); 34 | } 35 | } 36 | 37 | /* package */ void checkIntegerResult(String label, int actual, int expected) { 38 | if (expected == actual) { 39 | logResult(label + " - OK"); 40 | } else { 41 | ++errorCount; 42 | logErrorItem("FAILED CHECK: " + label); 43 | logErrorItem("expected: " + expected); 44 | logErrorItem("actual: " + actual); 45 | } 46 | } 47 | 48 | /* package */ void checkLongResult(String label, long actual, long expected) { 49 | if (expected == actual) { 50 | logResult(label + " - OK"); 51 | } else { 52 | ++errorCount; 53 | logErrorItem("FAILED CHECK: " + label); 54 | logErrorItem("expected: " + expected); 55 | logErrorItem("actual: " + actual); 56 | } 57 | } 58 | 59 | /* package */ void checkDoubleResult(String label, double actual, double expected) { 60 | if (expected == actual) { 61 | logResult(label + " - OK"); 62 | } else { 63 | ++errorCount; 64 | logErrorItem("FAILED CHECK: " + label); 65 | logErrorItem("expected: " + expected); 66 | logErrorItem("actual: " + actual); 67 | } 68 | } 69 | 70 | /* package */ void checkStringResult(String label, String actual, String expected) { 71 | if (expected.equals(actual)) { 72 | logResult(label + " - OK"); 73 | } else { 74 | ++errorCount; 75 | logErrorItem("FAILED CHECK: " + label); 76 | logErrorItem("expected: " + expected); 77 | logErrorItem("actual: " + actual); 78 | } 79 | } 80 | 81 | /* package */ void logResult(String result) { 82 | android.util.Log.i("SQLiteGlueTest", result); 83 | resultsAdapter.add(result); 84 | } 85 | 86 | /* package */ void logError(String result) { 87 | logErrorItem(result); 88 | ++errorCount; 89 | } 90 | 91 | /* package */ void logUnexpectedException(String result, java.lang.Exception ex) { 92 | android.util.Log.e("SQLiteGlueTest", "UNEXPECTED EXCEPTION IN " + result, ex); 93 | resultsAdapter.add("UNEXPECTED EXCEPTION IN " + result + " : " + ex); 94 | ++errorCount; 95 | } 96 | 97 | /** Called when the activity is first created. */ 98 | @Override 99 | public void onCreate(Bundle savedInstanceState) 100 | { 101 | super.onCreate(savedInstanceState); 102 | setContentView(R.layout.main); 103 | 104 | resultsAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1); 105 | ListView lv1 = (ListView)findViewById(R.id.results); 106 | lv1.setAdapter(resultsAdapter); 107 | 108 | // try { 109 | // runTest(); 110 | // } catch (java.sql.SQLException ex) { 111 | // android.util.Log.w("SQLiteGlueTest", "unexpected sql exception", ex); 112 | // r1.add("unexpected sql exception" + ex); 113 | // return; 114 | // } catch (java.lang.Exception ex) { 115 | // android.util.Log.w("SQLiteGlueTest", "unexpected exception", ex); 116 | // r1.add("unexpected exception: " + ex); 117 | // return; 118 | // } 119 | //} 120 | 121 | ///* package */ void runTest() { 122 | try { 123 | 124 | SQLiteConnector myconnector = new SQLiteConnector(); 125 | 126 | File dbfile = new File(getFilesDir(), "mytest.db"); 127 | 128 | SQLiteConnection mydbc = null; 129 | 130 | try { 131 | mydbc = myconnector.newSQLiteConnection(dbfile.getAbsolutePath(), 132 | SQLiteOpenFlags.READWRITE | SQLiteOpenFlags.CREATE); 133 | } catch (SQLException ex) { 134 | logUnexpectedException("DB open exception", ex); 135 | return; 136 | } 137 | 138 | SQLiteStatement mystatement; 139 | 140 | try { 141 | mystatement = mydbc.prepareStatement("SELECT UPPER('How about some ascii text?') AS caps"); 142 | } catch (SQLException ex) { 143 | logUnexpectedException("prepare statement exception", ex); 144 | mydbc.dispose(); 145 | return; 146 | } 147 | 148 | mystatement.step(); 149 | 150 | int mycolcount = mystatement.getColumnCount(); 151 | checkIntegerResult("SELECT UPPER() column count: ", mycolcount, 1); 152 | 153 | if (mycolcount > 0) { 154 | String colname = mystatement.getColumnName(0); 155 | checkStringResult("SELECT UPPER() caps column name", colname, "caps"); 156 | 157 | int coltype = mystatement.getColumnType(0); 158 | checkIntegerResult("SELECT UPPER() caps column type", coltype, 3); 159 | 160 | String coltext = mystatement.getColumnTextNativeString(0); 161 | checkStringResult("SELECT UPPER() as caps", coltext, "HOW ABOUT SOME ASCII TEXT?"); 162 | } 163 | 164 | mystatement.dispose(); 165 | 166 | // cleanup the table just in case it remains from an old run: 167 | try { 168 | mystatement = mydbc.prepareStatement("DROP TABLE IF EXISTS mytable;"); 169 | } catch (SQLException ex) { 170 | logUnexpectedException("prepare statement exception", ex); 171 | mydbc.dispose(); 172 | return; 173 | } 174 | mystatement.step(); 175 | mystatement.dispose(); 176 | 177 | try { 178 | mystatement = mydbc.prepareStatement("CREATE TABLE mytable (text1 TEXT NOT NULL, num1 INTEGER, num2 INTEGER, real1 REAL)"); 179 | } catch (SQLException ex) { 180 | logUnexpectedException("prepare statement exception", ex); 181 | mydbc.dispose(); 182 | return; 183 | } 184 | mystatement.step(); 185 | mystatement.dispose(); 186 | 187 | // test syntax error: 188 | try { 189 | mystatement = mydbc.prepareStatement("INVALID STATEMENT"); 190 | // should not get here: 191 | logError("INVALID STATEMENT should NOT have succeeded"); 192 | mystatement.dispose(); 193 | } catch (SQLException ex) { 194 | checkIntegerResult("Check SQLITE_ERROR code", ex.getErrorCode(), SQLCode.ERROR); 195 | checkStringResult("Check syntax error message", ex.getMessage(), "sqlite3_prepare_v2 failure: near \"INVALID\": syntax error"); 196 | } 197 | 198 | try { 199 | mystatement = mydbc.prepareStatement("INSERT INTO mytable (text1, num1, num2, real1) VALUES (?,?,?,?)"); 200 | } catch (SQLException ex) { 201 | // should not get here: 202 | logUnexpectedException("prepare statement exception (not expected)", ex); 203 | mydbc.dispose(); 204 | return; 205 | } 206 | mystatement.bindTextNativeString(1, "test"); 207 | mystatement.bindInteger(2, 10100); 208 | mystatement.bindLong(3, 0x1230000abcdL); 209 | mystatement.bindDouble(4, 123456.789); 210 | 211 | boolean keep_going = mystatement.step(); 212 | while (keep_going) { 213 | logError("ERROR: ROW result NOT EXPECTED for INSERT"); 214 | keep_going = mystatement.step(); 215 | } 216 | mystatement.dispose(); 217 | 218 | try { 219 | mystatement = mydbc.prepareStatement("SELECT * FROM mytable;"); 220 | } catch (SQLException ex) { 221 | logUnexpectedException("prepare statement exception", ex); 222 | mydbc.dispose(); 223 | return; 224 | } 225 | 226 | keep_going = mystatement.step(); 227 | checkBooleanResult("SELECT step result (keep_going flag)", keep_going, true); 228 | if (keep_going) { 229 | int colcount = mystatement.getColumnCount(); 230 | checkIntegerResult("SELECT column count", colcount, 4); 231 | 232 | if (colcount >= 3) { 233 | int colid = 0; 234 | String colname; 235 | int coltype; 236 | String coltext; 237 | int intval; 238 | long longval; 239 | double doubleval; 240 | 241 | colname = mystatement.getColumnName(colid); 242 | checkStringResult("SELECT column " + colid + " name", colname, "text1"); 243 | 244 | coltype = mystatement.getColumnType(colid); 245 | checkIntegerResult("SELECT column " + colid + " type", coltype, SQLColumnType.TEXT); 246 | 247 | coltext = mystatement.getColumnTextNativeString(colid); 248 | checkStringResult("SELECT column " + colid + " text string", coltext, "test"); 249 | 250 | ++colid; 251 | 252 | colname = mystatement.getColumnName(colid); 253 | checkStringResult("SELECT column " + colid + " name", colname, "num1"); 254 | 255 | coltype = mystatement.getColumnType(colid); 256 | checkIntegerResult("SELECT column " + colid + " type", coltype, SQLColumnType.INTEGER); 257 | 258 | coltext = mystatement.getColumnTextNativeString(colid); 259 | checkStringResult("SELECT column " + colid + " text string", coltext, "10100"); 260 | intval = mystatement.getColumnInteger(colid); 261 | checkIntegerResult("SELECT column " + colid + " int value", intval, 10100); 262 | longval = mystatement.getColumnLong(colid); 263 | checkLongResult("SELECT column " + colid + " long value", longval, 10100); 264 | 265 | ++colid; 266 | 267 | colname = mystatement.getColumnName(colid); 268 | checkStringResult("SELECT column " + colid + " name", colname, "num2"); 269 | 270 | coltype = mystatement.getColumnType(colid); 271 | checkIntegerResult("SELECT column " + colid + " type", coltype, SQLColumnType.INTEGER); 272 | 273 | longval = mystatement.getColumnLong(colid); 274 | checkLongResult("SELECT column " + colid + " long value", longval, 0x1230000abcdL); 275 | 276 | ++colid; 277 | 278 | colname = mystatement.getColumnName(colid); 279 | checkStringResult("SELECT column " + colid + " name", colname, "real1"); 280 | 281 | coltype = mystatement.getColumnType(colid); 282 | checkIntegerResult("SELECT column " + colid + " type", coltype, SQLColumnType.REAL); 283 | 284 | coltext = mystatement.getColumnTextNativeString(colid); 285 | checkStringResult("SELECT column " + colid + " text string", coltext, "123456.789"); 286 | doubleval = mystatement.getColumnDouble(colid); 287 | checkDoubleResult("SELECT column " + colid + " double (real) value", doubleval, 123456.789); 288 | } 289 | 290 | keep_going = mystatement.step(); 291 | } 292 | checkBooleanResult("SELECT step result (keep_going flag)", keep_going, false); 293 | 294 | // try to close the database (with the statement still open): 295 | try { 296 | mydbc.dispose(); 297 | 298 | // should not get here: 299 | logError("mydbc.dispose() should NOT have succeeded with a statement still open"); 300 | mydbc = null; 301 | } catch (SQLException ex) { 302 | checkIntegerResult("Check database close error code", ex.getErrorCode(), SQLCode.BUSY); 303 | checkStringResult("Check database close error message", ex.getMessage(), "sqlite3_close failure: unable to close due to unfinalized statements or unfinished backups"); 304 | } 305 | 306 | mystatement.dispose(); 307 | 308 | if (mydbc != null) { 309 | mydbc.dispose(); 310 | } 311 | 312 | // try to reopen database: 313 | try { 314 | mydbc = myconnector.newSQLiteConnection(dbfile.getAbsolutePath(), 315 | SQLiteOpenFlags.READWRITE | SQLiteOpenFlags.CREATE); 316 | } catch (SQLException ex) { 317 | logUnexpectedException("DB open exception", ex); 318 | return; 319 | } 320 | 321 | // Prepare to test constraint violation: 322 | try { 323 | mystatement = mydbc.prepareStatement("INSERT INTO mytable (text1, num1, num2, real1) VALUES (?,?,?,?)"); 324 | } catch (SQLException ex) { 325 | // should not get here: 326 | logUnexpectedException("prepare statement exception (not expected)", ex); 327 | mydbc.dispose(); 328 | return; 329 | } 330 | mystatement.bindNull(1); 331 | mystatement.bindInteger(2, 0); 332 | mystatement.bindInteger(3, 0); 333 | mystatement.bindInteger(4, 0); 334 | 335 | // test constraint violation: 336 | try { 337 | mystatement.step(); 338 | 339 | // should not get here: 340 | logError("constraint violation should NOT have succeeded"); 341 | } catch (SQLException ex) { 342 | checkIntegerResult("Check SQLITE_CONSTRAINT error code", ex.getErrorCode(), SQLCode.CONSTRAINT); 343 | checkStringResult("Check constraint violation message", ex.getMessage(), "sqlite3_step failure: NOT NULL constraint failed: mytable.text1"); 344 | } 345 | mystatement.dispose(); 346 | 347 | // try to cleanup the table: 348 | try { 349 | mystatement = mydbc.prepareStatement("DROP TABLE IF EXISTS mytable;"); 350 | } catch (SQLException ex) { 351 | logUnexpectedException("prepare statement exception", ex); 352 | mydbc.dispose(); 353 | return; 354 | } 355 | mystatement.step(); 356 | mystatement.dispose(); 357 | 358 | // XXX TODO: for some reason sqlite3_close as called by mydbc.dispose() does not work 359 | // since it was not possible to finalize the statement after the constraint violation. 360 | try { 361 | mydbc.dispose(); 362 | } catch (SQLException ex) { 363 | logUnexpectedException("Could not close database at the end", ex); 364 | } 365 | 366 | checkIntegerResult("TEST error count", errorCount, 0); 367 | 368 | } catch (java.lang.Exception ex) { 369 | logUnexpectedException("UNEXPECTED EXCEPTION", ex); 370 | return; 371 | } 372 | 373 | } 374 | } 375 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: javabuild 3 | 4 | javabuild: 5 | rm -rf build 6 | mkdir build 7 | javac -source 1.6 -target 1.6 -Xlint:-options -d build src/io/liteglue/*.java 8 | cd build && jar cf ../sqlite-connector.jar * 9 | 10 | clean: 11 | rm -rf build sqlite-connector.jar 12 | 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android sqlite connector 2 | 3 | Java classes with abstract interface layers to provide a simple, easy-to-use Java interface to the andriod-sqlite-native-driver library (may be adapted for other Java environments). 4 | 5 | With a simple test Android app included. 6 | 7 | by Christopher J. Brody aka Chris Brody mailto: brodybits@litehelpers.net 8 | 9 | License: UNLICENSE (public domain). 10 | 11 | ## Dependencies 12 | 13 | ### Included: 14 | 15 | - `src/io/liteglue/SQLiteNative.java` - low-level Java class from [@liteglue / Android-sqlite-native-driver](https://github.com/liteglue/Android-sqlite-native-driver) 16 | 17 | ### Not included 18 | 19 | - Native Android libraries, provided in `sqlite-native-driver-libs.zip` as built from [@liteglue / Android-sqlite-native-driver](https://github.com/liteglue/Android-sqlite-native-driver) 20 | 21 | ## TBD (TEMPORARILY BROKEN) Alternative native library builds 22 | 23 | - ~~**SQLCipher** - `sqlcipher-native-driver.jar` with native Android libraries that provide SQLCipher, as built from [@liteglue / Android-sqlcipher-native-driver](https://github.com/liteglue/Android-sqlcipher-native-driver)~~ 24 | - ~~**SQLite with ICU** - Native Android libraries with ICU built-in, as built from [@liteglue / Android-sqlite-native-driver-ICU](https://github.com/liteglue/Android-sqlite-native-driver-ICU)~~ 25 | 26 | **WARNING:** It is recommended to extract the native per-CPU Android library subdirectories from the JAR and put them in the `libs` directory of your project. Some newer Android systems do not 27 | 28 | ## Installation 29 | 30 | Include the following in your `libs` directory: 31 | - Contents of the `libs` subdirectory from `sqlite-native-driver-libs.zip`, as built from [@liteglue / Android-sqlite-native-driver](https://github.com/liteglue/Android-sqlite-native-driver) ~~-- or `sqlcipher-native-driver.jar` as built in [@liteglue / Android-sqlcipher-native-driver](https://github.com/liteglue/Android-sqlcipher-native-driver)~~ 32 | - `sqlite-connector.jar`, which is built by simply issuing the `make` command in this project 33 | 34 | ## Testing 35 | 36 | There is a simple test project in the `Android-SQLiteConnectorTest` subdirectory. To test: 37 | - Build `sqlite-connector.jar` in this project (using the `make` command) 38 | - Build the `sqlite-native-driver` native libs in [@liteglue / Android-sqlite-native-driver](https://github.com/liteglue/Android-sqlite-native-driver) 39 | - `cd Android-SQLiteConnectorTest` 40 | - Install `sqlite-connector.jar` and the contents of the `libs` subdirectory from `sqlite-native-driver-libs.zip` into the `libs` subdirectory of `Android-SQLiteConnectorTest` as described above 41 | - You *may* have to update your project using a command like: `android update project -p .` 42 | - install it on your emulator or device: `ant debug install` 43 | - run it on your emulator or device 44 | 45 | ## Sample API Usage 46 | 47 | **IMPORTANT:** Most of the methods described here will throw `java.sql.SQLException` if the sqlite library reports an error or if they detect a problem with the usage. 48 | 49 | ### First step 50 | 51 | Import `io.liteglue` package: 52 | 53 | ```Java 54 | import io.liteglue.*; 55 | ``` 56 | 57 | Get a SQLiteConnector (factory) instance: 58 | 59 | ```Java 60 | SQLiteConnector myconnector = new SQLiteConnector(); 61 | ``` 62 | 63 | ### Open a database 64 | 65 | ```Java 66 | File dbfile = new File(getFilesDir(), "my.db"); 67 | 68 | SQLiteConnection mydbc = myconnector.newSQLiteConnection(dbfile.getAbsolutePath(), 69 | SQLiteOpenFlags.READWRITE | SQLiteOpenFlags.CREATE); 70 | ``` 71 | 72 | OPTIONAL, for use with `sqlcipher-native-driver.jar` *only*: to specify the password key: 73 | 74 | ```Java 75 | mydbc.keyNativeString("your-password"); 76 | ``` 77 | 78 | ### Prepare and run a simple statement (with no parameters) 79 | 80 | ```Java 81 | SQLiteStatement mystatement = mydbc.prepareStatement("CREATE TABLE IF NOT EXISTS mytable (text1 TEXT, num1 INTEGER, num2 INTEGER, real1 REAL)"); 82 | mystatement.step(); 83 | mystatement.dispose(); 84 | ``` 85 | 86 | **IMPORTANT:** Whenever `SQLiteConnection.prepareStatement()` successfully returns a `SQLiteStatement`, it must be cleaned up using its `dispose()` method. 87 | 88 | ### Prepare and run a statement with parameter values 89 | 90 | ```Java 91 | SQLiteStatement mystatement = mydbc.prepareStatement("INSERT INTO mytable (text1, num1, num2, real1) VALUES (?,?,?,?)"); 92 | 93 | mystatement.bindTextNativeString(1, "test"); 94 | mystatement.bindInteger(2, 10100); 95 | mystatement.bindLong(3, 0x1230000abcdL); 96 | mystatement.bindDouble(4, 123456.789); 97 | 98 | mystatement.step(); 99 | mystatement.dispose(); 100 | ``` 101 | 102 | ### SELECT data and get row result(s) 103 | 104 | ```Java 105 | SQLiteStatement mystatement = mydbc.prepareStatement("SELECT * FROM mytable;"); 106 | 107 | boolean keep_going = mystatement.step(); 108 | while (keep_going) { 109 | int colcount = colcount = mystatement.getColumnCount(); 110 | android.util.Log.e("MySQLiteApp", "Row with " + colcount + " columns"); 111 | 112 | for (int i=0; i 25 | -------------------------------------------------------------------------------- /src/io/liteglue/SQLCode.java: -------------------------------------------------------------------------------- 1 | package io.liteglue; 2 | 3 | public class SQLCode { 4 | /* sqlite result codes: */ 5 | public static final int OK = 0; 6 | public static final int ERROR = 1; 7 | public static final int INTERNAL = 2; 8 | public static final int PERM = 3; 9 | public static final int ABORT = 4; 10 | public static final int BUSY = 5; 11 | /* TBD TODO: ... */ 12 | public static final int CONSTRAINT = 19; 13 | public static final int MISMATCH = 20; 14 | public static final int MISUSE = 21; 15 | /* TBD TODO: ... */ 16 | public static final int ROW = 100; 17 | public static final int DONE = 101; 18 | } 19 | -------------------------------------------------------------------------------- /src/io/liteglue/SQLColumnType.java: -------------------------------------------------------------------------------- 1 | package io.liteglue; 2 | 3 | public class SQLColumnType { 4 | public static final int INTEGER = 1; // SQLITE_INTEGER 5 | public static final int REAL = 2; // SQLITE_FLOAT 6 | public static final int TEXT = 3; 7 | public static final int BLOB = 4; 8 | public static final int NULL = 5; 9 | } 10 | -------------------------------------------------------------------------------- /src/io/liteglue/SQLDatabaseHandle.java: -------------------------------------------------------------------------------- 1 | package io.liteglue; 2 | 3 | /* package */ interface SQLDatabaseHandle { 4 | public int open(); 5 | public int close(); 6 | public int keyNativeString(String key); 7 | public boolean isOpen(); 8 | public SQLStatementHandle newStatementHandle(String sql); 9 | public long getLastInsertRowid(); 10 | public int getTotalChanges(); 11 | public String getLastErrorMessage(); 12 | } 13 | -------------------------------------------------------------------------------- /src/io/liteglue/SQLGDatabaseHandle.java: -------------------------------------------------------------------------------- 1 | package io.liteglue; 2 | 3 | /* package */ class SQLGDatabaseHandle implements SQLDatabaseHandle { 4 | public SQLGDatabaseHandle(String filename, int flags) { 5 | dbfilename = filename; 6 | openflags = flags; 7 | } 8 | 9 | @Override 10 | public int open() { 11 | /* check state (should be checked by caller): */ 12 | if (dbfilename == null || dbhandle != 0) return SQLCode.MISUSE; 13 | 14 | long handle = SQLiteNative.sqlc_db_open(dbfilename, openflags); 15 | if (handle < 0) return (int)(-handle); 16 | 17 | dbhandle = handle; 18 | return SQLCode.OK; /* 0 */ 19 | } 20 | 21 | @Override 22 | public int keyNativeString(String key) { 23 | /* check state (should be checked by caller): */ 24 | if (dbhandle == 0) return SQLCode.MISUSE; 25 | 26 | return SQLiteNative.sqlc_db_key_native_string(this.dbhandle, key); 27 | } 28 | 29 | @Override 30 | public int close() { 31 | /* check state (should be checked by caller): */ 32 | if (dbhandle == 0) return SQLCode.MISUSE; 33 | 34 | return SQLiteNative.sqlc_db_close(this.dbhandle); 35 | } 36 | 37 | @Override 38 | public boolean isOpen() { 39 | return (dbhandle != 0); 40 | } 41 | 42 | @Override 43 | public SQLStatementHandle newStatementHandle(String sql) { 44 | /* check state (should be checked by caller): */ 45 | if (dbhandle == 0) return null; 46 | 47 | return new SQLGStatementHandle(sql); 48 | } 49 | 50 | @Override 51 | public long getLastInsertRowid() { 52 | /* check state (should be checked by caller): */ 53 | if (dbhandle == 0) return -1; /* illegit value */ 54 | 55 | return SQLiteNative.sqlc_db_last_insert_rowid(dbhandle); 56 | } 57 | 58 | @Override 59 | public int getTotalChanges() { 60 | /* check state (should be checked by caller): */ 61 | if (dbhandle == 0) return -1; /* illegit value */ 62 | 63 | return SQLiteNative.sqlc_db_total_changes(dbhandle); 64 | } 65 | 66 | @Override 67 | public String getLastErrorMessage() { 68 | /* check state (should be checked by caller): */ 69 | if (dbhandle == 0) return null; /* illegit value */ 70 | return SQLiteNative.sqlc_db_errmsg_native(dbhandle); 71 | } 72 | 73 | // XXX TODO make this reusable: 74 | private class SQLGStatementHandle implements SQLStatementHandle { 75 | private SQLGStatementHandle(String sql) { 76 | this.sql = sql; 77 | } 78 | 79 | @Override 80 | public int prepare() { 81 | /* check state (should be checked by caller): */ 82 | if (sql == null || sthandle != 0) return SQLCode.MISUSE; 83 | 84 | long sh = SQLiteNative.sqlc_db_prepare_st(dbhandle, sql); 85 | if (sh < 0) return (int)(-sh); 86 | 87 | sthandle = sh; 88 | return SQLCode.OK; /* 0 */ 89 | } 90 | 91 | @Override 92 | public int bindDouble(int pos, double val) { 93 | /* check state (should be checked by caller): */ 94 | if (sthandle == 0) return SQLCode.MISUSE; 95 | 96 | return SQLiteNative.sqlc_st_bind_double(this.sthandle, pos, val); 97 | } 98 | 99 | @Override 100 | public int bindInteger(int pos, int val) { 101 | /* check state (should be checked by caller): */ 102 | if (sthandle == 0) return SQLCode.MISUSE; 103 | 104 | return SQLiteNative.sqlc_st_bind_int(this.sthandle, pos, val); 105 | } 106 | 107 | @Override 108 | public int bindLong(int pos, long val) { 109 | /* check state (should be checked by caller): */ 110 | if (sthandle == 0) return SQLCode.MISUSE; 111 | 112 | return SQLiteNative.sqlc_st_bind_long(this.sthandle, pos, val); 113 | } 114 | 115 | @Override 116 | public int bindNull(int pos) { 117 | /* check state (should be checked by caller): */ 118 | if (sthandle == 0) return SQLCode.MISUSE; 119 | 120 | return SQLiteNative.sqlc_st_bind_null(this.sthandle, pos); 121 | } 122 | 123 | @Override 124 | public int bindTextNativeString(int pos, String val) { 125 | /* check state (should be checked by caller): */ 126 | if (sthandle == 0) return SQLCode.MISUSE; 127 | 128 | return SQLiteNative.sqlc_st_bind_text_native(this.sthandle, pos, val); 129 | } 130 | 131 | @Override 132 | public int step() { 133 | /* check state (should be checked by caller): */ 134 | if (sthandle == 0) return SQLCode.MISUSE; 135 | 136 | return SQLiteNative.sqlc_st_step(this.sthandle); 137 | } 138 | 139 | @Override 140 | public int getColumnCount() { 141 | /* check state (should be checked by caller): */ 142 | if (sthandle == 0) return -1; 143 | 144 | return SQLiteNative.sqlc_st_column_count(this.sthandle); 145 | } 146 | 147 | @Override 148 | public String getColumnName(int col) { 149 | /* check state (should be checked by caller): */ 150 | if (sthandle == 0) return null; 151 | 152 | return SQLiteNative.sqlc_st_column_name(this.sthandle, col); 153 | } 154 | 155 | @Override 156 | public int getColumnType(int col) { 157 | /* check state (should be checked by caller): */ 158 | if (sthandle == 0) return -1; 159 | 160 | return SQLiteNative.sqlc_st_column_type(this.sthandle, col); 161 | } 162 | 163 | @Override 164 | public double getColumnDouble(int col) { 165 | /* check state (should be checked by caller): */ 166 | if (sthandle == 0) return -1; 167 | 168 | return SQLiteNative.sqlc_st_column_double(this.sthandle, col); 169 | } 170 | 171 | @Override 172 | public int getColumnInteger(int col) { 173 | /* check state (should be checked by caller): */ 174 | if (sthandle == 0) return -1; 175 | 176 | return SQLiteNative.sqlc_st_column_int(this.sthandle, col); 177 | } 178 | 179 | @Override 180 | public long getColumnLong(int col) { 181 | /* check state (should be checked by caller): */ 182 | if (sthandle == 0) return -1; 183 | 184 | return SQLiteNative.sqlc_st_column_long(this.sthandle, col); 185 | } 186 | 187 | @Override 188 | public String getColumnTextNativeString(int col) { 189 | /* check state (should be checked by caller): */ 190 | if (sthandle == 0) return null; 191 | 192 | return SQLiteNative.sqlc_st_column_text_native(this.sthandle, col); 193 | } 194 | 195 | @Override 196 | public int finish() { 197 | /* check state (should be checked by caller): */ 198 | if (sthandle == 0) return SQLCode.MISUSE; 199 | 200 | long mysthandle = sthandle; 201 | sql = null; 202 | sthandle = 0; 203 | 204 | return SQLiteNative.sqlc_st_finish(mysthandle); 205 | } 206 | 207 | String sql = null; 208 | private long sthandle = 0; 209 | } 210 | 211 | String dbfilename = null; 212 | int openflags = 0; 213 | private long dbhandle = 0; 214 | } 215 | -------------------------------------------------------------------------------- /src/io/liteglue/SQLStatementHandle.java: -------------------------------------------------------------------------------- 1 | package io.liteglue; 2 | 3 | /* package */ interface SQLStatementHandle { 4 | public int prepare(); 5 | public int bindDouble(int pos, double val); 6 | public int bindInteger(int pos, int val); 7 | public int bindLong(int pos, long val); 8 | public int bindNull(int pos); 9 | public int bindTextNativeString(int col, String val); 10 | public int step(); 11 | public int getColumnCount(); 12 | public String getColumnName(int col); 13 | public double getColumnDouble(int col); 14 | public int getColumnInteger(int col); 15 | public long getColumnLong(int col); 16 | public String getColumnTextNativeString(int col); 17 | public int getColumnType(int col); 18 | public int finish(); 19 | } 20 | -------------------------------------------------------------------------------- /src/io/liteglue/SQLiteConnection.java: -------------------------------------------------------------------------------- 1 | package io.liteglue; 2 | 3 | public interface SQLiteConnection { 4 | public void dispose() throws java.sql.SQLException; 5 | public void keyNativeString(String key) throws java.sql.SQLException; 6 | public SQLiteStatement prepareStatement(String sql) throws java.sql.SQLException; 7 | public long getLastInsertRowid() throws java.sql.SQLException; 8 | public int getTotalChanges() throws java.sql.SQLException; 9 | } 10 | -------------------------------------------------------------------------------- /src/io/liteglue/SQLiteConnectionFactory.java: -------------------------------------------------------------------------------- 1 | package io.liteglue; 2 | 3 | public interface SQLiteConnectionFactory { 4 | public SQLiteConnection newSQLiteConnection(String filename, int flags) throws java.sql.SQLException; 5 | } 6 | -------------------------------------------------------------------------------- /src/io/liteglue/SQLiteConnector.java: -------------------------------------------------------------------------------- 1 | package io.liteglue; 2 | 3 | public class SQLiteConnector implements SQLiteConnectionFactory { 4 | static boolean isLibLoaded = false; 5 | 6 | public SQLiteConnector() { 7 | if (!isLibLoaded) { 8 | System.loadLibrary("sqlc-native-driver"); 9 | 10 | if (SQLiteNative.sqlc_api_version_check(SQLiteNative.SQLC_API_VERSION) != SQLCode.OK) { 11 | throw new RuntimeException("native library version mismatch"); 12 | } 13 | 14 | isLibLoaded = true; 15 | } 16 | } 17 | 18 | @Override 19 | public SQLiteConnection newSQLiteConnection(String filename, int flags) throws java.sql.SQLException { 20 | return new SQLiteGlueConnection(filename, flags); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/io/liteglue/SQLiteGlueConnection.java: -------------------------------------------------------------------------------- 1 | package io.liteglue; 2 | 3 | /* package */ class SQLiteGlueConnection implements SQLiteConnection { 4 | public SQLiteGlueConnection(String filename, int flags) throws java.sql.SQLException 5 | { 6 | /* check param(s): */ 7 | if (filename == null) throw new java.sql.SQLException("null argument", "failed", SQLCode.MISUSE); 8 | 9 | SQLDatabaseHandle mydb = new SQLGDatabaseHandle(filename, flags); 10 | int rc = mydb.open(); 11 | 12 | if (rc != SQLCode.OK) throw new java.sql.SQLException("sqlite3_open_v2 failure: " + db.getLastErrorMessage(), "failure", rc); 13 | this.db = mydb; 14 | } 15 | 16 | @Override 17 | public void dispose() throws java.sql.SQLException { 18 | /* check state: */ 19 | if (db == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 20 | 21 | int rc = db.close(); 22 | if (rc != SQLCode.OK) throw new java.sql.SQLException("sqlite3_close failure: " + db.getLastErrorMessage(), "failure", rc); 23 | db = null; 24 | } 25 | 26 | @Override 27 | public void keyNativeString(String key) throws java.sql.SQLException { 28 | /* check state: */ 29 | if (db == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 30 | 31 | int rc = db.keyNativeString(key); 32 | if (rc != SQLCode.OK) throw new java.sql.SQLException("sqlite3_key failure: " + db.getLastErrorMessage(), "failure", rc); 33 | } 34 | 35 | @Override 36 | public SQLiteStatement prepareStatement(String sql) throws java.sql.SQLException { 37 | /* check state: */ 38 | if (db == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 39 | 40 | /* check param(s): */ 41 | if (sql == null) throw new java.sql.SQLException("null argument", "failed", SQLCode.MISUSE); 42 | 43 | SQLGStatement st = new SQLGStatement(sql); 44 | int rc = st.prepare(); 45 | if (rc != SQLCode.OK) { 46 | throw new java.sql.SQLException("sqlite3_prepare_v2 failure: " + db.getLastErrorMessage(), "failure", rc); 47 | } 48 | 49 | return st; 50 | } 51 | 52 | @Override 53 | public long getLastInsertRowid() throws java.sql.SQLException { 54 | /* check state: */ 55 | if (db == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 56 | 57 | return db.getLastInsertRowid(); 58 | } 59 | 60 | @Override 61 | public int getTotalChanges() throws java.sql.SQLException { 62 | /* check state: */ 63 | if (db == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 64 | 65 | return db.getTotalChanges(); 66 | } 67 | 68 | // XXX TODO make this reusable: 69 | private class SQLGStatement implements SQLiteStatement { 70 | SQLGStatement(String sql) { 71 | this.sql = sql; 72 | this.sthandle = db.newStatementHandle(sql); 73 | } 74 | 75 | int prepare() { 76 | // TBD check state here? 77 | return sthandle.prepare(); 78 | } 79 | 80 | @Override 81 | public void bindDouble(int pos, double val) throws java.sql.SQLException { 82 | /* check state: */ 83 | if (sthandle == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 84 | 85 | int rc = sthandle.bindDouble(pos, val); 86 | if (rc != SQLCode.OK) throw new java.sql.SQLException("sqlite3_bind_double failure: " + db.getLastErrorMessage(), "failure", rc); 87 | } 88 | 89 | @Override 90 | public void bindInteger(int pos, int val) throws java.sql.SQLException { 91 | /* check state: */ 92 | if (sthandle == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 93 | 94 | int rc = sthandle.bindInteger(pos, val); 95 | if (rc != SQLCode.OK) throw new java.sql.SQLException("sqlite3_bind_int failure: " + db.getLastErrorMessage(), "failure", rc); 96 | } 97 | 98 | @Override 99 | public void bindLong(int pos, long val) throws java.sql.SQLException { 100 | /* check state: */ 101 | if (sthandle == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 102 | 103 | int rc = sthandle.bindLong(pos, val); 104 | if (rc != SQLCode.OK) throw new java.sql.SQLException("sqlite3_bind_int64 (long) failure: " + db.getLastErrorMessage(), "failure", rc); 105 | } 106 | 107 | @Override 108 | public void bindNull(int pos) throws java.sql.SQLException { 109 | /* check state: */ 110 | if (sthandle == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 111 | 112 | int rc = sthandle.bindNull(pos); 113 | if (rc != SQLCode.OK) throw new java.sql.SQLException("sqlite3_bind_null failure: " + db.getLastErrorMessage(), "failure", rc); 114 | } 115 | 116 | @Override 117 | public void bindTextNativeString(int pos, String val) throws java.sql.SQLException { 118 | /* check state: */ 119 | if (sthandle == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 120 | 121 | /* check param(s): */ 122 | if (val == null) throw new java.sql.SQLException("null argument", "failed", SQLCode.MISUSE); 123 | 124 | int rc = sthandle.bindTextNativeString(pos, val); 125 | if (rc != SQLCode.OK) throw new java.sql.SQLException("sqlite3_bind_text failure: " + db.getLastErrorMessage(), "failure", rc); 126 | } 127 | 128 | @Override 129 | public boolean step() throws java.sql.SQLException { 130 | /* check state: */ 131 | if (sthandle == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 132 | 133 | int rc = sthandle.step(); 134 | if (rc != SQLCode.OK && rc != SQLCode.ROW && rc != SQLCode.DONE) { 135 | throw new java.sql.SQLException("sqlite3_step failure: " + db.getLastErrorMessage(), "failure", rc); 136 | } 137 | 138 | hasRow = (rc == SQLCode.ROW); 139 | if (hasRow) { 140 | columnCount = sthandle.getColumnCount(); 141 | } else columnCount = 0; 142 | 143 | return hasRow; 144 | } 145 | 146 | @Override 147 | public int getColumnCount() throws java.sql.SQLException { 148 | /* check state: */ 149 | if (sthandle == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 150 | if (!hasRow) throw new java.sql.SQLException("no result available", "failed", SQLCode.MISUSE); 151 | 152 | return columnCount; 153 | } 154 | 155 | @Override 156 | public String getColumnName(int col) throws java.sql.SQLException { 157 | /* check state: */ 158 | if (sthandle == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 159 | if (!hasRow) throw new java.sql.SQLException("no result available", "failed", SQLCode.MISUSE); 160 | if (col < 0 || col >= columnCount) throw new java.sql.SQLException("no result available", "failed", SQLCode.MISUSE); 161 | 162 | return sthandle.getColumnName(col); 163 | } 164 | 165 | @Override 166 | public int getColumnType(int col) throws java.sql.SQLException { 167 | /* check state: */ 168 | if (sthandle == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 169 | if (!hasRow) throw new java.sql.SQLException("no result available", "failed", SQLCode.MISUSE); 170 | if (col < 0 || col >= columnCount) throw new java.sql.SQLException("no result available", "failed", SQLCode.MISUSE); 171 | 172 | return sthandle.getColumnType(col); 173 | } 174 | 175 | @Override 176 | public double getColumnDouble(int col) throws java.sql.SQLException { 177 | /* check state: */ 178 | if (sthandle == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 179 | if (!hasRow) throw new java.sql.SQLException("no result available", "failed", SQLCode.MISUSE); 180 | if (col < 0 || col >= columnCount) throw new java.sql.SQLException("no result available", "failed", SQLCode.MISUSE); 181 | 182 | return sthandle.getColumnDouble(col); 183 | } 184 | 185 | @Override 186 | public int getColumnInteger(int col) throws java.sql.SQLException { 187 | /* check state: */ 188 | if (sthandle == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 189 | if (!hasRow) throw new java.sql.SQLException("no result available", "failed", SQLCode.MISUSE); 190 | if (col < 0 || col >= columnCount) throw new java.sql.SQLException("no result available", "failed", SQLCode.MISUSE); 191 | 192 | return sthandle.getColumnInteger(col); 193 | } 194 | 195 | @Override 196 | public long getColumnLong(int col) throws java.sql.SQLException { 197 | /* check state: */ 198 | if (sthandle == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 199 | if (!hasRow) throw new java.sql.SQLException("no result available", "failed", SQLCode.MISUSE); 200 | if (col < 0 || col >= columnCount) throw new java.sql.SQLException("no result available", "failed", SQLCode.MISUSE); 201 | 202 | return sthandle.getColumnLong(col); 203 | } 204 | 205 | @Override 206 | public String getColumnTextNativeString(int col) throws java.sql.SQLException { 207 | /* check state: */ 208 | if (sthandle == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 209 | if (!hasRow) throw new java.sql.SQLException("no result available", "failed", SQLCode.MISUSE); 210 | if (col < 0 || col >= columnCount) throw new java.sql.SQLException("no result available", "failed", SQLCode.MISUSE); 211 | 212 | return sthandle.getColumnTextNativeString(col); 213 | } 214 | 215 | @Override 216 | public void dispose() throws java.sql.SQLException { 217 | /* check state: */ 218 | if (sthandle == null) throw new java.sql.SQLException("already disposed", "failed", SQLCode.MISUSE); 219 | 220 | /* NOTE: no need to check the return code in this case. */ 221 | sthandle.finish(); 222 | sthandle = null; 223 | } 224 | 225 | private SQLStatementHandle sthandle = null; 226 | private String sql = null; 227 | private boolean hasRow = false; 228 | private int columnCount = 0; 229 | } 230 | 231 | private SQLDatabaseHandle db = null; 232 | } 233 | -------------------------------------------------------------------------------- /src/io/liteglue/SQLiteNative.java: -------------------------------------------------------------------------------- 1 | /* !---- DO NOT EDIT: This file autogenerated by com/jogamp/gluegen/JavaEmitter.java on Wed Oct 28 13:07:37 CET 2015 ----! */ 2 | 3 | package io.liteglue; 4 | 5 | //import com.jogamp.gluegen.runtime.*; 6 | //import com.jogamp.common.os.*; 7 | //import com.jogamp.common.nio.*; 8 | //import java.nio.*; 9 | 10 | public class SQLiteNative { 11 | 12 | public static final int SQLC_API_VERSION = 1; 13 | public static final int SQLC_OPEN_READONLY = 0x00001; 14 | public static final int SQLC_OPEN_READWRITE = 0x00002; 15 | public static final int SQLC_OPEN_CREATE = 0x00004; 16 | public static final int SQLC_OPEN_URI = 0x00040; 17 | public static final int SQLC_OPEN_MEMORY = 0x00080; 18 | public static final int SQLC_OPEN_NOMUTEX = 0x08000; 19 | public static final int SQLC_OPEN_FULLMUTEX = 0x10000; 20 | public static final int SQLC_OPEN_SHAREDCACHE = 0x20000; 21 | public static final int SQLC_OPEN_PRIVATECACHE = 0x40000; 22 | public static final int SQLC_RESULT_OK = 0; 23 | public static final int SQLC_RESULT_ERROR = 1; 24 | public static final int SQLC_RESULT_INTERNAL = 2; 25 | public static final int SQLC_RESULT_PERM = 3; 26 | public static final int SQLC_RESULT_ABORT = 4; 27 | public static final int SQLC_RESULT_CONSTRAINT = 19; 28 | public static final int SQLC_RESULT_MISMATCH = 20; 29 | public static final int SQLC_RESULT_MISUSE = 21; 30 | public static final int SQLC_RESULT_ROW = 100; 31 | public static final int SQLC_RESULT_DONE = 101; 32 | public static final int SQLC_INTEGER = 1; 33 | public static final int SQLC_FLOAT = 2; 34 | public static final int SQLC_TEXT = 3; 35 | public static final int SQLC_BLOB = 4; 36 | public static final int SQLC_NULL = 5; 37 | 38 | /** Interface to C language function:
sqlc_handle_t sqlc_api_db_open(int sqlc_api_version, const char * filename, int flags); */ 39 | public static native long sqlc_api_db_open(int sqlc_api_version, String filename, int flags); 40 | 41 | /** Interface to C language function:
int sqlc_api_version_check(int sqlc_api_version); */ 42 | public static native int sqlc_api_version_check(int sqlc_api_version); 43 | 44 | /** Interface to C language function:
int sqlc_db_close(sqlc_handle_t db); */ 45 | public static native int sqlc_db_close(long db); 46 | 47 | /** Interface to C language function:
int sqlc_db_errcode(sqlc_handle_t db); */ 48 | public static native int sqlc_db_errcode(long db); 49 | 50 | /** Interface to C language function:
const char * sqlc_db_errmsg_native(sqlc_handle_t db); */ 51 | public static native String sqlc_db_errmsg_native(long db); 52 | 53 | /** Interface to C language function:
int sqlc_db_key_native_string(sqlc_handle_t db, char * key_string); */ 54 | public static native int sqlc_db_key_native_string(long db, String key_string); 55 | 56 | /** Interface to C language function:
sqlc_long_t sqlc_db_last_insert_rowid(sqlc_handle_t db); */ 57 | public static native long sqlc_db_last_insert_rowid(long db); 58 | 59 | /** Interface to C language function:
sqlc_handle_t sqlc_db_open(const char * filename, int flags); */ 60 | public static native long sqlc_db_open(String filename, int flags); 61 | 62 | /** Interface to C language function:
sqlc_handle_t sqlc_db_prepare_st(sqlc_handle_t db, const char * sql); */ 63 | public static native long sqlc_db_prepare_st(long db, String sql); 64 | 65 | /** Interface to C language function:
int sqlc_db_total_changes(sqlc_handle_t db); */ 66 | public static native int sqlc_db_total_changes(long db); 67 | 68 | /** Interface to C language function:
const char * sqlc_errstr_native(int errcode); */ 69 | public static native String sqlc_errstr_native(int errcode); 70 | 71 | /** Interface to C language function:
int sqlc_st_bind_double(sqlc_handle_t st, int pos, double val); */ 72 | public static native int sqlc_st_bind_double(long st, int pos, double val); 73 | 74 | /** Interface to C language function:
int sqlc_st_bind_int(sqlc_handle_t st, int pos, int val); */ 75 | public static native int sqlc_st_bind_int(long st, int pos, int val); 76 | 77 | /** Interface to C language function:
int sqlc_st_bind_long(sqlc_handle_t st, int pos, sqlc_long_t val); */ 78 | public static native int sqlc_st_bind_long(long st, int pos, long val); 79 | 80 | /** Interface to C language function:
int sqlc_st_bind_null(sqlc_handle_t st, int pos); */ 81 | public static native int sqlc_st_bind_null(long st, int pos); 82 | 83 | /** Interface to C language function:
int sqlc_st_bind_text_native(sqlc_handle_t st, int col, const char * val); */ 84 | public static native int sqlc_st_bind_text_native(long st, int col, String val); 85 | 86 | /** Interface to C language function:
int sqlc_st_column_count(sqlc_handle_t st); */ 87 | public static native int sqlc_st_column_count(long st); 88 | 89 | /** Interface to C language function:
double sqlc_st_column_double(sqlc_handle_t st, int col); */ 90 | public static native double sqlc_st_column_double(long st, int col); 91 | 92 | /** Interface to C language function:
int sqlc_st_column_int(sqlc_handle_t st, int col); */ 93 | public static native int sqlc_st_column_int(long st, int col); 94 | 95 | /** Interface to C language function:
sqlc_long_t sqlc_st_column_long(sqlc_handle_t st, int col); */ 96 | public static native long sqlc_st_column_long(long st, int col); 97 | 98 | /** Interface to C language function:
const char * sqlc_st_column_name(sqlc_handle_t st, int col); */ 99 | public static native String sqlc_st_column_name(long st, int col); 100 | 101 | /** Interface to C language function:
const char * sqlc_st_column_text_native(sqlc_handle_t st, int col); */ 102 | public static native String sqlc_st_column_text_native(long st, int col); 103 | 104 | /** Interface to C language function:
int sqlc_st_column_type(sqlc_handle_t st, int col); */ 105 | public static native int sqlc_st_column_type(long st, int col); 106 | 107 | /** Interface to C language function:
int sqlc_st_finish(sqlc_handle_t st); */ 108 | public static native int sqlc_st_finish(long st); 109 | 110 | /** Interface to C language function:
int sqlc_st_step(sqlc_handle_t st); */ 111 | public static native int sqlc_st_step(long st); 112 | 113 | 114 | } // end of class SQLiteNative 115 | -------------------------------------------------------------------------------- /src/io/liteglue/SQLiteOpenFlags.java: -------------------------------------------------------------------------------- 1 | package io.liteglue; 2 | 3 | public class SQLiteOpenFlags { 4 | public static final int READONLY = 0x0001; 5 | public static final int READWRITE = 0x0002; 6 | public static final int CREATE = 0x0004; 7 | /* TBD TODO: ... */ 8 | } 9 | -------------------------------------------------------------------------------- /src/io/liteglue/SQLiteStatement.java: -------------------------------------------------------------------------------- 1 | package io.liteglue; 2 | 3 | public interface SQLiteStatement { 4 | public void bindDouble(int pos, double val) throws java.sql.SQLException; 5 | public void bindInteger(int pos, int val) throws java.sql.SQLException; 6 | public void bindLong(int pos, long val) throws java.sql.SQLException; 7 | public void bindNull(int pos) throws java.sql.SQLException; 8 | public void bindTextNativeString(int pos, String val) throws java.sql.SQLException; 9 | public boolean step() throws java.sql.SQLException; 10 | public int getColumnCount() throws java.sql.SQLException; 11 | public String getColumnName(int col) throws java.sql.SQLException; 12 | public double getColumnDouble(int col) throws java.sql.SQLException; 13 | public int getColumnInteger(int col) throws java.sql.SQLException; 14 | public long getColumnLong(int col) throws java.sql.SQLException; 15 | public String getColumnTextNativeString(int col) throws java.sql.SQLException; 16 | public int getColumnType(int col) throws java.sql.SQLException; 17 | public void dispose() throws java.sql.SQLException; 18 | } 19 | --------------------------------------------------------------------------------