Fixes default log output to console for macOS
[sqlcipher.git] / ext / wasm / api / sqlite3-api-oo1.js
blobe557cbd5788fe5a1357573ce023f5ea9294d915b
1 //#ifnot omit-oo1
2 /*
3   2022-07-22
5   The author disclaims copyright to this source code.  In place of a
6   legal notice, here is a blessing:
8   *   May you do good and not evil.
9   *   May you find forgiveness for yourself and forgive others.
10   *   May you share freely, never taking more than you give.
12   ***********************************************************************
14   This file contains the so-called OO #1 API wrapper for the sqlite3
15   WASM build. It requires that sqlite3-api-glue.js has already run
16   and it installs its deliverable as globalThis.sqlite3.oo1.
18 globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
19   const toss = (...args)=>{throw new Error(args.join(' '))};
20   const toss3 = (...args)=>{throw new sqlite3.SQLite3Error(...args)};
22   const capi = sqlite3.capi, wasm = sqlite3.wasm, util = sqlite3.util;
23   /* What follows is colloquially known as "OO API #1". It is a
24      binding of the sqlite3 API which is designed to be run within
25      the same thread (main or worker) as the one in which the
26      sqlite3 WASM binding was initialized. This wrapper cannot use
27      the sqlite3 binding if, e.g., the wrapper is in the main thread
28      and the sqlite3 API is in a worker. */
30   /**
31      In order to keep clients from manipulating, perhaps
32      inadvertently, the underlying pointer values of DB and Stmt
33      instances, we'll gate access to them via the `pointer` property
34      accessor and store their real values in this map. Keys = DB/Stmt
35      objects, values = pointer values. This also unifies how those are
36      accessed, for potential use downstream via custom
37      wasm.xWrap() function signatures which know how to extract
38      it.
39   */
40   const __ptrMap = new WeakMap();
41   /**
42      Map of DB instances to objects, each object being a map of Stmt
43      wasm pointers to Stmt objects.
44   */
45   const __stmtMap = new WeakMap();
47   /** If object opts has _its own_ property named p then that
48       property's value is returned, else dflt is returned. */
49   const getOwnOption = (opts, p, dflt)=>{
50     const d = Object.getOwnPropertyDescriptor(opts,p);
51     return d ? d.value : dflt;
52   };
54   // Documented in DB.checkRc()
55   const checkSqlite3Rc = function(dbPtr, sqliteResultCode){
56     if(sqliteResultCode){
57       if(dbPtr instanceof DB) dbPtr = dbPtr.pointer;
58       toss3(
59         sqliteResultCode,
60         "sqlite3 result code",sqliteResultCode+":",
61         (dbPtr
62          ? capi.sqlite3_errmsg(dbPtr)
63          : capi.sqlite3_errstr(sqliteResultCode))
64       );
65     }
66     return arguments[0];
67   };
69   /**
70      sqlite3_trace_v2() callback which gets installed by the DB ctor
71      if its open-flags contain "t".
72   */
73   const __dbTraceToConsole =
74         wasm.installFunction('i(ippp)', function(t,c,p,x){
75           if(capi.SQLITE_TRACE_STMT===t){
76             // x == SQL, p == sqlite3_stmt*
77             console.log("SQL TRACE #"+(++this.counter)+' via sqlite3@'+c+':',
78                         wasm.cstrToJs(x));
79           }
80         }.bind({counter: 0}));
82   /**
83      A map of sqlite3_vfs pointers to SQL code or a callback function
84      to run when the DB constructor opens a database with the given
85      VFS. In the latter case, the call signature is (theDbObject,sqlite3Namespace)
86      and the callback is expected to throw on error.
87   */
88   const __vfsPostOpenSql = Object.create(null);
90 //#if enable-see
91   /**
92      Converts ArrayBuffer or Uint8Array ba into a string of hex
93      digits.
94   */
95   const byteArrayToHex = function(ba){
96     if( ba instanceof ArrayBuffer ){
97       ba = new Uint8Array(ba);
98     }
99     const li = [];
100     const digits = "0123456789abcdef";
101     for( const d of ba ){
102       li.push( digits[(d & 0xf0) >> 4], digits[d & 0x0f] );
103     }
104     return li.join('');
105   };
107   /**
108      Internal helper to apply an SEE key to a just-opened
109      database. Requires that db be-a DB object which has just been
110      opened, opt be the options object processed by its ctor, and opt
111      must have either the key, hexkey, or textkey properties, either
112      as a string, an ArrayBuffer, or a Uint8Array.
114      This is a no-op in non-SEE builds. It throws on error and returns
115      without side effects if none of the key/textkey/hexkey options
116      are set. It throws if more than one is set or if any are set to
117      values of an invalid type.
119      Returns true if it applies the key, else an unspecified falsy value.
120   */
121   const dbCtorApplySEEKey = function(db,opt){
122     if( !capi.sqlite3_key_v2 ) return;
123     let keytype;
124     let key;
125     const check = (opt.key ? 1 : 0) + (opt.hexkey ? 1 : 0) + (opt.textkey ? 1 : 0);
126     if( !check ) return;
127     else if( check>1 ){
128       toss3(capi.SQLITE_MISUSE,
129             "Only ONE of (key, hexkey, textkey) may be provided.");
130     }
131     if( opt.key ){
132       /* It is not legal to bind an argument to PRAGMA key=?, so we
133          convert it to a hexkey... */
134       keytype = 'key';
135       key = opt.key;
136       if('string'===typeof key){
137         key = new TextEncoder('utf-8').encode(key);
138       }
139       if((key instanceof ArrayBuffer) || (key instanceof Uint8Array)){
140         key = byteArrayToHex(key);
141         keytype = 'hexkey';
142       }else{
143         toss3(capi.SQLITE_MISUSE,
144               "Invalid value for the 'key' option. Expecting a string,",
145               "ArrayBuffer, or Uint8Array.");
146         return;
147       }
148     }else if( opt.textkey ){
149       /* For textkey we need it to be in string form, so convert it to
150          a string if it's a byte array... */
151       keytype = 'textkey';
152       key = opt.textkey;
153       if(key instanceof ArrayBuffer){
154         key = new Uint8Array(key);
155       }
156       if(key instanceof Uint8Array){
157         key = new TextDecoder('utf-8').decode(key);
158       }else if('string'!==typeof key){
159         toss3(capi.SQLITE_MISUSE,
160               "Invalid value for the 'textkey' option. Expecting a string,",
161               "ArrayBuffer, or Uint8Array.");
162       }
163     }else if( opt.hexkey ){
164       keytype = 'hexkey';
165       key = opt.hexkey;
166       if((key instanceof ArrayBuffer) || (key instanceof Uint8Array)){
167         key = byteArrayToHex(key);
168       }else if('string'!==typeof key){
169         toss3(capi.SQLITE_MISUSE,
170               "Invalid value for the 'hexkey' option. Expecting a string,",
171               "ArrayBuffer, or Uint8Array.");
172       }
173       /* else assume it's valid hex codes */
174     }else{
175       return;
176     }
177     let stmt;
178     try{
179       stmt = db.prepare("PRAGMA "+keytype+"="+util.sqlite3__wasm_qfmt_token(key, 1));
180       stmt.step();
181     }finally{
182       if(stmt) stmt.finalize();
183     }
184     return true;
185   };
186 //#endif enable-see
188   /**
189      A proxy for DB class constructors. It must be called with the
190      being-construct DB object as its "this". See the DB constructor
191      for the argument docs. This is split into a separate function
192      in order to enable simple creation of special-case DB constructors,
193      e.g. JsStorageDb and OpfsDb.
195      Expects to be passed a configuration object with the following
196      properties:
198      - `.filename`: the db filename. It may be a special name like ":memory:"
199        or "".
201      - `.flags`: as documented in the DB constructor.
203      - `.vfs`: as documented in the DB constructor.
205      It also accepts those as the first 3 arguments.
206   */
207   const dbCtorHelper = function ctor(...args){
208     if(!ctor._name2vfs){
209       /**
210          Map special filenames which we handle here (instead of in C)
211          to some helpful metadata...
213          As of 2022-09-20, the C API supports the names :localStorage:
214          and :sessionStorage: for kvvfs. However, C code cannot
215          determine (without embedded JS code, e.g. via Emscripten's
216          EM_JS()) whether the kvvfs is legal in the current browser
217          context (namely the main UI thread). In order to help client
218          code fail early on, instead of it being delayed until they
219          try to read or write a kvvfs-backed db, we'll check for those
220          names here and throw if they're not legal in the current
221          context.
222       */
223       ctor._name2vfs = Object.create(null);
224       const isWorkerThread = ('function'===typeof importScripts/*===running in worker thread*/)
225             ? (n)=>toss3("The VFS for",n,"is only available in the main window thread.")
226             : false;
227       ctor._name2vfs[':localStorage:'] = {
228         vfs: 'kvvfs', filename: isWorkerThread || (()=>'local')
229       };
230       ctor._name2vfs[':sessionStorage:'] = {
231         vfs: 'kvvfs', filename: isWorkerThread || (()=>'session')
232       };
233     }
234     const opt = ctor.normalizeArgs(...args);
235     let fn = opt.filename, vfsName = opt.vfs, flagsStr = opt.flags;
236     if(('string'!==typeof fn && 'number'!==typeof fn)
237        || 'string'!==typeof flagsStr
238        || (vfsName && ('string'!==typeof vfsName && 'number'!==typeof vfsName))){
239       sqlite3.config.error("Invalid DB ctor args",opt,arguments);
240       toss3("Invalid arguments for DB constructor.");
241     }
242     let fnJs = ('number'===typeof fn) ? wasm.cstrToJs(fn) : fn;
243     const vfsCheck = ctor._name2vfs[fnJs];
244     if(vfsCheck){
245       vfsName = vfsCheck.vfs;
246       fn = fnJs = vfsCheck.filename(fnJs);
247     }
248     let pDb, oflags = 0;
249     if( flagsStr.indexOf('c')>=0 ){
250       oflags |= capi.SQLITE_OPEN_CREATE | capi.SQLITE_OPEN_READWRITE;
251     }
252     if( flagsStr.indexOf('w')>=0 ) oflags |= capi.SQLITE_OPEN_READWRITE;
253     if( 0===oflags ) oflags |= capi.SQLITE_OPEN_READONLY;
254     oflags |= capi.SQLITE_OPEN_EXRESCODE;
255     const stack = wasm.pstack.pointer;
256     try {
257       const pPtr = wasm.pstack.allocPtr() /* output (sqlite3**) arg */;
258       let rc = capi.sqlite3_open_v2(fn, pPtr, oflags, vfsName || 0);
259       pDb = wasm.peekPtr(pPtr);
260       checkSqlite3Rc(pDb, rc);
261       capi.sqlite3_extended_result_codes(pDb, 1);
262       if(flagsStr.indexOf('t')>=0){
263         capi.sqlite3_trace_v2(pDb, capi.SQLITE_TRACE_STMT,
264                               __dbTraceToConsole, pDb);
265       }
266     }catch( e ){
267       if( pDb ) capi.sqlite3_close_v2(pDb);
268       throw e;
269     }finally{
270       wasm.pstack.restore(stack);
271     }
272     this.filename = fnJs;
273     __ptrMap.set(this, pDb);
274     __stmtMap.set(this, Object.create(null));
275     try{
276 //#if enable-see
277       dbCtorApplySEEKey(this,opt);
278 //#endif
279       // Check for per-VFS post-open SQL/callback...
280       const pVfs = capi.sqlite3_js_db_vfs(pDb)
281             || toss3("Internal error: cannot get VFS for new db handle.");
282       const postInitSql = __vfsPostOpenSql[pVfs];
283       if(postInitSql){
284         /**
285            Reminder: if this db is encrypted and the client did _not_ pass
286            in the key, any init code will fail, causing the ctor to throw.
287            We don't actually know whether the db is encrypted, so we cannot
288            sensibly apply any heuristics which skip the init code only for
289            encrypted databases for which no key has yet been supplied.
290         */
291         if(postInitSql instanceof Function){
292           postInitSql(this, sqlite3);
293         }else{
294           checkSqlite3Rc(
295             pDb, capi.sqlite3_exec(pDb, postInitSql, 0, 0, 0)
296           );
297         }
298       }
299     }catch(e){
300       this.close();
301       throw e;
302     }
303   };
305   /**
306      Sets SQL which should be exec()'d on a DB instance after it is
307      opened with the given VFS pointer. The SQL may be any type
308      supported by the "string:flexible" function argument conversion.
309      Alternately, the 2nd argument may be a function, in which case it
310      is called with (theOo1DbObject,sqlite3Namespace) at the end of
311      the DB() constructor. The function must throw on error, in which
312      case the db is closed and the exception is propagated.  This
313      function is intended only for use by DB subclasses or sqlite3_vfs
314      implementations.
315   */
316   dbCtorHelper.setVfsPostOpenSql = function(pVfs, sql){
317     __vfsPostOpenSql[pVfs] = sql;
318   };
320   /**
321      A helper for DB constructors. It accepts either a single
322      config-style object or up to 3 arguments (filename, dbOpenFlags,
323      dbVfsName). It returns a new object containing:
325      { filename: ..., flags: ..., vfs: ... }
327      If passed an object, any additional properties it has are copied
328      as-is into the new object.
329   */
330   dbCtorHelper.normalizeArgs = function(filename=':memory:',flags = 'c',vfs = null){
331     const arg = {};
332     if(1===arguments.length && arguments[0] && 'object'===typeof arguments[0]){
333       Object.assign(arg, arguments[0]);
334       if(undefined===arg.flags) arg.flags = 'c';
335       if(undefined===arg.vfs) arg.vfs = null;
336       if(undefined===arg.filename) arg.filename = ':memory:';
337     }else{
338       arg.filename = filename;
339       arg.flags = flags;
340       arg.vfs = vfs;
341     }
342     return arg;
343   };
344   /**
345      The DB class provides a high-level OO wrapper around an sqlite3
346      db handle.
348      The given db filename must be resolvable using whatever
349      filesystem layer (virtual or otherwise) is set up for the default
350      sqlite3 VFS.
352      Note that the special sqlite3 db names ":memory:" and ""
353      (temporary db) have their normal special meanings here and need
354      not resolve to real filenames, but "" uses an on-storage
355      temporary database and requires that the VFS support that.
357      The second argument specifies the open/create mode for the
358      database. It must be string containing a sequence of letters (in
359      any order, but case sensitive) specifying the mode:
361      - "c": create if it does not exist, else fail if it does not
362        exist. Implies the "w" flag.
364      - "w": write. Implies "r": a db cannot be write-only.
366      - "r": read-only if neither "w" nor "c" are provided, else it
367        is ignored.
369      - "t": enable tracing of SQL executed on this database handle,
370        sending it to `console.log()`. To disable it later, call
371        `sqlite3.capi.sqlite3_trace_v2(thisDb.pointer, 0, 0, 0)`.
373      If "w" is not provided, the db is implicitly read-only, noting
374      that "rc" is meaningless
376      Any other letters are currently ignored. The default is
377      "c". These modes are ignored for the special ":memory:" and ""
378      names and _may_ be ignored altogether for certain VFSes.
380      The final argument is analogous to the final argument of
381      sqlite3_open_v2(): the name of an sqlite3 VFS. Pass a falsy value,
382      or none at all, to use the default. If passed a value, it must
383      be the string name of a VFS.
385      The constructor optionally (and preferably) takes its arguments
386      in the form of a single configuration object with the following
387      properties:
389      - `filename`: database file name
390      - `flags`: open-mode flags
391      - `vfs`: the VFS fname
393 //#if enable-see
395      SEE-capable builds optionally support ONE of the following
396      additional options:
398      - `key`, `hexkey`, or `textkey`: encryption key as a string,
399        ArrayBuffer, or Uint8Array. These flags function as documented
400        for the SEE pragmas of the same names. Using a byte array for
401        `hexkey` is equivalent to the same series of hex codes in
402        string form, so `'666f6f'` is equivalent to
403        `Uint8Array([0x66,0x6f,0x6f])`. A `textkey` byte array is
404        assumed to be UTF-8. A `key` string is transformed into a UTF-8
405        byte array, and a `key` byte array is transformed into a
406        `hexkey` with the same bytes.
408      In non-SEE builds, these options are ignored. In SEE builds,
409      `PRAGMA key/textkey/hexkey=X` is executed immediately after
410      opening the db. If more than one of the options is provided,
411      or any option has an invalid argument type, an exception is
412      thrown.
414      Note that some DB subclasses may run post-initialization SQL
415      code, e.g. to set a busy-handler timeout or tweak the page cache
416      size. Such code is run _after_ the SEE key is applied. If no key
417      is supplied and the database is encrypted, execution of the
418      post-initialization SQL will fail, causing the constructor to
419      throw.
421 //#endif enable-see
423      The `filename` and `vfs` arguments may be either JS strings or
424      C-strings allocated via WASM. `flags` is required to be a JS
425      string (because it's specific to this API, which is specific
426      to JS).
428      For purposes of passing a DB instance to C-style sqlite3
429      functions, the DB object's read-only `pointer` property holds its
430      `sqlite3*` pointer value. That property can also be used to check
431      whether this DB instance is still open: it will evaluate to
432      `undefined` after the DB object's close() method is called.
434      In the main window thread, the filenames `":localStorage:"` and
435      `":sessionStorage:"` are special: they cause the db to use either
436      localStorage or sessionStorage for storing the database using
437      the kvvfs. If one of these names are used, they trump
438      any vfs name set in the arguments.
439   */
440   const DB = function(...args){
441     dbCtorHelper.apply(this, args);
442   };
443   DB.dbCtorHelper = dbCtorHelper;
445   /**
446      Internal-use enum for mapping JS types to DB-bindable types.
447      These do not (and need not) line up with the SQLITE_type
448      values. All values in this enum must be truthy and distinct
449      but they need not be numbers.
450   */
451   const BindTypes = {
452     null: 1,
453     number: 2,
454     string: 3,
455     boolean: 4,
456     blob: 5
457   };
458   BindTypes['undefined'] == BindTypes.null;
459   if(wasm.bigIntEnabled){
460     BindTypes.bigint = BindTypes.number;
461   }
463   /**
464      This class wraps sqlite3_stmt. Calling this constructor
465      directly will trigger an exception. Use DB.prepare() to create
466      new instances.
468      For purposes of passing a Stmt instance to C-style sqlite3
469      functions, its read-only `pointer` property holds its `sqlite3_stmt*`
470      pointer value.
472      Other non-function properties include:
474      - `db`: the DB object which created the statement.
476      - `columnCount`: the number of result columns in the query, or 0
477      for queries which cannot return results. This property is a proxy
478      for sqlite3_column_count() and its use in loops should be avoided
479      because of the call overhead associated with that. The
480      `columnCount` is not cached when the Stmt is created because a
481      schema change made via a separate db connection between this
482      statement's preparation and when it is stepped may invalidate it.
484      - `parameterCount`: the number of bindable parameters in the query.
485   */
486   const Stmt = function(){
487     if(BindTypes!==arguments[2]){
488       toss3(capi.SQLITE_MISUSE, "Do not call the Stmt constructor directly. Use DB.prepare().");
489     }
490     this.db = arguments[0];
491     __ptrMap.set(this, arguments[1]);
492     this.parameterCount = capi.sqlite3_bind_parameter_count(this.pointer);
493   };
495   /** Throws if the given DB has been closed, else it is returned. */
496   const affirmDbOpen = function(db){
497     if(!db.pointer) toss3("DB has been closed.");
498     return db;
499   };
501   /** Throws if ndx is not an integer or if it is out of range
502       for stmt.columnCount, else returns stmt.
504       Reminder: this will also fail after the statement is finalized
505       but the resulting error will be about an out-of-bounds column
506       index rather than a statement-is-finalized error.
507   */
508   const affirmColIndex = function(stmt,ndx){
509     if((ndx !== (ndx|0)) || ndx<0 || ndx>=stmt.columnCount){
510       toss3("Column index",ndx,"is out of range.");
511     }
512     return stmt;
513   };
515   /**
516      Expects to be passed the `arguments` object from DB.exec(). Does
517      the argument processing/validation, throws on error, and returns
518      a new object on success:
520      { sql: the SQL, opt: optionsObj, cbArg: function}
522      The opt object is a normalized copy of any passed to this
523      function. The sql will be converted to a string if it is provided
524      in one of the supported non-string formats.
526      cbArg is only set if the opt.callback or opt.resultRows are set,
527      in which case it's a function which expects to be passed the
528      current Stmt and returns the callback argument of the type
529      indicated by the input arguments.
530   */
531   const parseExecArgs = function(db, args){
532     const out = Object.create(null);
533     out.opt = Object.create(null);
534     switch(args.length){
535         case 1:
536           if('string'===typeof args[0] || util.isSQLableTypedArray(args[0])){
537             out.sql = args[0];
538           }else if(Array.isArray(args[0])){
539             out.sql = args[0];
540           }else if(args[0] && 'object'===typeof args[0]){
541             out.opt = args[0];
542             out.sql = out.opt.sql;
543           }
544           break;
545         case 2:
546           out.sql = args[0];
547           out.opt = args[1];
548           break;
549         default: toss3("Invalid argument count for exec().");
550     };
551     out.sql = util.flexibleString(out.sql);
552     if('string'!==typeof out.sql){
553       toss3("Missing SQL argument or unsupported SQL value type.");
554     }
555     const opt = out.opt;
556     switch(opt.returnValue){
557         case 'resultRows':
558           if(!opt.resultRows) opt.resultRows = [];
559           out.returnVal = ()=>opt.resultRows;
560           break;
561         case 'saveSql':
562           if(!opt.saveSql) opt.saveSql = [];
563           out.returnVal = ()=>opt.saveSql;
564           break;
565         case undefined:
566         case 'this':
567           out.returnVal = ()=>db;
568           break;
569         default:
570           toss3("Invalid returnValue value:",opt.returnValue);
571     }
572     if(!opt.callback && !opt.returnValue && undefined!==opt.rowMode){
573       if(!opt.resultRows) opt.resultRows = [];
574       out.returnVal = ()=>opt.resultRows;
575     }
576     if(opt.callback || opt.resultRows){
577       switch((undefined===opt.rowMode) ? 'array' : opt.rowMode) {
578         case 'object':
579           out.cbArg = (stmt,cache)=>{
580             if( !cache.columnNames ) cache.columnNames = stmt.getColumnNames([]);
581             /* https://sqlite.org/forum/forumpost/3632183d2470617d:
582                conversion of rows to objects (key/val pairs) is
583                somewhat expensive for large data sets because of the
584                native-to-JS conversion of the column names. If we
585                instead cache the names and build objects from that
586                list of strings, it can run twice as fast. The
587                difference is not noticeable for small data sets but
588                becomes human-perceivable when enough rows are
589                involved. */
590             const row = stmt.get([]);
591             const rv = Object.create(null);
592             for( const i in cache.columnNames ) rv[cache.columnNames[i]] = row[i];
593             return rv;
594           };
595           break;
596         case 'array': out.cbArg = (stmt)=>stmt.get([]); break;
597         case 'stmt':
598           if(Array.isArray(opt.resultRows)){
599             toss3("exec(): invalid rowMode for a resultRows array: must",
600                   "be one of 'array', 'object',",
601                   "a result column number, or column name reference.");
602           }
603           out.cbArg = (stmt)=>stmt;
604           break;
605         default:
606           if(util.isInt32(opt.rowMode)){
607             out.cbArg = (stmt)=>stmt.get(opt.rowMode);
608             break;
609           }else if('string'===typeof opt.rowMode
610                    && opt.rowMode.length>1
611                    && '$'===opt.rowMode[0]){
612             /* "$X": fetch column named "X" (case-sensitive!). Prior
613                to 2022-12-14 ":X" and "@X" were also permitted, but
614                having so many options is unnecessary and likely to
615                cause confusion. */
616             const $colName = opt.rowMode.substr(1);
617             out.cbArg = (stmt)=>{
618               const rc = stmt.get(Object.create(null))[$colName];
619               return (undefined===rc)
620                 ? toss3(capi.SQLITE_NOTFOUND,
621                         "exec(): unknown result column:",$colName)
622                 : rc;
623             };
624             break;
625           }
626           toss3("Invalid rowMode:",opt.rowMode);
627       }
628     }
629     return out;
630   };
632   /**
633      Internal impl of the DB.selectValue(), selectArray(), and
634      selectObject() methods.
635   */
636   const __selectFirstRow = (db, sql, bind, ...getArgs)=>{
637     const stmt = db.prepare(sql);
638     try {
639       const rc = stmt.bind(bind).step() ? stmt.get(...getArgs) : undefined;
640       stmt.reset(/*for INSERT...RETURNING locking case*/);
641       return rc;
642     }finally{
643       stmt.finalize();
644     }
645   };
647   /**
648      Internal impl of the DB.selectArrays() and selectObjects()
649      methods.
650   */
651   const __selectAll =
652         (db, sql, bind, rowMode)=>db.exec({
653           sql, bind, rowMode, returnValue: 'resultRows'
654         });
656   /**
657      Expects to be given a DB instance or an `sqlite3*` pointer (may
658      be null) and an sqlite3 API result code. If the result code is
659      not falsy, this function throws an SQLite3Error with an error
660      message from sqlite3_errmsg(), using db (or, if db is-a DB,
661      db.pointer) as the db handle, or sqlite3_errstr() if db is
662      falsy. Note that if it's passed a non-error code like SQLITE_ROW
663      or SQLITE_DONE, it will still throw but the error string might be
664      "Not an error."  The various non-0 non-error codes need to be
665      checked for in client code where they are expected.
667      The thrown exception's `resultCode` property will be the value of
668      the second argument to this function.
670      If it does not throw, it returns its first argument.
671   */
672   DB.checkRc = (db,resultCode)=>checkSqlite3Rc(db,resultCode);
674   DB.prototype = {
675     /** Returns true if this db handle is open, else false. */
676     isOpen: function(){
677       return !!this.pointer;
678     },
679     /** Throws if this given DB has been closed, else returns `this`. */
680     affirmOpen: function(){
681       return affirmDbOpen(this);
682     },
683     /**
684        Finalizes all open statements and closes this database
685        connection. This is a no-op if the db has already been
686        closed. After calling close(), `this.pointer` will resolve to
687        `undefined`, so that can be used to check whether the db
688        instance is still opened.
690        If this.onclose.before is a function then it is called before
691        any close-related cleanup.
693        If this.onclose.after is a function then it is called after the
694        db is closed but before auxiliary state like this.filename is
695        cleared.
697        Both onclose handlers are passed this object, with the onclose
698        object as their "this," noting that the db will have been
699        closed when onclose.after is called. If this db is not opened
700        when close() is called, neither of the handlers are called. Any
701        exceptions the handlers throw are ignored because "destructors
702        must not throw."
704        Note that garbage collection of a db handle, if it happens at
705        all, will never trigger close(), so onclose handlers are not a
706        reliable way to implement close-time cleanup or maintenance of
707        a db.
708     */
709     close: function(){
710       if(this.pointer){
711         if(this.onclose && (this.onclose.before instanceof Function)){
712           try{this.onclose.before(this)}
713           catch(e){/*ignore*/}
714         }
715         const pDb = this.pointer;
716         Object.keys(__stmtMap.get(this)).forEach((k,s)=>{
717           if(s && s.pointer){
718             try{s.finalize()}
719             catch(e){/*ignore*/}
720           }
721         });
722         __ptrMap.delete(this);
723         __stmtMap.delete(this);
724         capi.sqlite3_close_v2(pDb);
725         if(this.onclose && (this.onclose.after instanceof Function)){
726           try{this.onclose.after(this)}
727           catch(e){/*ignore*/}
728         }
729         delete this.filename;
730       }
731     },
732     /**
733        Returns the number of changes, as per sqlite3_changes()
734        (if the first argument is false) or sqlite3_total_changes()
735        (if it's true). If the 2nd argument is true, it uses
736        sqlite3_changes64() or sqlite3_total_changes64(), which
737        will trigger an exception if this build does not have
738        BigInt support enabled.
739     */
740     changes: function(total=false,sixtyFour=false){
741       const p = affirmDbOpen(this).pointer;
742       if(total){
743         return sixtyFour
744           ? capi.sqlite3_total_changes64(p)
745           : capi.sqlite3_total_changes(p);
746       }else{
747         return sixtyFour
748           ? capi.sqlite3_changes64(p)
749           : capi.sqlite3_changes(p);
750       }
751     },
752     /**
753        Similar to the this.filename but returns the
754        sqlite3_db_filename() value for the given database name,
755        defaulting to "main".  The argument may be either a JS string
756        or a pointer to a WASM-allocated C-string.
757     */
758     dbFilename: function(dbName='main'){
759       return capi.sqlite3_db_filename(affirmDbOpen(this).pointer, dbName);
760     },
761     /**
762        Returns the name of the given 0-based db number, as documented
763        for sqlite3_db_name().
764     */
765     dbName: function(dbNumber=0){
766       return capi.sqlite3_db_name(affirmDbOpen(this).pointer, dbNumber);
767     },
768     /**
769        Returns the name of the sqlite3_vfs used by the given database
770        of this connection (defaulting to 'main'). The argument may be
771        either a JS string or a WASM C-string. Returns undefined if the
772        given db name is invalid. Throws if this object has been
773        close()d.
774     */
775     dbVfsName: function(dbName=0){
776       let rc;
777       const pVfs = capi.sqlite3_js_db_vfs(
778         affirmDbOpen(this).pointer, dbName
779       );
780       if(pVfs){
781         const v = new capi.sqlite3_vfs(pVfs);
782         try{ rc = wasm.cstrToJs(v.$zName) }
783         finally { v.dispose() }
784       }
785       return rc;
786     },
787     /**
788        Compiles the given SQL and returns a prepared Stmt. This is
789        the only way to create new Stmt objects. Throws on error.
791        The given SQL must be a string, a Uint8Array holding SQL, a
792        WASM pointer to memory holding the NUL-terminated SQL string,
793        or an array of strings. In the latter case, the array is
794        concatenated together, with no separators, to form the SQL
795        string (arrays are often a convenient way to formulate long
796        statements).  If the SQL contains no statements, an
797        SQLite3Error is thrown.
799        Design note: the C API permits empty SQL, reporting it as a 0
800        result code and a NULL stmt pointer. Supporting that case here
801        would cause extra work for all clients: any use of the Stmt API
802        on such a statement will necessarily throw, so clients would be
803        required to check `stmt.pointer` after calling `prepare()` in
804        order to determine whether the Stmt instance is empty or not.
805        Long-time practice (with other sqlite3 script bindings)
806        suggests that the empty-prepare case is sufficiently rare that
807        supporting it here would simply hurt overall usability.
808     */
809     prepare: function(sql){
810       affirmDbOpen(this);
811       const stack = wasm.pstack.pointer;
812       let ppStmt, pStmt;
813       try{
814         ppStmt = wasm.pstack.alloc(8)/* output (sqlite3_stmt**) arg */;
815         DB.checkRc(this, capi.sqlite3_prepare_v2(this.pointer, sql, -1, ppStmt, null));
816         pStmt = wasm.peekPtr(ppStmt);
817       }
818       finally {
819         wasm.pstack.restore(stack);
820       }
821       if(!pStmt) toss3("Cannot prepare empty SQL.");
822       const stmt = new Stmt(this, pStmt, BindTypes);
823       __stmtMap.get(this)[pStmt] = stmt;
824       return stmt;
825     },
826     /**
827        Executes one or more SQL statements in the form of a single
828        string. Its arguments must be either (sql,optionsObject) or
829        (optionsObject). In the latter case, optionsObject.sql must
830        contain the SQL to execute. By default it returns this object
831        but that can be changed via the `returnValue` option as
832        described below. Throws on error.
834        If no SQL is provided, or a non-string is provided, an
835        exception is triggered. Empty SQL, on the other hand, is
836        simply a no-op.
838        The optional options object may contain any of the following
839        properties:
841        - `sql` = the SQL to run (unless it's provided as the first
842        argument). This must be of type string, Uint8Array, or an array
843        of strings. In the latter case they're concatenated together
844        as-is, _with no separator_ between elements, before evaluation.
845        The array form is often simpler for long hand-written queries.
847        - `bind` = a single value valid as an argument for
848        Stmt.bind(). This is _only_ applied to the _first_ non-empty
849        statement in the SQL which has any bindable parameters. (Empty
850        statements are skipped entirely.)
852        - `saveSql` = an optional array. If set, the SQL of each
853        executed statement is appended to this array before the
854        statement is executed (but after it is prepared - we don't have
855        the string until after that). Empty SQL statements are elided
856        but can have odd effects in the output. e.g. SQL of: `"select
857        1; -- empty\n; select 2"` will result in an array containing
858        `["select 1;", "--empty \n; select 2"]`. That's simply how
859        sqlite3 records the SQL for the 2nd statement.
861        ==================================================================
862        The following options apply _only_ to the _first_ statement
863        which has a non-zero result column count, regardless of whether
864        the statement actually produces any result rows.
865        ==================================================================
867        - `columnNames`: if this is an array, the column names of the
868        result set are stored in this array before the callback (if
869        any) is triggered (regardless of whether the query produces any
870        result rows). If no statement has result columns, this value is
871        unchanged. Achtung: an SQL result may have multiple columns
872        with identical names.
874        - `callback` = a function which gets called for each row of the
875        result set, but only if that statement has any result rows. The
876        callback's "this" is the options object, noting that this
877        function synthesizes one if the caller does not pass one to
878        exec(). The second argument passed to the callback is always
879        the current Stmt object, as it's needed if the caller wants to
880        fetch the column names or some such (noting that they could
881        also be fetched via `this.columnNames`, if the client provides
882        the `columnNames` option). If the callback returns a literal
883        `false` (as opposed to any other falsy value, e.g. an implicit
884        `undefined` return), any ongoing statement-`step()` iteration
885        stops without an error. The return value of the callback is
886        otherwise ignored.
888        ACHTUNG: The callback MUST NOT modify the Stmt object. Calling
889        any of the Stmt.get() variants, Stmt.getColumnName(), or
890        similar, is legal, but calling step() or finalize() is
891        not. Member methods which are illegal in this context will
892        trigger an exception, but clients must also refrain from using
893        any lower-level (C-style) APIs which might modify the
894        statement.
896        The first argument passed to the callback defaults to an array of
897        values from the current result row but may be changed with ...
899        - `rowMode` = specifies the type of he callback's first argument.
900        It may be any of...
902        A) A string describing what type of argument should be passed
903        as the first argument to the callback:
905          A.1) `'array'` (the default) causes the results of
906          `stmt.get([])` to be passed to the `callback` and/or appended
907          to `resultRows`.
909          A.2) `'object'` causes the results of
910          `stmt.get(Object.create(null))` to be passed to the
911          `callback` and/or appended to `resultRows`.  Achtung: an SQL
912          result may have multiple columns with identical names. In
913          that case, the right-most column will be the one set in this
914          object!
916          A.3) `'stmt'` causes the current Stmt to be passed to the
917          callback, but this mode will trigger an exception if
918          `resultRows` is an array because appending the transient
919          statement to the array would be downright unhelpful.
921        B) An integer, indicating a zero-based column in the result
922        row. Only that one single value will be passed on.
924        C) A string with a minimum length of 2 and leading character of
925        '$' will fetch the row as an object, extract that one field,
926        and pass that field's value to the callback. Note that these
927        keys are case-sensitive so must match the case used in the
928        SQL. e.g. `"select a A from t"` with a `rowMode` of `'$A'`
929        would work but `'$a'` would not. A reference to a column not in
930        the result set will trigger an exception on the first row (as
931        the check is not performed until rows are fetched).  Note also
932        that `$` is a legal identifier character in JS so need not be
933        quoted.
935        Any other `rowMode` value triggers an exception.
937        - `resultRows`: if this is an array, it functions similarly to
938        the `callback` option: each row of the result set (if any),
939        with the exception that the `rowMode` 'stmt' is not legal. It
940        is legal to use both `resultRows` and `callback`, but
941        `resultRows` is likely much simpler to use for small data sets
942        and can be used over a WebWorker-style message interface.
943        exec() throws if `resultRows` is set and `rowMode` is 'stmt'.
945        - `returnValue`: is a string specifying what this function
946        should return:
948          A) The default value is (usually) `"this"`, meaning that the
949             DB object itself should be returned. The exception is if
950             the caller passes neither of `callback` nor `returnValue`
951             but does pass an explicit `rowMode` then the default
952             `returnValue` is `"resultRows"`, described below.
954          B) `"resultRows"` means to return the value of the
955             `resultRows` option. If `resultRows` is not set, this
956             function behaves as if it were set to an empty array.
958          C) `"saveSql"` means to return the value of the
959             `saveSql` option. If `saveSql` is not set, this
960             function behaves as if it were set to an empty array.
962        Potential TODOs:
964        - `bind`: permit an array of arrays/objects to bind. The first
965        sub-array would act on the first statement which has bindable
966        parameters (as it does now). The 2nd would act on the next such
967        statement, etc.
969        - `callback` and `resultRows`: permit an array entries with
970        semantics similar to those described for `bind` above.
972     */
973     exec: function(/*(sql [,obj]) || (obj)*/){
974       affirmDbOpen(this);
975       const arg = parseExecArgs(this, arguments);
976       if(!arg.sql){
977         return toss3("exec() requires an SQL string.");
978       }
979       const opt = arg.opt;
980       const callback = opt.callback;
981       const resultRows =
982             Array.isArray(opt.resultRows) ? opt.resultRows : undefined;
983       let stmt;
984       let bind = opt.bind;
985       let evalFirstResult = !!(
986         arg.cbArg || opt.columnNames || resultRows
987       ) /* true to step through the first result-returning statement */;
988       const stack = wasm.scopedAllocPush();
989       const saveSql = Array.isArray(opt.saveSql) ? opt.saveSql : undefined;
990       try{
991         const isTA = util.isSQLableTypedArray(arg.sql)
992         /* Optimization: if the SQL is a TypedArray we can save some string
993            conversion costs. */;
994         /* Allocate the two output pointers (ppStmt, pzTail) and heap
995            space for the SQL (pSql). When prepare_v2() returns, pzTail
996            will point to somewhere in pSql. */
997         let sqlByteLen = isTA ? arg.sql.byteLength : wasm.jstrlen(arg.sql);
998         const ppStmt  = wasm.scopedAlloc(
999           /* output (sqlite3_stmt**) arg and pzTail */
1000           (2 * wasm.ptrSizeof) + (sqlByteLen + 1/* SQL + NUL */)
1001         );
1002         const pzTail = ppStmt + wasm.ptrSizeof /* final arg to sqlite3_prepare_v2() */;
1003         let pSql = pzTail + wasm.ptrSizeof;
1004         const pSqlEnd = pSql + sqlByteLen;
1005         if(isTA) wasm.heap8().set(arg.sql, pSql);
1006         else wasm.jstrcpy(arg.sql, wasm.heap8(), pSql, sqlByteLen, false);
1007         wasm.poke(pSql + sqlByteLen, 0/*NUL terminator*/);
1008         while(pSql && wasm.peek(pSql, 'i8')
1009               /* Maintenance reminder:^^^ _must_ be 'i8' or else we
1010                  will very likely cause an endless loop. What that's
1011                  doing is checking for a terminating NUL byte. If we
1012                  use i32 or similar then we read 4 bytes, read stuff
1013                  around the NUL terminator, and get stuck in and
1014                  endless loop at the end of the SQL, endlessly
1015                  re-preparing an empty statement. */ ){
1016           wasm.pokePtr([ppStmt, pzTail], 0);
1017           DB.checkRc(this, capi.sqlite3_prepare_v3(
1018             this.pointer, pSql, sqlByteLen, 0, ppStmt, pzTail
1019           ));
1020           const pStmt = wasm.peekPtr(ppStmt);
1021           pSql = wasm.peekPtr(pzTail);
1022           sqlByteLen = pSqlEnd - pSql;
1023           if(!pStmt) continue;
1024           if(saveSql) saveSql.push(capi.sqlite3_sql(pStmt).trim());
1025           stmt = new Stmt(this, pStmt, BindTypes);
1026           if(bind && stmt.parameterCount){
1027             stmt.bind(bind);
1028             bind = null;
1029           }
1030           if(evalFirstResult && stmt.columnCount){
1031             /* Only forward SELECT-style results for the FIRST query
1032                in the SQL which potentially has them. */
1033             let gotColNames = Array.isArray(
1034               opt.columnNames
1035               /* As reported in
1036                  https://sqlite.org/forum/forumpost/7774b773937cbe0a
1037                  we need to delay fetching of the column names until
1038                  after the first step() (if we step() at all) because
1039                  a schema change between the prepare() and step(), via
1040                  another connection, may invalidate the column count
1041                  and names. */) ? 0 : 1;
1042             evalFirstResult = false;
1043             if(arg.cbArg || resultRows){
1044               const cbArgCache = Object.create(null)
1045               /* 2nd arg for arg.cbArg, used by (at least) row-to-object
1046                  converter */;
1047               for(; stmt.step(); stmt._lockedByExec = false){
1048                 if(0===gotColNames++){
1049                   stmt.getColumnNames(cbArgCache.columnNames = (opt.columnNames || []));
1050                 }
1051                 stmt._lockedByExec = true;
1052                 const row = arg.cbArg(stmt,cbArgCache);
1053                 if(resultRows) resultRows.push(row);
1054                 if(callback && false === callback.call(opt, row, stmt)){
1055                   break;
1056                 }
1057               }
1058               stmt._lockedByExec = false;
1059             }
1060             if(0===gotColNames){
1061               /* opt.columnNames was provided but we visited no result rows */
1062               stmt.getColumnNames(opt.columnNames);
1063             }
1064           }else{
1065             stmt.step();
1066           }
1067           stmt.reset(
1068             /* In order to trigger an exception in the
1069                INSERT...RETURNING locking scenario:
1070                https://sqlite.org/forum/forumpost/36f7a2e7494897df
1071             */).finalize();
1072           stmt = null;
1073         }/*prepare() loop*/
1074       }/*catch(e){
1075         sqlite3.config.warn("DB.exec() is propagating exception",opt,e);
1076         throw e;
1077       }*/finally{
1078         wasm.scopedAllocPop(stack);
1079         if(stmt){
1080           delete stmt._lockedByExec;
1081           stmt.finalize();
1082         }
1083       }
1084       return arg.returnVal();
1085     }/*exec()*/,
1087     /**
1088        Creates a new UDF (User-Defined Function) which is accessible
1089        via SQL code. This function may be called in any of the
1090        following forms:
1092        - (name, function)
1093        - (name, function, optionsObject)
1094        - (name, optionsObject)
1095        - (optionsObject)
1097        In the final two cases, the function must be defined as the
1098        `callback` property of the options object (optionally called
1099        `xFunc` to align with the C API documentation). In the final
1100        case, the function's name must be the 'name' property.
1102        The first two call forms can only be used for creating scalar
1103        functions. Creating an aggregate or window function requires
1104        the options-object form (see below for details).
1106        UDFs can be removed as documented for
1107        sqlite3_create_function_v2() and
1108        sqlite3_create_window_function(), but doing so will "leak" the
1109        JS-created WASM binding of those functions (meaning that their
1110        entries in the WASM indirect function table still
1111        exist). Eliminating that potential leak is a pending TODO.
1113        On success, returns this object. Throws on error.
1115        When called from SQL arguments to the UDF, and its result,
1116        will be converted between JS and SQL with as much fidelity as
1117        is feasible, triggering an exception if a type conversion
1118        cannot be determined. The docs for sqlite3_create_function_v2()
1119        describe the conversions in more detail.
1121        The values set in the options object differ for scalar and
1122        aggregate functions:
1124        - Scalar: set the `xFunc` function-type property to the UDF
1125          function.
1127        - Aggregate: set the `xStep` and `xFinal` function-type
1128          properties to the "step" and "final" callbacks for the
1129          aggregate. Do not set the `xFunc` property.
1131        - Window: set the `xStep`, `xFinal`, `xValue`, and `xInverse`
1132          function-type properties. Do not set the `xFunc` property.
1134        The options object may optionally have an `xDestroy`
1135        function-type property, as per sqlite3_create_function_v2().
1136        Its argument will be the WASM-pointer-type value of the `pApp`
1137        property, and this function will throw if `pApp` is defined but
1138        is not null, undefined, or a numeric (WASM pointer)
1139        value. i.e. `pApp`, if set, must be value suitable for use as a
1140        WASM pointer argument, noting that `null` or `undefined` will
1141        translate to 0 for that purpose.
1143        The options object may contain flags to modify how
1144        the function is defined:
1146        - `arity`: the number of arguments which SQL calls to this
1147        function expect or require. The default value is `xFunc.length`
1148        or `xStep.length` (i.e. the number of declared parameters it
1149        has) **MINUS 1** (see below for why). As a special case, if the
1150        `length` is 0, its arity is also 0 instead of -1. A negative
1151        arity value means that the function is variadic and may accept
1152        any number of arguments, up to sqlite3's compile-time
1153        limits. sqlite3 will enforce the argument count if is zero or
1154        greater. The callback always receives a pointer to an
1155        `sqlite3_context` object as its first argument. Any arguments
1156        after that are from SQL code. The leading context argument does
1157        _not_ count towards the function's arity. See the docs for
1158        sqlite3.capi.sqlite3_create_function_v2() for why that argument
1159        is needed in the interface.
1161        The following options-object properties correspond to flags
1162        documented at:
1164        https://sqlite.org/c3ref/create_function.html
1166        - `deterministic` = sqlite3.capi.SQLITE_DETERMINISTIC
1167        - `directOnly` = sqlite3.capi.SQLITE_DIRECTONLY
1168        - `innocuous` = sqlite3.capi.SQLITE_INNOCUOUS
1170        Sidebar: the ability to add new WASM-accessible functions to
1171        the runtime requires that the WASM build is compiled with the
1172        equivalent functionality as that provided by Emscripten's
1173        `-sALLOW_TABLE_GROWTH` flag.
1174     */
1175     createFunction: function f(name, xFunc, opt){
1176       const isFunc = (f)=>(f instanceof Function);
1177       switch(arguments.length){
1178           case 1: /* (optionsObject) */
1179             opt = name;
1180             name = opt.name;
1181             xFunc = opt.xFunc || 0;
1182             break;
1183           case 2: /* (name, callback|optionsObject) */
1184             if(!isFunc(xFunc)){
1185               opt = xFunc;
1186               xFunc = opt.xFunc || 0;
1187             }
1188             break;
1189           case 3: /* name, xFunc, opt */
1190             break;
1191           default: break;
1192       }
1193       if(!opt) opt = {};
1194       if('string' !== typeof name){
1195         toss3("Invalid arguments: missing function name.");
1196       }
1197       let xStep = opt.xStep || 0;
1198       let xFinal = opt.xFinal || 0;
1199       const xValue = opt.xValue || 0;
1200       const xInverse = opt.xInverse || 0;
1201       let isWindow = undefined;
1202       if(isFunc(xFunc)){
1203         isWindow = false;
1204         if(isFunc(xStep) || isFunc(xFinal)){
1205           toss3("Ambiguous arguments: scalar or aggregate?");
1206         }
1207         xStep = xFinal = null;
1208       }else if(isFunc(xStep)){
1209         if(!isFunc(xFinal)){
1210           toss3("Missing xFinal() callback for aggregate or window UDF.");
1211         }
1212         xFunc = null;
1213       }else if(isFunc(xFinal)){
1214         toss3("Missing xStep() callback for aggregate or window UDF.");
1215       }else{
1216         toss3("Missing function-type properties.");
1217       }
1218       if(false === isWindow){
1219         if(isFunc(xValue) || isFunc(xInverse)){
1220           toss3("xValue and xInverse are not permitted for non-window UDFs.");
1221         }
1222       }else if(isFunc(xValue)){
1223         if(!isFunc(xInverse)){
1224           toss3("xInverse must be provided if xValue is.");
1225         }
1226         isWindow = true;
1227       }else if(isFunc(xInverse)){
1228         toss3("xValue must be provided if xInverse is.");
1229       }
1230       const pApp = opt.pApp;
1231       if(undefined!==pApp &&
1232          null!==pApp &&
1233          (('number'!==typeof pApp) || !util.isInt32(pApp))){
1234         toss3("Invalid value for pApp property. Must be a legal WASM pointer value.");
1235       }
1236       const xDestroy = opt.xDestroy || 0;
1237       if(xDestroy && !isFunc(xDestroy)){
1238         toss3("xDestroy property must be a function.");
1239       }
1240       let fFlags = 0 /*flags for sqlite3_create_function_v2()*/;
1241       if(getOwnOption(opt, 'deterministic')) fFlags |= capi.SQLITE_DETERMINISTIC;
1242       if(getOwnOption(opt, 'directOnly')) fFlags |= capi.SQLITE_DIRECTONLY;
1243       if(getOwnOption(opt, 'innocuous')) fFlags |= capi.SQLITE_INNOCUOUS;
1244       name = name.toLowerCase();
1245       const xArity = xFunc || xStep;
1246       const arity = getOwnOption(opt, 'arity');
1247       const arityArg = ('number'===typeof arity
1248                         ? arity
1249                         : (xArity.length ? xArity.length-1/*for pCtx arg*/ : 0));
1250       let rc;
1251       if( isWindow ){
1252         rc = capi.sqlite3_create_window_function(
1253           this.pointer, name, arityArg,
1254           capi.SQLITE_UTF8 | fFlags, pApp || 0,
1255           xStep, xFinal, xValue, xInverse, xDestroy);
1256       }else{
1257         rc = capi.sqlite3_create_function_v2(
1258           this.pointer, name, arityArg,
1259           capi.SQLITE_UTF8 | fFlags, pApp || 0,
1260           xFunc, xStep, xFinal, xDestroy);
1261       }
1262       DB.checkRc(this, rc);
1263       return this;
1264     }/*createFunction()*/,
1265     /**
1266        Prepares the given SQL, step()s it one time, and returns
1267        the value of the first result column. If it has no results,
1268        undefined is returned.
1270        If passed a second argument, it is treated like an argument
1271        to Stmt.bind(), so may be any type supported by that
1272        function. Passing the undefined value is the same as passing
1273        no value, which is useful when...
1275        If passed a 3rd argument, it is expected to be one of the
1276        SQLITE_{typename} constants. Passing the undefined value is
1277        the same as not passing a value.
1279        Throws on error (e.g. malformed SQL).
1280     */
1281     selectValue: function(sql,bind,asType){
1282       return __selectFirstRow(this, sql, bind, 0, asType);
1283     },
1285     /**
1286        Runs the given query and returns an array of the values from
1287        the first result column of each row of the result set. The 2nd
1288        argument is an optional value for use in a single-argument call
1289        to Stmt.bind(). The 3rd argument may be any value suitable for
1290        use as the 2nd argument to Stmt.get(). If a 3rd argument is
1291        desired but no bind data are needed, pass `undefined` for the 2nd
1292        argument.
1294        If there are no result rows, an empty array is returned.
1295     */
1296     selectValues: function(sql,bind,asType){
1297       const stmt = this.prepare(sql), rc = [];
1298       try {
1299         stmt.bind(bind);
1300         while(stmt.step()) rc.push(stmt.get(0,asType));
1301         stmt.reset(/*for INSERT...RETURNING locking case*/);
1302       }finally{
1303         stmt.finalize();
1304       }
1305       return rc;
1306     },
1308     /**
1309        Prepares the given SQL, step()s it one time, and returns an
1310        array containing the values of the first result row. If it has
1311        no results, `undefined` is returned.
1313        If passed a second argument other than `undefined`, it is
1314        treated like an argument to Stmt.bind(), so may be any type
1315        supported by that function.
1317        Throws on error (e.g. malformed SQL).
1318     */
1319     selectArray: function(sql,bind){
1320       return __selectFirstRow(this, sql, bind, []);
1321     },
1323     /**
1324        Prepares the given SQL, step()s it one time, and returns an
1325        object containing the key/value pairs of the first result
1326        row. If it has no results, `undefined` is returned.
1328        Note that the order of returned object's keys is not guaranteed
1329        to be the same as the order of the fields in the query string.
1331        If passed a second argument other than `undefined`, it is
1332        treated like an argument to Stmt.bind(), so may be any type
1333        supported by that function.
1335        Throws on error (e.g. malformed SQL).
1336     */
1337     selectObject: function(sql,bind){
1338       return __selectFirstRow(this, sql, bind, {});
1339     },
1341     /**
1342        Runs the given SQL and returns an array of all results, with
1343        each row represented as an array, as per the 'array' `rowMode`
1344        option to `exec()`. An empty result set resolves
1345        to an empty array. The second argument, if any, is treated as
1346        the 'bind' option to a call to exec().
1347     */
1348     selectArrays: function(sql,bind){
1349       return __selectAll(this, sql, bind, 'array');
1350     },
1352     /**
1353        Works identically to selectArrays() except that each value
1354        in the returned array is an object, as per the 'object' `rowMode`
1355        option to `exec()`.
1356     */
1357     selectObjects: function(sql,bind){
1358       return __selectAll(this, sql, bind, 'object');
1359     },
1361     /**
1362        Returns the number of currently-opened Stmt handles for this db
1363        handle, or 0 if this DB instance is closed. Note that only
1364        handles prepared via this.prepare() are counted, and not
1365        handles prepared using capi.sqlite3_prepare_v3() (or
1366        equivalent).
1367     */
1368     openStatementCount: function(){
1369       return this.pointer ? Object.keys(__stmtMap.get(this)).length : 0;
1370     },
1372     /**
1373        Starts a transaction, calls the given callback, and then either
1374        rolls back or commits the savepoint, depending on whether the
1375        callback throws. The callback is passed this db object as its
1376        only argument. On success, returns the result of the
1377        callback. Throws on error.
1379        Note that transactions may not be nested, so this will throw if
1380        it is called recursively. For nested transactions, use the
1381        savepoint() method or manually manage SAVEPOINTs using exec().
1383        If called with 2 arguments, the first must be a keyword which
1384        is legal immediately after a BEGIN statement, e.g. one of
1385        "DEFERRED", "IMMEDIATE", or "EXCLUSIVE". Though the exact list
1386        of supported keywords is not hard-coded here, in order to be
1387        future-compatible, if the argument does not look like a single
1388        keyword then an exception is triggered with a description of
1389        the problem.
1390      */
1391     transaction: function(/* [beginQualifier,] */callback){
1392       let opener = 'BEGIN';
1393       if(arguments.length>1){
1394         if(/[^a-zA-Z]/.test(arguments[0])){
1395           toss3(capi.SQLITE_MISUSE, "Invalid argument for BEGIN qualifier.");
1396         }
1397         opener += ' '+arguments[0];
1398         callback = arguments[1];
1399       }
1400       affirmDbOpen(this).exec(opener);
1401       try {
1402         const rc = callback(this);
1403         this.exec("COMMIT");
1404         return rc;
1405       }catch(e){
1406         this.exec("ROLLBACK");
1407         throw e;
1408       }
1409     },
1411     /**
1412        This works similarly to transaction() but uses sqlite3's SAVEPOINT
1413        feature. This function starts a savepoint (with an unspecified name)
1414        and calls the given callback function, passing it this db object.
1415        If the callback returns, the savepoint is released (committed). If
1416        the callback throws, the savepoint is rolled back. If it does not
1417        throw, it returns the result of the callback.
1418     */
1419     savepoint: function(callback){
1420       affirmDbOpen(this).exec("SAVEPOINT oo1");
1421       try {
1422         const rc = callback(this);
1423         this.exec("RELEASE oo1");
1424         return rc;
1425       }catch(e){
1426         this.exec("ROLLBACK to SAVEPOINT oo1; RELEASE SAVEPOINT oo1");
1427         throw e;
1428       }
1429     },
1431     /**
1432        A convenience form of DB.checkRc(this,resultCode). If it does
1433        not throw, it returns this object.
1434     */
1435     checkRc: function(resultCode){
1436       return checkSqlite3Rc(this, resultCode);
1437     }
1438   }/*DB.prototype*/;
1441   /** Throws if the given Stmt has been finalized, else stmt is
1442       returned. */
1443   const affirmStmtOpen = function(stmt){
1444     if(!stmt.pointer) toss3("Stmt has been closed.");
1445     return stmt;
1446   };
1448   /** Returns an opaque truthy value from the BindTypes
1449       enum if v's type is a valid bindable type, else
1450       returns a falsy value. As a special case, a value of
1451       undefined is treated as a bind type of null. */
1452   const isSupportedBindType = function(v){
1453     let t = BindTypes[(null===v||undefined===v) ? 'null' : typeof v];
1454     switch(t){
1455         case BindTypes.boolean:
1456         case BindTypes.null:
1457         case BindTypes.number:
1458         case BindTypes.string:
1459           return t;
1460         case BindTypes.bigint:
1461           if(wasm.bigIntEnabled) return t;
1462           /* else fall through */
1463         default:
1464           return util.isBindableTypedArray(v) ? BindTypes.blob : undefined;
1465     }
1466   };
1468   /**
1469      If isSupportedBindType(v) returns a truthy value, this
1470      function returns that value, else it throws.
1471   */
1472   const affirmSupportedBindType = function(v){
1473     //sqlite3.config.log('affirmSupportedBindType',v);
1474     return isSupportedBindType(v) || toss3("Unsupported bind() argument type:",typeof v);
1475   };
1477   /**
1478      If key is a number and within range of stmt's bound parameter
1479      count, key is returned.
1481      If key is not a number then it is checked against named
1482      parameters. If a match is found, its index is returned.
1484      Else it throws.
1485   */
1486   const affirmParamIndex = function(stmt,key){
1487     const n = ('number'===typeof key)
1488           ? key : capi.sqlite3_bind_parameter_index(stmt.pointer, key);
1489     if(0===n || !util.isInt32(n)){
1490       toss3("Invalid bind() parameter name: "+key);
1491     }
1492     else if(n<1 || n>stmt.parameterCount) toss3("Bind index",key,"is out of range.");
1493     return n;
1494   };
1496   /**
1497      If stmt._lockedByExec is truthy, this throws an exception
1498      complaining that the 2nd argument (an operation name,
1499      e.g. "bind()") is not legal while the statement is "locked".
1500      Locking happens before an exec()-like callback is passed a
1501      statement, to ensure that the callback does not mutate or
1502      finalize the statement. If it does not throw, it returns stmt.
1503   */
1504   const affirmNotLockedByExec = function(stmt,currentOpName){
1505     if(stmt._lockedByExec){
1506       toss3("Operation is illegal when statement is locked:",currentOpName);
1507     }
1508     return stmt;
1509   };
1511   /**
1512      Binds a single bound parameter value on the given stmt at the
1513      given index (numeric or named) using the given bindType (see
1514      the BindTypes enum) and value. Throws on error. Returns stmt on
1515      success.
1516   */
1517   const bindOne = function f(stmt,ndx,bindType,val){
1518     affirmNotLockedByExec(affirmStmtOpen(stmt), 'bind()');
1519     if(!f._){
1520       f._tooBigInt = (v)=>toss3(
1521         "BigInt value is too big to store without precision loss:", v
1522       );
1523       f._ = {
1524         string: function(stmt, ndx, val, asBlob){
1525           const [pStr, n] = wasm.allocCString(val, true);
1526           const f = asBlob ? capi.sqlite3_bind_blob : capi.sqlite3_bind_text;
1527           return f(stmt.pointer, ndx, pStr, n, capi.SQLITE_WASM_DEALLOC);
1528         }
1529       };
1530     }/* static init */
1531     affirmSupportedBindType(val);
1532     ndx = affirmParamIndex(stmt,ndx);
1533     let rc = 0;
1534     switch((null===val || undefined===val) ? BindTypes.null : bindType){
1535         case BindTypes.null:
1536           rc = capi.sqlite3_bind_null(stmt.pointer, ndx);
1537           break;
1538         case BindTypes.string:
1539           rc = f._.string(stmt, ndx, val, false);
1540           break;
1541         case BindTypes.number: {
1542           let m;
1543           if(util.isInt32(val)) m = capi.sqlite3_bind_int;
1544           else if('bigint'===typeof val){
1545             if(!util.bigIntFits64(val)){
1546               f._tooBigInt(val);
1547             }else if(wasm.bigIntEnabled){
1548               m = capi.sqlite3_bind_int64;
1549             }else if(util.bigIntFitsDouble(val)){
1550               val = Number(val);
1551               m = capi.sqlite3_bind_double;
1552             }else{
1553               f._tooBigInt(val);
1554             }
1555           }else{ // !int32, !bigint
1556             val = Number(val);
1557             if(wasm.bigIntEnabled && Number.isInteger(val)){
1558               m = capi.sqlite3_bind_int64;
1559             }else{
1560               m = capi.sqlite3_bind_double;
1561             }
1562           }
1563           rc = m(stmt.pointer, ndx, val);
1564           break;
1565         }
1566         case BindTypes.boolean:
1567           rc = capi.sqlite3_bind_int(stmt.pointer, ndx, val ? 1 : 0);
1568           break;
1569         case BindTypes.blob: {
1570           if('string'===typeof val){
1571             rc = f._.string(stmt, ndx, val, true);
1572             break;
1573           }else if(val instanceof ArrayBuffer){
1574             val = new Uint8Array(val);
1575           }else if(!util.isBindableTypedArray(val)){
1576             toss3("Binding a value as a blob requires",
1577                   "that it be a string, Uint8Array, Int8Array, or ArrayBuffer.");
1578           }
1579           const pBlob = wasm.alloc(val.byteLength || 1);
1580           wasm.heap8().set(val.byteLength ? val : [0], pBlob)
1581           rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength,
1582                                       capi.SQLITE_WASM_DEALLOC);
1583           break;
1584         }
1585         default:
1586           sqlite3.config.warn("Unsupported bind() argument type:",val);
1587           toss3("Unsupported bind() argument type: "+(typeof val));
1588     }
1589     if(rc) DB.checkRc(stmt.db.pointer, rc);
1590     stmt._mayGet = false;
1591     return stmt;
1592   };
1594   Stmt.prototype = {
1595     /**
1596        "Finalizes" this statement. This is a no-op if the statement
1597        has already been finalized. Returns the result of
1598        sqlite3_finalize() (0 on success, non-0 on error), or the
1599        undefined value if the statement has already been
1600        finalized. Regardless of success or failure, most methods in
1601        this class will throw if called after this is.
1603        This method always throws if called when it is illegal to do
1604        so. Namely, when triggered via a per-row callback handler of a
1605        DB.exec() call.
1606     */
1607     finalize: function(){
1608       if(this.pointer){
1609         affirmNotLockedByExec(this,'finalize()');
1610         const rc = capi.sqlite3_finalize(this.pointer);
1611         delete __stmtMap.get(this.db)[this.pointer];
1612         __ptrMap.delete(this);
1613         delete this._mayGet;
1614         delete this.parameterCount;
1615         delete this._lockedByExec;
1616         delete this.db;
1617         return rc;
1618       }
1619     },
1620     /**
1621        Clears all bound values. Returns this object.  Throws if this
1622        statement has been finalized or if modification of the
1623        statement is currently illegal (e.g. in the per-row callback of
1624        a DB.exec() call).
1625     */
1626     clearBindings: function(){
1627       affirmNotLockedByExec(affirmStmtOpen(this), 'clearBindings()')
1628       capi.sqlite3_clear_bindings(this.pointer);
1629       this._mayGet = false;
1630       return this;
1631     },
1632     /**
1633        Resets this statement so that it may be step()ed again from the
1634        beginning. Returns this object. Throws if this statement has
1635        been finalized, if it may not legally be reset because it is
1636        currently being used from a DB.exec() callback, or if the
1637        underlying call to sqlite3_reset() returns non-0.
1639        If passed a truthy argument then this.clearBindings() is
1640        also called, otherwise any existing bindings, along with
1641        any memory allocated for them, are retained.
1643        In versions 3.42.0 and earlier, this function did not throw if
1644        sqlite3_reset() returns non-0, but it was discovered that
1645        throwing (or significant extra client-side code) is necessary
1646        in order to avoid certain silent failure scenarios, as
1647        discussed at:
1649        https://sqlite.org/forum/forumpost/36f7a2e7494897df
1650     */
1651     reset: function(alsoClearBinds){
1652       affirmNotLockedByExec(this,'reset()');
1653       if(alsoClearBinds) this.clearBindings();
1654       const rc = capi.sqlite3_reset(affirmStmtOpen(this).pointer);
1655       this._mayGet = false;
1656       checkSqlite3Rc(this.db, rc);
1657       return this;
1658     },
1659     /**
1660        Binds one or more values to its bindable parameters. It
1661        accepts 1 or 2 arguments:
1663        If passed a single argument, it must be either an array, an
1664        object, or a value of a bindable type (see below).
1666        If passed 2 arguments, the first one is the 1-based bind
1667        index or bindable parameter name and the second one must be
1668        a value of a bindable type.
1670        Bindable value types:
1672        - null is bound as NULL.
1674        - undefined as a standalone value is a no-op intended to
1675          simplify certain client-side use cases: passing undefined as
1676          a value to this function will not actually bind anything and
1677          this function will skip confirmation that binding is even
1678          legal. (Those semantics simplify certain client-side uses.)
1679          Conversely, a value of undefined as an array or object
1680          property when binding an array/object (see below) is treated
1681          the same as null.
1683        - Numbers are bound as either doubles or integers: doubles if
1684          they are larger than 32 bits, else double or int32, depending
1685          on whether they have a fractional part. Booleans are bound as
1686          integer 0 or 1. It is not expected the distinction of binding
1687          doubles which have no fractional parts and integers is
1688          significant for the majority of clients due to sqlite3's data
1689          typing model. If [BigInt] support is enabled then this
1690          routine will bind BigInt values as 64-bit integers if they'll
1691          fit in 64 bits. If that support disabled, it will store the
1692          BigInt as an int32 or a double if it can do so without loss
1693          of precision. If the BigInt is _too BigInt_ then it will
1694          throw.
1696        - Strings are bound as strings (use bindAsBlob() to force
1697          blob binding).
1699        - Uint8Array, Int8Array, and ArrayBuffer instances are bound as
1700          blobs.
1702        If passed an array, each element of the array is bound at
1703        the parameter index equal to the array index plus 1
1704        (because arrays are 0-based but binding is 1-based).
1706        If passed an object, each object key is treated as a
1707        bindable parameter name. The object keys _must_ match any
1708        bindable parameter names, including any `$`, `@`, or `:`
1709        prefix. Because `$` is a legal identifier chararacter in
1710        JavaScript, that is the suggested prefix for bindable
1711        parameters: `stmt.bind({$a: 1, $b: 2})`.
1713        It returns this object on success and throws on
1714        error. Errors include:
1716        - Any bind index is out of range, a named bind parameter
1717        does not match, or this statement has no bindable
1718        parameters.
1720        - Any value to bind is of an unsupported type.
1722        - Passed no arguments or more than two.
1724        - The statement has been finalized.
1725     */
1726     bind: function(/*[ndx,] arg*/){
1727       affirmStmtOpen(this);
1728       let ndx, arg;
1729       switch(arguments.length){
1730           case 1: ndx = 1; arg = arguments[0]; break;
1731           case 2: ndx = arguments[0]; arg = arguments[1]; break;
1732           default: toss3("Invalid bind() arguments.");
1733       }
1734       if(undefined===arg){
1735         /* It might seem intuitive to bind undefined as NULL
1736            but this approach simplifies certain client-side
1737            uses when passing on arguments between 2+ levels of
1738            functions. */
1739         return this;
1740       }else if(!this.parameterCount){
1741         toss3("This statement has no bindable parameters.");
1742       }
1743       this._mayGet = false;
1744       if(null===arg){
1745         /* bind NULL */
1746         return bindOne(this, ndx, BindTypes.null, arg);
1747       }
1748       else if(Array.isArray(arg)){
1749         /* bind each entry by index */
1750         if(1!==arguments.length){
1751           toss3("When binding an array, an index argument is not permitted.");
1752         }
1753         arg.forEach((v,i)=>bindOne(this, i+1, affirmSupportedBindType(v), v));
1754         return this;
1755       }else if(arg instanceof ArrayBuffer){
1756         arg = new Uint8Array(arg);
1757       }
1758       if('object'===typeof arg/*null was checked above*/
1759               && !util.isBindableTypedArray(arg)){
1760         /* Treat each property of arg as a named bound parameter. */
1761         if(1!==arguments.length){
1762           toss3("When binding an object, an index argument is not permitted.");
1763         }
1764         Object.keys(arg)
1765           .forEach(k=>bindOne(this, k,
1766                               affirmSupportedBindType(arg[k]),
1767                               arg[k]));
1768         return this;
1769       }else{
1770         return bindOne(this, ndx, affirmSupportedBindType(arg), arg);
1771       }
1772       toss3("Should not reach this point.");
1773     },
1774     /**
1775        Special case of bind() which binds the given value using the
1776        BLOB binding mechanism instead of the default selected one for
1777        the value. The ndx may be a numbered or named bind index. The
1778        value must be of type string, null/undefined (both get treated
1779        as null), or a TypedArray of a type supported by the bind()
1780        API. This API cannot bind numbers as blobs.
1782        If passed a single argument, a bind index of 1 is assumed and
1783        the first argument is the value.
1784     */
1785     bindAsBlob: function(ndx,arg){
1786       affirmStmtOpen(this);
1787       if(1===arguments.length){
1788         arg = ndx;
1789         ndx = 1;
1790       }
1791       const t = affirmSupportedBindType(arg);
1792       if(BindTypes.string !== t && BindTypes.blob !== t
1793          && BindTypes.null !== t){
1794         toss3("Invalid value type for bindAsBlob()");
1795       }
1796       return bindOne(this, ndx, BindTypes.blob, arg);
1797     },
1798     /**
1799        Steps the statement one time. If the result indicates that a
1800        row of data is available, a truthy value is returned.
1801        If no row of data is available, a falsy
1802        value is returned.  Throws on error.
1803     */
1804     step: function(){
1805       affirmNotLockedByExec(this, 'step()');
1806       const rc = capi.sqlite3_step(affirmStmtOpen(this).pointer);
1807       switch(rc){
1808           case capi.SQLITE_DONE: return this._mayGet = false;
1809           case capi.SQLITE_ROW: return this._mayGet = true;
1810           default:
1811             this._mayGet = false;
1812             sqlite3.config.warn("sqlite3_step() rc=",rc,
1813                          capi.sqlite3_js_rc_str(rc),
1814                          "SQL =", capi.sqlite3_sql(this.pointer));
1815             DB.checkRc(this.db.pointer, rc);
1816       }
1817     },
1818     /**
1819        Functions exactly like step() except that...
1821        1) On success, it calls this.reset() and returns this object.
1822        2) On error, it throws and does not call reset().
1824        This is intended to simplify constructs like:
1826        ```
1827        for(...) {
1828          stmt.bind(...).stepReset();
1829        }
1830        ```
1832        Note that the reset() call makes it illegal to call this.get()
1833        after the step.
1834     */
1835     stepReset: function(){
1836       this.step();
1837       return this.reset();
1838     },
1839     /**
1840        Functions like step() except that it calls finalize() on this
1841        statement immediately after stepping, even if the step() call
1842        throws.
1844        On success, it returns true if the step indicated that a row of
1845        data was available, else it returns false.
1847        This is intended to simplify use cases such as:
1849        ```
1850        aDb.prepare("insert into foo(a) values(?)").bind(123).stepFinalize();
1851        ```
1852     */
1853     stepFinalize: function(){
1854       try{
1855         const rc = this.step();
1856         this.reset(/*for INSERT...RETURNING locking case*/);
1857         return rc;
1858       }finally{
1859         try{this.finalize()}
1860         catch(e){/*ignored*/}
1861       }
1862     },
1863     /**
1864        Fetches the value from the given 0-based column index of
1865        the current data row, throwing if index is out of range.
1867        Requires that step() has just returned a truthy value, else
1868        an exception is thrown.
1870        By default it will determine the data type of the result
1871        automatically. If passed a second argument, it must be one
1872        of the enumeration values for sqlite3 types, which are
1873        defined as members of the sqlite3 module: SQLITE_INTEGER,
1874        SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB. Any other value,
1875        except for undefined, will trigger an exception. Passing
1876        undefined is the same as not passing a value. It is legal
1877        to, e.g., fetch an integer value as a string, in which case
1878        sqlite3 will convert the value to a string.
1880        If ndx is an array, this function behaves a differently: it
1881        assigns the indexes of the array, from 0 to the number of
1882        result columns, to the values of the corresponding column,
1883        and returns that array.
1885        If ndx is a plain object, this function behaves even
1886        differentlier: it assigns the properties of the object to
1887        the values of their corresponding result columns.
1889        Blobs are returned as Uint8Array instances.
1891        Potential TODO: add type ID SQLITE_JSON, which fetches the
1892        result as a string and passes it (if it's not null) to
1893        JSON.parse(), returning the result of that. Until then,
1894        getJSON() can be used for that.
1895     */
1896     get: function(ndx,asType){
1897       if(!affirmStmtOpen(this)._mayGet){
1898         toss3("Stmt.step() has not (recently) returned true.");
1899       }
1900       if(Array.isArray(ndx)){
1901         let i = 0;
1902         const n = this.columnCount;
1903         while(i<n){
1904           ndx[i] = this.get(i++);
1905         }
1906         return ndx;
1907       }else if(ndx && 'object'===typeof ndx){
1908         let i = 0;
1909         const n = this.columnCount;
1910         while(i<n){
1911           ndx[capi.sqlite3_column_name(this.pointer,i)] = this.get(i++);
1912         }
1913         return ndx;
1914       }
1915       affirmColIndex(this, ndx);
1916       switch(undefined===asType
1917              ? capi.sqlite3_column_type(this.pointer, ndx)
1918              : asType){
1919           case capi.SQLITE_NULL: return null;
1920           case capi.SQLITE_INTEGER:{
1921             if(wasm.bigIntEnabled){
1922               const rc = capi.sqlite3_column_int64(this.pointer, ndx);
1923               if(rc>=Number.MIN_SAFE_INTEGER && rc<=Number.MAX_SAFE_INTEGER){
1924                 /* Coerce "normal" number ranges to normal number values,
1925                    and only return BigInt-type values for numbers out of this
1926                    range. */
1927                 return Number(rc).valueOf();
1928               }
1929               return rc;
1930             }else{
1931               const rc = capi.sqlite3_column_double(this.pointer, ndx);
1932               if(rc>Number.MAX_SAFE_INTEGER || rc<Number.MIN_SAFE_INTEGER){
1933                 /* Throwing here is arguable but, since we're explicitly
1934                    extracting an SQLITE_INTEGER-type value, it seems fair to throw
1935                    if the extracted number is out of range for that type.
1936                    This policy may be laxened to simply pass on the number and
1937                    hope for the best, as the C API would do. */
1938                 toss3("Integer is out of range for JS integer range: "+rc);
1939               }
1940               //sqlite3.config.log("get integer rc=",rc,isInt32(rc));
1941               return util.isInt32(rc) ? (rc | 0) : rc;
1942             }
1943           }
1944           case capi.SQLITE_FLOAT:
1945             return capi.sqlite3_column_double(this.pointer, ndx);
1946           case capi.SQLITE_TEXT:
1947             return capi.sqlite3_column_text(this.pointer, ndx);
1948           case capi.SQLITE_BLOB: {
1949             const n = capi.sqlite3_column_bytes(this.pointer, ndx),
1950                   ptr = capi.sqlite3_column_blob(this.pointer, ndx),
1951                   rc = new Uint8Array(n);
1952             //heap = n ? wasm.heap8() : false;
1953             if(n) rc.set(wasm.heap8u().slice(ptr, ptr+n), 0);
1954             //for(let i = 0; i < n; ++i) rc[i] = heap[ptr + i];
1955             if(n && this.db._blobXfer instanceof Array){
1956               /* This is an optimization soley for the
1957                  Worker-based API. These values will be
1958                  transfered to the main thread directly
1959                  instead of being copied. */
1960               this.db._blobXfer.push(rc.buffer);
1961             }
1962             return rc;
1963           }
1964           default: toss3("Don't know how to translate",
1965                          "type of result column #"+ndx+".");
1966       }
1967       toss3("Not reached.");
1968     },
1969     /** Equivalent to get(ndx) but coerces the result to an
1970         integer. */
1971     getInt: function(ndx){return this.get(ndx,capi.SQLITE_INTEGER)},
1972     /** Equivalent to get(ndx) but coerces the result to a
1973         float. */
1974     getFloat: function(ndx){return this.get(ndx,capi.SQLITE_FLOAT)},
1975     /** Equivalent to get(ndx) but coerces the result to a
1976         string. */
1977     getString: function(ndx){return this.get(ndx,capi.SQLITE_TEXT)},
1978     /** Equivalent to get(ndx) but coerces the result to a
1979         Uint8Array. */
1980     getBlob: function(ndx){return this.get(ndx,capi.SQLITE_BLOB)},
1981     /**
1982        A convenience wrapper around get() which fetches the value
1983        as a string and then, if it is not null, passes it to
1984        JSON.parse(), returning that result. Throws if parsing
1985        fails. If the result is null, null is returned. An empty
1986        string, on the other hand, will trigger an exception.
1987     */
1988     getJSON: function(ndx){
1989       const s = this.get(ndx, capi.SQLITE_STRING);
1990       return null===s ? s : JSON.parse(s);
1991     },
1992     // Design note: the only reason most of these getters have a 'get'
1993     // prefix is for consistency with getVALUE_TYPE().  The latter
1994     // arguably really need that prefix for API readability and the
1995     // rest arguably don't, but consistency is a powerful thing.
1996     /**
1997        Returns the result column name of the given index, or
1998        throws if index is out of bounds or this statement has been
1999        finalized. This can be used without having run step()
2000        first.
2001     */
2002     getColumnName: function(ndx){
2003       return capi.sqlite3_column_name(
2004         affirmColIndex(affirmStmtOpen(this),ndx).pointer, ndx
2005       );
2006     },
2007     /**
2008        If this statement potentially has result columns, this function
2009        returns an array of all such names. If passed an array, it is
2010        used as the target and all names are appended to it. Returns
2011        the target array. Throws if this statement cannot have result
2012        columns. This object's columnCount property holds the number of
2013        columns.
2014     */
2015     getColumnNames: function(tgt=[]){
2016       affirmColIndex(affirmStmtOpen(this),0);
2017       const n = this.columnCount;
2018       for(let i = 0; i < n; ++i){
2019         tgt.push(capi.sqlite3_column_name(this.pointer, i));
2020       }
2021       return tgt;
2022     },
2023     /**
2024        If this statement has named bindable parameters and the
2025        given name matches one, its 1-based bind index is
2026        returned. If no match is found, 0 is returned. If it has no
2027        bindable parameters, the undefined value is returned.
2028     */
2029     getParamIndex: function(name){
2030       return (affirmStmtOpen(this).parameterCount
2031               ? capi.sqlite3_bind_parameter_index(this.pointer, name)
2032               : undefined);
2033     }
2034   }/*Stmt.prototype*/;
2036   {/* Add the `pointer` property to DB and Stmt. */
2037     const prop = {
2038       enumerable: true,
2039       get: function(){return __ptrMap.get(this)},
2040       set: ()=>toss3("The pointer property is read-only.")
2041     }
2042     Object.defineProperty(Stmt.prototype, 'pointer', prop);
2043     Object.defineProperty(DB.prototype, 'pointer', prop);
2044   }
2045   /**
2046      Stmt.columnCount is an interceptor for sqlite3_column_count().
2048      This requires an unfortunate performance hit compared to caching
2049      columnCount when the Stmt is created/prepared (as was done in
2050      SQLite <=3.42.0), but is necessary in order to handle certain
2051      corner cases, as described in
2052      https://sqlite.org/forum/forumpost/7774b773937cbe0a.
2053   */
2054   Object.defineProperty(Stmt.prototype, 'columnCount', {
2055     enumerable: false,
2056     get: function(){return capi.sqlite3_column_count(this.pointer)},
2057     set: ()=>toss3("The columnCount property is read-only.")
2058   });
2060   /** The OO API's public namespace. */
2061   sqlite3.oo1 = {
2062     DB,
2063     Stmt
2064   }/*oo1 object*/;
2066   if(util.isUIThread()){
2067     /**
2068        Functionally equivalent to DB(storageName,'c','kvvfs') except
2069        that it throws if the given storage name is not one of 'local'
2070        or 'session'.
2072        As of version 3.46, the argument may optionally be an options
2073        object in the form:
2075        {
2076          filename: 'session'|'local',
2077          ... etc. (all options supported by the DB ctor)
2078        }
2080        noting that the 'vfs' option supported by main DB
2081        constructor is ignored here: the vfs is always 'kvvfs'.
2082     */
2083     sqlite3.oo1.JsStorageDb = function(storageName='session'){
2084       const opt = dbCtorHelper.normalizeArgs(...arguments);
2085       storageName = opt.filename;
2086       if('session'!==storageName && 'local'!==storageName){
2087         toss3("JsStorageDb db name must be one of 'session' or 'local'.");
2088       }
2089       opt.vfs = 'kvvfs';
2090       dbCtorHelper.call(this, opt);
2091     };
2092     const jdb = sqlite3.oo1.JsStorageDb;
2093     jdb.prototype = Object.create(DB.prototype);
2094     /** Equivalent to sqlite3_js_kvvfs_clear(). */
2095     jdb.clearStorage = capi.sqlite3_js_kvvfs_clear;
2096     /**
2097        Clears this database instance's storage or throws if this
2098        instance has been closed. Returns the number of
2099        database blocks which were cleaned up.
2100     */
2101     jdb.prototype.clearStorage = function(){
2102       return jdb.clearStorage(affirmDbOpen(this).filename);
2103     };
2104     /** Equivalent to sqlite3_js_kvvfs_size(). */
2105     jdb.storageSize = capi.sqlite3_js_kvvfs_size;
2106     /**
2107        Returns the _approximate_ number of bytes this database takes
2108        up in its storage or throws if this instance has been closed.
2109     */
2110     jdb.prototype.storageSize = function(){
2111       return jdb.storageSize(affirmDbOpen(this).filename);
2112     };
2113   }/*main-window-only bits*/
2116 //#else
2117 /* Built with the omit-oo1 flag. */
2118 //#endif ifnot omit-oo1