mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-27 20:41:58 +03:00
Numerous cleanups in the JS bits. Removed some now-defunct wasm test files. Expose sqlite3.opfs object containing various OPFS-specific utilities.
FossilOrigin-Name: 26e625d05d9820033b23536f18ad3ddc59ed712ad507d4b0c7fe88abd15d2be8
This commit is contained in:
@ -85,9 +85,24 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
|
||||
/**
|
||||
A proxy for DB class constructors. It must be called with the
|
||||
being-construct DB object as its "this".
|
||||
being-construct DB object as its "this". See the DB constructor
|
||||
for the argument docs. This is split into a separate function
|
||||
in order to enable simple creation of special-case DB constructors,
|
||||
e.g. a hypothetical LocalStorageDB or OpfsDB.
|
||||
|
||||
Expects to be passed a configuration object with the following
|
||||
properties:
|
||||
|
||||
- `.filename`: the db filename. It may be a special name like ":memory:"
|
||||
or "".
|
||||
|
||||
- `.flags`: as documented in the DB constructor.
|
||||
|
||||
- `.vfs`: as documented in the DB constructor.
|
||||
|
||||
It also accepts those as the first 3 arguments.
|
||||
*/
|
||||
const dbCtorHelper = function ctor(fn=':memory:', flags='c', vfsName){
|
||||
const dbCtorHelper = function ctor(...args){
|
||||
if(!ctor._name2vfs){
|
||||
// Map special filenames which we handle here (instead of in C)
|
||||
// to some helpful metadata...
|
||||
@ -104,25 +119,33 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
filename: isWorkerThread || (()=>'session')
|
||||
};
|
||||
}
|
||||
if('string'!==typeof fn){
|
||||
toss3("Invalid filename for DB constructor.");
|
||||
const opt = ctor.normalizeArgs(...args);
|
||||
let fn = opt.filename, vfsName = opt.vfs, flagsStr = opt.flags;
|
||||
if(('string'!==typeof fn && 'number'!==typeof fn)
|
||||
|| 'string'!==typeof flagsStr
|
||||
|| (vfsName && ('string'!==typeof vfsName && 'number'!==typeof vfsName))){
|
||||
console.error("Invalid DB ctor args",opt,arguments);
|
||||
toss3("Invalid arguments for DB constructor.");
|
||||
}
|
||||
const vfsCheck = ctor._name2vfs[fn];
|
||||
let fnJs = ('number'===typeof fn) ? capi.wasm.cstringToJs(fn) : fn;
|
||||
const vfsCheck = ctor._name2vfs[fnJs];
|
||||
if(vfsCheck){
|
||||
vfsName = vfsCheck.vfs;
|
||||
fn = vfsCheck.filename(fn);
|
||||
fn = fnJs = vfsCheck.filename(fnJs);
|
||||
}
|
||||
let ptr, oflags = 0;
|
||||
if( flags.indexOf('c')>=0 ){
|
||||
if( flagsStr.indexOf('c')>=0 ){
|
||||
oflags |= capi.SQLITE_OPEN_CREATE | capi.SQLITE_OPEN_READWRITE;
|
||||
}
|
||||
if( flags.indexOf('w')>=0 ) oflags |= capi.SQLITE_OPEN_READWRITE;
|
||||
if( flagsStr.indexOf('w')>=0 ) oflags |= capi.SQLITE_OPEN_READWRITE;
|
||||
if( 0===oflags ) oflags |= capi.SQLITE_OPEN_READONLY;
|
||||
oflags |= capi.SQLITE_OPEN_EXRESCODE;
|
||||
const stack = capi.wasm.scopedAllocPush();
|
||||
try {
|
||||
const ppDb = capi.wasm.scopedAllocPtr() /* output (sqlite3**) arg */;
|
||||
const pVfsName = vfsName ? capi.wasm.scopedAllocCString(vfsName) : 0;
|
||||
const pVfsName = vfsName ? (
|
||||
('number'===typeof vfsName ? vfsName : capi.wasm.scopedAllocCString(vfsName))
|
||||
): 0;
|
||||
const rc = capi.sqlite3_open_v2(fn, ppDb, oflags, pVfsName);
|
||||
ptr = capi.wasm.getPtrValue(ppDb);
|
||||
checkSqlite3Rc(ptr, rc);
|
||||
@ -132,11 +155,36 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
}finally{
|
||||
capi.wasm.scopedAllocPop(stack);
|
||||
}
|
||||
this.filename = fn;
|
||||
this.filename = fnJs;
|
||||
__ptrMap.set(this, ptr);
|
||||
__stmtMap.set(this, Object.create(null));
|
||||
__udfMap.set(this, Object.create(null));
|
||||
};
|
||||
|
||||
/**
|
||||
A helper for DB constructors. It accepts either a single
|
||||
config-style object or up to 3 arguments (filename, dbOpenFlags,
|
||||
dbVfsName). It returns a new object containing:
|
||||
|
||||
{ filename: ..., flags: ..., vfs: ... }
|
||||
|
||||
If passed an object, any additional properties it has are copied
|
||||
as-is into the new object.
|
||||
*/
|
||||
dbCtorHelper.normalizeArgs = function(filename,flags = 'c',vfs = null){
|
||||
const arg = {};
|
||||
if(1===arguments.length && 'object'===typeof arguments[0]){
|
||||
const x = arguments[0];
|
||||
Object.keys(x).forEach((k)=>arg[k] = x[k]);
|
||||
if(undefined===arg.flags) arg.flags = 'c';
|
||||
if(undefined===arg.vfs) arg.vfs = null;
|
||||
}else{
|
||||
arg.filename = filename;
|
||||
arg.flags = flags;
|
||||
arg.vfs = vfs;
|
||||
}
|
||||
return arg;
|
||||
};
|
||||
|
||||
/**
|
||||
The DB class provides a high-level OO wrapper around an sqlite3
|
||||
@ -175,6 +223,17 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
or not at all, to use the default. If passed a value, it must
|
||||
be the string name of a VFS
|
||||
|
||||
The constructor optionally (and preferably) takes its arguments
|
||||
in the form of a single configuration object with the following
|
||||
properties:
|
||||
|
||||
- `.filename`: database file name
|
||||
- `.flags`: open-mode flags
|
||||
- `.vfs`: the VFS fname
|
||||
|
||||
The `filename` and `vfs` arguments may be either JS strings or
|
||||
C-strings allocated via WASM.
|
||||
|
||||
For purposes of passing a DB instance to C-style sqlite3
|
||||
functions, the DB object's read-only `pointer` property holds its
|
||||
`sqlite3*` pointer value. That property can also be used to check
|
||||
@ -187,12 +246,12 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
the database. In this mode, only a single database is permitted
|
||||
in each storage object. This feature is experimental and subject
|
||||
to any number of changes (including outright removal). This
|
||||
support requires a specific build of sqlite3, the existence of
|
||||
which can be determined at runtime by checking for a non-0 return
|
||||
value from sqlite3.capi.sqlite3_vfs_find("kvvfs").
|
||||
support requires the kvvfs sqlite3 VFS, the existence of which
|
||||
can be determined at runtime by checking for a non-0 return value
|
||||
from sqlite3.capi.sqlite3_vfs_find("kvvfs").
|
||||
*/
|
||||
const DB = function ctor(fn=':memory:', flags='c', vfsName){
|
||||
dbCtorHelper.apply(this, Array.prototype.slice.call(arguments));
|
||||
const DB = function(...args){
|
||||
dbCtorHelper.apply(this, args);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -361,12 +420,31 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
closed. After calling close(), `this.pointer` will resolve to
|
||||
`undefined`, so that can be used to check whether the db
|
||||
instance is still opened.
|
||||
|
||||
If this.onclose.before is a function then it is called before
|
||||
any close-related cleanup.
|
||||
|
||||
If this.onclose.after is a function then it is called after the
|
||||
db is closed but before auxiliary state like this.filename is
|
||||
cleared.
|
||||
|
||||
Both onclose handlers are passed this object. If this db is not
|
||||
opened, neither of the handlers are called. Any exceptions the
|
||||
handlers throw are ignored because "destructors must not
|
||||
throw."
|
||||
|
||||
Note that garbage collection of a db handle, if it happens at
|
||||
all, will never trigger close(), so onclose handlers are not a
|
||||
reliable way to implement close-time cleanup or maintenance of
|
||||
a db.
|
||||
*/
|
||||
close: function(){
|
||||
if(this.pointer){
|
||||
if(this.onclose && (this.onclose.before instanceof Function)){
|
||||
try{this.onclose.before(this)}
|
||||
catch(e){/*ignore*/}
|
||||
}
|
||||
const pDb = this.pointer;
|
||||
let s;
|
||||
const that = this;
|
||||
Object.keys(__stmtMap.get(this)).forEach((k,s)=>{
|
||||
if(s && s.pointer) s.finalize();
|
||||
});
|
||||
@ -377,6 +455,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
__stmtMap.delete(this);
|
||||
__udfMap.delete(this);
|
||||
capi.sqlite3_close_v2(pDb);
|
||||
if(this.onclose && (this.onclose.after instanceof Function)){
|
||||
try{this.onclose.after(this)}
|
||||
catch(e){/*ignore*/}
|
||||
}
|
||||
delete this.filename;
|
||||
}
|
||||
},
|
||||
@ -401,13 +483,13 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
}
|
||||
},
|
||||
/**
|
||||
Similar to this.filename but will return NULL for special names
|
||||
like ":memory:". Not of much use until we have filesystem
|
||||
support. Throws if the DB has been closed. If passed an
|
||||
argument it then it will return the filename of the ATTACHEd db
|
||||
with that name, else it assumes a name of `main`.
|
||||
Similar to this.filename but will return a falsy value for
|
||||
special names like ":memory:". Throws if the DB has been
|
||||
closed. If passed an argument it then it will return the
|
||||
filename of the ATTACHEd db with that name, else it assumes a
|
||||
name of `main`.
|
||||
*/
|
||||
fileName: function(dbName='main'){
|
||||
getFilename: function(dbName='main'){
|
||||
return capi.sqlite3_db_filename(affirmDbOpen(this).pointer, dbName);
|
||||
},
|
||||
/**
|
||||
@ -1591,7 +1673,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
ooApi: "0.1"
|
||||
},
|
||||
DB,
|
||||
Stmt
|
||||
Stmt,
|
||||
dbCtorHelper
|
||||
}/*oo1 object*/;
|
||||
|
||||
});
|
||||
|
Reference in New Issue
Block a user