]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Lots of tweaking in batch-runner.js. Minor internal API update in OO #1 API.
authorstephan <stephan@noemail.net>
Mon, 29 Aug 2022 18:58:38 +0000 (18:58 +0000)
committerstephan <stephan@noemail.net>
Mon, 29 Aug 2022 18:58:38 +0000 (18:58 +0000)
FossilOrigin-Name: 24b82b9504db3d8e1335c2300b133f897dc1a541026dc24be5b0ffd8be66d977

ext/wasm/GNUmakefile
ext/wasm/api/sqlite3-api-oo1.js
ext/wasm/batch-runner.html
ext/wasm/batch-runner.js
manifest
manifest.uuid

index 25d1e98084d9b567e30192ba04d0e7b2840091d8..6a0835ece4ba1e1ee8da2b5ab758050890e71b82 100644 (file)
@@ -294,10 +294,12 @@ $(speedtest1):
        $(MAKE) -C ../.. speedtest1
 speedtest1.sql: $(speedtest1)
        $(speedtest1) --script $@
-batch-sql.in := $(sort $(wildcard *.sql))
-batch-runner.list: $(batch-sql.in) $(MAKEFILE) speedtest1.sql
+speedtest1-000.sql:
+       echo "select 1;" > $@
+batch-runner.list: $(MAKEFILE) speedtest1.sql speedtest1-000.sql
        bash split-speedtest1-script.sh speedtest1.sql
-       ls -1 *.sql | sort > $@
+       ls -1 *.sql | grep -v speedtest1.sql | sort > $@
+CLEAN_FILES += batch-runner.list speedtest1*.sql
 batch: batch-runner.list
 
 ########################################################################
index 5d4b19b5a97d23f048289b8bae60d27bb4a08ec4..2cfb478865266e945510f76a481dfcf22c0e4489 100644 (file)
@@ -540,7 +540,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
         if(isTA) wasm.heap8().set(arg.sql, pSql);
         else wasm.jstrcpy(arg.sql, wasm.heap8(), pSql, sqlByteLen, false);
         wasm.setMemValue(pSql + sqlByteLen, 0/*NUL terminator*/);
