]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
General internal cleanups in the oo1 API.
authorstephan <stephan@noemail.net>
Sun, 2 Oct 2022 00:09:40 +0000 (00:09 +0000)
committerstephan <stephan@noemail.net>
Sun, 2 Oct 2022 00:09:40 +0000 (00:09 +0000)
FossilOrigin-Name: f9db664f756f3707afcb5dce87f6d946625848f27ea84337af68de72d4ad6c6b

ext/wasm/api/sqlite3-api-oo1.js
ext/wasm/api/sqlite3-api-prologue.js
ext/wasm/testing1.js
manifest
manifest.uuid

index 19e9e61f08374150888d41ad357c37915be3bbd2..627af2e8a595ed1747296e3cb312af6d7b4e2d99 100644 (file)
@@ -16,6 +16,7 @@
 */
 self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
   const toss = (...args)=>{throw new Error(args.join(' '))};
+  const toss3 = (...args)=>{throw new sqlite3.SQLite3Error(...args)};
 
   const capi = sqlite3.capi, util = capi.util;
   /* What follows is colloquially known as "OO API #1". It is a
@@ -53,28 +54,11 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
   const getOwnOption = (opts, p, dflt)=>
         opts.hasOwnProperty(p) ? opts[p] : dflt;
 
-  /**
-     An Error subclass specifically for reporting DB-level errors and
-     enabling clients to unambiguously identify such exceptions.
-  */
-  class SQLite3Error extends Error {
-    /**
-       Constructs this object with a message equal to all arguments
-       concatenated with a space between each one.
-    */
-    constructor(...args){
-      super(args.join(' '));
-      this.name = 'SQLite3Error';
-    }
-  };
-  const toss3 = (...args)=>{throw new SQLite3Error(...args)};
-  sqlite3.SQLite3Error = SQLite3Error;
-
   // Documented in DB.checkRc()
   const checkSqlite3Rc = function(dbPtr, sqliteResultCode){
     if(sqliteResultCode){
       if(dbPtr instanceof DB) dbPtr = dbPtr.pointer;
-      throw new SQLite3Error(
+      toss3(
         "sqlite result code",sqliteResultCode+":",
         (dbPtr
          ? capi.sqlite3_errmsg(dbPtr)
@@ -183,13 +167,14 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
      If passed an object, any additional properties it has are copied
      as-is into the new object.
   */
-  dbCtorHelper.normalizeArgs = function(filename,flags = 'c',vfs = null){
+  dbCtorHelper.normalizeArgs = function(filename=':memory:',flags = 'c',vfs = null){
     const arg = {};
     if(1===arguments.length && 'object'===typeof arguments[0]){
       const x = arguments[0];
       Object.keys(x).forEach((k)=>arg[k] = x[k]);
       if(undefined===arg.flags) arg.flags = 'c';
       if(undefined===arg.vfs) arg.vfs = null;
+      if(undefined===arg.filename) arg.filename = ':memory:';
     }else{
       arg.filename = filename;
       arg.flags = flags;
@@ -232,7 +217,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
 
      The final argument is analogous to the final argument of
      sqlite3_open_v2(): the name of an sqlite3 VFS. Pass a falsy value,
-     or not at all, to use the default. If passed a value, it must
+     or none at all, to use the default. If passed a value, it must
      be the string name of a VFS
 
      The constructor optionally (and preferably) takes its arguments
@@ -554,15 +539,16 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
     */
     prepare: function(sql){
       affirmDbOpen(this);
-      if(Array.isArray(sql)) sql = sql.join('');
-      const stack = capi.wasm.scopedAllocPush();
+      const stack = capi.wasm.pstack.pointer;
       let ppStmt, pStmt;
       try{
-        ppStmt = capi.wasm.scopedAllocPtr()/* output (sqlite3_stmt**) arg */;
+        ppStmt = capi.wasm.pstack.alloc(8)/* output (sqlite3_stmt**) arg */;
         DB.checkRc(this, capi.sqlite3_prepare_v2(this.pointer, sql, -1, ppStmt, null));
         pStmt = capi.wasm.getPtrValue(ppStmt);
       }
-      finally {capi.wasm.scopedAllocPop(stack)}
+      finally {
+        capi.wasm.pstack.restore(stack);
+      }
       if(!pStmt) toss3("Cannot prepare empty SQL.");
       const stmt = new Stmt(this, pStmt, BindTypes);
       __stmtMap.get(this)[pStmt] = stmt;
@@ -977,7 +963,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
        SQLITE_{typename} constants. Passing the undefined value is
        the same as not passing a value.
 
-       Throws on error (e.g. malformedSQL).
+       Throws on error (e.g. malformed SQL).
     */
     selectValue: function(sql,bind,asType){
       let stmt, rc;
@@ -1157,7 +1143,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
           }
         }
       };
-    }
+    }/* static init */
     affirmSupportedBindType(val);
     ndx = affirmParamIndex(stmt,ndx);
     let rc = 0;
@@ -1171,15 +1157,24 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
         case BindTypes.number: {
           let m;
           if(util.isInt32(val)) m = capi.sqlite3_bind_int;
-          else if(capi.wasm.bigIntEnabled && ('bigint'===typeof val)){
+          else if('bigint'===typeof val){
             if(val<f._minInt || val>f._maxInt){
-              toss3("BigInt value is out of range for int64: "+val);
+              toss3("BigInt value is out of range for storing as int64: "+val);
+            }else if(capi.wasm.bigIntEnabled){
+              m = capi.sqlite3_bind_int64;
+            }else if(val >= Number.MIN_SAFE_INTEGER && val <= Number.MAX_SAFE_INTEGER){
+              val = Number(val);
+              m = capi.sqlite3_bind_double;
+            }else{
+              toss3("BigInt value is out of range for storing as double: "+val);
+            }
+          }else{ // !int32, !bigint
+            val = Number(val);
+            if(capi.wasm.bigIntEnabled && Number.isInteger(val)){
+              m = capi.sqlite3_bind_int64;
+            }else{
+              m = capi.sqlite3_bind_double;
             }
-            m = capi.sqlite3_bind_int64;
-          }else if(Number.isInteger(val)){
-            m = capi.sqlite3_bind_int64;
-          }else{
-            m = capi.sqlite3_bind_double;
           }
           rc = m(stmt.pointer, ndx, val);
           break;
@@ -1283,31 +1278,32 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
        - null is bound as NULL.
 
        - undefined as a standalone value is a no-op intended to
-       simplify certain client-side use cases: passing undefined
-       as a value to this function will not actually bind
-       anything and this function will skip confirmation that
-       binding is even legal. (Those semantics simplify certain
-       client-side uses.) Conversely, a value of undefined as an
-       array or object property when binding an array/object
-       (see below) is treated the same as null.
-
-       - Numbers are bound as either doubles or integers: doubles
-       if they are larger than 32 bits, else double or int32,
-       depending on whether they have a fractional part. (It is,
-       as of this writing, illegal to call (from JS) a WASM
-       function which either takes or returns an int64.)
-       Booleans are bound as integer 0 or 1. It is not expected
-       the distinction of binding doubles which have no
-       fractional parts is integers is significant for the
-       majority of clients due to sqlite3's data typing
-       model. If capi.wasm.bigIntEnabled is true then this
-       routine will bind BigInt values as 64-bit integers.
+         simplify certain client-side use cases: passing undefined as
+         a value to this function will not actually bind anything and
+         this function will skip confirmation that binding is even
+         legal. (Those semantics simplify certain client-side uses.)
+         Conversely, a value of undefined as an array or object
+         property when binding an array/object (see below) is treated
+         the same as null.
+
+       - Numbers are bound as either doubles or integers: doubles if
+         they are larger than 32 bits, else double or int32, depending
+         on whether they have a fractional part. Booleans are bound as
+         integer 0 or 1. It is not expected the distinction of binding
+         doubles which have no fractional parts is integers is
+         significant for the majority of clients due to sqlite3's data
+         typing model. If [BigInt] support is enabled then this
+         routine will bind BigInt values as 64-bit integers if they'll
+         fit in 64 bits. If that support disabled, it will store the
+         BigInt as an int32 or a double if it can do so without loss
+         of precision. If the BigInt is _too BigInt_ then it will
+         throw.
 
        - Strings are bound as strings (use bindAsBlob() to force
-       blob binding).
+         blob binding).
 
        - Uint8Array and Int8Array instances are bound as blobs.
-       (TODO: binding the other TypedArray types.)
+         (TODO: binding the other TypedArray types.)
 
        If passed an array, each element of the array is bound at
        the parameter index equal to the array index plus 1
@@ -1458,7 +1454,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
        This is intended to simplify use cases such as:
 
        ```
-       aDb.prepare("insert in foo(a) values(?)").bind(123).stepFinalize();
+       aDb.prepare("insert into foo(a) values(?)").bind(123).stepFinalize();
        ```
     */
     stepFinalize: function(){
@@ -1595,7 +1591,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
     },
     // Design note: the only reason most of these getters have a 'get'
     // prefix is for consistency with getVALUE_TYPE().  The latter
-    // arguablly really need that prefix for API readability and the
+    // arguably really need that prefix for API readability and the
     // rest arguably don't, but consistency is a powerful thing.
     /**
        Returns the result column name of the given index, or
@@ -1616,9 +1612,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
        cannot have result columns. This object's columnCount member
        holds the number of columns.
     */
-    getColumnNames: function(tgt){
+    getColumnNames: function(tgt=[]){
       affirmColIndex(affirmStmtOpen(this),0);
-      if(!tgt) tgt = [];
       for(let i = 0; i < this.columnCount; ++i){
         tgt.push(capi.sqlite3_column_name(this.pointer, i));
       }
index b00eeb8633b8e0e56b167c76582aeb91c1fc577f..97376be6c89ecea4d12e2f59c0791c30302029e0 100644 (file)
@@ -785,7 +785,9 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
        be released using restore().
 
        This method always adjusts the given value to be a multiple
-       of 8 in order to keep alignment guarantees.
+       of 8 bytes because failing to do so can lead to incorrect
+       results when reading and writing 64-bit values from/to the WASM
+       heap.
     */
     alloc: capi.wasm.exports.sqlite3_wasm_pstack_alloc
   });
@@ -809,6 +811,24 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
     get: capi.wasm.exports.sqlite3_wasm_pstack_remaining
   });
 
+  /**
+     An Error subclass specifically for reporting DB-level errors and
+     enabling clients to unambiguously identify such exceptions.
+     The C-level APIs never throw, but some of the higher-level
+     C-style APIs do and the object-oriented APIs use exceptions
+     exclusively to report errors.
+  */
+  class SQLite3Error extends Error {
+    /**
+       Constructs this object with a message equal to all arguments
+       concatenated with a space between each one.
+    */
+    constructor(...args){
+      super(args.join(' '));
+      this.name = 'SQLite3Error';
+    }
+  };
+
 
   /** State for sqlite3_wasmfs_opfs_dir(). */
   let __persistentDir = undefined;
@@ -1059,6 +1079,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
   /* The remainder of the API will be set up in later steps. */
   const sqlite3 = {
     WasmAllocError: WasmAllocError,
+    SQLite3Error: SQLite3Error,
     capi,
     config,
     /**
index ffe63c537c796af1d2e1d07c6a56db396d799bc1..dd61ab28141d2052a79848ef7770d73a22028647 100644 (file)
         T.assert(g64(pMin) === minMaxI64[0]).
           assert(minMaxI64[0] === db.selectValue("select ?",g64(pMin))).
           assert(minMaxI64[1] === db.selectValue("select ?",g64(pMax)));
-        const rxRange = /out of range for int64/;
+        const rxRange = /out of range for storing as int64/;
         T.mustThrowMatching(()=>{db.prepare("select ?").bind(minMaxI64[0] - BigInt(1))},
                           rxRange).
           mustThrowMatching(()=>{db.prepare("select ?").bind(minMaxI64[1] + BigInt(1))},
index 8e269668d89860e7e84c614df8a048b4df4ba7b3..44d3de74a97de477b94decaccfd7dce676cfb0be 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Correct\sfiddle\sdb\sexport\sbreakage\scaused\sby\sa\spost-testing\sAPI\schange\smade\sin\s[1fa019c88dea].
-D 2022-10-01T19:21:52.215
+C General\sinternal\scleanups\sin\sthe\soo1\sAPI.
+D 2022-10-02T00:09:40.160
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -486,9 +486,9 @@ F ext/wasm/api/post-js-header.js 2e5c886398013ba2af88028ecbced1e4b22dc96a86467f1
 F ext/wasm/api/pre-js.js 2db711eb637991b383fc6b5c0f3df65ec48a7201e5730e304beba8de2d3f9b0b
 F ext/wasm/api/sqlite3-api-cleanup.js 5d22d1d3818ecacb23bfa223d5970cd0617d8cdbb48c8bc4bbd463f05b021a99
 F ext/wasm/api/sqlite3-api-glue.js b15a51b88aaa472d36bf82d5123dbfdafe8ddf6ca75fba934510e4a20bbe4adb
-F ext/wasm/api/sqlite3-api-oo1.js 9caed0757a5e039ed92467e827fd3ca347fa08f19fe086fcbdd14a4ebe9c2f01
+F ext/wasm/api/sqlite3-api-oo1.js 7667d320f6b9fb5252050a2f9c0b1769e11b84dbc0763b999baf65b451b14369
 F ext/wasm/api/sqlite3-api-opfs.js 1b097808b7b081b0f0700cf97d49ef19760e401706168edff9cd45cf9169f541
-F ext/wasm/api/sqlite3-api-prologue.js 8692571345efc0f6844092e5ffa86cbd72af0fa23696599c04cc28d64c5d1d11
+F ext/wasm/api/sqlite3-api-prologue.js a93bd69969eb8b8f9c4cb34e5d86dcbbe5adbeeea39c1cce57194256c5f28434
 F ext/wasm/api/sqlite3-api-worker1.js 7f4f46cb6b512a48572d7567233896e6a9c46570c44bdc3d13419730c7c221c8
 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
 F ext/wasm/api/sqlite3-wasm.c d72aecf0e50a4403402095ef4e8d6a814fdc2256589944c1dc974c70d2f65b7e
@@ -530,7 +530,7 @@ F ext/wasm/test-opfs-vfs.js a59ff9210b17d46b0c6fbf6a0ba60143c033327865f2e556e14f
 F ext/wasm/testing-worker1-promiser.html 6eaec6e04a56cf24cf4fa8ef49d78ce8905dde1354235c9125dca6885f7ce893
 F ext/wasm/testing-worker1-promiser.js bd788e33c1807e0a6dda9c9a9d784bd3350ca49c9dd8ae2cc8719b506b6e013e
 F ext/wasm/testing1.html 50575755e43232dbe4c2f97c9086b3118eb91ec2ee1fae931e6d7669fb17fcae
-F ext/wasm/testing1.js 419e029ee4ae3cf98dd4c20aebdb111afe743b54ed8856e5f59775c3241fd21f
+F ext/wasm/testing1.js 51ef1ced0669f804787ce96f19dcf64367550a7923a998514be56076326988d7
 F ext/wasm/testing2.html a66951c38137ff1d687df79466351f3c734fa9c6d9cce71d3cf97c291b2167e3
 F ext/wasm/testing2.js 88f40ef3cd8201bdadd120a711c36bbf0ce56cc0eab1d5e7debb71fed7822494
 F ext/wasm/wasmfs.make 3cce1820006196de140f90f2da4b4ea657083fb5bfee7d125be43f7a85748c8f
@@ -2029,8 +2029,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P c8a173cf16d2567bf9b13f52904077a2e7209776c76613c7bff59cd66e24bf11
-R d4bf3165ea62de5a9f288d66d4a2cd95
+P e73cc44ec36c7585ebb914bdeed5b39480fca7c7a8d3c4426bfe769c87b98d17
+R 4b53a976c2062b810a77639258e8be02
 U stephan
-Z a03f054bd345e55a260c4a080b874912
+Z f0b55570286779c7113ac4ef57233011
 # Remove this line to create a well-formed Fossil manifest.
index 6eb12af986a2e73890bb285175883ed177f9689f..1d593beead7b341b06fe3ea153fa3194c0f91581 100644 (file)
@@ -1 +1 @@
-e73cc44ec36c7585ebb914bdeed5b39480fca7c7a8d3c4426bfe769c87b98d17
\ No newline at end of file
+f9db664f756f3707afcb5dce87f6d946625848f27ea84337af68de72d4ad6c6b
\ No newline at end of file