mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Internal JNI refacoring to support the pending sqlite3_collation_needed() callback. Correct a bug in the linked-list handling of PerDbStateJni which triggered an assert().
FossilOrigin-Name: 7ac6614e69b03304d09745619ed83f12c7eb775aaf4a636a79289b01642ddd14
This commit is contained in:
@ -366,7 +366,8 @@ typedef struct PerDbStateJni PerDbStateJni;
|
||||
struct PerDbStateJni {
|
||||
JNIEnv *env;
|
||||
sqlite3 * pDb;
|
||||
jobject jDb /* the object which was passed to sqlite3_open(_v2)() */;
|
||||
jobject jDb /* a global ref of the object which was passed to
|
||||
sqlite3_open(_v2)() */;
|
||||
PerDbStateJni * pNext;
|
||||
PerDbStateJni * pPrev;
|
||||
JniHookState trace;
|
||||
@ -644,22 +645,29 @@ static void * getNativePointer(JNIEnv * env, jobject pObj, const char *zClassNam
|
||||
/**
|
||||
Extracts the new PerDbStateJni instance from the free-list, or
|
||||
allocates one if needed, associats it with pDb, and returns.
|
||||
Returns NULL on OOM.
|
||||
Returns NULL on OOM. pDb MUST be associated with jDb via
|
||||
setNativePointer().
|
||||
*/
|
||||
static PerDbStateJni * PerDbStateJni_alloc(JNIEnv *env, sqlite3 *pDb){
|
||||
static PerDbStateJni * PerDbStateJni_alloc(JNIEnv *env, sqlite3 *pDb, jobject jDb){
|
||||
PerDbStateJni * rv;
|
||||
assert( pDb );
|
||||
if(S3Global.perDb.aFree){
|
||||
rv = S3Global.perDb.aFree;
|
||||
//MARKER(("state@%p for db allocating for db@%p from free-list\n", rv, pDb));
|
||||
//MARKER(("%p->pPrev@%p, pNext@%p\n", rv, rv->pPrev, rv->pNext));
|
||||
S3Global.perDb.aFree = rv->pNext;
|
||||
assert(rv->pNext != rv);
|
||||
assert(rv->pPrev != rv);
|
||||
assert(rv->pPrev ? (rv->pPrev!=rv->pNext) : 1);
|
||||
if(rv->pNext){
|
||||
assert(rv->pNext->pPrev == rv);
|
||||
assert(rv->pNext == rv->pNext->pPrev);
|
||||
assert(rv->pPrev ? (rv->pNext == rv->pPrev->pNext) : 1);
|
||||
rv->pNext->pPrev = 0;
|
||||
rv->pNext = 0;
|
||||
}
|
||||
}else{
|
||||
rv = s3jni_malloc(env, sizeof(PerDbStateJni));
|
||||
//MARKER(("state@%p for db allocating for db@%p from heap\n", rv, pDb));
|
||||
if(rv){
|
||||
memset(rv, 0, sizeof(PerDbStateJni));
|
||||
}
|
||||
@ -671,6 +679,7 @@ static PerDbStateJni * PerDbStateJni_alloc(JNIEnv *env, sqlite3 *pDb){
|
||||
assert(!rv->pNext->pPrev);
|
||||
rv->pNext->pPrev = rv;
|
||||
}
|
||||
rv->jDb = REF_G(jDb);
|
||||
rv->pDb = pDb;
|
||||
rv->env = env;
|
||||
}
|
||||
@ -685,6 +694,10 @@ static void PerDbStateJni_set_aside(PerDbStateJni * const s){
|
||||
if(s){
|
||||
JNIEnv * const env = s->env;
|
||||
assert(s->pDb && "Else this object is already in the free-list.");
|
||||
//MARKER(("state@%p for db@%p setting aside\n", s, s->pDb));
|
||||
assert(s->pPrev != s);
|
||||
assert(s->pNext != s);
|
||||
assert(s->pPrev ? (s->pPrev!=s->pNext) : 1);
|
||||
if(s->pNext) s->pNext->pPrev = s->pPrev;
|
||||
if(s->pPrev) s->pPrev->pNext = s->pNext;
|
||||
else if(S3Global.perDb.aUsed == s){
|
||||
@ -699,7 +712,10 @@ static void PerDbStateJni_set_aside(PerDbStateJni * const s){
|
||||
BusyHandlerJni_clear(&s->busyHandler);
|
||||
memset(s, 0, sizeof(PerDbStateJni));
|
||||
s->pNext = S3Global.perDb.aFree;
|
||||
if(s->pNext) s->pNext->pPrev = s;
|
||||
S3Global.perDb.aFree = s;
|
||||
//MARKER(("%p->pPrev@%p, pNext@%p\n", s, s->pPrev, s->pNext));
|
||||
//if(s->pNext) MARKER(("next: %p->pPrev@%p\n", s->pNext, s->pNext->pPrev));
|
||||
}
|
||||
}
|
||||
|
||||
@ -720,14 +736,24 @@ static void PerDbStateJni_dump(PerDbStateJni *s){
|
||||
true then a new instance will be allocated if no mapping currently
|
||||
exists, else NULL is returned if no mapping is found.
|
||||
|
||||
The 3rd and 4th args should only be non-0 for
|
||||
sqlite3_open(_v2)(). For all other cases, they must be 0, in which
|
||||
case the db handle will be fished out of the jDb object and NULL is
|
||||
returned if jDb does not have any associated PerDbStateJni.
|
||||
*/
|
||||
FIXME_THREADING
|
||||
static PerDbStateJni * PerDbStateJni_for_db(JNIEnv *env, sqlite3 *pDb, int allocIfNeeded){
|
||||
static PerDbStateJni * PerDbStateJni_for_db(JNIEnv *env, jobject jDb, sqlite3 *pDb, int allocIfNeeded){
|
||||
PerDbStateJni * s = S3Global.perDb.aUsed;
|
||||
for( ; s; s = s->pNext){
|
||||
assert(allocIfNeeded ? !!pDb : 1);
|
||||
if(!allocIfNeeded && !pDb){
|
||||
pDb = PtrGet_sqlite3_value(jDb);
|
||||
}
|
||||
for( ; pDb && s; s = s->pNext){
|
||||
if(s->pDb == pDb) return s;
|
||||
}
|
||||
if(allocIfNeeded) s = PerDbStateJni_alloc(env, pDb);
|
||||
if(allocIfNeeded){
|
||||
s = PerDbStateJni_alloc(env, pDb, jDb);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -736,19 +762,19 @@ static PerDbStateJni * PerDbStateJni_for_db(JNIEnv *env, sqlite3 *pDb, int alloc
|
||||
*/
|
||||
FIXME_THREADING
|
||||
static void PerDbStateJni_free_all(void){
|
||||
PerDbStateJni * pS = S3Global.perDb.aUsed;
|
||||
PerDbStateJni * ps = S3Global.perDb.aUsed;
|
||||
PerDbStateJni * pSNext = 0;
|
||||
for( ; pS; pS = pSNext ){
|
||||
pSNext = pS->pNext;
|
||||
PerDbStateJni_set_aside(pS);
|
||||
for( ; ps; ps = pSNext ){
|
||||
pSNext = ps->pNext;
|
||||
PerDbStateJni_set_aside(ps);
|
||||
assert(pSNext ? !pSNext->pPrev : 1);
|
||||
}
|
||||
assert( 0==S3Global.perDb.aUsed );
|
||||
pS = S3Global.perDb.aFree;
|
||||
ps = S3Global.perDb.aFree;
|
||||
S3Global.perDb.aFree = 0;
|
||||
pSNext = 0;
|
||||
for( ; pS; pS = pSNext ){
|
||||
pSNext = pS->pNext;
|
||||
for( ; ps; ps = pSNext ){
|
||||
pSNext = ps->pNext;
|
||||
s3jni_free(pSNext);
|
||||
}
|
||||
}
|
||||
@ -1358,59 +1384,59 @@ JDECL(jint,1bind_1zeroblob64)(JENV_JSELF, jobject jpStmt,
|
||||
}
|
||||
|
||||
static int s3jni_busy_handler(void* pState, int n){
|
||||
PerDbStateJni * const pS = (PerDbStateJni *)pState;
|
||||
PerDbStateJni * const ps = (PerDbStateJni *)pState;
|
||||
int rc = 0;
|
||||
if( pS->busyHandler.jObj ){
|
||||
JNIEnv * const env = pS->env;
|
||||
rc = (*env)->CallIntMethod(env, pS->busyHandler.jObj,
|
||||
pS->busyHandler.jmidxCallback, (jint)n);
|
||||
if( ps->busyHandler.jObj ){
|
||||
JNIEnv * const env = ps->env;
|
||||
rc = (*env)->CallIntMethod(env, ps->busyHandler.jObj,
|
||||
ps->busyHandler.jmidxCallback, (jint)n);
|
||||
IFTHREW_CLEAR;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
JDECL(jint,1busy_1handler)(JENV_JSELF, jobject jDb, jobject jBusy){
|
||||
sqlite3 * const pDb = PtrGet_sqlite3(jDb);
|
||||
PerDbStateJni * const pS = PerDbStateJni_for_db(env, pDb, 1);
|
||||
PerDbStateJni * const ps = PerDbStateJni_for_db(env, jDb, 0, 0);
|
||||
int rc;
|
||||
if(!pS) return (jint)SQLITE_NOMEM;
|
||||
if(!ps) return (jint)SQLITE_NOMEM;
|
||||
if(jBusy){
|
||||
if(pS->busyHandler.jObj &&
|
||||
(*env)->IsSameObject(env, pS->busyHandler.jObj, jBusy)){
|
||||
if(ps->busyHandler.jObj &&
|
||||
(*env)->IsSameObject(env, ps->busyHandler.jObj, jBusy)){
|
||||
/* Same object - this is a no-op. */
|
||||
return 0;
|
||||
}
|
||||
rc = BusyHandlerJni_init(env, &pS->busyHandler, jBusy);
|
||||
rc = BusyHandlerJni_init(env, &ps->busyHandler, jBusy);
|
||||
if(rc){
|
||||
assert(!pS->busyHandler.jObj);
|
||||
assert(!ps->busyHandler.jObj);
|
||||
return (jint)rc;
|
||||
}
|
||||
assert(pS->busyHandler.jObj && pS->busyHandler.klazz);
|
||||
assert( (*env)->IsSameObject(env, pS->busyHandler.jObj, jBusy) );
|
||||
assert(ps->busyHandler.jObj && ps->busyHandler.klazz);
|
||||
assert( (*env)->IsSameObject(env, ps->busyHandler.jObj, jBusy) );
|
||||
}else{
|
||||
BusyHandlerJni_clear(&pS->busyHandler);
|
||||
BusyHandlerJni_clear(&ps->busyHandler);
|
||||
}
|
||||
return jBusy
|
||||
? sqlite3_busy_handler(pDb, s3jni_busy_handler, pS)
|
||||
: sqlite3_busy_handler(pDb, 0, 0);
|
||||
? sqlite3_busy_handler(ps->pDb, s3jni_busy_handler, ps)
|
||||
: sqlite3_busy_handler(ps->pDb, 0, 0);
|
||||
}
|
||||
|
||||
JDECL(jint,1busy_1timeout)(JENV_JSELF, jobject jDb, jint ms){
|
||||
sqlite3* const pDb = PtrGet_sqlite3(jDb);
|
||||
PerDbStateJni * const pS = PerDbStateJni_for_db(env, pDb, 0);
|
||||
if( pS && pS->busyHandler.jObj ){
|
||||
BusyHandlerJni_clear(&pS->busyHandler);
|
||||
PerDbStateJni * const ps = PerDbStateJni_for_db(env, jDb, 0, 0);
|
||||
if( ps ){
|
||||
if( ps->busyHandler.jObj ){
|
||||
BusyHandlerJni_clear(&ps->busyHandler);
|
||||
}
|
||||
return sqlite3_busy_timeout(ps->pDb, (int)ms);
|
||||
}
|
||||
return sqlite3_busy_timeout(pDb, (int)ms);
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
|
||||
/**
|
||||
Wrapper for sqlite3_close(_v2)().
|
||||
*/
|
||||
static jint s3jni_close_db(JNIEnv *env, jobject jDb, int version){
|
||||
sqlite3 * pDb;
|
||||
int rc = 0;
|
||||
PerDbStateJni * pS = 0;
|
||||
PerDbStateJni * ps = 0;
|
||||
assert(version == 1 || version == 2);
|
||||
if(0){
|
||||
PerDbStateJni * s = S3Global.perDb.aUsed;
|
||||
@ -1418,12 +1444,11 @@ static jint s3jni_close_db(JNIEnv *env, jobject jDb, int version){
|
||||
PerDbStateJni_dump(s);
|
||||
}
|
||||
}
|
||||
pDb = PtrGet_sqlite3(jDb);
|
||||
if(!pDb) return rc;
|
||||
pS = PerDbStateJni_for_db(env, pDb, 0);
|
||||
rc = 1==version ? (jint)sqlite3_close(pDb) : (jint)sqlite3_close_v2(pDb);
|
||||
if(pS) PerDbStateJni_set_aside(pS)
|
||||
/* MUST come after close() because of pS->trace. */;
|
||||
ps = PerDbStateJni_for_db(env, jDb, 0, 0);
|
||||
if(!ps) return rc;
|
||||
rc = 1==version ? (jint)sqlite3_close(ps->pDb) : (jint)sqlite3_close_v2(ps->pDb);
|
||||
if(ps) PerDbStateJni_set_aside(ps)
|
||||
/* MUST come after close() because of ps->trace. */;
|
||||
setNativePointer(env, jDb, 0, ClassNames.sqlite3);
|
||||
return (jint)rc;
|
||||
}
|
||||
@ -1536,14 +1561,13 @@ static void s3jni_rollback_hook_impl(void *pP){
|
||||
|
||||
static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv *env,jobject jDb,
|
||||
jobject jHook){
|
||||
sqlite3 * const pDb = PtrGet_sqlite3(jDb);
|
||||
PerDbStateJni * const ps = PerDbStateJni_for_db(env, pDb, 1);
|
||||
PerDbStateJni * const ps = PerDbStateJni_for_db(env, jDb, 0, 0);
|
||||
jclass klazz;
|
||||
jobject pOld = 0;
|
||||
jmethodID xCallback;
|
||||
JniHookState * const pHook = isCommit ? &ps->commitHook : &ps->rollbackHook;
|
||||
if(!ps){
|
||||
s3jni_db_error(pDb, SQLITE_NOMEM, 0);
|
||||
s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0);
|
||||
return 0;
|
||||
}
|
||||
pOld = pHook->jObj;
|
||||
@ -1558,8 +1582,8 @@ static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv *env,jobject jDb,
|
||||
pOld = tmp;
|
||||
}
|
||||
memset(pHook, 0, sizeof(JniHookState));
|
||||
if( isCommit ) sqlite3_commit_hook(pDb, 0, 0);
|
||||
else sqlite3_rollback_hook(pDb, 0, 0);
|
||||
if( isCommit ) sqlite3_commit_hook(ps->pDb, 0, 0);
|
||||
else sqlite3_rollback_hook(ps->pDb, 0, 0);
|
||||
return pOld;
|
||||
}
|
||||
klazz = (*env)->GetObjectClass(env, jHook);
|
||||
@ -1569,14 +1593,14 @@ static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv *env,jobject jDb,
|
||||
IFTHREW {
|
||||
EXCEPTION_REPORT;
|
||||
EXCEPTION_CLEAR;
|
||||
s3jni_db_error(pDb, SQLITE_ERROR,
|
||||
s3jni_db_error(ps->pDb, SQLITE_ERROR,
|
||||
"Cannot not find matching callback on "
|
||||
"hook object.");
|
||||
}else{
|
||||
pHook->midCallback = xCallback;
|
||||
pHook->jObj = REF_G(jHook);
|
||||
if( isCommit ) sqlite3_commit_hook(pDb, s3jni_commit_hook_impl, ps);
|
||||
else sqlite3_rollback_hook(pDb, s3jni_rollback_hook_impl, ps);
|
||||
if( isCommit ) sqlite3_commit_hook(ps->pDb, s3jni_commit_hook_impl, ps);
|
||||
else sqlite3_rollback_hook(ps->pDb, s3jni_rollback_hook_impl, ps);
|
||||
if(pOld){
|
||||
jobject tmp = REF_L(pOld);
|
||||
UNREF_G(pOld);
|
||||
@ -1729,27 +1753,39 @@ JDECL(jlong,1last_1insert_1rowid)(JENV_JSELF, jobject jpDb){
|
||||
return (jlong)sqlite3_last_insert_rowid(PtrGet_sqlite3(jpDb));
|
||||
}
|
||||
|
||||
static int s3jni_open_post(JNIEnv *env, sqlite3 **ppDb, jobject jDb, int theRc){
|
||||
if(1 && *ppDb){
|
||||
PerDbStateJni * const s = PerDbStateJni_for_db(env, jDb, *ppDb, 1);
|
||||
if(!s && 0==theRc){
|
||||
sqlite3_close(*ppDb);
|
||||
*ppDb = 0;
|
||||
theRc = SQLITE_NOMEM;
|
||||
}
|
||||
}
|
||||
setNativePointer(env, jDb, *ppDb, ClassNames.sqlite3);
|
||||
return theRc;
|
||||
}
|
||||
|
||||
JDECL(jint,1open)(JENV_JSELF, jstring strName, jobject ppOut){
|
||||
JDECL(jint,1open)(JENV_JSELF, jstring strName, jobject jOut){
|
||||
sqlite3 * pOut = 0;
|
||||
const char *zName = strName ? JSTR_TOC(strName) : 0;
|
||||
int nrc = sqlite3_open(zName, &pOut);
|
||||
//MARKER(("env=%p, *env=%p\n", env, *env));
|
||||
setNativePointer(env, ppOut, pOut, ClassNames.sqlite3);
|
||||
nrc = s3jni_open_post(env, &pOut, jOut, nrc);
|
||||
assert(nrc==0 ? pOut!=0 : 1);
|
||||
JSTR_RELEASE(strName, zName);
|
||||
return (jint)nrc;
|
||||
}
|
||||
|
||||
JDECL(jint,1open_1v2)(JENV_JSELF, jstring strName,
|
||||
jobject ppOut, jint flags, jstring strVfs){
|
||||
jobject jOut, jint flags, jstring strVfs){
|
||||
sqlite3 * pOut = 0;
|
||||
const char *zName = strName ? JSTR_TOC(strName) : 0;
|
||||
const char *zVfs = strVfs ? JSTR_TOC(strVfs) : 0;
|
||||
int nrc = sqlite3_open_v2(zName, &pOut, (int)flags, zVfs);
|
||||
/*MARKER(("zName=%s, zVfs=%s, pOut=%p, flags=%d, nrc=%d\n",
|
||||
zName, zVfs, pOut, (int)flags, nrc));*/
|
||||
setNativePointer(env, ppOut, pOut, ClassNames.sqlite3);
|
||||
nrc = s3jni_open_post(env, &pOut, jOut, nrc);
|
||||
assert(nrc==0 ? pOut!=0 : 1);
|
||||
JSTR_RELEASE(strName, zName);
|
||||
JSTR_RELEASE(strVfs, zVfs);
|
||||
@ -1820,8 +1856,7 @@ static int s3jni_progress_handler_impl(void *pP){
|
||||
}
|
||||
|
||||
JDECL(void,1progress_1handler)(JENV_JSELF,jobject jDb, jint n, jobject jProgress){
|
||||
sqlite3 * const pDb = PtrGet_sqlite3(jDb);
|
||||
PerDbStateJni * ps = PerDbStateJni_for_db(env, pDb, 1);
|
||||
PerDbStateJni * ps = PerDbStateJni_for_db(env, jDb, 0, 0);
|
||||
jclass klazz;
|
||||
jmethodID xCallback;
|
||||
if( n<1 || !jProgress ){
|
||||
@ -1829,25 +1864,25 @@ JDECL(void,1progress_1handler)(JENV_JSELF,jobject jDb, jint n, jobject jProgress
|
||||
UNREF_G(ps->progress.jObj);
|
||||
memset(&ps->progress, 0, sizeof(ps->progress));
|
||||
}
|
||||
sqlite3_progress_handler(pDb, 0, 0, 0);
|
||||
sqlite3_progress_handler(ps->pDb, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
if(!ps){
|
||||
s3jni_db_error(pDb, SQLITE_NOMEM, 0);
|
||||
s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0);
|
||||
return;
|
||||
}
|
||||
klazz = (*env)->GetObjectClass(env, jProgress);
|
||||
xCallback = (*env)->GetMethodID(env, klazz, "xCallback", "()I");
|
||||
IFTHREW {
|
||||
EXCEPTION_CLEAR;
|
||||
s3jni_db_error(pDb, SQLITE_ERROR,
|
||||
s3jni_db_error(ps->pDb, SQLITE_ERROR,
|
||||
"Cannot not find matching xCallback() on "
|
||||
"ProgressHandler object.");
|
||||
}else{
|
||||
UNREF_G(ps->progress.jObj);
|
||||
ps->progress.midCallback = xCallback;
|
||||
ps->progress.jObj = REF_G(jProgress);
|
||||
sqlite3_progress_handler(pDb, (int)n, s3jni_progress_handler_impl, ps);
|
||||
sqlite3_progress_handler(ps->pDb, (int)n, s3jni_progress_handler_impl, ps);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2081,15 +2116,14 @@ static int s3jni_trace_impl(unsigned traceflag, void *pC, void *pP, void *pX){
|
||||
}
|
||||
|
||||
JDECL(jint,1trace_1v2)(JENV_JSELF,jobject jDb, jint traceMask, jobject jTracer){
|
||||
sqlite3 * const pDb = PtrGet_sqlite3(jDb);
|
||||
PerDbStateJni * const ps = PerDbStateJni_for_db(env, pDb, 1);
|
||||
PerDbStateJni * const ps = PerDbStateJni_for_db(env, jDb, 0, 0);
|
||||
jclass klazz;
|
||||
if( !traceMask || !jTracer ){
|
||||
if(ps){
|
||||
UNREF_G(ps->trace.jObj);
|
||||
memset(&ps->trace, 0, sizeof(ps->trace));
|
||||
}
|
||||
return (jint)sqlite3_trace_v2(pDb, 0, 0, 0);
|
||||
return (jint)sqlite3_trace_v2(ps->pDb, 0, 0, 0);
|
||||
}
|
||||
if(!ps) return SQLITE_NOMEM;
|
||||
klazz = (*env)->GetObjectClass(env, jTracer);
|
||||
@ -2097,11 +2131,11 @@ JDECL(jint,1trace_1v2)(JENV_JSELF,jobject jDb, jint traceMask, jobject jTracer){
|
||||
"(IJLjava/lang/Object;)I");
|
||||
IFTHREW {
|
||||
EXCEPTION_CLEAR;
|
||||
return s3jni_db_error(pDb, SQLITE_ERROR,
|
||||
return s3jni_db_error(ps->pDb, SQLITE_ERROR,
|
||||
"Cannot not find matching xCallback() on Tracer object.");
|
||||
}
|
||||
ps->trace.jObj = REF_G(jTracer);
|
||||
return sqlite3_trace_v2(pDb, (unsigned)traceMask, s3jni_trace_impl, ps);
|
||||
return sqlite3_trace_v2(ps->pDb, (unsigned)traceMask, s3jni_trace_impl, ps);
|
||||
}
|
||||
|
||||
static void s3jni_update_hook_impl(void * pState, int opId, const char *zDb,
|
||||
@ -2133,14 +2167,13 @@ static void s3jni_update_hook_impl(void * pState, int opId, const char *zDb,
|
||||
|
||||
|
||||
JDECL(jobject,1update_1hook)(JENV_JSELF, jobject jDb, jobject jHook){
|
||||
sqlite3 * const pDb = PtrGet_sqlite3(jDb);
|
||||
PerDbStateJni * const ps = PerDbStateJni_for_db(env, pDb, 1);
|
||||
PerDbStateJni * const ps = PerDbStateJni_for_db(env, jDb, 0, 0);
|
||||
jclass klazz;
|
||||
jobject pOld = 0;
|
||||
jmethodID xCallback;
|
||||
JniHookState * const pHook = &ps->updateHook;
|
||||
if(!ps){
|
||||
s3jni_db_error(pDb, SQLITE_NOMEM, 0);
|
||||
s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0);
|
||||
return 0;
|
||||
}
|
||||
pOld = pHook->jObj;
|
||||
@ -2155,7 +2188,7 @@ JDECL(jobject,1update_1hook)(JENV_JSELF, jobject jDb, jobject jHook){
|
||||
pOld = tmp;
|
||||
}
|
||||
memset(pHook, 0, sizeof(JniHookState));
|
||||
sqlite3_update_hook(pDb, 0, 0);
|
||||
sqlite3_update_hook(ps->pDb, 0, 0);
|
||||
return pOld;
|
||||
}
|
||||
klazz = (*env)->GetObjectClass(env, jHook);
|
||||
@ -2163,13 +2196,13 @@ JDECL(jobject,1update_1hook)(JENV_JSELF, jobject jDb, jobject jHook){
|
||||
"(ILjava/lang/String;Ljava/lang/String;J)V");
|
||||
IFTHREW {
|
||||
EXCEPTION_CLEAR;
|
||||
s3jni_db_error(pDb, SQLITE_ERROR,
|
||||
s3jni_db_error(ps->pDb, SQLITE_ERROR,
|
||||
"Cannot not find matching callback on "
|
||||
"update hook object.");
|
||||
}else{
|
||||
pHook->midCallback = xCallback;
|
||||
pHook->jObj = REF_G(jHook);
|
||||
sqlite3_update_hook(pDb, s3jni_update_hook_impl, ps);
|
||||
sqlite3_update_hook(ps->pDb, s3jni_update_hook_impl, ps);
|
||||
if(pOld){
|
||||
jobject tmp = REF_L(pOld);
|
||||
UNREF_G(pOld);
|
||||
|
12
manifest
12
manifest
@ -1,5 +1,5 @@
|
||||
C Incremental\scheckin\sto\sminimize\sthe\sdiff\swhile\snarrowing\sin\son\san\sassertion\scaused\sby\srefactoring.
|
||||
D 2023-07-30T09:45:54.025
|
||||
C Internal\sJNI\srefacoring\sto\ssupport\sthe\spending\ssqlite3_collation_needed()\scallback.\sCorrect\sa\sbug\sin\sthe\slinked-list\shandling\sof\sPerDbStateJni\swhich\striggered\san\sassert().
|
||||
D 2023-07-30T10:47:38.755
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -232,7 +232,7 @@ F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282
|
||||
F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8
|
||||
F ext/jni/GNUmakefile 56a014dbff9516774d895ec1ae9df0ed442765b556f79a0fc0b5bc438217200d
|
||||
F ext/jni/README.md c0e6e80935e7761acead89b69c87765b23a6bcb2858c321c3d05681fd338292a
|
||||
F ext/jni/src/c/sqlite3-jni.c 5b5631520dd2e3ae6890bcbbee2aad3d7b5c404e96ae826b661e1105d2d2a69d
|
||||
F ext/jni/src/c/sqlite3-jni.c 57db39bd2443435764777a1e43e2f8e356b8c411ee2649ad08df4b32087cbe80
|
||||
F ext/jni/src/c/sqlite3-jni.h 85345dd3c970b539f1de4e6ad59c245fa6e80ca775a498ab1ed3d67f8615ce34
|
||||
F ext/jni/src/org/sqlite/jni/BusyHandler.java 1b1d3e5c86cd796a0580c81b6af6550ad943baa25e47ada0dcca3aff3ebe978c
|
||||
F ext/jni/src/org/sqlite/jni/Collation.java 8dffbb00938007ad0967b2ab424d3c908413af1bbd3d212b9c9899910f1218d1
|
||||
@ -2071,8 +2071,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 5e592ed2dfc89225fff3a1c76509adc799a238282413984e0c4b32af18525d18
|
||||
R a4ee8dd84c4c810bd2a0b503fc8278d5
|
||||
P 2d7a91b1396d87852f1153ab7af7385514a9537cb64ba3bbd0faba2d28704214
|
||||
R 5bff367529a1829789141e745a6b193a
|
||||
U stephan
|
||||
Z f4150e59d6c4033aef1bd32347c40f57
|
||||
Z a4b019fdb819701e83942a71127183e7
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
2d7a91b1396d87852f1153ab7af7385514a9537cb64ba3bbd0faba2d28704214
|
||||
7ac6614e69b03304d09745619ed83f12c7eb775aaf4a636a79289b01642ddd14
|
Reference in New Issue
Block a user