-        while(wasm.getMemValue(pSql, 'i8')
+        while(pSql && wasm.getMemValue(pSql, 'i8')
               /* Maintenance reminder:^^^ _must_ be 'i8' or else we
                  will very likely cause an endless loop. What that's
                  doing is checking for a terminating NUL byte. If we
@@ -548,8 +548,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
                  around the NUL terminator, and get stuck in and
                  endless loop at the end of the SQL, endlessly
                  re-preparing an empty statement. */ ){
-          wasm.setMemValue(ppStmt, 0, wasm.ptrIR);
-          wasm.setMemValue(pzTail, 0, wasm.ptrIR);
+          wasm.setPtrValue(ppStmt, 0);
+          wasm.setPtrValue(pzTail, 0);
           DB.checkRc(this, capi.sqlite3_prepare_v3(
             this.pointer, pSql, sqlByteLen, 0, ppStmt, pzTail
           ));
index f5031f8fe1e20dcf8e8283242e094309948587e6..c91e59155313748e44b8472a5830b8949ef28ca3 100644 (file)
     <div class="emscripten">
       <progress value="0" max="100" id="module-progress" hidden='1'></progress>  
     </div><!-- /emscripten bits -->
-    <p class='warning'>ACHTUNG: this file requires a generated input list
+    <p>
+      This page is for running extracts from the output of <tt>speedtest --script</tt>.
+    </p>
+    <p id='warn-list' class='warning'>ACHTUNG: this file requires a generated input list
       file. Run "make batch" from this directory to generate it.
     </p>
-    <p class='warning'>WARNING: if the WASMFS/OPFS layer crashes, this page may
+    <p id='warn-opfs' class='warning'>WARNING: if the WASMFS/OPFS layer crashes, this page may
       become completely unresponsive and need to be closed and
       reloaded to recover.
     </p>
     <hr>
     <div>
-      <select id='sql-select'>
+      <select class='disable-during-eval' id='sql-select'>
         <option disabled selected>Populated via script code</option>
       </select>
-      <button id='sql-run'>Run selected SQL</button>
+      <button class='disable-during-eval' id='sql-run'>Run selected SQL</button>
+      <button class='disable-during-eval' id='sql-run-next'>Run next...</button>
+      <button class='disable-during-eval' id='sql-run-remaining'>Run all remaining...</button>
+      <button class='disable-during-eval' id='db-reset'>Reset db</button>
       <button id='output-clear'>Clear output</button>
     </div>
     <hr>
+    <div>(Log output is in reverse order, newest first!)</div>
     <div id='test-output'></div>
     
     <script src="sqlite3.js"></script>
     <script src="common/SqliteTestUtil.js"></script>
     <script src="batch-runner.js"></script>
     <style>
+      body {
+          display: flex;
+          flex-direction: column;
+          flex-wrap: wrap;
+      }
       .warning { color: firebrick; } 
       #test-output {
           border: 1px inset;
           padding: 0.25em;
-          max-height: 20em;
+          /*max-height: 30em;*/
           overflow: auto;
           white-space: break-spaces;
+          display: flex; flex-direction: column-reverse;
       }
     </style>
   </body>
index b412dc2cedfb6ee2a232515080b95fcc6a430a2c..0f5406f9024215b236da8c846e84f35bb5a3c7c4 100644 (file)
 (function(){
   const T = self.SqliteTestUtil;
   const toss = function(...args){throw new Error(args.join(' '))};
-  const debug = console.debug.bind(console);
+  const warn = console.warn.bind(console);
 
   const App = {
     e: {
       output: document.querySelector('#test-output'),
       selSql: document.querySelector('#sql-select'),
       btnRun: document.querySelector('#sql-run'),
-      btnClear: document.querySelector('#output-clear')
+      btnRunNext: document.querySelector('#sql-run-next'),
+      btnRunRemaining: document.querySelector('#sql-run-remaining'),
+      btnClear: document.querySelector('#output-clear'),
+      btnReset: document.querySelector('#db-reset')
     },
+    cache:{},
     log: console.log.bind(console),
     warn: console.warn.bind(console),
     cls: function(){this.e.output.innerHTML = ''},
@@ -34,6 +38,7 @@
       if(cssClass) ln.classList.add(cssClass);
       ln.append(document.createTextNode(args.join(' ')));
       this.e.output.append(ln);
+      //this.e.output.lastElementChild.scrollIntoViewIfNeeded();
     },
     logHtml: function(...args){
       console.log(...args);
       if(1) this.logHtml2('error', ...args);
     },
 
-    openDb: function(fn){
-      if(this.pDb){
+    openDb: function(fn, unlinkFirst=true){
+      if(this.db && this.db.ptr){
         toss("Already have an opened db.");
       }
       const capi = this.sqlite3.capi, wasm = capi.wasm;
       const stack = wasm.scopedAllocPush();
       let pDb = 0;
       try{
+        /*if(unlinkFirst && fn && ':memory:'!==fn){
+          capi.sqlite3_wasm_vfs_unlink(fn);
+        }*/
         const oFlags = capi.SQLITE_OPEN_CREATE | capi.SQLITE_OPEN_READWRITE;
         const ppDb = wasm.scopedAllocPtr();
         const rc = capi.sqlite3_open_v2(fn, ppDb, oFlags, null);
+        if(rc) toss("sqlite3_open_v2() failed with code",rc);
         pDb = wasm.getPtrValue(ppDb)
       }finally{
         wasm.scopedAllocPop(stack);
       }
-      this.logHtml("Opened db:",capi.sqlite3_db_filename(pDb, 'main'));
-      return this.pDb = pDb;
+      this.db = Object.create(null);
+      this.db.filename = fn;
+      this.db.ptr = pDb;
+      this.logHtml("Opened db:",fn);
+      return this.db.ptr;
     },
 
-    closeDb: function(){
-      if(this.pDb){
-        this.sqlite3.capi.sqlite3_close_v2(this.pDb);
-        this.pDb = undefined;
+    closeDb: function(unlink=false){
+      if(this.db && this.db.ptr){
+        this.sqlite3.capi.sqlite3_close_v2(this.db.ptr);
+        this.logHtml("Closed db",this.db.filename);
+        if(unlink) capi.sqlite3_wasm_vfs_unlink(this.db.filename);
+        this.db.ptr = this.db.filename = undefined;
       }
     },
 
         }
         if(!r.ok) toss("Loading",infile,"failed:",r.statusText);
         txt = await r.text();
+        const warning = document.querySelector('#warn-list');
+        if(warning) warning.remove();
       }catch(e){
         this.logErr(e.message);
         throw e;
       }finally{
         this.blockControls(false);
       }
-      const list = txt.split('\n');
+      const list = txt.split(/\n+/);
       let opt;
       if(0){
         opt = document.createElement('option');
         sel.appendChild(opt);
       }
       list.forEach(function(fn){
+        if(!fn) return;
         opt = document.createElement('option');
         opt.value = opt.innerText = fn;
         sel.appendChild(opt);
     },
 
     /** Fetch ./fn and return its contents as a Uint8Array. */
-    fetchFile: async function(fn){
+    fetchFile: async function(fn, cacheIt=false){
+      if(cacheIt && this.cache[fn]) return this.cache[fn];
       this.logHtml("Fetching",fn,"...");
       let sql;
       try {
         throw e;
       }
       this.logHtml("Fetched",sql.length,"bytes from",fn);
+      if(cacheIt) this.cache[fn] = sql;
       return sql;
-    },
+    }/*fetchFile()*/,
 
+    /** Throws if the given sqlite3 result code is not 0. */
     checkRc: function(rc){
-      if(rc){
-        toss("Prepare failed:",this.sqlite3.capi.sqlite3_errmsg(this.pDb));
+      if(this.db.ptr && rc){
+        toss("Prepare failed:",this.sqlite3.capi.sqlite3_errmsg(this.db.ptr));
       }
     },
 
-    blockControls: function(block){
-      [
-        this.e.selSql, this.e.btnRun, this.e.btnClear
-      ].forEach((e)=>e.disabled = block);
+    /** Disable or enable certain UI controls. */
+    blockControls: function(disable){
+      document.querySelectorAll('.disable-during-eval').forEach((e)=>e.disabled = disable);
     },
-    
+
     /** Fetch ./fn and eval it as an SQL blob. */
     evalFile: async function(fn){
       const sql = await this.fetchFile(fn);
-      this.logHtml("Running",fn,'...');
+      const banner = "========================================";
+      this.logHtml(banner,
+                   "Running",fn,'('+sql.length,'bytes)...');
       const capi = this.sqlite3.capi, wasm = capi.wasm;
       let pStmt = 0, pSqlBegin;
       const stack = wasm.scopedAllocPush();
       metrics.prepTotal = metrics.stepTotal = 0;
       metrics.stmtCount = 0;
       this.blockControls(true);
-      // Use setTimeout() so that the above log messages run before the loop starts.
-      setTimeout((function(){
-        metrics.timeStart = performance.now();
+      if(this.gotErr){
+        this.logErr("Cannot run ["+fn+"]: error cleanup is pending.");
+        return;
+      }
+      // Run this async so that the UI can be updated for the above header...
+      const ff = function(resolve, reject){
+        metrics.evalFileStart = performance.now();
         try {
           let t;
           let sqlByteLen = sql.byteLength;
           const [ppStmt, pzTail] = wasm.scopedAllocPtr(2);
-          pSqlBegin = wasm.alloc( sqlByteLen + 1/*SQL + NUL*/);
+          pSqlBegin = wasm.alloc( sqlByteLen + 1/*SQL + NUL*/) || toss("alloc(",sqlByteLen,") failed");
           let pSql = pSqlBegin;
           const pSqlEnd = pSqlBegin + sqlByteLen;
           wasm.heap8().set(sql, pSql);
           wasm.setMemValue(pSql + sqlByteLen, 0);
-          while(wasm.getMemValue(pSql,'i8')){
-            pStmt = 0;
+          let breaker = 0;
+          while(pSql && wasm.getMemValue(pSql,'i8')){
             wasm.setPtrValue(ppStmt, 0);
             wasm.setPtrValue(pzTail, 0);
             t = performance.now();
             let rc = capi.sqlite3_prepare_v3(
-              this.pDb, pSql, sqlByteLen, 0, ppStmt, pzTail
+              this.db.ptr, pSql, sqlByteLen, 0, ppStmt, pzTail
             );
             metrics.prepTotal += performance.now() - t;
             this.checkRc(rc);
-            ++metrics.stmtCount;
             pStmt = wasm.getPtrValue(ppStmt);
             pSql = wasm.getPtrValue(pzTail);
             sqlByteLen = pSqlEnd - pSql;
             if(!pStmt) continue/*empty statement*/;
+            ++metrics.stmtCount;
             t = performance.now();
             rc = capi.sqlite3_step(pStmt);
+            capi.sqlite3_finalize(pStmt);
+            pStmt = 0;
             metrics.stepTotal += performance.now() - t;
             switch(rc){
                 case capi.SQLITE_ROW:
             }
           }
         }catch(e){
-          this.logErr(e.message);
-          throw e;
+          if(pStmt) capi.sqlite3_finalize(pStmt);
+          this.gotErr = e;
+          //throw e;
+          reject(e);
+          return;
         }finally{
           wasm.dealloc(pSqlBegin);
           wasm.scopedAllocPop(stack);
           this.blockControls(false);
         }
-        metrics.timeEnd = performance.now();
-        metrics.timeTotal = (metrics.timeEnd - metrics.timeStart);
+        metrics.evalFileEnd = performance.now();
+        metrics.evalTimeTotal = (metrics.evalFileEnd - metrics.evalFileStart);
         this.logHtml("Metrics:");//,JSON.stringify(metrics, undefined, ' '));
         this.logHtml("prepare() count:",metrics.stmtCount);
         this.logHtml("Time in prepare_v2():",metrics.prepTotal,"ms",
                      "("+(metrics.prepTotal / metrics.stmtCount),"ms per prepare())");
         this.logHtml("Time in step():",metrics.stepTotal,"ms",
                      "("+(metrics.stepTotal / metrics.stmtCount),"ms per step())");
-        this.logHtml("Total runtime:",metrics.timeTotal,"ms");
+        this.logHtml("Total runtime:",metrics.evalTimeTotal,"ms");
         this.logHtml("Overhead (time - prep - step):",
-                     (metrics.timeTotal - metrics.prepTotal - metrics.stepTotal)+"ms");
-      }.bind(this)), 10);
-    },
+                     (metrics.evalTimeTotal - metrics.prepTotal - metrics.stepTotal)+"ms");
+        this.logHtml(banner,"End of",fn);
+        resolve(this);
+      }.bind(this);
+      let p;
+      if(1){
+        p = new Promise(function(res,rej){
+          setTimeout(()=>ff(res, rej), 50)/*give UI a chance to output the "running" banner*/;
+        });
+      }else{
+        p = new Promise(ff);
+      }
+      return p.catch((e)=>this.logErr("Error via evalFile("+fn+"):",e.message));
+    }/*evalFile()*/,
 
     run: function(sqlite3){
+      delete this.run;
       this.sqlite3 = sqlite3;
       const capi = sqlite3.capi, wasm = capi.wasm;
       this.logHtml("Loaded module:",capi.sqlite3_libversion(), capi.sqlite3_sourceid());
       this.logHtml("WASM heap size =",wasm.heap8().length);
-      this.logHtml("WARNING: if the WASMFS/OPFS layer crashes, this page may",
-                   "become unresponsive and need to be closed and ",
-                   "reloaded to recover.");
+      this.loadSqlList();
       const pDir = capi.sqlite3_web_persistent_dir();
       const dbFile = pDir ? pDir+"/speedtest.db" : ":memory:";
-      if(pDir){
-        // We initially need a clean db file, so...
-        capi.sqlite3_wasm_vfs_unlink(dbFile);
+      if(!pDir){
+        document.querySelector('#warn-opfs').remove();
       }
-      this.openDb(dbFile);
-      this.loadSqlList();
+      this.openDb(dbFile, !!pDir);
       const who = this;
       this.e.btnClear.addEventListener('click', ()=>this.cls(), false);
       this.e.btnRun.addEventListener('click', function(){
         if(!who.e.selSql.value) return;
         who.evalFile(who.e.selSql.value);
       }, false);
-    }
+      this.e.btnRunNext.addEventListener('click', function(){
+        ++who.e.selSql.selectedIndex;
+        if(!who.e.selSql.value) return;
+        who.evalFile(who.e.selSql.value);
+      }, false);
+      this.e.btnReset.addEventListener('click', function(){
+        const fn = who.db.filename;
+        if(fn){
+          who.closeDb(true);
+          who.openDb(fn,true);
+        }
+      }, false);
+      this.e.btnRunRemaining.addEventListener('click', async function(){
+        let v = who.e.selSql.value;
+        const timeStart = performance.now();
+        while(v){
+          await who.evalFile(v);
+          if(who.gotError){
+            who.logErr("Error handling script",v,":",who.gotError.message);
+            break;
+          }
+          ++who.e.selSql.selectedIndex;
+          v = who.e.selSql.value;
+        }
+        const timeTotal = performance.now() - timeStart;
+        who.logHtml("Run-remaining time:",timeTotal,"ms ("+(timeTotal/1000/60)+" minute(s))");
+      }, false);
+    }/*run()*/
   }/*App*/;
 
   self.sqlite3TestModule.initSqlite3().then(function(theEmccModule){
index 6eb43c0ef2b920660f8a7a4a0c2bc39a2ed3338f..bfcc12ac8f4fc1b145ad68ebb917e9dbf420fbf9 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\stest\sdescriptions\sto\sthe\sspeedtest1\s'--\sbegin'\smarkers\sfor\spotential\sdisplay\sby\sthe\sdownstream\sJS\scode\swhich\suses\sthose\smarkers.
-D 2022-08-29T17:41:16.571
+C Lots\sof\stweaking\sin\sbatch-runner.js.\sMinor\sinternal\sAPI\supdate\sin\sOO\s#1\sAPI.
+D 2022-08-29T18:58:38.025
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -474,7 +474,7 @@ F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
 F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
 F ext/wasm/EXPORTED_FUNCTIONS.fiddle db7a4602f043cf4a5e4135be3609a487f9f1c83f05778bfbdf93766be4541b96
 F ext/wasm/EXPORTED_RUNTIME_METHODS.fiddle a004bd5eeeda6d3b28d16779b7f1a80305bfe009dfc7f0721b042967f0d39d02
-F ext/wasm/GNUmakefile 61c0d9dcda9ca174907f87770c9440b26408dc415d2e11a3cbcae017358fd08c
+F ext/wasm/GNUmakefile cabfbb177d16c550442313416698e66dde575df27177d4ca3ccece5a66b37de4
 F ext/wasm/README.md e1ee1e7c321c6a250bf78a84ca6f5882890a237a450ba5a0649c7a8399194c52
 F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 77ef4bcf37e362b9ad61f9c175dfc0f1b3e571563fb311b96581cf422ee6a8ec
 F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
@@ -483,14 +483,14 @@ F ext/wasm/api/post-js-footer.js b64319261d920211b8700004d08b956a6c285f3b0bba814
 F ext/wasm/api/post-js-header.js 0e853b78db83cb1c06b01663549e0e8b4f377f12f5a2d9a4a06cb776c003880b
 F ext/wasm/api/sqlite3-api-cleanup.js 1a12e64060c2cb0defd34656a76a9b1d7ed58459c290249bb31567c806fd44de
 F ext/wasm/api/sqlite3-api-glue.js 67ca83974410961953eeaa1dfed3518530d68381729ed1d27f95122f5baeabd3
-F ext/wasm/api/sqlite3-api-oo1.js 46a5151610076f45472c8d4fd31b728cc12e6fac4d44ea5c7cd1af087a906539
+F ext/wasm/api/sqlite3-api-oo1.js 183e863eedaba547ffe4981ab95797813b60da46749992bca400d2646e5ccd82
 F ext/wasm/api/sqlite3-api-opfs.js 011799db398157cbd254264b6ebae00d7234b93d0e9e810345f213a5774993c0
 F ext/wasm/api/sqlite3-api-prologue.js 2d5c5d3355f55eefe51922cec5bfedbec0f8300db98a17685ab7a34a03953c7a
 F ext/wasm/api/sqlite3-api-worker1.js 73579555563b789785ae83724014eaf31811073aad9be6596c8336ffb51edd71
 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
 F ext/wasm/api/sqlite3-wasm.c 0d81282eaeff2a6e9fc5c28a388c5c5b45cf25a9393992fa511ac009b27df982
-F ext/wasm/batch-runner.html f9068c4b4222d0c11ba0590391892e4d7576ef1a4fb76974ba0bd3b80c6217f9
-F ext/wasm/batch-runner.js 57f325e40812a89f8d47c918963f278d7a249d158cf0d245d75e74577af638c8
+F ext/wasm/batch-runner.html e5c3edd4a6c9359f6d9e6c99cb5f87f09007d98fa1c705ed3efa370abcd4323e
+F ext/wasm/batch-runner.js 84a465acde760de81d0372415cce56737799876395a878c44a7d3ce5dfe29e39
 F ext/wasm/common/SqliteTestUtil.js eb96275bed43fdb364b7d65bcded0ca5e22aaacff120d593d1385f852f486247
 F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
 F ext/wasm/common/testing.css 572cf1ffae0b6eb7ca63684d3392bf350217a07b90e7a896e4fa850700c989b0
@@ -2012,8 +2012,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 11f3ed61150c5940da6c157e5063e70c3aa0628dfd0023c47bb65b00af74ab1f
-R 2ae8456ec9776838052861c3fb138f8f
+P e5b7006f0f57f10a490d7eaeb7df77251a2f684602fed8ff161d8ce60033e7bc
+R ac09921b66efbf8cc7311954674841d9
 U stephan
-Z 47d6dbc110cfca896ac7235ddcb7f7bf
+Z 16cfbad53a69907d89a4919845ccdd35
 # Remove this line to create a well-formed Fossil manifest.
index 99bc257577d608b67f63e95ac570594f57f69bdb..622070996df4c6eb69b2d40c154f7c51f9c8b946 100644 (file)
@@ -1 +1 @@
-e5b7006f0f57f10a490d7eaeb7df77251a2f684602fed8ff161d8ce60033e7bc
\ No newline at end of file
+24b82b9504db3d8e1335c2300b133f897dc1a541026dc24be5b0ffd8be66d977
\ No newline at end of file