Rework the sqlite3_open(_v2)() order of operations so that pending auto-extension support can get ahold of the open-time Java state despite the Java/C (sqlite3*) binding not having yet been established.

FossilOrigin-Name: 34da294ab558880e81eebd7d261bc590551d5a7d2855e844695cef6394647ea7
This commit is contained in:
stephan
2023-08-06 22:09:09 +00:00
parent d85f9bf6d5
commit 60745265e1
3 changed files with 80 additions and 46 deletions
+73 -39
View File
@@ -968,7 +968,7 @@ static jfieldID NativePointerHolder_getField(JNIEnv * const env, jclass klazz){
as a cache key.
*/
static void NativePointerHolder_set(JNIEnv * env, jobject ppOut, const void * p,
const char *zClassName){
const char *zClassName){
jfieldID setter = 0;
struct NphCacheLine * const cacheLine = S3Global_nph_cache(env, zClassName);
if(cacheLine && cacheLine->klazz && cacheLine->fidValue){
@@ -1026,9 +1026,9 @@ static void * NativePointerHolder_get(JNIEnv * env, jobject pObj, const char *zC
Returns NULL on OOM. pDb MUST be associated with jDb via
NativePointerHolder_set().
*/
static PerDbStateJni * PerDbStateJni_alloc(JNIEnv * const env, sqlite3 *pDb, jobject jDb){
static PerDbStateJni * PerDbStateJni_alloc(JNIEnv * const 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));
@@ -2382,56 +2382,90 @@ JDECL(jlong,1last_1insert_1rowid)(JENV_CSELF, jobject jpDb){
return (jlong)sqlite3_last_insert_rowid(PtrGet_sqlite3(jpDb));
}
/**
Code common to both the sqlite3_open() and sqlite3_open_v2()
bindings. Allocates the PerDbStateJni for *ppDb if *ppDb is not
NULL. jDb must be the org.sqlite.jni.sqlite3 object which will hold
the db's native pointer. theRc must be the result code of the open
op(). If allocation of the PerDbStateJni object fails then *ppDb is
passed to sqlite3_close(), *ppDb is assigned to 0, and SQLITE_NOMEM
is returned, else theRc is returned. In in case, *ppDb is stored in
jDb's native pointer property (even if it's NULL).
*/
static int s3jni_open_post(JNIEnv * const env, sqlite3 **ppDb, jobject jOut, int theRc){
jobject jDb = 0;
if(*ppDb){
jDb = new_sqlite3_wrapper(env, *ppDb);
PerDbStateJni * const s = jDb ? PerDbStateJni_for_db(env, jDb, *ppDb, 1) : 0;
if(!s && 0==theRc){
UNREF_L(jDb);
sqlite3_close(*ppDb);
*ppDb = 0;
theRc = SQLITE_NOMEM;
}
//! Pre-open() code common to sqlite3_open(_v2)().
static int s3jni_open_pre(JNIEnv * const env, JNIEnvCache **jc,
jstring jDbName, char **zDbName,
PerDbStateJni ** ps, jobject *jDb){
*jc = S3Global_env_cache(env);
if(!*jc) return SQLITE_NOMEM;
*zDbName = jDbName ? s3jni_jstring_to_utf8(*jc, jDbName, 0) : 0;
if(jDbName && !*zDbName) return SQLITE_NOMEM;
*jDb = new_sqlite3_wrapper(env, 0);
if( !*jDb ){
sqlite3_free(*zDbName);
*zDbName = 0;
return SQLITE_NOMEM;
}
OutputPointer_set_sqlite3(env, jOut, jDb);
*ps = PerDbStateJni_alloc(env, 0, *jDb);
return *ps ? 0 : SQLITE_NOMEM;
}
/**
Post-open() code common to both the sqlite3_open() and
sqlite3_open_v2() bindings. ps->jDb must be the
org.sqlite.jni.sqlite3 object which will hold the db's native
pointer. theRc must be the result code of the open() op. If
*ppDb is NULL then ps is set aside and its state cleared,
else ps is associated with *ppDb. If *ppDb is not NULL then
ps->jDb is stored in jOut (an OutputPointer.sqlite3 instance).
Returns theRc.
*/
static int s3jni_open_post(JNIEnv * const env, PerDbStateJni * ps,
sqlite3 **ppDb, jobject jOut, int theRc){
if(*ppDb){
assert(ps->jDb);
ps->pDb = *ppDb;
NativePointerHolder_set(env, ps->jDb, *ppDb, S3ClassNames.sqlite3);
}else{
PerDbStateJni_set_aside(ps);
ps = 0;
}
OutputPointer_set_sqlite3(env, jOut, ps ? ps->jDb : 0);
return theRc;
}
JDECL(jint,1open)(JENV_CSELF, jstring strName, jobject jOut){
sqlite3 * pOut = 0;
const char *zName = strName ? JSTR_TOC(strName) : 0;
int nrc = sqlite3_open(zName, &pOut);
char *zName = 0;
jobject jDb = 0;
PerDbStateJni * ps = 0;
JNIEnvCache * jc = 0;
int rc = s3jni_open_pre(env, &jc, strName, &zName, &ps, &jDb);
if( rc ) return rc;
rc = sqlite3_open(zName, &pOut);
//MARKER(("env=%p, *env=%p\n", env, *env));
nrc = s3jni_open_post(env, &pOut, jOut, nrc);
assert(nrc==0 ? pOut!=0 : 1);
JSTR_RELEASE(strName, zName);
return (jint)nrc;
rc = s3jni_open_post(env, ps, &pOut, jOut, rc);
assert(rc==0 ? pOut!=0 : 1);
sqlite3_free(zName);
return (jint)rc;
}
JDECL(jint,1open_1v2)(JENV_CSELF, jstring strName,
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);
char *zName = 0;
jobject jDb = 0;
PerDbStateJni * ps = 0;
JNIEnvCache * jc = 0;
char *zVfs = 0;
int rc = s3jni_open_pre(env, &jc, strName, &zName, &ps, &jDb);
if( 0==rc && strVfs ){
zVfs = s3jni_jstring_to_utf8(jc, strVfs, 0);
if( !zVfs ){
rc = SQLITE_NOMEM;
}
}
if( 0==rc ){
rc = 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));*/
nrc = s3jni_open_post(env, &pOut, jOut, nrc);
assert(nrc==0 ? pOut!=0 : 1);
JSTR_RELEASE(strName, zName);
JSTR_RELEASE(strVfs, zVfs);
return (jint)nrc;
rc = s3jni_open_post(env, ps, &pOut, jOut, rc);
assert(rc==0 ? pOut!=0 : 1);
sqlite3_free(zName);
sqlite3_free(zVfs);
return (jint)rc;
}
/* Proxy for the sqlite3_prepare[_v2/3]() family. */
+6 -6
View File
@@ -1,5 +1,5 @@
C Completely\srework\show\sthe\sJNI\ssqlite3_open(_v2)\sand\ssqlite3_prepare(_vN)()\sbindings\sdeal\swith\soutput\spointers\sto\sgive\sthe\sJNI\sside\sfull\scontrol\sover\sthe\sorigin\sof\sdb\sand\sstmt\shandles\s(necessary\sfor\ssolving\schicken/egg\ssituations\sin\sauto-extensions\sand\sprepare-time\strace).\sLots\sof\sadjacent\sinternal\sAPI\srenaming.
D 2023-08-06T21:29:13.410
C Rework\sthe\ssqlite3_open(_v2)()\sorder\sof\soperations\sso\sthat\spending\sauto-extension\ssupport\scan\sget\sahold\sof\sthe\sopen-time\sJava\sstate\sdespite\sthe\sJava/C\s(sqlite3*)\sbinding\snot\shaving\syet\sbeen\sestablished.
D 2023-08-06T22:09:09.175
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 61d9bbc179a49523a142928455b3297779b9c40f25783ecf1538279e426cbc99
F ext/jni/README.md e965674505e105626127ad45e628e4d19fcd379cdafc4d23c814c1ac2c55681d
F ext/jni/src/c/sqlite3-jni.c 22f463b0bf4e79ccbc0dcd157e8c419e1a6ab1a88afbd565db818aec2802241e
F ext/jni/src/c/sqlite3-jni.c 21177d7c3492f84aad0666c43ea6d9bc0ebd544f66dcb41219f966b137e86c1b
F ext/jni/src/c/sqlite3-jni.h 2108bb9434fe873e08d6388bce102a474b5c6b00c2ea47d8aee257aca2de2a67
F ext/jni/src/org/sqlite/jni/Authorizer.java 1308988f7f40579ea0e4deeaec3c6be971630566bd021c31367fe3f5140db892
F ext/jni/src/org/sqlite/jni/BusyHandler.java 1b1d3e5c86cd796a0580c81b6af6550ad943baa25e47ada0dcca3aff3ebe978c
@@ -2082,8 +2082,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 77a32d238e80fe1d237768d88780043a7bd2b3543e6672536254782cbea0039c
R 218b9f82589d0175238ee5cd53ac1842
P 644999caff9db79562d45520d94aaa24ee88c65e397b6fb9c20a4f0e7f84e1a5
R c4d749cda5fec61bfb97a76dd1b71afd
U stephan
Z f6066ff3c416a47c98afc4ffb5e0f6a5
Z cb93209a7d6706bee6dfc5cbdd5b5747
# Remove this line to create a well-formed Fossil manifest.
+1 -1
View File
@@ -1 +1 @@
644999caff9db79562d45520d94aaa24ee88c65e397b6fb9c20a4f0e7f84e1a5
34da294ab558880e81eebd7d261bc590551d5a7d2855e844695cef6394647ea7