@@ -205,9 +205,10 @@ string GenomicSQLiteURI(const string &dbfile, const string &config_json = "") {
205205 uri << " &immutable=1" ;
206206 }
207207 if (cfg.GetBool (" $.unsafe_load" )) {
208- uri << " &nolock=1&outer_unsafe" ;
208+ uri << " &nolock=1&outer_unsafe=1 " ;
209209 }
210210 }
211+ _DBG << uri.str () << endl;
211212 return uri.str ();
212213}
213214
@@ -298,6 +299,7 @@ string GenomicSQLiteTuningSQL(const string &config_json, const string &schema =
298299 for (const auto &p : pragmas) {
299300 out << " ; PRAGMA " << p.first << " =" << p.second ;
300301 }
302+ _DBG << out.str () << endl;
301303 return out.str ();
302304}
303305
@@ -315,14 +317,13 @@ static void sqlfn_genomicsqlite_tuning_sql(sqlite3_context *ctx, int argc, sqlit
315317
316318void GenomicSQLiteInit (int (*open_v2)(const char *, sqlite3 **, int , const char *),
317319 int (*enable_load_extension)(sqlite3 *, int ),
318- int (*load_extension)(sqlite3 *, const char *, const char *, char **)) {
319- static bool ext_loaded = false ;
320- if (!ext_loaded) {
321-
320+ int (*load_extension)(sqlite3 *, const char *, const char *, char **),
321+ int (*close_)(sqlite3 *), void (*free_)(void *)) {
322+ if (!sqlite3_api) {
322323 sqlite3 *memdb = nullptr ;
323324 int rc = open_v2 (" :memory:" , &memdb, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, nullptr );
324325 if (rc != SQLITE_OK) {
325- sqlite3_close (memdb);
326+ close_ (memdb);
326327 throw runtime_error (" GenomicSQLiteInit() unable to open temporary SQLite connection" );
327328 }
328329 enable_load_extension (memdb, 1 );
@@ -331,30 +332,28 @@ void GenomicSQLiteInit(int (*open_v2)(const char *, sqlite3 **, int, const char
331332 if (rc != SQLITE_OK) {
332333 string err = " GenomicSQLiteInit() unable to load the extension" +
333334 (zErrMsg ? " : " + string (zErrMsg) : " " );
334- sqlite3_free (zErrMsg);
335- sqlite3_close (memdb);
335+ free_ (zErrMsg);
336+ close_ (memdb);
336337 throw runtime_error (err);
337338 }
338- sqlite3_free (zErrMsg);
339- rc = sqlite3_close (memdb);
339+ free_ (zErrMsg);
340+ rc = close_ (memdb);
340341 if (rc != SQLITE_OK) {
341342 throw runtime_error (" GenomicSQLiteInit() unable to close temporary SQLite connection" );
342343 }
343- }
344- if (open_v2 != sqlite3_api->open_v2 ) {
344+ } else if (open_v2 != sqlite3_api->open_v2 ) {
345345 throw std::runtime_error (
346- " GenomicSQLiteInit() saw inconsistent libsqlite3/libgenomicsqlite library linkage in this process" );
346+ " Two distinct copies of SQLite in this process attempted to load Genomics Extension " );
347347 }
348- ext_loaded = true ;
349348}
350349
351- extern " C" int genomicsqlite_init ( int (*open_v2)( const char *, sqlite3 **, int , const char *),
352- int (*enable_load_extension)( sqlite3 *, int ),
353- int (*load_extension )(sqlite3 *, const char *, const char * ,
354- char **),
355- char **pzErrMsg) {
350+ extern " C" int
351+ genomicsqlite_init ( int (*open_v2)( const char *, sqlite3 ** , int , const char * ),
352+ int (*enable_load_extension )(sqlite3 *, int ) ,
353+ int (*load_extension)(sqlite3 *, const char *, const char *, char **),
354+ int (*close_)(sqlite3 *), void (*free_)( void *), char **pzErrMsg) {
356355 try {
357- GenomicSQLiteInit (open_v2, enable_load_extension, load_extension);
356+ GenomicSQLiteInit (open_v2, enable_load_extension, load_extension, close_, free_ );
358357 return SQLITE_OK;
359358 } catch (std::bad_alloc &) {
360359 return SQLITE_NOMEM;
@@ -458,7 +457,7 @@ static void sqlfn_genomicsqlite_attach_sql(sqlite3_context *ctx, int argc, sqlit
458457}
459458
460459string GenomicSQLiteVacuumIntoSQL (const string &destfile, const string &config_json) {
461- string desturi = GenomicSQLiteURI (destfile, config_json) + " &outer_unsafe=true " ;
460+ string desturi = GenomicSQLiteURI (destfile, config_json) + " &outer_unsafe=1 " ;
462461
463462 ConfigParser cfg (config_json);
464463 ostringstream ans;
@@ -1786,6 +1785,14 @@ static int register_genomicsqlite_functions(sqlite3 *db, const char **pzErrMsg,
17861785*/
17871786extern " C" int sqlite3_genomicsqlite_init (sqlite3 *db, char **pzErrMsg,
17881787 const sqlite3_api_routines *pApi) {
1788+ if (sqlite3_api && sqlite3_api != pApi) {
1789+ if (pzErrMsg) {
1790+ *pzErrMsg = sqlite3_mprintf (
1791+ " Two distinct copies of SQLite in this process attempted to load Genomics Extension %s" ,
1792+ GIT_REVISION);
1793+ }
1794+ return SQLITE_ERROR;
1795+ }
17891796 SQLITE_EXTENSION_INIT2 (pApi);
17901797
17911798 // The newest SQLite feature currently required is "Generated Columns"
@@ -1800,10 +1807,7 @@ extern "C" int sqlite3_genomicsqlite_init(sqlite3 *db, char **pzErrMsg,
18001807 return SQLITE_ERROR;
18011808 }
18021809
1803- /* disabled b/c JDBC bindings "legitimately" entail two different dynamically-linked sqlite libs!
1804- // Check that SQLiteCpp is using the same SQLite library that's loading us. This may not be the
1805- // case when different versions of SQLite are linked into the running process, one static and
1806- // one dynamic.
1810+ // Check that SQLiteCpp is using the same SQLite library that's loading us.
18071811 string static_version (pApi->libversion ()), dynamic_version (" UNKNOWN" );
18081812 {
18091813 SQLite::Database tmpdb (" :memory:" , SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE);
@@ -1815,12 +1819,11 @@ extern "C" int sqlite3_genomicsqlite_init(sqlite3 *db, char **pzErrMsg,
18151819 if (static_version != dynamic_version) {
18161820 if (pzErrMsg) {
18171821 *pzErrMsg = sqlite3_mprintf (
1818- "Two distinct versions of SQLite (%s & %s) detected by Genomics Extension %s. Eliminate static linking of SQLite from the main executable. ",
1822+ " Two distinct versions of SQLite (%s & %s) in this process detected by Genomics Extension %s" ,
18191823 static_version.c_str (), dynamic_version.c_str (), GIT_REVISION);
18201824 }
18211825 return SQLITE_ERROR;
18221826 }
1823- */
18241827
18251828 int rc = (new WebVFS::VFS ())->Register (" web" );
18261829 if (rc != SQLITE_OK) {
0 commit comments