diff options
author | stephan <stephan@noemail.net> | 2024-01-11 12:31:58 +0000 |
---|---|---|
committer | stephan <stephan@noemail.net> | 2024-01-11 12:31:58 +0000 |
commit | 598328209f421d48e98115dd6816da5114403616 (patch) | |
tree | 7d333fc901bd29e575c7b22fd173e93e4ce23866 /ext/wasm/api/sqlite3-v-helper.js | |
parent | 6b36d0b46189d217721d25ce475fad171ae0a227 (diff) | |
download | sqlite-598328209f421d48e98115dd6816da5114403616.tar.gz sqlite-598328209f421d48e98115dd6816da5114403616.zip |
Split the JS vfs/vtab helper code into discreet units as a step towards a build which optionally elides those pieces. This is an internal restructuring change and does not affect the API.
FossilOrigin-Name: ede945fd2360097d9961b8a4b8fb48fea57399cb9163534ed1c3c6b86588b0a5
Diffstat (limited to 'ext/wasm/api/sqlite3-v-helper.js')
-rw-r--r-- | ext/wasm/api/sqlite3-v-helper.js | 718 |
1 files changed, 0 insertions, 718 deletions
diff --git a/ext/wasm/api/sqlite3-v-helper.js b/ext/wasm/api/sqlite3-v-helper.js deleted file mode 100644 index e63da8afc..000000000 --- a/ext/wasm/api/sqlite3-v-helper.js +++ /dev/null @@ -1,718 +0,0 @@ -/* -** 2022-11-30 -** -** The author disclaims copyright to this source code. In place of a -** legal notice, here is a blessing: -** -** * May you do good and not evil. -** * May you find forgiveness for yourself and forgive others. -** * May you share freely, never taking more than you give. -*/ - -/** - This file installs sqlite3.vfs, and object which exists to assist - in the creation of JavaScript implementations of sqlite3_vfs, along - with its virtual table counterpart, sqlite3.vtab. -*/ -'use strict'; -globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ - const wasm = sqlite3.wasm, capi = sqlite3.capi, toss = sqlite3.util.toss3; - const vfs = Object.create(null), vtab = Object.create(null); - - const StructBinder = sqlite3.StructBinder - /* we require a local alias b/c StructBinder is removed from the sqlite3 - object during the final steps of the API cleanup. */; - sqlite3.vfs = vfs; - sqlite3.vtab = vtab; - - const sii = capi.sqlite3_index_info; - /** - If n is >=0 and less than this.$nConstraint, this function - returns either a WASM pointer to the 0-based nth entry of - this.$aConstraint (if passed a truthy 2nd argument) or an - sqlite3_index_info.sqlite3_index_constraint object wrapping that - address (if passed a falsy value or no 2nd argument). Returns a - falsy value if n is out of range. - */ - sii.prototype.nthConstraint = function(n, asPtr=false){ - if(n<0 || n>=this.$nConstraint) return false; - const ptr = this.$aConstraint + ( - sii.sqlite3_index_constraint.structInfo.sizeof * n - ); - return asPtr ? ptr : new sii.sqlite3_index_constraint(ptr); - }; - - /** - Works identically to nthConstraint() but returns state from - this.$aConstraintUsage, so returns an - sqlite3_index_info.sqlite3_index_constraint_usage instance - if passed no 2nd argument or a falsy 2nd argument. - */ - sii.prototype.nthConstraintUsage = function(n, asPtr=false){ - if(n<0 || n>=this.$nConstraint) return false; - const ptr = this.$aConstraintUsage + ( - sii.sqlite3_index_constraint_usage.structInfo.sizeof * n - ); - return asPtr ? ptr : new sii.sqlite3_index_constraint_usage(ptr); - }; - - /** - If n is >=0 and less than this.$nOrderBy, this function - returns either a WASM pointer to the 0-based nth entry of - this.$aOrderBy (if passed a truthy 2nd argument) or an - sqlite3_index_info.sqlite3_index_orderby object wrapping that - address (if passed a falsy value or no 2nd argument). Returns a - falsy value if n is out of range. - */ - sii.prototype.nthOrderBy = function(n, asPtr=false){ - if(n<0 || n>=this.$nOrderBy) return false; - const ptr = this.$aOrderBy + ( - sii.sqlite3_index_orderby.structInfo.sizeof * n - ); - return asPtr ? ptr : new sii.sqlite3_index_orderby(ptr); - }; - - /** - Installs a StructBinder-bound function pointer member of the - given name and function in the given StructType target object. - - It creates a WASM proxy for the given function and arranges for - that proxy to be cleaned up when tgt.dispose() is called. Throws - on the slightest hint of error, e.g. tgt is-not-a StructType, - name does not map to a struct-bound member, etc. - - As a special case, if the given function is a pointer, then - `wasm.functionEntry()` is used to validate that it is a known - function. If so, it is used as-is with no extra level of proxying - or cleanup, else an exception is thrown. It is legal to pass a - value of 0, indicating a NULL pointer, with the caveat that 0 - _is_ a legal function pointer in WASM but it will not be accepted - as such _here_. (Justification: the function at address zero must - be one which initially came from the WASM module, not a method we - want to bind to a virtual table or VFS.) - - This function returns a proxy for itself which is bound to tgt - and takes 2 args (name,func). That function returns the same - thing as this one, permitting calls to be chained. - - If called with only 1 arg, it has no side effects but returns a - func with the same signature as described above. - - ACHTUNG: because we cannot generically know how to transform JS - exceptions into result codes, the installed functions do no - automatic catching of exceptions. It is critical, to avoid - undefined behavior in the C layer, that methods mapped via - this function do not throw. The exception, as it were, to that - rule is... - - If applyArgcCheck is true then each JS function (as opposed to - function pointers) gets wrapped in a proxy which asserts that it - is passed the expected number of arguments, throwing if the - argument count does not match expectations. That is only intended - for dev-time usage for sanity checking, and will leave the C - environment in an undefined state. - */ - const installMethod = function callee( - tgt, name, func, applyArgcCheck = callee.installMethodArgcCheck - ){ - if(!(tgt instanceof StructBinder.StructType)){ - toss("Usage error: target object is-not-a StructType."); - }else if(!(func instanceof Function) && !wasm.isPtr(func)){ - toss("Usage errror: expecting a Function or WASM pointer to one."); - } - if(1===arguments.length){ - return (n,f)=>callee(tgt, n, f, applyArgcCheck); - } - if(!callee.argcProxy){ - callee.argcProxy = function(tgt, funcName, func,sig){ - return function(...args){ - if(func.length!==arguments.length){ - toss("Argument mismatch for", - tgt.structInfo.name+"::"+funcName - +": Native signature is:",sig); - } - return func.apply(this, args); - } - }; - /* An ondispose() callback for use with - StructBinder-created types. */ - callee.removeFuncList = function(){ - if(this.ondispose.__removeFuncList){ - this.ondispose.__removeFuncList.forEach( - (v,ndx)=>{ - if('number'===typeof v){ - try{wasm.uninstallFunction(v)} - catch(e){/*ignore*/} - } - /* else it's a descriptive label for the next number in - the list. */ - } - ); - delete this.ondispose.__removeFuncList; - } - }; - }/*static init*/ - const sigN = tgt.memberSignature(name); - if(sigN.length<2){ - toss("Member",name,"does not have a function pointer signature:",sigN); - } - const memKey = tgt.memberKey(name); - const fProxy = (applyArgcCheck && !wasm.isPtr(func)) - /** This middle-man proxy is only for use during development, to - confirm that we always pass the proper number of - arguments. We know that the C-level code will always use the - correct argument count. */ - ? callee.argcProxy(tgt, memKey, func, sigN) - : func; - if(wasm.isPtr(fProxy)){ - if(fProxy && !wasm.functionEntry(fProxy)){ - toss("Pointer",fProxy,"is not a WASM function table entry."); - } - tgt[memKey] = fProxy; - }else{ - const pFunc = wasm.installFunction(fProxy, tgt.memberSignature(name, true)); - tgt[memKey] = pFunc; - if(!tgt.ondispose || !tgt.ondispose.__removeFuncList){ - tgt.addOnDispose('ondispose.__removeFuncList handler', - callee.removeFuncList); - tgt.ondispose.__removeFuncList = []; - } - tgt.ondispose.__removeFuncList.push(memKey, pFunc); - } - return (n,f)=>callee(tgt, n, f, applyArgcCheck); - }/*installMethod*/; - installMethod.installMethodArgcCheck = false; - - /** - Installs methods into the given StructType-type instance. Each - entry in the given methods object must map to a known member of - the given StructType, else an exception will be triggered. See - installMethod() for more details, including the semantics of the - 3rd argument. - - As an exception to the above, if any two or more methods in the - 2nd argument are the exact same function, installMethod() is - _not_ called for the 2nd and subsequent instances, and instead - those instances get assigned the same method pointer which is - created for the first instance. This optimization is primarily to - accommodate special handling of sqlite3_module::xConnect and - xCreate methods. - - On success, returns its first argument. Throws on error. - */ - const installMethods = function( - structInstance, methods, applyArgcCheck = installMethod.installMethodArgcCheck - ){ - const seen = new Map /* map of <Function, memberName> */; - for(const k of Object.keys(methods)){ - const m = methods[k]; - const prior = seen.get(m); - if(prior){ - const mkey = structInstance.memberKey(k); - structInstance[mkey] = structInstance[structInstance.memberKey(prior)]; - }else{ - installMethod(structInstance, k, m, applyArgcCheck); - seen.set(m, k); - } - } - return structInstance; - }; - - /** - Equivalent to calling installMethod(this,...arguments) with a - first argument of this object. If called with 1 or 2 arguments - and the first is an object, it's instead equivalent to calling - installMethods(this,...arguments). - */ - StructBinder.StructType.prototype.installMethod = function callee( - name, func, applyArgcCheck = installMethod.installMethodArgcCheck - ){ - return (arguments.length < 3 && name && 'object'===typeof name) - ? installMethods(this, ...arguments) - : installMethod(this, ...arguments); - }; - - /** - Equivalent to calling installMethods() with a first argument - of this object. - */ - StructBinder.StructType.prototype.installMethods = function( - methods, applyArgcCheck = installMethod.installMethodArgcCheck - ){ - return installMethods(this, methods, applyArgcCheck); - }; - - /** - Uses sqlite3_vfs_register() to register this - sqlite3.capi.sqlite3_vfs. This object must have already been - filled out properly. If the first argument is truthy, the VFS is - registered as the default VFS, else it is not. - - On success, returns this object. Throws on error. - */ - capi.sqlite3_vfs.prototype.registerVfs = function(asDefault=false){ - if(!(this instanceof sqlite3.capi.sqlite3_vfs)){ - toss("Expecting a sqlite3_vfs-type argument."); - } - const rc = capi.sqlite3_vfs_register(this, asDefault ? 1 : 0); - if(rc){ - toss("sqlite3_vfs_register(",this,") failed with rc",rc); - } - if(this.pointer !== capi.sqlite3_vfs_find(this.$zName)){ - toss("BUG: sqlite3_vfs_find(vfs.$zName) failed for just-installed VFS", - this); - } - return this; - }; - - /** - A wrapper for installMethods() or registerVfs() to reduce - installation of a VFS and/or its I/O methods to a single - call. - - Accepts an object which contains the properties "io" and/or - "vfs", each of which is itself an object with following properties: - - - `struct`: an sqlite3.StructType-type struct. This must be a - populated (except for the methods) object of type - sqlite3_io_methods (for the "io" entry) or sqlite3_vfs (for the - "vfs" entry). - - - `methods`: an object mapping sqlite3_io_methods method names - (e.g. 'xClose') to JS implementations of those methods. The JS - implementations must be call-compatible with their native - counterparts. - - For each of those object, this function passes its (`struct`, - `methods`, (optional) `applyArgcCheck`) properties to - installMethods(). - - If the `vfs` entry is set then: - - - Its `struct` property's registerVfs() is called. The - `vfs` entry may optionally have an `asDefault` property, which - gets passed as the argument to registerVfs(). - - - If `struct.$zName` is falsy and the entry has a string-type - `name` property, `struct.$zName` is set to the C-string form of - that `name` value before registerVfs() is called. That string - gets added to the on-dispose state of the struct. - - On success returns this object. Throws on error. - */ - vfs.installVfs = function(opt){ - let count = 0; - const propList = ['io','vfs']; - for(const key of propList){ - const o = opt[key]; - if(o){ - ++count; - installMethods(o.struct, o.methods, !!o.applyArgcCheck); - if('vfs'===key){ - if(!o.struct.$zName && 'string'===typeof o.name){ - o.struct.addOnDispose( - o.struct.$zName = wasm.allocCString(o.name) - ); - } - o.struct.registerVfs(!!o.asDefault); - } - } - } - if(!count) toss("Misuse: installVfs() options object requires at least", - "one of:", propList); - return this; - }; - - /** - Internal factory function for xVtab and xCursor impls. - */ - const __xWrapFactory = function(methodName,StructType){ - return function(ptr,removeMapping=false){ - if(0===arguments.length) ptr = new StructType; - if(ptr instanceof StructType){ - //T.assert(!this.has(ptr.pointer)); - this.set(ptr.pointer, ptr); - return ptr; - }else if(!wasm.isPtr(ptr)){ - sqlite3.SQLite3Error.toss("Invalid argument to",methodName+"()"); - } - let rc = this.get(ptr); - if(removeMapping) this.delete(ptr); - return rc; - }.bind(new Map); - }; - - /** - A factory function which implements a simple lifetime manager for - mappings between C struct pointers and their JS-level wrappers. - The first argument must be the logical name of the manager - (e.g. 'xVtab' or 'xCursor'), which is only used for error - reporting. The second must be the capi.XYZ struct-type value, - e.g. capi.sqlite3_vtab or capi.sqlite3_vtab_cursor. - - Returns an object with 4 methods: create(), get(), unget(), and - dispose(), plus a StructType member with the value of the 2nd - argument. The methods are documented in the body of this - function. - */ - const StructPtrMapper = function(name, StructType){ - const __xWrap = __xWrapFactory(name,StructType); - /** - This object houses a small API for managing mappings of (`T*`) - to StructType<T> objects, specifically within the lifetime - requirements of sqlite3_module methods. - */ - return Object.assign(Object.create(null),{ - /** The StructType object for this object's API. */ - StructType, - /** - Creates a new StructType object, writes its `pointer` - value to the given output pointer, and returns that - object. Its intended usage depends on StructType: - - sqlite3_vtab: to be called from sqlite3_module::xConnect() - or xCreate() implementations. - - sqlite3_vtab_cursor: to be called from xOpen(). - - This will throw if allocation of the StructType instance - fails or if ppOut is not a pointer-type value. - */ - create: (ppOut)=>{ - const rc = __xWrap(); - wasm.pokePtr(ppOut, rc.pointer); - return rc; - }, - /** - Returns the StructType object previously mapped to the - given pointer using create(). Its intended usage depends - on StructType: - - sqlite3_vtab: to be called from sqlite3_module methods which - take a (sqlite3_vtab*) pointer _except_ for - xDestroy()/xDisconnect(), in which case unget() or dispose(). - - sqlite3_vtab_cursor: to be called from any sqlite3_module methods - which take a `sqlite3_vtab_cursor*` argument except xClose(), - in which case use unget() or dispose(). - - Rule to remember: _never_ call dispose() on an instance - returned by this function. - */ - get: (pCObj)=>__xWrap(pCObj), - /** - Identical to get() but also disconnects the mapping between the - given pointer and the returned StructType object, such that - future calls to this function or get() with the same pointer - will return the undefined value. Its intended usage depends - on StructType: - - sqlite3_vtab: to be called from sqlite3_module::xDisconnect() or - xDestroy() implementations or in error handling of a failed - xCreate() or xConnect(). - - sqlite3_vtab_cursor: to be called from xClose() or during - cleanup in a failed xOpen(). - - Calling this method obligates the caller to call dispose() on - the returned object when they're done with it. - */ - unget: (pCObj)=>__xWrap(pCObj,true), - /** - Works like unget() plus it calls dispose() on the - StructType object. - */ - dispose: (pCObj)=>{ - const o = __xWrap(pCObj,true); - if(o) o.dispose(); - } - }); - }; - - /** - A lifetime-management object for mapping `sqlite3_vtab*` - instances in sqlite3_module methods to capi.sqlite3_vtab - objects. - - The API docs are in the API-internal StructPtrMapper(). - */ - vtab.xVtab = StructPtrMapper('xVtab', capi.sqlite3_vtab); - - /** - A lifetime-management object for mapping `sqlite3_vtab_cursor*` - instances in sqlite3_module methods to capi.sqlite3_vtab_cursor - objects. - - The API docs are in the API-internal StructPtrMapper(). - */ - vtab.xCursor = StructPtrMapper('xCursor', capi.sqlite3_vtab_cursor); - - /** - Convenience form of creating an sqlite3_index_info wrapper, - intended for use in xBestIndex implementations. Note that the - caller is expected to call dispose() on the returned object - before returning. Though not _strictly_ required, as that object - does not own the pIdxInfo memory, it is nonetheless good form. - */ - vtab.xIndexInfo = (pIdxInfo)=>new capi.sqlite3_index_info(pIdxInfo); - - /** - Given an error object, this function returns - sqlite3.capi.SQLITE_NOMEM if (e instanceof - sqlite3.WasmAllocError), else it returns its - second argument. Its intended usage is in the methods - of a sqlite3_vfs or sqlite3_module: - - ``` - try{ - let rc = ... - return rc; - }catch(e){ - return sqlite3.vtab.exceptionToRc(e, sqlite3.capi.SQLITE_XYZ); - // where SQLITE_XYZ is some call-appropriate result code. - } - ``` - */ - /**vfs.exceptionToRc = vtab.exceptionToRc = - (e, defaultRc=capi.SQLITE_ERROR)=>( - (e instanceof sqlite3.WasmAllocError) - ? capi.SQLITE_NOMEM - : defaultRc - );*/ - - /** - Given an sqlite3_module method name and error object, this - function returns sqlite3.capi.SQLITE_NOMEM if (e instanceof - sqlite3.WasmAllocError), else it returns its second argument. Its - intended usage is in the methods of a sqlite3_vfs or - sqlite3_module: - - ``` - try{ - let rc = ... - return rc; - }catch(e){ - return sqlite3.vtab.xError( - 'xColumn', e, sqlite3.capi.SQLITE_XYZ); - // where SQLITE_XYZ is some call-appropriate result code. - } - ``` - - If no 3rd argument is provided, its default depends on - the error type: - - - An sqlite3.WasmAllocError always resolves to capi.SQLITE_NOMEM. - - - If err is an SQLite3Error then its `resultCode` property - is used. - - - If all else fails, capi.SQLITE_ERROR is used. - - If xError.errorReporter is a function, it is called in - order to report the error, else the error is not reported. - If that function throws, that exception is ignored. - */ - vtab.xError = function f(methodName, err, defaultRc){ - if(f.errorReporter instanceof Function){ - try{f.errorReporter("sqlite3_module::"+methodName+"(): "+err.message);} - catch(e){/*ignored*/} - } - let rc; - if(err instanceof sqlite3.WasmAllocError) rc = capi.SQLITE_NOMEM; - else if(arguments.length>2) rc = defaultRc; - else if(err instanceof sqlite3.SQLite3Error) rc = err.resultCode; - return rc || capi.SQLITE_ERROR; - }; - vtab.xError.errorReporter = 1 ? console.error.bind(console) : false; - - /** - "The problem" with this is that it introduces an outer function with - a different arity than the passed-in method callback. That means we - cannot do argc validation on these. Additionally, some methods (namely - xConnect) may have call-specific error handling. It would be a shame to - hard-coded that per-method support in this function. - */ - /** vtab.methodCatcher = function(methodName, method, defaultErrRc=capi.SQLITE_ERROR){ - return function(...args){ - try { method(...args); } - }catch(e){ return vtab.xError(methodName, e, defaultRc) } - }; - */ - - /** - A helper for sqlite3_vtab::xRowid() and xUpdate() - implementations. It must be passed the final argument to one of - those methods (an output pointer to an int64 row ID) and the - value to store at the output pointer's address. Returns the same - as wasm.poke() and will throw if the 1st or 2nd arguments - are invalid for that function. - - Example xRowid impl: - - ``` - const xRowid = (pCursor, ppRowid64)=>{ - const c = vtab.xCursor(pCursor); - vtab.xRowid(ppRowid64, c.myRowId); - return 0; - }; - ``` - */ - vtab.xRowid = (ppRowid64, value)=>wasm.poke(ppRowid64, value, 'i64'); - - /** - A helper to initialize and set up an sqlite3_module object for - later installation into individual databases using - sqlite3_create_module(). Requires an object with the following - properties: - - - `methods`: an object containing a mapping of properties with - the C-side names of the sqlite3_module methods, e.g. xCreate, - xBestIndex, etc., to JS implementations for those functions. - Certain special-case handling is performed, as described below. - - - `catchExceptions` (default=false): if truthy, the given methods - are not mapped as-is, but are instead wrapped inside wrappers - which translate exceptions into result codes of SQLITE_ERROR or - SQLITE_NOMEM, depending on whether the exception is an - sqlite3.WasmAllocError. In the case of the xConnect and xCreate - methods, the exception handler also sets the output error - string to the exception's error string. - - - OPTIONAL `struct`: a sqlite3.capi.sqlite3_module() instance. If - not set, one will be created automatically. If the current - "this" is-a sqlite3_module then it is unconditionally used in - place of `struct`. - - - OPTIONAL `iVersion`: if set, it must be an integer value and it - gets assigned to the `$iVersion` member of the struct object. - If it's _not_ set, and the passed-in `struct` object's `$iVersion` - is 0 (the default) then this function attempts to define a value - for that property based on the list of methods it has. - - If `catchExceptions` is false, it is up to the client to ensure - that no exceptions escape the methods, as doing so would move - them through the C API, leading to undefined - behavior. (vtab.xError() is intended to assist in reporting - such exceptions.) - - Certain methods may refer to the same implementation. To simplify - the definition of such methods: - - - If `methods.xConnect` is `true` then the value of - `methods.xCreate` is used in its place, and vice versa. sqlite - treats xConnect/xCreate functions specially if they are exactly - the same function (same pointer value). - - - If `methods.xDisconnect` is true then the value of - `methods.xDestroy` is used in its place, and vice versa. - - This is to facilitate creation of those methods inline in the - passed-in object without requiring the client to explicitly get a - reference to one of them in order to assign it to the other - one. - - The `catchExceptions`-installed handlers will account for - identical references to the above functions and will install the - same wrapper function for both. - - The given methods are expected to return integer values, as - expected by the C API. If `catchExceptions` is truthy, the return - value of the wrapped function will be used as-is and will be - translated to 0 if the function returns a falsy value (e.g. if it - does not have an explicit return). If `catchExceptions` is _not_ - active, the method implementations must explicitly return integer - values. - - Throws on error. On success, returns the sqlite3_module object - (`this` or `opt.struct` or a new sqlite3_module instance, - depending on how it's called). - */ - vtab.setupModule = function(opt){ - let createdMod = false; - const mod = (this instanceof capi.sqlite3_module) - ? this : (opt.struct || (createdMod = new capi.sqlite3_module())); - try{ - const methods = opt.methods || toss("Missing 'methods' object."); - for(const e of Object.entries({ - // -----^ ==> [k,v] triggers a broken code transformation in - // some versions of the emsdk toolchain. - xConnect: 'xCreate', xDisconnect: 'xDestroy' - })){ - // Remap X=true to X=Y for certain X/Y combinations - const k = e[0], v = e[1]; - if(true === methods[k]) methods[k] = methods[v]; - else if(true === methods[v]) methods[v] = methods[k]; - } - if(opt.catchExceptions){ - const fwrap = function(methodName, func){ - if(['xConnect','xCreate'].indexOf(methodName) >= 0){ - return function(pDb, pAux, argc, argv, ppVtab, pzErr){ - try{return func(...arguments) || 0} - catch(e){ - if(!(e instanceof sqlite3.WasmAllocError)){ - wasm.dealloc(wasm.peekPtr(pzErr)); - wasm.pokePtr(pzErr, wasm.allocCString(e.message)); - } - return vtab.xError(methodName, e); - } - }; - }else{ - return function(...args){ - try{return func(...args) || 0} - catch(e){ - return vtab.xError(methodName, e); - } - }; - } - }; - const mnames = [ - 'xCreate', 'xConnect', 'xBestIndex', 'xDisconnect', - 'xDestroy', 'xOpen', 'xClose', 'xFilter', 'xNext', - 'xEof', 'xColumn', 'xRowid', 'xUpdate', - 'xBegin', 'xSync', 'xCommit', 'xRollback', - 'xFindFunction', 'xRename', 'xSavepoint', 'xRelease', - 'xRollbackTo', 'xShadowName' - ]; - const remethods = Object.create(null); - for(const k of mnames){ - const m = methods[k]; - if(!(m instanceof Function)) continue; - else if('xConnect'===k && methods.xCreate===m){ - remethods[k] = methods.xCreate; - }else if('xCreate'===k && methods.xConnect===m){ - remethods[k] = methods.xConnect; - }else{ - remethods[k] = fwrap(k, m); - } - } - installMethods(mod, remethods, false); - }else{ - // No automatic exception handling. Trust the client - // to not throw. - installMethods( - mod, methods, !!opt.applyArgcCheck/*undocumented option*/ - ); - } - if(0===mod.$iVersion){ - let v; - if('number'===typeof opt.iVersion) v = opt.iVersion; - else if(mod.$xShadowName) v = 3; - else if(mod.$xSavePoint || mod.$xRelease || mod.$xRollbackTo) v = 2; - else v = 1; - mod.$iVersion = v; - } - }catch(e){ - if(createdMod) createdMod.dispose(); - throw e; - } - return mod; - }/*setupModule()*/; - - /** - Equivalent to calling vtab.setupModule() with this sqlite3_module - object as the call's `this`. - */ - capi.sqlite3_module.prototype.setupModule = function(opt){ - return vtab.setupModule.call(this, opt); - }; -}/*sqlite3ApiBootstrap.initializers.push()*/); |