]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Significant restructuring of the Worker #1 request/response object structures to...
authorstephan <stephan@noemail.net>
Wed, 24 Aug 2022 00:10:45 +0000 (00:10 +0000)
committerstephan <stephan@noemail.net>
Wed, 24 Aug 2022 00:10:45 +0000 (00:10 +0000)
FossilOrigin-Name: 03b9db9b98cb36faa7de5a8a64d2e13c4aeaadfefb33ac92bb41056f6be3f121

ext/wasm/api/sqlite3-api-worker1.js
ext/wasm/sqlite3-worker1.js
ext/wasm/testing2.js
manifest
manifest.uuid

index a7b759851f58160aac3abb34c2f13e38c7bdda8c..2e8d5a25d043649df2e0ea71c9408405b73367f4 100644 (file)
@@ -34,7 +34,7 @@
   messages and then it posts a message in the form:
 
   ```
-  {type:'sqlite3-api',data:'worker1-ready'}
+  {type:'sqlite3-api',result:'worker1-ready'}
   ```
 
   to let the client know that it has been initialized. Clients may
@@ -60,15 +60,6 @@ sqlite3.initWorker1API = function(){
 
      - Support for handling multiple DBs via this interface is under
      development.
-
-     - Revisit how virtual files are managed. We currently delete DBs
-     from the virtual filesystem when we close them, for the sake of
-     saving memory (the VFS lives in RAM). Supporting multiple DBs may
-     require that we give up that habit. Similarly, fully supporting
-     ATTACH, where a user can upload multiple DBs and ATTACH them,
-     also requires the that we manage the VFS entries better.
-     Related: we most definitely do not want to delete persistent DBs
-     (e.g. stored on OPFS) when they're closed.
   */
   const toss = (...args)=>{throw new Error(args.join(' '))};
   if('function' !== typeof importScripts){
@@ -102,10 +93,9 @@ sqlite3.initWorker1API = function(){
     idSeq: 0,
     idMap: new WeakMap,
     open: function(arg){
-      // TODO: if arg is a filename, look for a db in this.dbs with the
+      // TODO? if arg is a filename, look for a db in this.dbs with the
       // same filename and close/reopen it (or just pass it back as is?).
       if(!arg && this.defaultDb) return this.defaultDb;
-      //???if(this.defaultDb) this.defaultDb.close();
       const db = (Array.isArray(arg) ? new DB(...arg) : new DB(arg));
       this.dbs[getDbId(db)] = db;
       if(!this.defaultDb) this.defaultDb = db;
@@ -122,12 +112,12 @@ sqlite3.initWorker1API = function(){
         }
       }
     },
-    post: function(type,data,xferList){
+    post: function(msg,xferList){
       if(xferList){
-        self.postMessage( {type, data}, xferList );
+        self.postMessage( msg, xferList );
         xferList.length = 0;
       }else{
-        self.postMessage({type, data});
+        self.postMessage(msg);
       }
     },
     /** Map of DB IDs to DBs. */
@@ -167,49 +157,42 @@ sqlite3.initWorker1API = function(){
     xfer: [/*Temp holder for "transferable" postMessage() state.*/],
     /**
        Proxy for the DB constructor. Expects to be passed a single
-       object or a falsy value to use defaults. The object may
-       have a filename property to name the db file (see the DB
-       constructor for peculiarities and transformations) and/or a
-       buffer property (a Uint8Array holding a complete database
-       file's contents). The response is an object:
+       object or a falsy value to use defaults. The object may have a
+       filename property to name the db file (see the DB constructor
+       for peculiarities and transformations). The response is an
+       object:
 
        {
          filename: db filename (possibly differing from the input),
 
-         dbId: an opaque ID value which must be passed to other calls
-               in this API to tell them which db to use. If it is not
-               provided to future calls, they will default to
-               operating on the first-opened db.
-
-          messageId: if the client-sent message included this field,
-              it is mirrored in the response.
+         dbId: an opaque ID value which must be passed in the message
+               envelope to other calls in this API to tell them which
+               db to use. If it is not provided to future calls, they
+               will default to operating on the first-opened db.
        }
     */
     open: function(ev){
-      const args = [], data = (ev.data || {});
-      if(data.simulateError){ // undocumented internal testing option
+      const oargs = [], args = (ev.args || {});
+      if(args.simulateError){ // undocumented internal testing option
         toss("Throwing because of simulateError flag.");
       }
-      if(data.filename) args.push(data.filename);
-      const db = wState.open(args);
+      if(args.filename) oargs.push(args.filename);
+      const db = wState.open(oargs);
       return {
         filename: db.filename,
         dbId: getDbId(db)
       };
     },
     /**
-       Proxy for DB.close(). If ev.data may either be a boolean or
-       an object with an `unlink` property. If that value is
-       truthy then the db file (if the db is currently open) will
-       be unlinked from the virtual filesystem, else it will be
-       kept intact. The response object is:
+       Proxy for DB.close(). ev.args may either be a boolean or an
+       object with an `unlink` property. If that value is truthy then
+       the db file (if the db is currently open) will be unlinked from
+       the virtual filesystem, else it will be kept intact. The
+       result object is:
 
        {
          filename: db filename _if_ the db is opened when this
-                   is called, else the undefined value,
-         unlink: boolean. If true, unlink() (delete) the db file
-                 after closing int. Any error while deleting it is
-                 ignored.
+                   is called, else the undefined value
        }
 
        It does not error if the given db is already closed or no db is
@@ -222,8 +205,8 @@ sqlite3.initWorker1API = function(){
         dbId: db ? getDbId(db) : undefined
       };
       if(db){
-        wState.close(db, !!((ev.data && 'object'===typeof ev.data)
-                            ? ev.data.unlink : false));
+        wState.close(db, ((ev.args && 'object'===typeof ev.args)
+                          ? !!ev.args.unlink : false));
       }
       return response;
     },
@@ -242,11 +225,11 @@ sqlite3.initWorker1API = function(){
        message type key, in which case a callback function will be
        applied which posts each row result via:
 
-       postMessage({type: thatKeyType, data: theRow})
+       postMessage({type: thatKeyType, row: theRow})
 
        And, at the end of the result set (whether or not any
        result rows were produced), it will post an identical
-       message with data:null to alert the caller than the result
+       message with row:null to alert the caller than the result
        set is completed.
 
        The callback proxy must not recurse into this interface, or
@@ -264,8 +247,8 @@ sqlite3.initWorker1API = function(){
     */
     exec: function(ev){
       const opt = (
-        'string'===typeof ev.data
-      ) ? {sql: ev.data} : (ev.data || Object.create(null));
+        'string'===typeof ev.args
+      ) ? {sql: ev.args} : (ev.args || Object.create(null));
       if(undefined===opt.rowMode){
         /* Since the default rowMode of 'stmt' is not useful
            for the Worker interface, we'll default to
@@ -286,13 +269,13 @@ sqlite3.initWorker1API = function(){
            row as a message of that type. */
         const that = this;
         opt.callback =
-          (row)=>wState.post(callbackMsgType,row,this.xfer);
+          (row)=>wState.post({type: callbackMsgType, row:row}, this.xfer);
       }
       try {
         db.exec(opt);
         if(opt.callback instanceof Function){
           opt.callback = callbackMsgType;
-          wState.post(callbackMsgType, null);
+          wState.post({type: callbackMsgType, row: null});
         }
       }/*catch(e){
          console.warn("Worker is propagating:",e);throw e;
@@ -305,7 +288,7 @@ sqlite3.initWorker1API = function(){
       return opt;
     }/*exec()*/,
     /**
-       TO(re)DO, once we can abstract away access to the
+       TO(RE)DO, once we can abstract away access to the
        JS environment's virtual filesystem. Currently this
        always throws.
 
@@ -352,73 +335,77 @@ sqlite3.initWorker1API = function(){
      form:
 
      { type: apiCommand,
-       dbId: optional DB ID value (else uses a default db handle)
-       data: apiArguments,
+       dbId: optional DB ID value (else uses a default db handle),
+       args: apiArguments,
        messageId: optional client-specific value
      }
 
      As a rule, these commands respond with a postMessage() of their
-     own in the same form, but will, if needed, transform the `data`
-     member to an object and may add state to it. The responses
-     always have an object-format `data` part. If the inbound `data`
-     is an object which has a `messageId` property, that property is
+     own in the form:
+
+     TODO: refactoring is underway.
+
+     The responses always have an object-format `result` part. If the
+     inbound object has a `messageId` property, that property is
      always mirrored in the result object, for use in client-side
      dispatching of these asynchronous results. Exceptions thrown
-     during processing result in an `error`-type event with a
-     payload in the form:
+     during processing result in an `error`-type event with a payload
+     in the form:
 
-     {
-       message: error string,
-       errorClass: class name of the error type,
+     { type: 'error',
        dbId: DB handle ID,
-       input: ev.data,
-       [messageId: if set in the inbound message]
+       [messageId: if set in the inbound message],
+       result: {
+         message: error string,
+         errorClass: class name of the error type,
+         input: ev.data
+       }
      }
 
      The individual APIs are documented in the wMsgHandler object.
   */
   self.onmessage = function(ev){
     ev = ev.data;
-    let response, dbId = ev.dbId, evType = ev.type;
+    let result, dbId = ev.dbId, evType = ev.type;
     const arrivalTime = performance.now();
     try {
       if(wMsgHandler.hasOwnProperty(evType) &&
          wMsgHandler[evType] instanceof Function){
-        response = wMsgHandler[evType](ev);
+        result = wMsgHandler[evType](ev);
       }else{
         toss("Unknown db worker message type:",ev.type);
       }
     }catch(err){
       evType = 'error';
-      response = {
+      result = {
         message: err.message,
         errorClass: err.name,
         input: ev
       };
       if(err.stack){
-        response.stack = ('string'===typeof err.stack)
+        result.stack = ('string'===typeof err.stack)
           ? err.stack.split('\n') : err.stack;
       }
       if(0) console.warn("Worker is propagating an exception to main thread.",
-                         "Reporting it _here_ for the stack trace:",err,response);
-    }
-    if(!response.messageId && ev.data
-       && 'object'===typeof ev.data && ev.data.messageId){
-      response.messageId = ev.data.messageId;
+                         "Reporting it _here_ for the stack trace:",err,result);
     }
     if(!dbId){
-      dbId = response.dbId/*from 'open' cmd*/
+      dbId = result.dbId/*from 'open' cmd*/
         || getDefaultDbId();
     }
-    if(!response.dbId) response.dbId = dbId;
     // Timing info is primarily for use in testing this API. It's not part of
     // the public API. arrivalTime = when the worker got the message.
-    response.workerReceivedTime = arrivalTime;
-    response.workerRespondTime = performance.now();
-    response.departureTime = ev.departureTime;
-    wState.post(evType, response, wMsgHandler.xfer);
+    wState.post({
+      type: evType,
+      dbId: dbId,
+      messageId: ev.messageId,
+      workerReceivedTime: arrivalTime,
+      workerRespondTime: performance.now(),
+      departureTime: ev.departureTime,
+      result: result
+    }, wMsgHandler.xfer);
   };
-  setTimeout(()=>self.postMessage({type:'sqlite3-api',data:'worker1-ready'}), 0);
+  setTimeout(()=>self.postMessage({type:'sqlite3-api',result:'worker1-ready'}), 0);
 }.bind({self, sqlite3});
 });
 
index 3982ddaa2b50bc772268e2d042c60ed79617f1d9..ff024d82158ae19aabb425eb50753108bbe50c66 100644 (file)
@@ -14,7 +14,7 @@
   sqlite3.js, initializes the module, and postMessage()'s a message
   after the module is initialized:
 
-  {type: 'sqlite3-api', data: 'worker1-ready'}
+  {type: 'sqlite3-api', result: 'worker1-ready'}
 
   This seemingly superfluous level of indirection is necessary when
   loading sqlite3.js via a Worker. Instantiating a worker with new
index bcbe7b50de719172dfb6263b1ed155cc0a77450c..b051cc04ccccf4b91fb39681855bfe70b7fabc0f 100644 (file)
   const warn = console.warn.bind(console);
   const error = console.error.bind(console);
   const toss = (...args)=>{throw new Error(args.join(' '))};
-  /** Posts a worker message as {type:type, data:data}. */
-  const wMsg = function(type,data){
-    log("Posting message to worker dbId="+(DbState.id||'default')+':',data);
-    SW.postMessage({
-      type,
-      dbId: DbState.id,
-      data,
-      departureTime: performance.now()
-    });
-    return SW;
-  };
 
   SW.onerror = function(event){
     error("onerror",event);
     logHtml("","Total test count:",T.counter+". Total time =",(performance.now() - startTime),"ms");
   };
 
-  const logEventResult = function(evd){
+  const logEventResult = function(ev){
+    const evd = ev.result;
     logHtml(evd.errorClass ? 'error' : '',
-            "runOneTest",evd.messageId,"Worker time =",
-            (evd.workerRespondTime - evd.workerReceivedTime),"ms.",
+            "runOneTest",ev.messageId,"Worker time =",
+            (ev.workerRespondTime - ev.workerReceivedTime),"ms.",
             "Round-trip event time =",
-            (performance.now() - evd.departureTime),"ms.",
-            (evd.errorClass ? evd.message : "")
+            (performance.now() - ev.departureTime),"ms.",
+            (evd.errorClass ? ev.message : ""), evd
            );
   };
 
-  const runOneTest = function(eventType, eventData, callback){
-    T.assert(eventData && 'object'===typeof eventData);
+  const runOneTest = function(eventType, eventArgs, callback){
+    T.assert(eventArgs && 'object'===typeof eventArgs);
     /* ^^^ that is for the testing and messageId-related code, not
        a hard requirement of all of the Worker-exposed APIs. */
-    eventData.messageId = MsgHandlerQueue.push(eventType,function(ev){
-      logEventResult(ev.data);
+    const messageId = MsgHandlerQueue.push(eventType,function(ev){
+      logEventResult(ev);
       if(callback instanceof Function){
         callback(ev);
         testCount();
       }
     });
-    wMsg(eventType, eventData);
+    const msg = {
+      type: eventType,
+      args: eventArgs,
+      dbId: DbState.id,
+      messageId: messageId,
+      departureTime: performance.now()
+    };
+    log("Posting",eventType,"message to worker dbId="+(DbState.id||'default')+':',msg);
+    SW.postMessage(msg);
   };
 
   /** Methods which map directly to onmessage() event.type keys.
   const dbMsgHandler = {
     open: function(ev){
       DbState.id = ev.dbId;
-      log("open result",ev.data);
+      log("open result",ev);
     },
     exec: function(ev){
-      log("exec result",ev.data);
+      log("exec result",ev);
     },
     export: function(ev){
-      log("export result",ev.data);
+      log("export result",ev);
     },
     error: function(ev){
-      error("ERROR from the worker:",ev.data);
-      logEventResult(ev.data);
+      error("ERROR from the worker:",ev);
+      logEventResult(ev);
     },
     resultRowTest1: function f(ev){
       if(undefined === f.counter) f.counter = 0;
-      if(ev.data) ++f.counter;
-      //log("exec() result row:",ev.data);
-      T.assert(null===ev.data || 'number' === typeof ev.data.b);
+      if(ev.row) ++f.counter;
+      //log("exec() result row:",ev.row);
+      T.assert(null===ev.row || 'number' === typeof ev.row.b);
     }
   };
 
       multi: true,
       resultRows: [], columnNames: []
     }, function(ev){
-      ev = ev.data;
+      ev = ev.result;
       T.assert(0===ev.resultRows.length)
         .assert(0===ev.columnNames.length);
     });
       sql: 'select a a, b b from t order by a',
       resultRows: [], columnNames: [],
     }, function(ev){
-      ev = ev.data;
+      ev = ev.result;
       T.assert(3===ev.resultRows.length)
         .assert(1===ev.resultRows[0][0])
         .assert(6===ev.resultRows[2][1])
       resultRows: [], columnNames: [],
       rowMode: 'object'
     }, function(ev){
-      ev = ev.data;
+      ev = ev.result;
       T.assert(3===ev.resultRows.length)
         .assert(1===ev.resultRows[0].a)
         .assert(6===ev.resultRows[2].b)
       resultRows: [],
       //rowMode: 'array', // array is the default in the Worker interface
     }, function(ev){
-      ev = ev.data;
+      ev = ev.result;
       T.assert(1 === ev.resultRows.length)
         .assert(1 === ev.resultRows[0][0]);
     });
       rowMode: 1,
       resultRows: []
     },function(ev){
-      const rows = ev.data.resultRows;
+      const rows = ev.result.resultRows;
       T.assert(3===rows.length).
         assert(6===rows[0]);
     });
       sql: 'select count(a) from t',
       resultRows: []
     },function(ev){
-      ev = ev.data;
+      ev = ev.result;
       T.assert(1===ev.resultRows.length)
         .assert(2===ev.resultRows[0][0]);
     });
     if(0){
       // export requires reimpl. for portability reasons.
       runOneTest('export',{}, function(ev){
-        ev = ev.data;
+        ev = ev.result;
         T.assert('string' === typeof ev.filename)
           .assert(ev.buffer instanceof Uint8Array)
           .assert(ev.buffer.length > 1024)
     }
     /***** close() tests must come last. *****/
     runOneTest('close',{unlink:true},function(ev){
-      ev = ev.data;
+      ev = ev.result;
       T.assert('string' === typeof ev.filename);
     });
     runOneTest('close',{unlink:true},function(ev){
-      ev = ev.data;
+      ev = ev.result;
       T.assert(undefined === ev.filename);
     });
   };
       filename:'testing2.sqlite3',
       simulateError: simulateOpenError
     }, function(ev){
-      //log("open result",ev);
-      T.assert('testing2.sqlite3'===ev.data.filename)
-        .assert(ev.data.dbId)
-        .assert(ev.data.messageId);
-      DbState.id = ev.data.dbId;
+      log("open result",ev);
+      T.assert('testing2.sqlite3'===ev.result.filename)
+        .assert(ev.dbId)
+        .assert(ev.messageId);
+      DbState.id = ev.dbId;
       if(waitForOpen) setTimeout(runTests2, 0);
     });
     if(!waitForOpen) runTests2();
     }
     ev = ev.data/*expecting a nested object*/;
     //log("main window onmessage:",ev);
-    if(ev.data && ev.data.messageId){
+    if(ev.result && ev.messageId){
       /* We're expecting a queued-up callback handler. */
       const f = MsgHandlerQueue.shift();
       if('error'===ev.type){
     }
     switch(ev.type){
         case 'sqlite3-api':
-          switch(ev.data){
+          switch(ev.result){
               case 'worker1-ready':
                 log("Message:",ev);
                 self.sqlite3TestModule.setStatus(null);
index ef10d9657a360550f80d675943f686c0f38a8fb7..fc1e6d40bd72f39af319453bfc3ea3cb05a09897 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Wasm\sbuild\sflag\stweaks\sand\sdocumentation.
-D 2022-08-23T17:02:46.959
+C Significant\srestructuring\sof\sthe\sWorker\s#1\srequest/response\sobject\sstructures\sto\simprove\sreadability\sand\sclarity.
+D 2022-08-24T00:10:45.121
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -486,7 +486,7 @@ F ext/wasm/api/sqlite3-api-glue.js 67ca83974410961953eeaa1dfed3518530d68381729ed
 F ext/wasm/api/sqlite3-api-oo1.js f6dcaac3270182471f97efcfda25bd4a4ac1777b8ec52ebd1c6846721160e54c
 F ext/wasm/api/sqlite3-api-opfs.js 011799db398157cbd254264b6ebae00d7234b93d0e9e810345f213a5774993c0
 F ext/wasm/api/sqlite3-api-prologue.js 6e0e7787ed955ea2b6158e0bb7608f63b54236847700d183e49e1f10d0525b8f
-F ext/wasm/api/sqlite3-api-worker1.js ceb1fc88d8a3742c069632e88fd05c14d5a79eb86bdb9e12969ec37f64fbf42b
+F ext/wasm/api/sqlite3-api-worker1.js c9e4edb89f41a4fa65d136ae180c1bc0beb694eb95f7d9e6936fbb702914c160
 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
 F ext/wasm/api/sqlite3-wasm.c 0d81282eaeff2a6e9fc5c28a388c5c5b45cf25a9393992fa511ac009b27df982
 F ext/wasm/common/SqliteTestUtil.js 04156a3b714b1b17a7261d21dd51341a8aeb9880a223e1e7519de98c2cceb414
@@ -508,11 +508,11 @@ F ext/wasm/scratchpad-opfs-main.js 69e960e9161f6412fd0c30f355d4112f1894d6609eb43
 F ext/wasm/scratchpad-opfs-worker.html 66c1d15d678f3bd306373d76b61c6c8aef988f61f4a8dd40185d452f9c6d2bf5
 F ext/wasm/scratchpad-opfs-worker.js 3ec2868c669713145c76eb5877c64a1b20741f741817b87c907a154b676283a9
 F ext/wasm/scratchpad-opfs-worker2.js 5f2237427ac537b8580b1c659ff14ad2621d1694043eaaf41ae18dbfef2e48c0
-F ext/wasm/sqlite3-worker1.js e93fe8e5da7cb56dcf4d1bb0aa44bf681b509e1c56f2a75885c0f408f034c42b
+F ext/wasm/sqlite3-worker1.js 0c1e7626304543969c3846573e080c082bf43bcaa47e87d416458af84f340a9e
 F ext/wasm/testing1.html 528001c7e32ee567abc195aa071fd9820cc3c8ffc9c8a39a75e680db05f0c409
 F ext/wasm/testing1.js 2def7a86c52ff28b145cb86188d5c7a49d5993f9b78c50d140e1c31551220955
 F ext/wasm/testing2.html a66951c38137ff1d687df79466351f3c734fa9c6d9cce71d3cf97c291b2167e3
-F ext/wasm/testing2.js e16ae385cd24c4a4ec5de6f1c02e621d243e1f179204ac8df31068faa9e31b1a
+F ext/wasm/testing2.js f01e8d7b32f6d4790f8352bf8dc17d2b860afa58f6c8ea1f824ef1c0d2068138
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
@@ -2006,8 +2006,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 ea2acc454c012a62556f6d0623d6eff60736d24aa214a64462b423623ef44d47
-R 72b1967923c17320161370eaaa7aa1c3
+P c8eb3aa8e0f487f14791214caf70d1aa03866e01345c7fa1d5607c24c39dde1d
+R ea27eb9ac1a6ed815943946a889ca949
 U stephan
-Z 64cee0eefa2cd9236a38fc28a7dddd9f
+Z 3af622548a101a1182c5d00aa6a9dd08
 # Remove this line to create a well-formed Fossil manifest.
index 5d826619c010ded4f93dee5dbf09db8769881292..9b2d03d93cce8f75d40404fc6853e72ce0c6ff68 100644 (file)
@@ -1 +1 @@
-c8eb3aa8e0f487f14791214caf70d1aa03866e01345c7fa1d5607c24c39dde1d
\ No newline at end of file
+03b9db9b98cb36faa7de5a8a64d2e13c4aeaadfefb33ac92bb41056f6be3f121
\ No newline at end of file