aboutsummaryrefslogtreecommitdiff
path: root/ext/jni/src
diff options
context:
space:
mode:
Diffstat (limited to 'ext/jni/src')
-rw-r--r--ext/jni/src/c/sqlite3-jni.c87
-rw-r--r--ext/jni/src/c/sqlite3-jni.h16
-rw-r--r--ext/jni/src/org/sqlite/jni/CApi.java9
-rw-r--r--ext/jni/src/org/sqlite/jni/Tester1.java8
4 files changed, 88 insertions, 32 deletions
diff --git a/ext/jni/src/c/sqlite3-jni.c b/ext/jni/src/c/sqlite3-jni.c
index 1465c9e65..919f48bc1 100644
--- a/ext/jni/src/c/sqlite3-jni.c
+++ b/ext/jni/src/c/sqlite3-jni.c
@@ -909,7 +909,7 @@ static S3JniEnv * S3JniEnv__get(JNIEnv * const env){
**
** For purposes of certain hand-crafted JNI function bindings, we
** need a way of reporting errors which is consistent with the rest of
-** the C API, as opposed to throwing JS exceptions. To that end, this
+** the C API, as opposed to throwing Java exceptions. To that end, this
** internal-use-only function is a thin proxy around
** sqlite3ErrorWithMessage(). The intent is that it only be used from
** JNI bindings such as sqlite3_prepare_v2/v3(), and definitely not
@@ -2057,6 +2057,13 @@ static void udf_xInverse(sqlite3_context* cx, int argc,
JniDecl(jlong,JniNameSuffix)(JniArgsEnvClass, jlong jpDb){ \
return (jlong)CName(S3JniLongPtr_sqlite3(jpDb)); \
}
+/** Create a trivial JNI wrapper for (jstring CName(sqlite3*,int)). */
+#define WRAP_STR_DB_INT(JniNameSuffix,CName) \
+ JniDecl(jstring,JniNameSuffix)(JniArgsEnvClass, jlong jpDb, jint ndx){ \
+ return s3jni_utf8_to_jstring( \
+ CName(S3JniLongPtr_sqlite3(jpDb), (int)ndx), \
+ -1); \
+ }
/** Create a trivial JNI wrapper for (int CName(sqlite3_value*)). */
#define WRAP_INT_SVALUE(JniNameSuffix,CName) \
JniDecl(jint,JniNameSuffix)(JniArgsEnvClass, jlong jpSValue){ \
@@ -2082,6 +2089,7 @@ WRAP_STR_STMT_INT(1column_1origin_1name, sqlite3_column_origin_name)
WRAP_STR_STMT_INT(1column_1table_1name, sqlite3_column_table_name)
WRAP_INT_STMT_INT(1column_1type, sqlite3_column_type)
WRAP_INT_STMT(1data_1count, sqlite3_data_count)
+WRAP_STR_DB_INT(1db_1name, sqlite3_db_name)
WRAP_INT_DB(1error_1offset, sqlite3_error_offset)
WRAP_INT_DB(1extended_1errcode, sqlite3_extended_errcode)
WRAP_BOOL_DB(1get_1autocommit, sqlite3_get_autocommit)
@@ -2125,6 +2133,7 @@ WRAP_INT_SVALUE(1value_1type, sqlite3_value_type)
#undef WRAP_INT_VOID
#undef WRAP_MUTF8_VOID
#undef WRAP_STR_STMT_INT
+#undef WRAP_STR_DB_INT
S3JniApi(sqlite3_aggregate_context(),jlong,1aggregate_1context)(
JniArgsEnvClass, jobject jCx, jboolean initialize
@@ -2866,7 +2875,7 @@ static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv * const env,
S3JniDb_mutex_enter;
ps = S3JniDb_from_jlong(jpDb);
if( !ps ){
- s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0);
+ s3jni_db_error(ps->pDb, SQLITE_MISUSE, 0);
S3JniDb_mutex_leave;
return 0;
}
@@ -3252,36 +3261,6 @@ error_cleanup:
return (jint)rc;
}
-S3JniApi(sqlite3_db_filename(),jstring,1db_1filename)(
- JniArgsEnvClass, jobject jDb, jstring jDbName
-){
- S3JniDb * const ps = S3JniDb_from_java(jDb);
- char *zDbName;
- jstring jRv = 0;
- int nStr = 0;
-
- if( !ps || !jDbName ){
- return 0;
- }
- zDbName = s3jni_jstring_to_utf8( jDbName, &nStr);
- if( zDbName ){
- char const * zRv = sqlite3_db_filename(ps->pDb, zDbName);
- sqlite3_free(zDbName);
- if( zRv ){
- jRv = s3jni_utf8_to_jstring( zRv, -1);
- }
- }
- return jRv;
-}
-
-S3JniApi(sqlite3_db_handle(),jobject,1db_1handle)(
- JniArgsEnvClass, jobject jpStmt
-){
- sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt);
- sqlite3 * const pDb = pStmt ? sqlite3_db_handle(pStmt) : 0;
- S3JniDb * const ps = pDb ? S3JniDb_from_c(pDb) : 0;
- return ps ? ps->jDb : 0;
-}
S3JniApi(sqlite3_db_config() /*for MAINDBNAME*/,
jint,1db_1config__Lorg_sqlite_jni_sqlite3_2ILjava_lang_String_2
@@ -3309,6 +3288,7 @@ S3JniApi(sqlite3_db_config() /*for MAINDBNAME*/,
}
S3JniDb_mutex_leave;
break;
+ case 0:
default:
rc = SQLITE_MISUSE;
}
@@ -3352,6 +3332,7 @@ S3JniApi(
}
break;
}
+ case 0:
default:
rc = SQLITE_MISUSE;
}
@@ -3372,6 +3353,48 @@ JniDecl(jint,1db_1config__Lorg_sqlite_jni_sqlite3_2IILorg_sqlite_jni_OutputPoint
);
}
+S3JniApi(sqlite3_db_filename(),jstring,1db_1filename)(
+ JniArgsEnvClass, jobject jDb, jstring jDbName
+){
+ S3JniDb * const ps = S3JniDb_from_java(jDb);
+ char *zDbName;
+ jstring jRv = 0;
+ int nStr = 0;
+
+ if( !ps || !jDbName ){
+ return 0;
+ }
+ zDbName = s3jni_jstring_to_utf8( jDbName, &nStr);
+ if( zDbName ){
+ char const * zRv = sqlite3_db_filename(ps->pDb, zDbName);
+ sqlite3_free(zDbName);
+ if( zRv ){
+ jRv = s3jni_utf8_to_jstring( zRv, -1);
+ }
+ }
+ return jRv;
+}
+
+S3JniApi(sqlite3_db_handle(),jobject,1db_1handle)(
+ JniArgsEnvClass, jobject jpStmt
+){
+ sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt);
+ sqlite3 * const pDb = pStmt ? sqlite3_db_handle(pStmt) : 0;
+ S3JniDb * const ps = pDb ? S3JniDb_from_c(pDb) : 0;
+ return ps ? ps->jDb : 0;
+}
+
+S3JniApi(sqlite3_db_readonly(),jint,1db_1readonly)(
+ JniArgsEnvClass, jobject jDb, jstring jDbName
+){
+ int rc = 0;
+ S3JniDb * const ps = S3JniDb_from_java(jDb);
+ char *zDbName = jDbName ? s3jni_jstring_to_utf8( jDbName, 0 ) : 0;
+ rc = sqlite3_db_readonly(ps ? ps->pDb : 0, zDbName);
+ sqlite3_free(zDbName);
+ return (jint)rc;
+}
+
S3JniApi(sqlite3_db_release_memory(),int,1db_1release_1memory)(
JniArgsEnvClass, jobject jDb
){
diff --git a/ext/jni/src/c/sqlite3-jni.h b/ext/jni/src/c/sqlite3-jni.h
index 6d38adf06..4195ad6db 100644
--- a/ext/jni/src/c/sqlite3-jni.h
+++ b/ext/jni/src/c/sqlite3-jni.h
@@ -1309,6 +1309,14 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_CApi_sqlite3_1db_1config__Lorg_sqlite
/*
* Class: org_sqlite_jni_CApi
+ * Method: sqlite3_db_name
+ * Signature: (JI)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_org_sqlite_jni_CApi_sqlite3_1db_1name
+ (JNIEnv *, jclass, jlong, jint);
+
+/*
+ * Class: org_sqlite_jni_CApi
* Method: sqlite3_db_filename
* Signature: (Lorg/sqlite/jni/sqlite3;Ljava/lang/String;)Ljava/lang/String;
*/
@@ -1325,6 +1333,14 @@ JNIEXPORT jobject JNICALL Java_org_sqlite_jni_CApi_sqlite3_1db_1handle
/*
* Class: org_sqlite_jni_CApi
+ * Method: sqlite3_db_readonly
+ * Signature: (Lorg/sqlite/jni/sqlite3;Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_sqlite_jni_CApi_sqlite3_1db_1readonly
+ (JNIEnv *, jclass, jobject, jstring);
+
+/*
+ * Class: org_sqlite_jni_CApi
* Method: sqlite3_db_release_memory
* Signature: (Lorg/sqlite/jni/sqlite3;)I
*/
diff --git a/ext/jni/src/org/sqlite/jni/CApi.java b/ext/jni/src/org/sqlite/jni/CApi.java
index 8149d624a..90e833979 100644
--- a/ext/jni/src/org/sqlite/jni/CApi.java
+++ b/ext/jni/src/org/sqlite/jni/CApi.java
@@ -811,12 +811,21 @@ final class CApi {
@NotNull sqlite3 db, int op, @NotNull String val
);
+ private static native String sqlite3_db_name(@NotNull long ptrToDb, int ndx);
+
+ public static String sqlite3_db_name(@NotNull sqlite3 db, int ndx){
+ return null==db ? null : sqlite3_db_name(db.getNativePointer(), ndx);
+ }
+
+
public static native String sqlite3_db_filename(
@NotNull sqlite3 db, @NotNull String dbName
);
public static native sqlite3 sqlite3_db_handle(@NotNull sqlite3_stmt stmt);
+ public static native int sqlite3_db_readonly(@NotNull sqlite3 db, String dbName);
+
public static native int sqlite3_db_release_memory(sqlite3 db);
public static native int sqlite3_db_status(
diff --git a/ext/jni/src/org/sqlite/jni/Tester1.java b/ext/jni/src/org/sqlite/jni/Tester1.java
index 0ff1c98db..4d9061538 100644
--- a/ext/jni/src/org/sqlite/jni/Tester1.java
+++ b/ext/jni/src/org/sqlite/jni/Tester1.java
@@ -255,6 +255,11 @@ public class Tester1 implements Runnable {
and this call is here to ensure that the build fails
if it cannot find both names. */;
+ affirm( 0==sqlite3_db_readonly(db,"main") );
+ affirm( 0==sqlite3_db_readonly(db,null) );
+ affirm( 0>sqlite3_db_readonly(db,"nope") );
+ affirm( 0>sqlite3_db_readonly(null,null) );
+
// These interrupt checks are only to make sure that the JNI binding
// has the proper exported symbol names. They don't actually test
// anything useful.
@@ -1028,8 +1033,11 @@ public class Tester1 implements Runnable {
affirm( 0 == rc );
affirm( outDb.get() != db1 );
final sqlite3 db2 = outDb.get();
+
+ affirm( "main".equals( sqlite3_db_name(db1, 0) ) );
rc = sqlite3_db_config(db1, SQLITE_DBCONFIG_MAINDBNAME, "foo");
affirm( sqlite3_db_filename(db1, "foo").endsWith(dbName) );
+ affirm( "foo".equals( sqlite3_db_name(db1, 0) ) );
final ValueHolder<Integer> xBusyCalled = new ValueHolder<>(0);
BusyHandlerCallback handler = new BusyHandlerCallback(){