fiddle: lots of generic refactoring, restructuring, and cleanup in the higher-level code. Added push-fiddle ext/fiddle/Makefile target to push the fiddle app to a remote server via rsync.
FossilOrigin-Name: ed19fef3459499abb0a4a010f368b4576d6e068d930c8480446ea677ac87c1c1
This commit is contained in:
+99
-95
@@ -17,31 +17,33 @@
|
||||
Note that this file is not named sqlite3.js because that file gets
|
||||
generated by emscripten as the JS-glue counterpart of sqlite3.wasm.
|
||||
|
||||
This code installs an object named self.sqlite3, where self is
|
||||
expected to be either the global window or Worker object:
|
||||
This code installs an object named self.Module.sqlite3, where self
|
||||
is expected to be either the global window or Worker object and
|
||||
Module is the object set up by the emscripten infrastructure. The
|
||||
sqlite3 object looks like:
|
||||
|
||||
self.sqlite3 = {
|
||||
api: core WASM bindings of sqlite3 APIs,
|
||||
{
|
||||
api: bindings for much of the core sqlite3 APIs,
|
||||
SQLite3: high-level OO API wrapper
|
||||
};
|
||||
}
|
||||
|
||||
The way we export this module is not _really_ modern-JS-friendly
|
||||
because it exports a global symbol (which is admittedly not
|
||||
ideal). Exporting it "cleanly," without introducing any global-scope
|
||||
symbols, requires using a module loader in all client code. As there
|
||||
are several different approaches, none of which this developer is
|
||||
currently truly familiar with, the current approach will have to do
|
||||
for the time being.
|
||||
because it exports/relies on a global symbol (which is admittedly
|
||||
not ideal). Exporting it "cleanly," without introducing any
|
||||
global-scope symbols, requires using a module loader in all client
|
||||
code. As there are several different approaches, none of which this
|
||||
developer is currently truly familiar with, the current approach
|
||||
will have to do for the time being.
|
||||
|
||||
Because using the low-level API properly requires some degree of
|
||||
WASM-related magic, it is not recommended that that API be used
|
||||
as-is in client-level code. Rather, client code should use the
|
||||
higher-level OO API or write a custom wrapper on top of the
|
||||
lower-level API.
|
||||
|
||||
This file installs namespace.sqlite3, where namespace is `self`,
|
||||
meaning either the global window or worker, depending on where this
|
||||
is loaded from.
|
||||
Because using certain parts of the low-level API properly requires
|
||||
some degree of WASM-related magic, it is not recommended that that
|
||||
API be used as-is in client-level code. Rather, client code should
|
||||
use the higher-level OO API or write a custom wrapper on top of the
|
||||
lower-level API. In short, using any C-style APIs which take
|
||||
pointers-to-pointer arguments require WASM-specific interfaces
|
||||
installed by emcscripten-generated code. Those which take or return
|
||||
only integers, doubles, strings, or "plain" pointers to db or
|
||||
statement objects can be used in a straightforward manner.
|
||||
|
||||
# Goals and Non-goals of this API
|
||||
|
||||
@@ -60,13 +62,16 @@
|
||||
can be interacted with, but keeping the DB operations out of the
|
||||
UI thread is generally desirable.
|
||||
|
||||
- Insofar as possible, support client-side storage using JS
|
||||
filesystem APIs. As of this writing, such things are still very
|
||||
much TODO.
|
||||
|
||||
Non-goals:
|
||||
|
||||
- As WASM is a web-based technology and UTF-8 is the King of
|
||||
Encodings in that realm, there are no plans to support the
|
||||
UTF16-related APIs will not be. They would add a complication to
|
||||
the bindings for no appreciable benefit.
|
||||
- As WASM is a web-centric technology and UTF-8 is the King of
|
||||
Encodings in that realm, there are no current plans to support the
|
||||
UTF16-related APIs. They would add a complication to the bindings
|
||||
for no appreciable benefit.
|
||||
|
||||
- Supporting old or niche-market platforms. WASM is built for a
|
||||
modern web and requires modern platforms.
|
||||
@@ -247,8 +252,6 @@
|
||||
throw new Error(Array.prototype.join.call(arguments, ' '));
|
||||
};
|
||||
|
||||
const S/*convenience alias*/ = api;
|
||||
|
||||
/**
|
||||
The DB class wraps a sqlite3 db handle.
|
||||
*/
|
||||
@@ -258,7 +261,7 @@
|
||||
toss("TODO: support blob image of db here.");
|
||||
}
|
||||
setValue(pPtrArg, 0, "i32");
|
||||
this.checkRc(S.sqlite3_open(name, pPtrArg));
|
||||
this.checkRc(api.sqlite3_open(name, pPtrArg));
|
||||
this._pDb = getValue(pPtrArg, "i32");
|
||||
this.filename = name;
|
||||
this._statements = {/*map of open Stmt _pointers_ to Stmt*/};
|
||||
@@ -291,8 +294,8 @@
|
||||
}
|
||||
this.db = arguments[0];
|
||||
this._pStmt = arguments[1];
|
||||
this.columnCount = S.sqlite3_column_count(this._pStmt);
|
||||
this.parameterCount = S.sqlite3_bind_parameter_count(this._pStmt);
|
||||
this.columnCount = api.sqlite3_column_count(this._pStmt);
|
||||
this.parameterCount = api.sqlite3_bind_parameter_count(this._pStmt);
|
||||
this._allocs = [/*list of alloc'd memory blocks for bind() values*/]
|
||||
};
|
||||
|
||||
@@ -370,7 +373,7 @@
|
||||
checkRc: function(sqliteResultCode){
|
||||
if(!sqliteResultCode) return this;
|
||||
toss("sqlite result code",sqliteResultCode+":",
|
||||
S.sqlite3_errmsg(this._pDb) || "Unknown db error.");
|
||||
api.sqlite3_errmsg(this._pDb) || "Unknown db error.");
|
||||
},
|
||||
/**
|
||||
Finalizes all open statements and closes this database
|
||||
@@ -388,7 +391,7 @@
|
||||
Object.values(this._udfs).forEach(Module.removeFunction);
|
||||
delete this._udfs;
|
||||
delete this._statements;
|
||||
S.sqlite3_close_v2(this._pDb);
|
||||
api.sqlite3_close_v2(this._pDb);
|
||||
delete this._pDb;
|
||||
}
|
||||
},
|
||||
@@ -401,7 +404,7 @@
|
||||
a name of `main`.
|
||||
*/
|
||||
fileName: function(dbName){
|
||||
return S.sqlite3_db_filename(affirmDbOpen(this)._pDb, dbName||"main");
|
||||
return api.sqlite3_db_filename(affirmDbOpen(this)._pDb, dbName||"main");
|
||||
},
|
||||
/**
|
||||
Compiles the given SQL and returns a prepared Stmt. This is
|
||||
@@ -410,7 +413,7 @@
|
||||
prepare: function(sql){
|
||||
affirmDbOpen(this);
|
||||
setValue(pPtrArg,0,"i32");
|
||||
this.checkRc(S.sqlite3_prepare_v2(this._pDb, sql, -1, pPtrArg, null));
|
||||
this.checkRc(api.sqlite3_prepare_v2(this._pDb, sql, -1, pPtrArg, null));
|
||||
const pStmt = getValue(pPtrArg, "i32");
|
||||
if(!pStmt) toss("Empty SQL is not permitted.");
|
||||
const stmt = new Stmt(this, pStmt, BindTypes);
|
||||
@@ -533,14 +536,14 @@
|
||||
while(getValue(pSql, "i8")){
|
||||
setValue(pPtrArg, 0, "i32");
|
||||
setValue(pzTail, 0, "i32");
|
||||
this.checkRc(S.sqlite3_prepare_v2_sqlptr(
|
||||
this.checkRc(api.sqlite3_prepare_v2_sqlptr(
|
||||
this._pDb, pSql, -1, pPtrArg, pzTail
|
||||
));
|
||||
const pStmt = getValue(pPtrArg, "i32");
|
||||
pSql = getValue(pzTail, "i32");
|
||||
if(!pStmt) continue;
|
||||
if(opt.saveSql){
|
||||
opt.saveSql.push(S.sqlite3_sql(pStmt).trim());
|
||||
opt.saveSql.push(api.sqlite3_sql(pStmt).trim());
|
||||
}
|
||||
stmt = new Stmt(this, pStmt, BindTypes);
|
||||
if(bind && stmt.parameterCount){
|
||||
@@ -653,18 +656,18 @@
|
||||
const tgt = [];
|
||||
for(i = 0; i < argc; ++i){
|
||||
pVal = getValue(pArgv + (4 * i), "i32");
|
||||
valType = S.sqlite3_value_type(pVal);
|
||||
valType = api.sqlite3_value_type(pVal);
|
||||
switch(valType){
|
||||
case S.SQLITE_INTEGER:
|
||||
case S.SQLITE_FLOAT:
|
||||
arg = S.sqlite3_value_double(pVal);
|
||||
case api.SQLITE_INTEGER:
|
||||
case api.SQLITE_FLOAT:
|
||||
arg = api.sqlite3_value_double(pVal);
|
||||
break;
|
||||
case SQLITE_TEXT:
|
||||
arg = S.sqlite3_value_text(pVal);
|
||||
arg = api.sqlite3_value_text(pVal);
|
||||
break;
|
||||
case SQLITE_BLOB:{
|
||||
const n = S.sqlite3_value_bytes(ptr);
|
||||
const pBlob = S.sqlite3_value_blob(ptr);
|
||||
const n = api.sqlite3_value_bytes(ptr);
|
||||
const pBlob = api.sqlite3_value_blob(ptr);
|
||||
arg = new Uint8Array(n);
|
||||
let i;
|
||||
for(i = 0; i < n; ++i) arg[i] = HEAP8[pBlob+i];
|
||||
@@ -680,25 +683,25 @@
|
||||
f._setResult = function(pCx, val){
|
||||
switch(typeof val) {
|
||||
case 'boolean':
|
||||
S.sqlite3_result_int(pCx, val ? 1 : 0);
|
||||
api.sqlite3_result_int(pCx, val ? 1 : 0);
|
||||
break;
|
||||
case 'number': {
|
||||
(isInt32(val)
|
||||
? S.sqlite3_result_int
|
||||
: S.sqlite3_result_double)(pCx, val);
|
||||
? api.sqlite3_result_int
|
||||
: api.sqlite3_result_double)(pCx, val);
|
||||
break;
|
||||
}
|
||||
case 'string':
|
||||
S.sqlite3_result_text(pCx, val, -1,
|
||||
api.sqlite3_result_text(pCx, val, -1,
|
||||
-1/*==SQLITE_TRANSIENT*/);
|
||||
break;
|
||||
case 'object':
|
||||
if(null===val) {
|
||||
S.sqlite3_result_null(pCx);
|
||||
api.sqlite3_result_null(pCx);
|
||||
break;
|
||||
}else if(undefined!==val.length){
|
||||
const pBlob = Module.allocate(val, ALLOC_NORMAL);
|
||||
S.sqlite3_result_blob(pCx, pBlob, val.length, -1/*==SQLITE_TRANSIENT*/);
|
||||
api.sqlite3_result_blob(pCx, pBlob, val.length, -1/*==SQLITE_TRANSIENT*/);
|
||||
Module._free(blobptr);
|
||||
break;
|
||||
}
|
||||
@@ -712,20 +715,20 @@
|
||||
try{
|
||||
f._setResult(pCx, callback.apply(null, f._extractArgs(argc, pArgv)));
|
||||
}catch(e){
|
||||
S.sqlite3_result_error(pCx, e.message, -1);
|
||||
api.sqlite3_result_error(pCx, e.message, -1);
|
||||
}
|
||||
};
|
||||
const pUdf = Module.addFunction(wrapper, "viii");
|
||||
let fFlags = 0;
|
||||
if(getOwnOption(opt, 'deterministic')) fFlags |= S.SQLITE_DETERMINISTIC;
|
||||
if(getOwnOption(opt, 'directOnly')) fFlags |= S.SQLITE_DIRECTONLY;
|
||||
if(getOwnOption(opt, 'innocuous')) fFlags |= S.SQLITE_INNOCUOUS;
|
||||
if(getOwnOption(opt, 'deterministic')) fFlags |= api.SQLITE_DETERMINISTIC;
|
||||
if(getOwnOption(opt, 'directOnly')) fFlags |= api.SQLITE_DIRECTONLY;
|
||||
if(getOwnOption(opt, 'innocuous')) fFlags |= api.SQLITE_INNOCUOUS;
|
||||
name = name.toLowerCase();
|
||||
try {
|
||||
this.checkRc(S.sqlite3_create_function_v2(
|
||||
this.checkRc(api.sqlite3_create_function_v2(
|
||||
this._pDb, name,
|
||||
(opt.hasOwnProperty('arity') ? +opt.arity : callback.length),
|
||||
S.SQLITE_UTF8 | fFlags, null/*pApp*/, pUdf,
|
||||
api.SQLITE_UTF8 | fFlags, null/*pApp*/, pUdf,
|
||||
null/*xStep*/, null/*xFinal*/, null/*xDestroy*/));
|
||||
}catch(e){
|
||||
Module.removeFunction(pUdf);
|
||||
@@ -802,7 +805,7 @@
|
||||
*/
|
||||
const affirmParamIndex = function(stmt,key){
|
||||
const n = ('number'===typeof key)
|
||||
? key : S.sqlite3_bind_parameter_index(stmt._pStmt, key);
|
||||
? key : api.sqlite3_bind_parameter_index(stmt._pStmt, key);
|
||||
if(0===n || (n===key && (n!==(n|0)/*floating point*/))){
|
||||
toss("Invalid bind() parameter name: "+key);
|
||||
}
|
||||
@@ -853,7 +856,7 @@
|
||||
const bytes = intArrayFromString(val,true);
|
||||
const pStr = Module.allocate(bytes, ALLOC_NORMAL);
|
||||
stmt._allocs.push(pStr);
|
||||
const func = asBlob ? S.sqlite3_bind_blob : S.sqlite3_bind_text;
|
||||
const func = asBlob ? api.sqlite3_bind_blob : api.sqlite3_bind_text;
|
||||
return func(stmt._pStmt, ndx, pStr, bytes.length, 0);
|
||||
}
|
||||
};
|
||||
@@ -863,7 +866,7 @@
|
||||
let rc = 0;
|
||||
switch((null===val || undefined===val) ? BindTypes.null : bindType){
|
||||
case BindTypes.null:
|
||||
rc = S.sqlite3_bind_null(stmt._pStmt, ndx);
|
||||
rc = api.sqlite3_bind_null(stmt._pStmt, ndx);
|
||||
break;
|
||||
case BindTypes.string:{
|
||||
rc = f._.string(stmt, ndx, val, false);
|
||||
@@ -871,15 +874,15 @@
|
||||
}
|
||||
case BindTypes.number: {
|
||||
const m = (isInt32(val)
|
||||
? S.sqlite3_bind_int
|
||||
? api.sqlite3_bind_int
|
||||
/*It's illegal to bind a 64-bit int
|
||||
from here*/
|
||||
: S.sqlite3_bind_double);
|
||||
: api.sqlite3_bind_double);
|
||||
rc = m(stmt._pStmt, ndx, val);
|
||||
break;
|
||||
}
|
||||
case BindTypes.boolean:
|
||||
rc = S.sqlite3_bind_int(stmt._pStmt, ndx, val ? 1 : 0);
|
||||
rc = api.sqlite3_bind_int(stmt._pStmt, ndx, val ? 1 : 0);
|
||||
break;
|
||||
case BindTypes.blob: {
|
||||
if('string'===typeof val){
|
||||
@@ -892,7 +895,7 @@
|
||||
}
|
||||
const pBlob = Module.allocate(val, ALLOC_NORMAL);
|
||||
stmt._allocs.push(pBlob);
|
||||
rc = S.sqlite3_bind_blob(stmt._pStmt, ndx, pBlob, len, 0);
|
||||
rc = api.sqlite3_bind_blob(stmt._pStmt, ndx, pBlob, len, 0);
|
||||
}
|
||||
}
|
||||
default: toss("Unsupported bind() argument type.");
|
||||
@@ -923,7 +926,7 @@
|
||||
affirmUnlocked(this,'finalize()');
|
||||
freeBindMemory(this);
|
||||
delete this.db._statements[this._pStmt];
|
||||
S.sqlite3_finalize(this._pStmt);
|
||||
api.sqlite3_finalize(this._pStmt);
|
||||
delete this.columnCount;
|
||||
delete this.parameterCount;
|
||||
delete this._pStmt;
|
||||
@@ -937,7 +940,7 @@
|
||||
freeBindMemory(
|
||||
affirmUnlocked(affirmStmtOpen(this), 'clearBindings()')
|
||||
);
|
||||
S.sqlite3_clear_bindings(this._pStmt);
|
||||
api.sqlite3_clear_bindings(this._pStmt);
|
||||
this._mayGet = false;
|
||||
return this;
|
||||
},
|
||||
@@ -953,7 +956,7 @@
|
||||
reset: function(alsoClearBinds){
|
||||
affirmUnlocked(this,'reset()');
|
||||
if(alsoClearBinds) this.clearBindings();
|
||||
S.sqlite3_reset(affirmStmtOpen(this)._pStmt);
|
||||
api.sqlite3_reset(affirmStmtOpen(this)._pStmt);
|
||||
this._mayGet = false;
|
||||
return this;
|
||||
},
|
||||
@@ -1098,14 +1101,14 @@
|
||||
*/
|
||||
step: function(){
|
||||
affirmUnlocked(this, 'step()');
|
||||
const rc = S.sqlite3_step(affirmStmtOpen(this)._pStmt);
|
||||
const rc = api.sqlite3_step(affirmStmtOpen(this)._pStmt);
|
||||
switch(rc){
|
||||
case S.SQLITE_DONE: return this._mayGet = false;
|
||||
case S.SQLITE_ROW: return this._mayGet = true;
|
||||
case api.SQLITE_DONE: return this._mayGet = false;
|
||||
case api.SQLITE_ROW: return this._mayGet = true;
|
||||
default:
|
||||
this._mayGet = false;
|
||||
console.warn("sqlite3_step() rc=",rc,"SQL =",
|
||||
S.sqlite3_sql(this._pStmt));
|
||||
api.sqlite3_sql(this._pStmt));
|
||||
this.db.checkRc(rc);
|
||||
};
|
||||
},
|
||||
@@ -1155,27 +1158,27 @@
|
||||
}else if(ndx && 'object'===typeof ndx){
|
||||
let i = 0;
|
||||
while(i<this.columnCount){
|
||||
ndx[S.sqlite3_column_name(this._pStmt,i)] = this.get(i++);
|
||||
ndx[api.sqlite3_column_name(this._pStmt,i)] = this.get(i++);
|
||||
}
|
||||
return ndx;
|
||||
}
|
||||
affirmColIndex(this, ndx);
|
||||
switch(undefined===asType
|
||||
? S.sqlite3_column_type(this._pStmt, ndx)
|
||||
? api.sqlite3_column_type(this._pStmt, ndx)
|
||||
: asType){
|
||||
case S.SQLITE_NULL: return null;
|
||||
case S.SQLITE_INTEGER:{
|
||||
return 0 | S.sqlite3_column_double(this._pStmt, ndx);
|
||||
case api.SQLITE_NULL: return null;
|
||||
case api.SQLITE_INTEGER:{
|
||||
return 0 | api.sqlite3_column_double(this._pStmt, ndx);
|
||||
/* ^^^^^^^^ strips any fractional part and handles
|
||||
handles >32bits */
|
||||
}
|
||||
case S.SQLITE_FLOAT:
|
||||
return S.sqlite3_column_double(this._pStmt, ndx);
|
||||
case S.SQLITE_TEXT:
|
||||
return S.sqlite3_column_text(this._pStmt, ndx);
|
||||
case S.SQLITE_BLOB: {
|
||||
const n = S.sqlite3_column_bytes(this._pStmt, ndx);
|
||||
const ptr = S.sqlite3_column_blob(this._pStmt, ndx);
|
||||
case api.SQLITE_FLOAT:
|
||||
return api.sqlite3_column_double(this._pStmt, ndx);
|
||||
case api.SQLITE_TEXT:
|
||||
return api.sqlite3_column_text(this._pStmt, ndx);
|
||||
case api.SQLITE_BLOB: {
|
||||
const n = api.sqlite3_column_bytes(this._pStmt, ndx);
|
||||
const ptr = api.sqlite3_column_blob(this._pStmt, ndx);
|
||||
const rc = new Uint8Array(n);
|
||||
for(let i = 0; i < n; ++i) rc[i] = HEAP8[ptr + i];
|
||||
return rc;
|
||||
@@ -1187,16 +1190,16 @@
|
||||
},
|
||||
/** Equivalent to get(ndx) but coerces the result to an
|
||||
integer. */
|
||||
getInt: function(ndx){return this.get(ndx,S.SQLITE_INTEGER)},
|
||||
getInt: function(ndx){return this.get(ndx,api.SQLITE_INTEGER)},
|
||||
/** Equivalent to get(ndx) but coerces the result to a
|
||||
float. */
|
||||
getFloat: function(ndx){return this.get(ndx,S.SQLITE_FLOAT)},
|
||||
getFloat: function(ndx){return this.get(ndx,api.SQLITE_FLOAT)},
|
||||
/** Equivalent to get(ndx) but coerces the result to a
|
||||
string. */
|
||||
getString: function(ndx){return this.get(ndx,S.SQLITE_TEXT)},
|
||||
getString: function(ndx){return this.get(ndx,api.SQLITE_TEXT)},
|
||||
/** Equivalent to get(ndx) but coerces the result to a
|
||||
Uint8Array. */
|
||||
getBlob: function(ndx){return this.get(ndx,S.SQLITE_BLOB)},
|
||||
getBlob: function(ndx){return this.get(ndx,api.SQLITE_BLOB)},
|
||||
/**
|
||||
A convenience wrapper around get() which fetches the value
|
||||
as a string and then, if it is not null, passes it to
|
||||
@@ -1205,16 +1208,17 @@
|
||||
string, on the other hand, will trigger an exception.
|
||||
*/
|
||||
getJSON: function(ndx){
|
||||
const s = this.get(ndx, S.SQLITE_STRING);
|
||||
const s = this.get(ndx, api.SQLITE_STRING);
|
||||
return null===s ? s : JSON.parse(s);
|
||||
},
|
||||
/**
|
||||
Returns the result column name of the given index, or
|
||||
throws if index is out of bounds or this statement has been
|
||||
finalized.
|
||||
finalized. This can be used without having run step()
|
||||
first.
|
||||
*/
|
||||
getColumnName: function(ndx){
|
||||
return S.sqlite3_column_name(
|
||||
return api.sqlite3_column_name(
|
||||
affirmColIndex(affirmStmtOpen(this),ndx)._pStmt, ndx
|
||||
);
|
||||
},
|
||||
@@ -1230,7 +1234,7 @@
|
||||
affirmColIndex(affirmStmtOpen(this),0);
|
||||
if(!tgt) tgt = [];
|
||||
for(let i = 0; i < this.columnCount; ++i){
|
||||
tgt.push(S.sqlite3_column_name(this._pStmt, i));
|
||||
tgt.push(api.sqlite3_column_name(this._pStmt, i));
|
||||
}
|
||||
return tgt;
|
||||
},
|
||||
@@ -1242,7 +1246,7 @@
|
||||
*/
|
||||
getParamIndex: function(name){
|
||||
return (affirmStmtOpen(this).parameterCount
|
||||
? S.sqlite3_bind_parameter_index(this._pStmt, name)
|
||||
? api.sqlite3_bind_parameter_index(this._pStmt, name)
|
||||
: undefined);
|
||||
}
|
||||
}/*Stmt.prototype*/;
|
||||
@@ -1250,7 +1254,7 @@
|
||||
/** OO binding's namespace. */
|
||||
const SQLite3 = {
|
||||
version: {
|
||||
lib: S.sqlite3_libversion(),
|
||||
lib: api.sqlite3_libversion(),
|
||||
ooApi: "0.0.1"
|
||||
},
|
||||
DB,
|
||||
@@ -1293,7 +1297,7 @@
|
||||
}
|
||||
const rc = {}, ov = [0,0];
|
||||
let i = 0, k;
|
||||
while((k = S.sqlite3_compileoption_get(i++))){
|
||||
while((k = api.sqlite3_compileoption_get(i++))){
|
||||
f._opt(k,ov);
|
||||
rc[ov[0]] = ov[1];
|
||||
}
|
||||
@@ -1302,19 +1306,19 @@
|
||||
else if(Array.isArray(optName)){
|
||||
const rc = {};
|
||||
optName.forEach((v)=>{
|
||||
rc[v] = S.sqlite3_compileoption_used(v);
|
||||
rc[v] = api.sqlite3_compileoption_used(v);
|
||||
});
|
||||
return rc;
|
||||
}
|
||||
else if('object' === typeof optName){
|
||||
Object.keys(optName).forEach((k)=> {
|
||||
optName[k] = S.sqlite3_compileoption_used(k);
|
||||
optName[k] = api.sqlite3_compileoption_used(k);
|
||||
});
|
||||
return optName;
|
||||
}
|
||||
return (
|
||||
'string'===typeof optName
|
||||
) ? !!S.sqlite3_compileoption_used(optName) : false;
|
||||
) ? !!api.sqlite3_compileoption_used(optName) : false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1322,4 +1326,4 @@
|
||||
api: api,
|
||||
SQLite3
|
||||
};
|
||||
})(self/*worker or window*/);
|
||||
})(self/*worker or window*/.Module);
|
||||
|
||||
Reference in New Issue
Block a user