Correct JNI layer's misuse of an sqlite3-internal error-reporting API (no mutex held). Style cleanups. Eliminate lookups of per-thread state by approximately 85% across the test suite.
FossilOrigin-Name: 1f46ba8d3bc61af771c1e33d09ad25f0da4fc4f915f7a9f6223ebfd99526d81d
This commit is contained in:
parent
bfdc7ab5a7
commit
e7a4685837
@ -303,7 +303,7 @@ static const struct {
|
||||
/** Create a trivial JNI wrapper for (jstring CName(sqlite3_stmt*,int)). */
|
||||
#define WRAP_STR_STMT_INT(JniNameSuffix,CName) \
|
||||
JDECL(jstring,JniNameSuffix)(JENV_CSELF, jobject pStmt, jint ndx){ \
|
||||
return s3jni_utf8_to_jstring(S3JniGlobal_env_cache(env), \
|
||||
return s3jni_utf8_to_jstring(env, \
|
||||
CName(PtrGet_sqlite3_stmt(pStmt), (int)ndx), \
|
||||
-1); \
|
||||
}
|
||||
@ -324,10 +324,10 @@ static const struct {
|
||||
}
|
||||
|
||||
/* Helpers for jstring and jbyteArray. */
|
||||
#define JSTR_TOC(ARG) (*env)->GetStringUTFChars(env, ARG, NULL)
|
||||
#define JSTR_RELEASE(ARG,VAR) if(VAR) (*env)->ReleaseStringUTFChars(env, ARG, VAR)
|
||||
#define JBA_TOC(ARG) (*env)->GetByteArrayElements(env,ARG, NULL)
|
||||
#define JBA_RELEASE(ARG,VAR) if(VAR) (*env)->ReleaseByteArrayElements(env, ARG, VAR, JNI_ABORT)
|
||||
#define s3jni_jstring_to_mutf8(ARG) (*env)->GetStringUTFChars(env, ARG, NULL)
|
||||
#define s3jni_mutf8_release(ARG,VAR) if(VAR) (*env)->ReleaseStringUTFChars(env, ARG, VAR)
|
||||
#define s3jni_jbytearray_bytes(ARG) (*env)->GetByteArrayElements(env,ARG, NULL)
|
||||
#define s3jni_jbytearray_release(ARG,VAR) if(VAR) (*env)->ReleaseByteArrayElements(env, ARG, VAR, JNI_ABORT)
|
||||
|
||||
enum {
|
||||
/*
|
||||
@ -423,9 +423,7 @@ struct S3JniEnv {
|
||||
**
|
||||
** - In the JNI side of sqlite3_open(), allocate the Java side of
|
||||
** that connection and set pdbOpening to point to that
|
||||
** object. Note that it's per-thread, and we remain in that
|
||||
** thread until after the auto-extensions are run, so we don't
|
||||
** need to mutex-lock this.
|
||||
** object.
|
||||
**
|
||||
** - Call sqlite3_open(), which triggers the auto-extension
|
||||
** handler. That handler uses pdbOpening to connect the native
|
||||
@ -631,7 +629,7 @@ static void s3jni_incr( volatile unsigned int * const p ){
|
||||
SJG.perDb.locker = 0; \
|
||||
sqlite3_mutex_leave( SJG.perDb.mutex )
|
||||
|
||||
#define OOM_CHECK(VAR) if(!(VAR)) s3jni_oom(env)
|
||||
#define s3jni_oom_check(VAR) if(!(VAR)) s3jni_oom(env)
|
||||
static inline void s3jni_oom(JNIEnv * const env){
|
||||
(*env)->FatalError(env, "Out of memory.") /* does not return */;
|
||||
}
|
||||
@ -706,7 +704,9 @@ static int s3jni_db_error(sqlite3* const db, int err_code,
|
||||
sqlite3Error(db, err_code);
|
||||
}else{
|
||||
const int nMsg = sqlite3Strlen30(zMsg);
|
||||
sqlite3_mutex_enter(sqlite3_db_mutex(db));
|
||||
sqlite3ErrorWithMsg(db, err_code, "%.*s", nMsg, zMsg);
|
||||
sqlite3_mutex_leave(sqlite3_db_mutex(db));
|
||||
}
|
||||
}
|
||||
return err_code;
|
||||
@ -753,10 +753,9 @@ static JNIEnv * s3jni_get_env(void){
|
||||
** standard UTF-8 to a Java string, but JNI offers only algorithms for
|
||||
** working with MUTF-8, not UTF-8.
|
||||
*/
|
||||
static jstring s3jni_utf8_to_jstring(S3JniEnv * const jc,
|
||||
static jstring s3jni_utf8_to_jstring(JNIEnv * const env,
|
||||
const char * const z, int n){
|
||||
jstring rv = NULL;
|
||||
LocalJniGetEnv;
|
||||
if( 0==n || (n<0 && z && !z[0]) ){
|
||||
/* Fast-track the empty-string case via the MUTF-8 API. We could
|
||||
hypothetically do this for any strings where n<4 and z is
|
||||
@ -790,9 +789,8 @@ static jstring s3jni_utf8_to_jstring(S3JniEnv * const jc,
|
||||
** The returned memory is allocated from sqlite3_malloc() and
|
||||
** ownership is transferred to the caller.
|
||||
*/
|
||||
static char * s3jni_jstring_to_utf8(S3JniEnv * const jc,
|
||||
static char * s3jni_jstring_to_utf8(JNIEnv * const env,
|
||||
jstring jstr, int *nLen){
|
||||
LocalJniGetEnv;
|
||||
jbyteArray jba;
|
||||
jsize nBa;
|
||||
char *rv;
|
||||
@ -844,7 +842,6 @@ static jstring s3jni_text16_to_jstring(JNIEnv * const env, const void * const p,
|
||||
** System.out.println(e.getMessage()); // Hi
|
||||
*/
|
||||
static char * s3jni_exception_error_msg(JNIEnv * const env, jthrowable jx ){
|
||||
S3JniEnv * const jc = S3JniGlobal_env_cache(env);
|
||||
jmethodID mid;
|
||||
jstring msg;
|
||||
char * zMsg;
|
||||
@ -862,7 +859,7 @@ static char * s3jni_exception_error_msg(JNIEnv * const env, jthrowable jx ){
|
||||
EXCEPTION_CLEAR;
|
||||
return 0;
|
||||
}
|
||||
zMsg = s3jni_jstring_to_utf8(jc, msg, 0);
|
||||
zMsg = s3jni_jstring_to_utf8(env, msg, 0);
|
||||
UNREF_L(msg);
|
||||
return zMsg;
|
||||
}
|
||||
@ -1484,7 +1481,7 @@ static jobject new_NativePointerHolder_object(JNIEnv * const env, S3NphRef const
|
||||
}
|
||||
rv = (*env)->NewObject(env, pNC->klazz, pNC->midCtor);
|
||||
EXCEPTION_IS_FATAL("No-arg constructor threw.");
|
||||
OOM_CHECK(rv);
|
||||
s3jni_oom_check(rv);
|
||||
if(rv) NativePointerHolder_set(env, rv, pNative, pRef);
|
||||
return rv;
|
||||
}
|
||||
@ -1807,6 +1804,16 @@ WRAP_INT_SVALUE(1value_1numeric_1type, sqlite3_value_numeric_type)
|
||||
WRAP_INT_SVALUE(1value_1subtype, sqlite3_value_subtype)
|
||||
WRAP_INT_SVALUE(1value_1type, sqlite3_value_type)
|
||||
|
||||
#undef WRAP_INT64_DB
|
||||
#undef WRAP_INT_DB
|
||||
#undef WRAP_INT_INT
|
||||
#undef WRAP_INT_STMT
|
||||
#undef WRAP_INT_STMT_INT
|
||||
#undef WRAP_INT_SVALUE
|
||||
#undef WRAP_INT_VOID
|
||||
#undef WRAP_MUTF8_VOID
|
||||
#undef WRAP_STR_STMT_INT
|
||||
|
||||
/* Central auto-extension handler. */
|
||||
static int s3jni_run_java_auto_extensions(sqlite3 *pDb, const char **pzErr,
|
||||
const struct sqlite3_api_routines *ignored){
|
||||
@ -1915,10 +1922,10 @@ JDECL(jint,1auto_1extension)(JENV_CSELF, jobject jAutoExt){
|
||||
|
||||
JDECL(jint,1bind_1blob)(JENV_CSELF, jobject jpStmt,
|
||||
jint ndx, jbyteArray baData, jint nMax){
|
||||
jbyte * const pBuf = baData ? JBA_TOC(baData) : 0;
|
||||
jbyte * const pBuf = baData ? s3jni_jbytearray_bytes(baData) : 0;
|
||||
int const rc = sqlite3_bind_blob(PtrGet_sqlite3_stmt(jpStmt), (int)ndx,
|
||||
pBuf, (int)nMax, SQLITE_TRANSIENT);
|
||||
JBA_RELEASE(baData,pBuf);
|
||||
s3jni_jbytearray_release(baData,pBuf);
|
||||
return (jint)rc;
|
||||
}
|
||||
|
||||
@ -1944,31 +1951,31 @@ JDECL(jint,1bind_1null)(JENV_CSELF, jobject jpStmt,
|
||||
|
||||
JDECL(jint,1bind_1parameter_1index)(JENV_CSELF, jobject jpStmt, jbyteArray jName){
|
||||
int rc = 0;
|
||||
jbyte * const pBuf = JBA_TOC(jName);
|
||||
jbyte * const pBuf = s3jni_jbytearray_bytes(jName);
|
||||
if(pBuf){
|
||||
rc = sqlite3_bind_parameter_index(PtrGet_sqlite3_stmt(jpStmt),
|
||||
(const char *)pBuf);
|
||||
JBA_RELEASE(jName, pBuf);
|
||||
s3jni_jbytearray_release(jName, pBuf);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
JDECL(jint,1bind_1text)(JENV_CSELF, jobject jpStmt,
|
||||
jint ndx, jbyteArray baData, jint nMax){
|
||||
jbyte * const pBuf = baData ? JBA_TOC(baData) : 0;
|
||||
jbyte * const pBuf = baData ? s3jni_jbytearray_bytes(baData) : 0;
|
||||
int const rc = sqlite3_bind_text(PtrGet_sqlite3_stmt(jpStmt), (int)ndx,
|
||||
(const char *)pBuf,
|
||||
(int)nMax, SQLITE_TRANSIENT);
|
||||
JBA_RELEASE(baData, pBuf);
|
||||
s3jni_jbytearray_release(baData, pBuf);
|
||||
return (jint)rc;
|
||||
}
|
||||
|
||||
JDECL(jint,1bind_1text16)(JENV_CSELF, jobject jpStmt,
|
||||
jint ndx, jbyteArray baData, jint nMax){
|
||||
jbyte * const pBuf = baData ? JBA_TOC(baData) : 0;
|
||||
jbyte * const pBuf = baData ? s3jni_jbytearray_bytes(baData) : 0;
|
||||
int const rc = sqlite3_bind_text16(PtrGet_sqlite3_stmt(jpStmt), (int)ndx,
|
||||
pBuf, (int)nMax, SQLITE_TRANSIENT);
|
||||
JBA_RELEASE(baData, pBuf);
|
||||
s3jni_jbytearray_release(baData, pBuf);
|
||||
return (jint)rc;
|
||||
}
|
||||
|
||||
@ -2295,10 +2302,10 @@ JDECL(jstring,1compileoption_1get)(JENV_CSELF, jint n){
|
||||
}
|
||||
|
||||
JDECL(jboolean,1compileoption_1used)(JENV_CSELF, jstring name){
|
||||
const char *zUtf8 = JSTR_TOC(name);
|
||||
const char *zUtf8 = s3jni_jstring_to_mutf8(name);
|
||||
const jboolean rc =
|
||||
0==sqlite3_compileoption_used(zUtf8) ? JNI_FALSE : JNI_TRUE;
|
||||
JSTR_RELEASE(name, zUtf8);
|
||||
s3jni_mutf8_release(name, zUtf8);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -2323,7 +2330,6 @@ static void s3jni_config_sqllog(void *ignored, sqlite3 *pDb, const char *z, int
|
||||
jobject jArg0 = 0;
|
||||
jstring jArg1 = 0;
|
||||
LocalJniGetEnv;
|
||||
S3JniEnv * const jc = S3JniGlobal_env_cache(env);
|
||||
S3JniDb * const ps = S3JniDb_for_db(env, 0, pDb);
|
||||
S3JniHook * const hook = &SJG.hooks.sqllog;
|
||||
|
||||
@ -2332,7 +2338,7 @@ static void s3jni_config_sqllog(void *ignored, sqlite3 *pDb, const char *z, int
|
||||
switch(op){
|
||||
case 0: /* db opened */
|
||||
case 1: /* SQL executed */
|
||||
jArg1 = s3jni_utf8_to_jstring(jc, z, -1);
|
||||
jArg1 = s3jni_utf8_to_jstring(env, z, -1);
|
||||
break;
|
||||
case 2: /* db closed */
|
||||
break;
|
||||
@ -2420,11 +2426,11 @@ JDECL(jint,1create_1collation)(JENV_CSELF, jobject jDb,
|
||||
return s3jni_db_error(ps->pDb, SQLITE_ERROR,
|
||||
"Could not get xCompare() method for object.");
|
||||
}
|
||||
zName = JSTR_TOC(name);
|
||||
zName = s3jni_jstring_to_mutf8(name);
|
||||
rc = sqlite3_create_collation_v2(ps->pDb, zName, (int)eTextRep,
|
||||
ps, CollationState_xCompare,
|
||||
CollationState_xDestroy);
|
||||
JSTR_RELEASE(name, zName);
|
||||
s3jni_mutf8_release(name, zName);
|
||||
if( 0==rc ){
|
||||
pHook->jObj = REF_G(oCollation);
|
||||
}else{
|
||||
@ -2438,7 +2444,7 @@ JDECL(jint,1create_1function)(JENV_CSELF, jobject jDb, jstring jFuncName,
|
||||
S3JniUdf * s = 0;
|
||||
int rc;
|
||||
sqlite3 * const pDb = PtrGet_sqlite3(jDb);
|
||||
const char * zFuncName = 0;
|
||||
char * zFuncName = 0;
|
||||
|
||||
if( !encodingTypeIsValid(eTextRep) ){
|
||||
return s3jni_db_error(pDb, SQLITE_FORMAT,
|
||||
@ -2452,7 +2458,7 @@ JDECL(jint,1create_1function)(JENV_CSELF, jobject jDb, jstring jFuncName,
|
||||
S3JniUdf_free(s);
|
||||
goto error_cleanup;
|
||||
}
|
||||
zFuncName = JSTR_TOC(jFuncName);
|
||||
zFuncName = s3jni_jstring_to_utf8(env,jFuncName,0);
|
||||
if(!zFuncName){
|
||||
rc = SQLITE_NOMEM;
|
||||
S3JniUdf_free(s);
|
||||
@ -2476,14 +2482,8 @@ JDECL(jint,1create_1function)(JENV_CSELF, jobject jDb, jstring jFuncName,
|
||||
rc = sqlite3_create_function_v2(pDb, zFuncName, nArg, eTextRep, s,
|
||||
xFunc, xStep, xFinal, S3JniUdf_finalizer);
|
||||
}
|
||||
if( 0==rc ){
|
||||
s->zFuncName = sqlite3_mprintf("%s", zFuncName)
|
||||
/* OOM here is non-fatal. Ignore it. Handling it would require
|
||||
** re-calling the appropriate create_function() func with 0
|
||||
** for all xAbc args so that s would be finalized. */;
|
||||
}
|
||||
error_cleanup:
|
||||
JSTR_RELEASE(jFuncName, zFuncName);
|
||||
sqlite3_free(zFuncName);
|
||||
/* on sqlite3_create_function() error, s will be destroyed via
|
||||
** create_function(), so we're not leaking s. */
|
||||
return (jint)rc;
|
||||
@ -2499,7 +2499,7 @@ JDECL(int,1db_1config__Lorg_sqlite_jni_sqlite3_2ILjava_lang_String_2)(
|
||||
|
||||
switch( (ps && jStr) ? op : 0 ){
|
||||
case SQLITE_DBCONFIG_MAINDBNAME:
|
||||
zStr = s3jni_jstring_to_utf8(S3JniGlobal_env_cache(env), jStr, 0);
|
||||
zStr = s3jni_jstring_to_utf8(env, jStr, 0);
|
||||
if( zStr ){
|
||||
rc = sqlite3_db_config(ps->pDb, (int)op, zStr);
|
||||
if( rc ){
|
||||
@ -2577,7 +2577,6 @@ JDECL(jint,1db_1config__Lorg_sqlite_jni_sqlite3_2IILorg_sqlite_jni_OutputPointer
|
||||
|
||||
JDECL(jstring,1db_1filename)(JENV_CSELF, jobject jDb, jstring jDbName){
|
||||
S3JniDb * const ps = S3JniDb_for_db(env, jDb, 0);
|
||||
S3JniEnv * const jc = ps ? S3JniGlobal_env_cache(env) : 0;
|
||||
char *zDbName;
|
||||
jstring jRv = 0;
|
||||
int nStr = 0;
|
||||
@ -2585,12 +2584,12 @@ JDECL(jstring,1db_1filename)(JENV_CSELF, jobject jDb, jstring jDbName){
|
||||
if( !ps || !jDbName ){
|
||||
return 0;
|
||||
}
|
||||
zDbName = s3jni_jstring_to_utf8(jc, jDbName, &nStr);
|
||||
zDbName = s3jni_jstring_to_utf8(env, jDbName, &nStr);
|
||||
if( zDbName ){
|
||||
char const * zRv = sqlite3_db_filename(ps->pDb, zDbName);
|
||||
sqlite3_free(zDbName);
|
||||
if( zRv ){
|
||||
jRv = s3jni_utf8_to_jstring(jc, zRv, -1);
|
||||
jRv = s3jni_utf8_to_jstring(env, zRv, -1);
|
||||
}
|
||||
}
|
||||
return jRv;
|
||||
@ -2617,8 +2616,7 @@ JDECL(jint,1errcode)(JENV_CSELF, jobject jpDb){
|
||||
|
||||
JDECL(jstring,1errmsg)(JENV_CSELF, jobject jpDb){
|
||||
sqlite3 * const pDb = PtrGet_sqlite3(jpDb);
|
||||
S3JniEnv * const jc = pDb ? S3JniGlobal_env_cache(env) : 0;
|
||||
return jc ? s3jni_utf8_to_jstring(jc, sqlite3_errmsg(pDb), -1) : 0;
|
||||
return pDb ? s3jni_utf8_to_jstring(env, sqlite3_errmsg(pDb), -1) : 0;
|
||||
}
|
||||
|
||||
JDECL(jstring,1errstr)(JENV_CSELF, jint rcCode){
|
||||
@ -2631,11 +2629,10 @@ JDECL(jstring,1expanded_1sql)(JENV_CSELF, jobject jpStmt){
|
||||
sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt);
|
||||
jstring rv = 0;
|
||||
if( pStmt ){
|
||||
S3JniEnv * const jc = S3JniGlobal_env_cache(env);
|
||||
char * zSql = sqlite3_expanded_sql(pStmt);
|
||||
OOM_CHECK(zSql);
|
||||
s3jni_oom_check(zSql);
|
||||
if( zSql ){
|
||||
rv = s3jni_utf8_to_jstring(jc, zSql, -1);
|
||||
rv = s3jni_utf8_to_jstring(env, zSql, -1);
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
}
|
||||
@ -2692,7 +2689,7 @@ static int s3jni_open_pre(JNIEnv * const env, S3JniEnv **jc,
|
||||
rc = SQLITE_NOMEM;
|
||||
goto end;
|
||||
}
|
||||
*zDbName = jDbName ? s3jni_jstring_to_utf8(*jc, jDbName, 0) : 0;
|
||||
*zDbName = jDbName ? s3jni_jstring_to_utf8(env, jDbName, 0) : 0;
|
||||
if(jDbName && !*zDbName){
|
||||
rc = SQLITE_NOMEM;
|
||||
goto end;
|
||||
@ -2771,7 +2768,7 @@ JDECL(jint,1open_1v2)(JENV_CSELF, jstring strName,
|
||||
char *zVfs = 0;
|
||||
int rc = s3jni_open_pre(env, &jc, strName, &zName, &ps);
|
||||
if( 0==rc && strVfs ){
|
||||
zVfs = s3jni_jstring_to_utf8(jc, strVfs, 0);
|
||||
zVfs = s3jni_jstring_to_utf8(env, strVfs, 0);
|
||||
if( !zVfs ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
@ -2794,7 +2791,7 @@ static jint sqlite3_jni_prepare_v123(int prepVersion, JNIEnv * const env, jclass
|
||||
sqlite3_stmt * pStmt = 0;
|
||||
jobject jStmt = 0;
|
||||
const char * zTail = 0;
|
||||
jbyte * const pBuf = JBA_TOC(baSql);
|
||||
jbyte * const pBuf = s3jni_jbytearray_bytes(baSql);
|
||||
int rc = SQLITE_ERROR;
|
||||
assert(prepVersion==1 || prepVersion==2 || prepVersion==3);
|
||||
if( !pBuf ){
|
||||
@ -2821,7 +2818,7 @@ static jint sqlite3_jni_prepare_v123(int prepVersion, JNIEnv * const env, jclass
|
||||
assert(0 && "Invalid prepare() version");
|
||||
}
|
||||
end:
|
||||
JBA_RELEASE(baSql,pBuf);
|
||||
s3jni_jbytearray_release(baSql,pBuf);
|
||||
if( 0==rc ){
|
||||
if( 0!=outTail ){
|
||||
/* Noting that pBuf is deallocated now but its address is all we need for
|
||||
@ -2879,7 +2876,6 @@ static void s3jni_updatepre_hook_impl(void * pState, sqlite3 *pDb, int opId,
|
||||
sqlite3_int64 iKey1, sqlite3_int64 iKey2){
|
||||
S3JniDb * const ps = pState;
|
||||
LocalJniGetEnv;
|
||||
S3JniEnv * const jc = S3JniGlobal_env_cache(env);
|
||||
jstring jDbName;
|
||||
jstring jTable;
|
||||
S3JniHook * pHook;
|
||||
@ -2894,8 +2890,8 @@ static void s3jni_updatepre_hook_impl(void * pState, sqlite3 *pDb, int opId,
|
||||
: &ps->hooks.update;
|
||||
|
||||
assert( pHook );
|
||||
jDbName = s3jni_utf8_to_jstring(jc, zDb, -1);
|
||||
jTable = jDbName ? s3jni_utf8_to_jstring(jc, zTable, -1) : 0;
|
||||
jDbName = s3jni_utf8_to_jstring(env, zDb, -1);
|
||||
jTable = jDbName ? s3jni_utf8_to_jstring(env, zTable, -1) : 0;
|
||||
IFTHREW {
|
||||
EXCEPTION_CLEAR;
|
||||
s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0);
|
||||
@ -3131,7 +3127,7 @@ static void result_blob_text(int asBlob, int as64,
|
||||
JNIEnv * const env, sqlite3_context *pCx,
|
||||
jbyteArray jBa, jlong nMax){
|
||||
if(jBa){
|
||||
jbyte * const pBuf = JBA_TOC(jBa);
|
||||
jbyte * const pBuf = s3jni_jbytearray_bytes(jBa);
|
||||
jsize nBa = (*env)->GetArrayLength(env, jBa);
|
||||
if( nMax>=0 && nBa>(jsize)nMax ){
|
||||
nBa = (jsize)nMax;
|
||||
@ -3196,7 +3192,7 @@ static void result_blob_text(int asBlob, int as64,
|
||||
break;
|
||||
}
|
||||
}
|
||||
JBA_RELEASE(jBa, pBuf);
|
||||
s3jni_jbytearray_release(jBa, pBuf);
|
||||
}
|
||||
}else{
|
||||
sqlite3_result_null(pCx);
|
||||
@ -3219,7 +3215,7 @@ JDECL(void,1result_1error)(JENV_CSELF, jobject jpCx, jbyteArray baMsg,
|
||||
int eTextRep){
|
||||
const char * zUnspecified = "Unspecified error.";
|
||||
jsize const baLen = (*env)->GetArrayLength(env, baMsg);
|
||||
jbyte * const pjBuf = baMsg ? JBA_TOC(baMsg) : NULL;
|
||||
jbyte * const pjBuf = baMsg ? s3jni_jbytearray_bytes(baMsg) : NULL;
|
||||
switch(pjBuf ? eTextRep : SQLITE_UTF8){
|
||||
case SQLITE_UTF8: {
|
||||
const char *zMsg = pjBuf ? (const char *)pjBuf : zUnspecified;
|
||||
@ -3238,7 +3234,7 @@ JDECL(void,1result_1error)(JENV_CSELF, jobject jpCx, jbyteArray baMsg,
|
||||
"to sqlite3_result_error().", -1);
|
||||
break;
|
||||
}
|
||||
JBA_RELEASE(baMsg,pjBuf);
|
||||
s3jni_jbytearray_release(baMsg,pjBuf);
|
||||
}
|
||||
|
||||
JDECL(void,1result_1error_1code)(JENV_CSELF, jobject jpCx, jint v){
|
||||
@ -3313,12 +3309,11 @@ static int s3jni_xAuth(void* pState, int op,const char*z0, const char*z1,
|
||||
const char*z2,const char*z3){
|
||||
S3JniDb * const ps = pState;
|
||||
LocalJniGetEnv;
|
||||
S3JniEnv * const jc = S3JniGlobal_env_cache(env);
|
||||
S3JniHook const * const pHook = &ps->hooks.auth;
|
||||
jstring const s0 = z0 ? s3jni_utf8_to_jstring(jc, z0, -1) : 0;
|
||||
jstring const s1 = z1 ? s3jni_utf8_to_jstring(jc, z1, -1) : 0;
|
||||
jstring const s2 = z2 ? s3jni_utf8_to_jstring(jc, z2, -1) : 0;
|
||||
jstring const s3 = z3 ? s3jni_utf8_to_jstring(jc, z3, -1) : 0;
|
||||
jstring const s0 = z0 ? s3jni_utf8_to_jstring(env, z0, -1) : 0;
|
||||
jstring const s1 = z1 ? s3jni_utf8_to_jstring(env, z1, -1) : 0;
|
||||
jstring const s2 = z2 ? s3jni_utf8_to_jstring(env, z2, -1) : 0;
|
||||
jstring const s3 = z3 ? s3jni_utf8_to_jstring(env, z3, -1) : 0;
|
||||
int rc;
|
||||
|
||||
assert( pHook->jObj );
|
||||
@ -3405,18 +3400,18 @@ JDECL(jint,1status64)(JENV_CSELF, jint op, jobject jOutCurrent, jobject jOutHigh
|
||||
static int s3jni_strlike_glob(int isLike, JNIEnv *const env,
|
||||
jbyteArray baG, jbyteArray baT, jint escLike){
|
||||
int rc = 0;
|
||||
jbyte * const pG = JBA_TOC(baG);
|
||||
jbyte * const pT = pG ? JBA_TOC(baT) : 0;
|
||||
jbyte * const pG = s3jni_jbytearray_bytes(baG);
|
||||
jbyte * const pT = pG ? s3jni_jbytearray_bytes(baT) : 0;
|
||||
|
||||
OOM_CHECK(pT);
|
||||
s3jni_oom_check(pT);
|
||||
/* Note that we're relying on the byte arrays having been
|
||||
NUL-terminated on the Java side. */
|
||||
rc = isLike
|
||||
? sqlite3_strlike((const char *)pG, (const char *)pT,
|
||||
(unsigned int)escLike)
|
||||
: sqlite3_strglob((const char *)pG, (const char *)pT);
|
||||
JBA_RELEASE(baG, pG);
|
||||
JBA_RELEASE(baT, pT);
|
||||
s3jni_jbytearray_release(baG, pG);
|
||||
s3jni_jbytearray_release(baT, pT);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -3445,10 +3440,9 @@ JDECL(jstring,1sql)(JENV_CSELF, jobject jpStmt){
|
||||
jstring rv = 0;
|
||||
if( pStmt ){
|
||||
const char * zSql = 0;
|
||||
S3JniEnv * const jc = S3JniGlobal_env_cache(env);
|
||||
zSql = sqlite3_sql(pStmt);
|
||||
rv = s3jni_utf8_to_jstring(jc, zSql, -1);
|
||||
OOM_CHECK(rv);
|
||||
rv = s3jni_utf8_to_jstring(env, zSql, -1);
|
||||
s3jni_oom_check(rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@ -3468,12 +3462,11 @@ static int s3jni_trace_impl(unsigned traceflag, void *pC, void *pP, void *pX){
|
||||
jobject jX = NULL /* the tracer's X arg */;
|
||||
jobject jP = NULL /* the tracer's P arg */;
|
||||
jobject jPUnref = NULL /* potentially a local ref to jP */;
|
||||
S3JniEnv * const jc = S3JniGlobal_env_cache(env);
|
||||
int rc;
|
||||
int createStmt = 0;
|
||||
switch(traceflag){
|
||||
case SQLITE_TRACE_STMT:
|
||||
jX = s3jni_utf8_to_jstring(jc, (const char *)pX, -1);
|
||||
jX = s3jni_utf8_to_jstring(env, (const char *)pX, -1);
|
||||
if(!jX) return SQLITE_NOMEM;
|
||||
/*MARKER(("TRACE_STMT@%p SQL=%p / %s\n", pP, jX, (const char *)pX));*/
|
||||
createStmt = 1;
|
||||
@ -3858,8 +3851,7 @@ JDECLFtsXA(jint,xColumnText)(JENV_OSELF,jobject jCtx, jint iCol,
|
||||
int rc = fext->xColumnText(PtrGet_Fts5Context(jCtx), (int)iCol,
|
||||
&pz, &pn);
|
||||
if( 0==rc ){
|
||||
S3JniEnv * const jc = S3JniGlobal_env_cache(env);
|
||||
jstring jstr = pz ? s3jni_utf8_to_jstring(jc, pz, pn) : 0;
|
||||
jstring jstr = pz ? s3jni_utf8_to_jstring(env, pz, pn) : 0;
|
||||
if( pz ){
|
||||
if( jstr ){
|
||||
OutputPointer_set_String(env, jOut, jstr);
|
||||
@ -3929,7 +3921,7 @@ JDECLFtsApi(jint,xCreateFunction)(JENV_OSELF, jstring jName,
|
||||
Fts5JniAux * pAux;
|
||||
|
||||
assert(pApi);
|
||||
zName = JSTR_TOC(jName);
|
||||
zName = s3jni_jstring_to_mutf8(jName);
|
||||
if(!zName) return SQLITE_NOMEM;
|
||||
pAux = Fts5JniAux_alloc(env, jFunc);
|
||||
if( pAux ){
|
||||
@ -3944,7 +3936,7 @@ JDECLFtsApi(jint,xCreateFunction)(JENV_OSELF, jstring jName,
|
||||
pAux->zFuncName = sqlite3_mprintf("%s", zName)
|
||||
/* OOM here is non-fatal. Ignore it. */;
|
||||
}
|
||||
JSTR_RELEASE(jName, zName);
|
||||
s3jni_mutf8_release(jName, zName);
|
||||
return (jint)rc;
|
||||
}
|
||||
|
||||
@ -4222,7 +4214,7 @@ static jint s3jni_fts5_xTokenize(JENV_OSELF, S3NphRef const *pRef,
|
||||
S3JniEnv * const jc = S3JniGlobal_env_cache(env);
|
||||
struct s3jni_xQueryPhraseState s;
|
||||
int rc = 0;
|
||||
jbyte * const pText = jCallback ? JBA_TOC(jbaText) : 0;
|
||||
jbyte * const pText = jCallback ? s3jni_jbytearray_bytes(jbaText) : 0;
|
||||
jsize nText = pText ? (*env)->GetArrayLength(env, jbaText) : 0;
|
||||
jclass const klazz = jCallback ? (*env)->GetObjectClass(env, jCallback) : NULL;
|
||||
|
||||
@ -4237,7 +4229,7 @@ static jint s3jni_fts5_xTokenize(JENV_OSELF, S3NphRef const *pRef,
|
||||
IFTHREW {
|
||||
EXCEPTION_REPORT;
|
||||
EXCEPTION_CLEAR;
|
||||
JBA_RELEASE(jbaText, pText);
|
||||
s3jni_jbytearray_release(jbaText, pText);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
s.tok.jba = REF_L(jbaText);
|
||||
@ -4259,7 +4251,7 @@ static jint s3jni_fts5_xTokenize(JENV_OSELF, S3NphRef const *pRef,
|
||||
assert( s.tok.zPrev );
|
||||
UNREF_L(s.tok.jba);
|
||||
}
|
||||
JBA_RELEASE(jbaText, pText);
|
||||
s3jni_jbytearray_release(jbaText, pText);
|
||||
return (jint)rc;
|
||||
}
|
||||
|
||||
@ -4457,15 +4449,15 @@ Java_org_sqlite_jni_tester_SQLTester_strglob(
|
||||
JENV_CSELF, jbyteArray baG, jbyteArray baT
|
||||
){
|
||||
int rc = 0;
|
||||
jbyte * const pG = JBA_TOC(baG);
|
||||
jbyte * const pT = pG ? JBA_TOC(baT) : 0;
|
||||
jbyte * const pG = s3jni_jbytearray_bytes(baG);
|
||||
jbyte * const pT = pG ? s3jni_jbytearray_bytes(baT) : 0;
|
||||
|
||||
OOM_CHECK(pT);
|
||||
s3jni_oom_check(pT);
|
||||
/* Note that we're relying on the byte arrays having been
|
||||
NUL-terminated on the Java side. */
|
||||
rc = !SQLTester_strnotglob((const char *)pG, (const char *)pT);
|
||||
JBA_RELEASE(baG, pG);
|
||||
JBA_RELEASE(baT, pT);
|
||||
s3jni_jbytearray_release(baG, pG);
|
||||
s3jni_jbytearray_release(baT, pT);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -4610,15 +4602,15 @@ Java_org_sqlite_jni_SQLite3Jni_init(JENV_CSELF){
|
||||
#endif
|
||||
|
||||
SJG.envCache.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
||||
OOM_CHECK( SJG.envCache.mutex );
|
||||
s3jni_oom_check( SJG.envCache.mutex );
|
||||
SJG.perDb.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
||||
OOM_CHECK( SJG.perDb.mutex );
|
||||
s3jni_oom_check( SJG.perDb.mutex );
|
||||
SJG.autoExt.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
||||
OOM_CHECK( SJG.autoExt.mutex );
|
||||
s3jni_oom_check( SJG.autoExt.mutex );
|
||||
|
||||
#if S3JNI_METRICS_MUTEX
|
||||
SJG.metrics.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
||||
OOM_CHECK( SJG.metrics.mutex );
|
||||
s3jni_oom_check( SJG.metrics.mutex );
|
||||
#endif
|
||||
|
||||
sqlite3_shutdown()
|
||||
|
@ -680,7 +680,8 @@ public class Tester1 implements Runnable {
|
||||
sqlite3_finalize(stmt);
|
||||
affirm( 0 != rc );
|
||||
affirm( sqlite3_errmsg(db).indexOf("an xFunc") > 0 );
|
||||
|
||||
rc = sqlite3_create_function(db, "mysca", 1, -1, funcSc);
|
||||
affirm( SQLITE_FORMAT==rc, "invalid encoding value." );
|
||||
sqlite3_close_v2(db);
|
||||
}
|
||||
|
||||
|
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Add\smore\sJNI\sdocs,\stests,\sand\sa\shandful\sof\sJava-side\soverloads.
|
||||
D 2023-08-24T11:57:51.863
|
||||
C Correct\sJNI\slayer's\smisuse\sof\san\ssqlite3-internal\serror-reporting\sAPI\s(no\smutex\sheld).\sStyle\scleanups.\sEliminate\slookups\sof\sper-thread\sstate\sby\sapproximately\s85%\sacross\sthe\stest\ssuite.
|
||||
D 2023-08-24T14:31:36.028
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -235,7 +235,7 @@ F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a3
|
||||
F ext/jni/GNUmakefile 0a823c56f081294e7797dae303380ac989ebaa801bba970968342b7358f07aed
|
||||
F ext/jni/README.md 64bf1da0d562d051207ca1c5cfa52e8b7a69120533cc034a3da7670ef920cbef
|
||||
F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
|
||||
F ext/jni/src/c/sqlite3-jni.c e1e3cde4d08925282b5bc949f9ed8f613a6a2c6f60d0c697e79d59fb49f9fe4b
|
||||
F ext/jni/src/c/sqlite3-jni.c d7d6d420f2a13d55828cee19ba17a37c4244532dafbc5822582d7fd52ae2aaf0
|
||||
F ext/jni/src/c/sqlite3-jni.h cc24d6742b29a52338ffd3b47caf923facb8ae77f9c2fc9c2de82673bf339ea2
|
||||
F ext/jni/src/org/sqlite/jni/Authorizer.java 1308988f7f40579ea0e4deeaec3c6be971630566bd021c31367fe3f5140db892
|
||||
F ext/jni/src/org/sqlite/jni/AutoExtension.java bcc1849b2fccbe5e2d7ac9e9ac7f8d05a6d7088a8fedbaad90e39569745a61e6
|
||||
@ -258,7 +258,7 @@ F ext/jni/src/org/sqlite/jni/RollbackHook.java b04c8abcc6ade44a8a57129e33765793f
|
||||
F ext/jni/src/org/sqlite/jni/SQLFunction.java f697cf2a81c4119f2baf0682af689686f0466f1dd83dba00885f5603e693fe16
|
||||
F ext/jni/src/org/sqlite/jni/SQLLog.java c60610b35208416940822e834d61f08fbbe5d6e06b374b541b49e41fd56c9798
|
||||
F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 956063c854c4f662183c41c65d0ab48b5e2127824b8053eeb05b9fc40f0d09e3
|
||||
F ext/jni/src/org/sqlite/jni/Tester1.java b5a4bb2a969df053d5c138887f04039a79b36170372a2efdf5dfbd6ac90db4c9
|
||||
F ext/jni/src/org/sqlite/jni/Tester1.java 9b6ec0ae299a56822e82e7dc2cf7ef1031ae87bcb595065bef84b7edac7114f5
|
||||
F ext/jni/src/org/sqlite/jni/TesterFts5.java 6f135c60e24c89e8eecb9fe61dde0f3bb2906de668ca6c9186bcf34bdaf94629
|
||||
F ext/jni/src/org/sqlite/jni/Tracer.java a5cece9f947b0af27669b8baec300b6dd7ff859c3e6a6e4a1bd8b50f9714775d
|
||||
F ext/jni/src/org/sqlite/jni/UpdateHook.java e58645a1727f8a9bbe72dc072ec5b40d9f9362cb0aa24acfe93f49ff56a9016d
|
||||
@ -2094,8 +2094,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P a9e6d5158b8a4a6b8554a5f8f0a35785ee450d42ea877275dc27085e89716c18
|
||||
R cb79df5ad40cc86377d98f5a1329b589
|
||||
P d19a431facbde6a6b960664674753ee85d2c051a76109ce7db0b079c65fbdea0
|
||||
R a3460d6a3bf6ffdc6985db3e6bc764fc
|
||||
U stephan
|
||||
Z 39e8fbdcbc2ebaa58ed84b96f0374c06
|
||||
Z 4bd864e1476ea863a52783451fa010a4
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
d19a431facbde6a6b960664674753ee85d2c051a76109ce7db0b079c65fbdea0
|
||||
1f46ba8d3bc61af771c1e33d09ad25f0da4fc4f915f7a9f6223ebfd99526d81d
|
Loading…
Reference in New Issue
Block a user