diff --git a/java/io/liteglue/SQLiteNative.java b/java/io/liteglue/SQLiteNative.java index 2a179f9..0f164f2 100644 --- a/java/io/liteglue/SQLiteNative.java +++ b/java/io/liteglue/SQLiteNative.java @@ -57,10 +57,10 @@ public class SQLiteNative { public static native long sqlc_db_last_insert_rowid(long db); /** Interface to C language function:
sqlc_handle_t sqlc_db_open(const char * filename, int flags); */ - public static native long sqlc_db_open(String filename, int flags); + public static native SQLiteResponse sqlc_db_open(String filename, int flags); /** Interface to C language function:
sqlc_handle_t sqlc_db_prepare_st(sqlc_handle_t db, const char * sql); */ - public static native long sqlc_db_prepare_st(long db, String sql); + public static native SQLiteResponse sqlc_db_prepare_st(long db, String sql); /** Interface to C language function:
int sqlc_db_total_changes(sqlc_handle_t db); */ public static native int sqlc_db_total_changes(long db); diff --git a/java/io/liteglue/SQLiteResponse.java b/java/io/liteglue/SQLiteResponse.java new file mode 100644 index 0000000..cc6b9d4 --- /dev/null +++ b/java/io/liteglue/SQLiteResponse.java @@ -0,0 +1,20 @@ +package io.liteglue; + +public class SQLiteResponse { + private int result; + private long handle; + + public SQLiteResponse(int result, long handle) { + this.result = result; + this.handle = handle; + } + + public int getResult() { + return this.result; + } + + public long getHandle() { + return this.handle; + } + +} \ No newline at end of file diff --git a/jni/Application.mk b/jni/Application.mk index 64623e9..8d0d6ea 100644 --- a/jni/Application.mk +++ b/jni/Application.mk @@ -1,5 +1,5 @@ #APP_ABI := all -APP_ABI := armeabi armeabi-v7a x86 x86_64 arm64-v8a +APP_ABI := armeabi-v7a x86 x86_64 arm64-v8a # For future consideration (needs testing): #APP_ABI += mips mips64 - +APP_PLATFORM := android-23 diff --git a/native/SQLiteNative_JNI.c b/native/SQLiteNative_JNI.c index a266ffe..32f6ca0 100644 --- a/native/SQLiteNative_JNI.c +++ b/native/SQLiteNative_JNI.c @@ -8,13 +8,13 @@ /* Java->C glue code: * Java package: io.liteglue.SQLiteNative - * Java method: long sqlc_api_db_open(int sqlc_api_version, java.lang.String filename, int flags) - * C function: sqlc_handle_t sqlc_api_db_open(int sqlc_api_version, const char * filename, int flags); + * Java method: SQLiteResponse sqlc_api_db_open(int sqlc_api_version, java.lang.String filename, int flags) + * C function: sqlc_handle_ct* sqlc_api_db_open(int sqlc_api_version, const char * filename, int flags); */ -JNIEXPORT jlong JNICALL +JNIEXPORT jobject JNICALL Java_io_liteglue_SQLiteNative_sqlc_1api_1db_1open__ILjava_lang_String_2I(JNIEnv *env, jclass _unused, jint sqlc_api_version, jstring filename, jint flags) { const char* _strchars_filename = NULL; - sqlc_handle_t _res; + sqlc_handle_ct* _res; if ( NULL != filename ) { _strchars_filename = (*env)->GetStringUTFChars(env, filename, (jboolean*)NULL); if ( NULL == _strchars_filename ) { @@ -27,7 +27,14 @@ Java_io_liteglue_SQLiteNative_sqlc_1api_1db_1open__ILjava_lang_String_2I(JNIEnv if ( NULL != filename ) { (*env)->ReleaseStringUTFChars(env, filename, _strchars_filename); } - return _res; + + jclass class = (*env)->FindClass(env,"io/liteglue/SQLiteResponse"); + jmethodID constructor = (*env)->GetMethodID(env, class, "", "(IJ)V"); + jobject instance = (*env)->NewObject(env, class, constructor, _res->result, _res->handle); + + free(_res); + + return instance; } @@ -124,13 +131,13 @@ Java_io_liteglue_SQLiteNative_sqlc_1db_1last_1insert_1rowid__J(JNIEnv *env, jcla /* Java->C glue code: * Java package: io.liteglue.SQLiteNative - * Java method: long sqlc_db_open(java.lang.String filename, int flags) - * C function: sqlc_handle_t sqlc_db_open(const char * filename, int flags); + * Java method: SQLiteResponse sqlc_db_open(java.lang.String filename, int flags) + * C function: sqlc_handle_ct* sqlc_db_open(const char * filename, int flags); */ -JNIEXPORT jlong JNICALL +JNIEXPORT jobject JNICALL Java_io_liteglue_SQLiteNative_sqlc_1db_1open__Ljava_lang_String_2I(JNIEnv *env, jclass _unused, jstring filename, jint flags) { const char* _strchars_filename = NULL; - sqlc_handle_t _res; + sqlc_handle_ct* _res; if ( NULL != filename ) { _strchars_filename = (*env)->GetStringUTFChars(env, filename, (jboolean*)NULL); if ( NULL == _strchars_filename ) { @@ -143,19 +150,26 @@ Java_io_liteglue_SQLiteNative_sqlc_1db_1open__Ljava_lang_String_2I(JNIEnv *env, if ( NULL != filename ) { (*env)->ReleaseStringUTFChars(env, filename, _strchars_filename); } - return _res; + + jclass class = (*env)->FindClass(env,"io/liteglue/SQLiteResponse"); + jmethodID constructor = (*env)->GetMethodID(env, class, "", "(IJ)V"); + jobject instance = (*env)->NewObject(env, class, constructor, _res->result, _res->handle); + + free(_res); + + return instance; } /* Java->C glue code: * Java package: io.liteglue.SQLiteNative - * Java method: long sqlc_db_prepare_st(long db, java.lang.String sql) - * C function: sqlc_handle_t sqlc_db_prepare_st(sqlc_handle_t db, const char * sql); + * Java method: SQLiteResponse sqlc_db_prepare_st(long db, java.lang.String sql) + * C function: sqlc_handle_ct* sqlc_db_prepare_st(sqlc_handle_t db, const char * sql); */ -JNIEXPORT jlong JNICALL +JNIEXPORT jobject JNICALL Java_io_liteglue_SQLiteNative_sqlc_1db_1prepare_1st__JLjava_lang_String_2(JNIEnv *env, jclass _unused, jlong db, jstring sql) { const char* _strchars_sql = NULL; - sqlc_handle_t _res; + sqlc_handle_ct* _res; if ( NULL != sql ) { _strchars_sql = (*env)->GetStringUTFChars(env, sql, (jboolean*)NULL); if ( NULL == _strchars_sql ) { @@ -168,7 +182,14 @@ Java_io_liteglue_SQLiteNative_sqlc_1db_1prepare_1st__JLjava_lang_String_2(JNIEnv if ( NULL != sql ) { (*env)->ReleaseStringUTFChars(env, sql, _strchars_sql); } - return _res; + + jclass class = (*env)->FindClass(env,"io/liteglue/SQLiteResponse"); + jmethodID constructor = (*env)->GetMethodID(env, class, "", "(IJ)V"); + jobject instance = (*env)->NewObject(env, class, constructor, _res->result, _res->handle); + + free(_res); + + return instance; } diff --git a/native/sqlc.c b/native/sqlc.c index aa5099a..d8b65a3 100644 --- a/native/sqlc.c +++ b/native/sqlc.c @@ -6,8 +6,6 @@ #include "sqlite3.h" -#define BASE_HANDLE_OFFSET 0x100000000LL - #ifdef SQLC_KEEP_ANDROID_LOG // ref: http://www.ibm.com/developerworks/opensource/tutorials/os-androidndk/index.html #define MYLOG(...) __android_log_print(ANDROID_LOG_VERBOSE, "sqlc", __VA_ARGS__) @@ -15,23 +13,29 @@ #define MYLOG(...) ; #endif -#define HANDLE_FROM_VP(p) ( BASE_HANDLE_OFFSET + ( (unsigned char *)(p) - (unsigned char *)NULL ) ) -#define HANDLE_TO_VP(h) (void *)( (unsigned char *)NULL + (ptrdiff_t)((h) - BASE_HANDLE_OFFSET) ) +#define HANDLE_FROM_VP(p) (( (unsigned char *)(p) - (unsigned char *)NULL ) ) +#define HANDLE_TO_VP(h) (void *)( (unsigned char *)NULL + (ptrdiff_t)((h)) ) int sqlc_api_version_check(int sqlc_api_version) { return (sqlc_api_version != SQLC_API_VERSION) ? SQLC_RESULT_ERROR : SQLC_RESULT_OK; } -sqlc_handle_t sqlc_api_db_open(int sqlc_api_version, const char *filename, int flags) +sqlc_handle_ct* sqlc_api_db_open(int sqlc_api_version, const char *filename, int flags) { - if (sqlc_api_version != SQLC_API_VERSION) return SQLC_RESULT_ERROR; + if (sqlc_api_version != SQLC_API_VERSION) { + sqlc_handle_ct* resp = malloc(sizeof(sqlc_handle_ct)); + resp->result = SQLC_RESULT_ERROR; + resp->handle = 0; + return resp; + } return sqlc_db_open(filename, flags); } -sqlc_handle_t sqlc_db_open(const char *filename, int flags) +sqlc_handle_ct* sqlc_db_open(const char *filename, int flags) { + sqlc_handle_ct *resp; sqlite3 *d1; int r1; @@ -41,11 +45,16 @@ sqlc_handle_t sqlc_db_open(const char *filename, int flags) MYLOG("db_open %s result %d ptr %p", filename, r1, d1); - return (r1 == 0) ? HANDLE_FROM_VP(d1) : -r1; + resp = malloc (sizeof (sqlc_handle_ct)); + resp->result = (r1 == 0) ? 0 : -r1; + resp->handle = HANDLE_FROM_VP(d1); + + return resp; } -sqlc_handle_t sqlc_db_prepare_st(sqlc_handle_t db, const char *sql) +sqlc_handle_ct* sqlc_db_prepare_st(sqlc_handle_t db, const char *sql) { + sqlc_handle_ct *resp; sqlite3 *mydb = HANDLE_TO_VP(db); sqlite3_stmt *s; int rv; @@ -54,7 +63,11 @@ sqlc_handle_t sqlc_db_prepare_st(sqlc_handle_t db, const char *sql) rv = sqlite3_prepare_v2(mydb, sql, -1, &s, NULL); - return (rv == 0) ? HANDLE_FROM_VP(s) : -rv; + resp = malloc (sizeof (sqlc_handle_ct)); + resp->result = (rv == 0) ? 0 : -rv; + resp->handle = HANDLE_FROM_VP(s); + + return resp; } /** FUTURE TBD (???) for sqlcipher: diff --git a/native/sqlc.h b/native/sqlc.h index 2cf47ce..9f58136 100644 --- a/native/sqlc.h +++ b/native/sqlc.h @@ -39,14 +39,20 @@ typedef long long sqlc_long_t; /* negative number indicates an error: */ typedef sqlc_long_t sqlc_handle_t; +#pragma once +typedef struct { + int result; + sqlc_handle_t handle; +}sqlc_handle_ct; + /* RECOMMENDED (alt 1): Use this call at startup to check Java/native library match * (returns SQLC_RESULT_OK [0] if OK, other value in case of mismatch) */ int sqlc_api_version_check(int sqlc_api_version); /* RECOMMENDED (alt 2): Check Java/native library match and open database handle */ -sqlc_handle_t sqlc_api_db_open(int sqlc_api_version, const char *filename, int flags); +sqlc_handle_ct* sqlc_api_db_open(int sqlc_api_version, const char *filename, int flags); -sqlc_handle_t sqlc_db_open(const char *filename, int flags); +sqlc_handle_ct* sqlc_db_open(const char *filename, int flags); // FUTURE TBD (???): //sqlc_handle_t sqlc_db_open_vfs(const char *filename, int flags, const char *vfs); @@ -59,7 +65,7 @@ int sqlc_db_key_native_string(sqlc_handle_t db, char *key_string); // FUTURE TBD (???) for sqlcipher: // int sqlc_db_rekey_string_native(sqlc_handle_t db, char *key_string); -sqlc_handle_t sqlc_db_prepare_st(sqlc_handle_t db, const char *sql); +sqlc_handle_ct* sqlc_db_prepare_st(sqlc_handle_t db, const char *sql); sqlc_long_t sqlc_db_last_insert_rowid(sqlc_handle_t db); int sqlc_db_total_changes(sqlc_handle_t db); diff --git a/sqlite-amalgamation b/sqlite-amalgamation index 295f7c8..ae04d99 160000 --- a/sqlite-amalgamation +++ b/sqlite-amalgamation @@ -1 +1 @@ -Subproject commit 295f7c89b3cdd1575ca8298317535a39a4877264 +Subproject commit ae04d995a77a2682f965731f9abf15a8c089a4d4