]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add sqlite3.oo1.DB.clearKvvfsStorage(). Add controls to kvvfs1.js demo to reset and...
authorstephan <stephan@noemail.net>
Mon, 12 Sep 2022 17:59:04 +0000 (17:59 +0000)
committerstephan <stephan@noemail.net>
Mon, 12 Sep 2022 17:59:04 +0000 (17:59 +0000)
FossilOrigin-Name: d845c6c22bd5d3fffc66e0566df346d690dd8bd1fc1688e312161b1a1edcfd79

ext/wasm/api/sqlite3-api-oo1.js
ext/wasm/kvvfs1.html
ext/wasm/kvvfs1.js
manifest
manifest.uuid
src/os_win.c
src/pcache.c
src/pcache1.c
tool/speed-check.sh

index af179d1fe1c77aa3d9394236991c2747f46056d0..3dfe5bfb0528491c4101faec3814ea0105768c4a 100644 (file)
@@ -1581,17 +1581,30 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
   }/*oo1 object*/;
 
   if( self.window===self && 0!==capi.sqlite3_vfs_find('kvvfs') ){
-    /* In the main window thread, add a couple of convenience proxies
-       for localStorage and sessionStorage DBs... */
-    let klass = sqlite3.oo1.LocalStorageDb = function(){
-      dbCtorHelper.call(this, 'local', 'c', 'kvvfs');
-    };
-    klass.prototype = DB.prototype;
-
-    klass = sqlite3.oo1.SessionStorageDb = function(){
-      dbCtorHelper.call(this, 'session', 'c', 'kvvfs');
+    /* Features specific to kvvfs... */
+    /**
+       Clears all storage used by the kvvfs DB backend, deleting any
+       DB(s) stored there. Its argument must be either 'session',
+       'local', or ''. In the first two cases, only sessionStorage
+       resp. localStorage is cleared. If it's an empty string (the
+       default) then both are cleared. Only storage keys which match
+       the pattern used by kvvfs are cleared: any other client-side
+       data are retained.
+    */
+    DB.clearKvvfsStorage = function(which=''){
+      const prefix = 'kvvfs-'+which;
+      const stores = [];
+      if('session'===which || ''===which) stores.push(sessionStorage);
+      if('local'===which || ''===which) stores.push(localStorage);
+      stores.forEach(function(s){
+        const toRm = [];
+        let i = 0, k;
+        for( i = 0; (k = s.key(i)); ++i ){
+          if(k.startsWith(prefix)) toRm.push(k);
+        }
+        toRm.forEach((kk)=>s.removeItem(kk));
+      });
     };
-    klass.prototype = DB.prototype;
-  }
+  }/* main-window-only bits */
 });
 
index 773de0a6031b6165fdded59c5e3da72025826144..1a5eb62cf141db1055f264fd04373b529b4ecf4a 100644 (file)
     <div class="emscripten">
       <progress value="0" max="100" id="module-progress" hidden='1'></progress>  
     </div><!-- /emscripten bits -->
-    <div>Everything on this page happens in the dev console. TODOs for this demo include,
-      but are not necessarily limited to:
-
-      <ul>
-        <li>UI controls to switch between localStorage and sessionStorage</li>
-        <li>Button to clear storage.</li>
-        <li>Button to dump the current db contents.</li>
-        <!--li></li-->
-      </ul>
-    </div>
-    <hr>
+    <fieldset>
+      <legend>Options</legend>
+      <div class='toolbar'>
+        <button id='btn-clear-log'>Clear log</button>
+        <button id='btn-clear-storage'>Clear storage</button>
+        <button id='btn-init-db'>(Re)init db</button>
+        <button id='btn-select1'>Select db rows</button>
+      </div>
+    </fieldset>
     <div id='test-output'></div>
+    <style>
+      .toolbar {
+          display: flex;
+      }
+      .toolbar > * { margin: 0.25em; }
+      fieldset { border-radius: 0.5em; }
+    </style>
     <script src="sqlite3-kvvfs.js"></script>
     <script src="common/SqliteTestUtil.js"></script>
     <script src="kvvfs1.js"></script>
index 169fcc8bdf4764b01ba28c44fd772c1be3dc91a4..c29426fc6301d05f7524b506194cf93a7a5fc2fd 100644 (file)
   const toss = function(...args){throw new Error(args.join(' '))};
   const debug = console.debug.bind(console);
   const eOutput = document.querySelector('#test-output');
-  const log = console.log.bind(console)
-  const logHtml = function(...args){
-    log.apply(this, args);
+  const logC = console.log.bind(console)
+  const logE = function(domElement){
+    eOutput.append(domElement);
+  };
+  const logHtml = function(cssClass,...args){
     const ln = document.createElement('div');
+    if(cssClass) ln.classList.add(cssClass);
     ln.append(document.createTextNode(args.join(' ')));
-    eOutput.append(ln);
+    logE(ln);
+  }
+  const log = function(...args){
+    logC(...args);
+    logHtml('',...args);
+  };
+  const warn = function(...args){
+    logHtml('warning',...args);
+  };
+  const error = function(...args){
+    logHtml('error',...args);
   };
 
   const runTests = function(Module){
           oo = sqlite3.oo1,
           wasm = capi.wasm;
     log("Loaded module:",capi.sqlite3_libversion(), capi.sqlite3_sourceid());
-    log("Build options:",wasm.compileOptionUsed());
     T.assert( 0 !== capi.sqlite3_vfs_find(null) );
-
+    if(!oo.DB.clearKvvfsStorage){
+      warn("This build is not kvvfs-capable.");
+      return;
+    }
+    
     const dbStorage = 1 ? ':sessionStorage:' : ':localStorage:';
+    const theStore = 's'===dbStorage[1] ? sessionStorage : localStorage;
     /**
        The names ':sessionStorage:' and ':localStorage:' are handled
        via the DB class constructor, not the C level. In the C API,
        names for those keys, but that is subject to change.
     */
     const db = new oo.DB( dbStorage );
-    log("Storage backend:",db.filename /* note that the name was internally translated */);
-    try {
-      db.exec("create table if not exists t(a)");
-      if(undefined===db.selectValue("select a from t limit 1")){
-        log("New db. Populating. This DB will persist across page reloads.");
-        db.exec("insert into t(a) values(1),(2),(3)");
-      }else{
-        log("Found existing table data:");
+
+    document.querySelector('#btn-clear-storage').addEventListener('click',function(){
+      oo.DB.clearKvvfsStorage();
+      log("kvvfs localStorage and sessionStorage cleared.");
+    });
+    document.querySelector('#btn-clear-log').addEventListener('click',function(){
+      eOutput.innerText = '';
+    });
+    document.querySelector('#btn-init-db').addEventListener('click',function(){
+      const saveSql = [];
+      try{
+        db.exec({
+          sql:["drop table if exists t;",
+               "create table if not exists t(a);",
+               "insert into t(a) values(?),(?),(?)"],
+          bind: [performance.now() >> 0,
+                 (performance.now() * 2) >> 0,
+                 (performance.now() / 2) >> 0],
+          saveSql
+        });
+        console.log("saveSql =",saveSql,theStore);
+        log("DB (re)initialized.");
+      }catch(e){
+        error(e.message);
+      }
+    });
+    const btnSelect = document.querySelector('#btn-select1');
+    btnSelect.addEventListener('click',function(){
+      log("DB rows:");
+      try{
         db.exec({
           sql: "select * from t order by a",
           rowMode: 0,
-          callback: function(v){log(v)}
+          callback: (v)=>log(v)
         });
+      }catch(e){
+        error(e.message);
       }
-    }finally{
-      db.close();
+    });
+    log("Storage backend:",db.filename /* note that the name was internally translated */);
+    if(0===db.selectValue('select count(*) from sqlite_master')){
+      log("DB is empty. Use the init button to populate it.");
+    }else{
+      log("DB contains data from a previous session. Use the Clear Ctorage button to delete it.");
+      btnSelect.click();
     }
-    log("End of demo.");
   };
 
   sqlite3InitModule(self.sqlite3TestModule).then(function(theModule){
index c182819a9753c3f0924db9bd0fcb2b9c46d0ea6a..f11a02ef2a08891c44cf10df0a91772c16e5dcf2 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\skv-vfs\sbranch\sinto\sfiddle-opfs\sbranch\sto\sadd\skvvfs-based\swasm\sbuild\sand\sdemo.
-D 2022-09-12T16:09:50.625
+C Add\ssqlite3.oo1.DB.clearKvvfsStorage().\sAdd\scontrols\sto\skvvfs1.js\sdemo\sto\sreset\sand\squery\sthe\sdb\swithout\srequiring\sthe\sdev\sconsole.
+D 2022-09-12T17:59:04.237
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -483,7 +483,7 @@ 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 101919ec261644e2f6f0a59952fd9612127b69ea99b493277b2789ea478f9b6b
 F ext/wasm/api/sqlite3-api-glue.js 2bf536a38cde324cf352bc2c575f8e22c6d204d667c0eda5a254ba45318914bc
-F ext/wasm/api/sqlite3-api-oo1.js a9d8892be246548a9978ace506d108954aa13eb5ce25332975c8377953804ff3
+F ext/wasm/api/sqlite3-api-oo1.js b498662748918c132aa59433ea2bd2ebb7e026549fd68506a1ae1ea94736f4f6
 F ext/wasm/api/sqlite3-api-opfs.js 011799db398157cbd254264b6ebae00d7234b93d0e9e810345f213a5774993c0
 F ext/wasm/api/sqlite3-api-prologue.js 9e37ce4dfd74926d0df80dd7e72e33085db4bcee48e2c21236039be416a7dff2
 F ext/wasm/api/sqlite3-api-worker1.js d33062afa045fd4be01ba4abc266801807472558b862b30056211b00c9c347b4
@@ -507,8 +507,8 @@ F ext/wasm/jaccwabyt/jaccwabyt.md 447cc02b598f7792edaa8ae6853a7847b8178a18ed356a
 F ext/wasm/jaccwabyt/jaccwabyt_test.c 39e4b865a33548f943e2eb9dd0dc8d619a80de05d5300668e9960fff30d0d36f
 F ext/wasm/jaccwabyt/jaccwabyt_test.exports 5ff001ef975c426ffe88d7d8a6e96ec725e568d2c2307c416902059339c06f19
 F ext/wasm/kvvfs.make dba616578bf91a76370a46494dd68a09c6dff5beb6d5561e2db65a27216e9630
-F ext/wasm/kvvfs1.html b8304cd5c7e7ec32c3b15521a95c322d6efdb8d22b3c4156123545dc54e07583
-F ext/wasm/kvvfs1.js a5075f98ffecd7d32348697db991fc61342d89aa20651034d1572af61890fb8b
+F ext/wasm/kvvfs1.html 83bac238d1e93ed102a461672fc58fe74e611e426708e9a5c66002c01eadb942
+F ext/wasm/kvvfs1.js 53721a42e0ec45f6978cc723e5de47f882517867d0fcff4c6ff05f4c422e27c4
 F ext/wasm/scratchpad-opfs-main.html 4565cf194e66188190d35f70e82553e2e2d72b9809b73c94ab67b8cfd14d2e0c
 F ext/wasm/scratchpad-opfs-main.js 69e960e9161f6412fd0c30f355d4112f1894d6609eb431e2d16d207d1380518e
 F ext/wasm/scratchpad-opfs-worker.html 66c1d15d678f3bd306373d76b61c6c8aef988f61f4a8dd40185d452f9c6d2bf5
@@ -596,14 +596,14 @@ F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
 F src/os_kv.c a188e92dac693b1c1b512d93b0c4dc85c1baad11e322b01121f87057996e4d11
 F src/os_setup.h 0711dbc4678f3ac52d7fe736951b6384a0615387c4ba5135a4764e4e31f4b6a6
 F src/os_unix.c d6322b78130d995160bb9cfb7850678ad6838b08c1d13915461b33326a406c04
-F src/os_win.c e9454cb141908e8eef2102180bad353a36480612d5b736e4c2bd5777d9b25a34
+F src/os_win.c 8d129ae3e59e0fa900e20d0ad789e96f2e08177f0b00b53cdda65c40331e0902
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
 F src/pager.c 6176d9752eb580419e8fef4592dc417a6b00ddfd43ee22f818819bf8840ceee8
 F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3
 F src/parse.y 8e67d820030d2655b9942ffe61c1e7e6b96cea2f2f72183533299393907d0564
-F src/pcache.c 22a6ebe498d1d26c85fd1e3bcb246d97b882c060027c1e1688fbea905f5ac3cf
+F src/pcache.c f4268f7f73c6a3db12ce22fd25bc68dc42315d19599414ab1207d7cf32f79197
 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
-F src/pcache1.c 849a26ea9dc1e6a176b75dc576672a598170b0b46aeef87a981dd25e0af0ccf9
+F src/pcache1.c dee95e3cd2b61e6512dc814c5ab76d5eb36f0bfc9441dbb4260fccc0d12bbddc
 F src/pragma.c 9bf7d8a2a9ad3bc36df3ec0d61817a44c38a1da527d59c26c203047f906e334a
 F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
 F src/prepare.c 971d5819a4bda88038c2283d71fc0a2974ffc3dd480f9bd941341017abacfd1b
@@ -1981,7 +1981,7 @@ F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c
 F tool/showwal.c 0253c187ae16fdae9cde89e63e1dfcd3bb35e5416d066415f99e2f8cac6ab03d
 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
 F tool/spaceanal.tcl 1b5be34c6223cb1af06da2a10fb77863eb869b1962d055820b0a11cf2336ab45
-F tool/speed-check.sh ff74a68bb95a0341275f4d3c9a7d8a3800bd278aceecf1913295a1f0175bc3e6
+F tool/speed-check.sh 13f8e07dbfe25f3aecda33fb6068894665af61ca1360a7b654be0ad0c3f3ae0b
 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
@@ -2023,8 +2023,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 4e6ce329872eb733ba2f7f7879747c52761ae97790fd8ed169a25a79854cc3d9 e49682c5eac91958f143e639c5656ca54560d14f5805d514bf4aa0c206e63844
-R f15733833cf5e73dce86b4365f218581
+P a7d8b26acd3c1ae344369e4d70804c0cab45272c0983cfd32d616a0a7b28acb9
+R 984d02350bb7056e7ff7dbf797b44085
 U stephan
-Z f2a01bf4c99986993a2e00b39e93be73
+Z f41406c18c315f5b1f10f4c607ad1f16
 # Remove this line to create a well-formed Fossil manifest.
index bde2102af8a926efcd231c86ad33ab0824cdae51..c3f74348266504a7af5328e8cd4def98285b7c9e 100644 (file)
@@ -1 +1 @@
-a7d8b26acd3c1ae344369e4d70804c0cab45272c0983cfd32d616a0a7b28acb9
\ No newline at end of file
+d845c6c22bd5d3fffc66e0566df346d690dd8bd1fc1688e312161b1a1edcfd79
\ No newline at end of file
index 2827b0b49b9c92fc645c52daca06eb68cea91771..d71fb39220c5862ba25d4ec49b5816b6a7b897a8 100644 (file)
@@ -5763,7 +5763,8 @@ static int winFullPathname(
   char *zFull                   /* Output buffer */
 ){
   int rc;
-  sqlite3_mutex *pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR);
+  MUTEX_LOGIC( sqlite3_mutex *pMutex; )
+  MUTEX_LOGIC( pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR); )
   sqlite3_mutex_enter(pMutex);
   rc = winFullPathnameNoMutex(pVfs, zRelative, nFull, zFull);
   sqlite3_mutex_leave(pMutex);
index 8c57f5b1eb2633ec32911d99c10c14e3c4eb255e..0407e06b2fafa14c4390fdbd6011f978926592e9 100644 (file)
@@ -655,14 +655,14 @@ void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
   assert( sqlite3PcachePageSanity(p) );
   pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno));
   pOther = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, newPgno, 0);
-  sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
   if( pOther ){
-    PgHdr *pPg = (PgHdr*)pOther->pExtra;
-    pPg->pgno = p->pgno;
-    if( pPg->pPage==0 ){
-      sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pOther, 0);
-    }
+    PgHdr *pXPage = (PgHdr*)pOther->pExtra;
+    assert( pXPage->nRef==0 );
+    pXPage->nRef++;
+    pCache->nRefSum++;
+    sqlite3PcacheDrop(pXPage);
   }
+  sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
   p->pgno = newPgno;
   if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
     pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
index a47087fa1134df2b2d63721c9f996d7f8d50f5e6..adbe953959bc15563220c85f38710003ea81c125 100644 (file)
@@ -1125,7 +1125,7 @@ static void pcache1Rekey(
   assert( iOld!=iNew );               /* The page number really is changing */
 
   pcache1EnterMutex(pCache->pGroup);
-  
+
   assert( pcache1FetchNoMutex(p, iOld, 0)==pPage ); /* pPg really is iOld */
   hOld = iOld%pCache->nHash;
   pp = &pCache->apHash[hOld];
@@ -1134,23 +1134,8 @@ static void pcache1Rekey(
   }
   *pp = pPage->pNext;
 
+  assert( pcache1FetchNoMutex(p, iNew, 0)==0 ); /* iNew not in cache */
   hNew = iNew%pCache->nHash;
-  pp = &pCache->apHash[hNew];
-  while( *pp ){
-    if( (*pp)->iKey==iNew ){
-      /* If there is already another pcache entry at iNew, change it to iOld,
-      ** thus swapping the positions of iNew and iOld */
-      PgHdr1 *pOld = *pp;
-      *pp = pOld->pNext;
-      pOld->pNext = pCache->apHash[hOld];
-      pCache->apHash[hOld] = pOld;
-      pOld->iKey = iOld;
-      break;
-    }else{
-      pp = &(*pp)->pNext;
-    }
-  }
-
   pPage->iKey = iNew;
   pPage->pNext = pCache->apHash[hNew];
   pCache->apHash[hNew] = pPage;
index 6b0fbeb43a4e8ca984b308e7c9c90f3717890299..879ffa9562b70d618d3a204e27ab08c29e36ff65 100644 (file)
@@ -96,6 +96,9 @@ while test "$1" != ""; do
     --cachesize)
         shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --cachesize $1"
         ;;
+    --stmtcache)
+        shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --stmtcache $1"
+        ;;
     --checkpoint)
         SPEEDTEST_OPTS="$SPEEDTEST_OPTS --checkpoint"
         ;;
@@ -143,6 +146,9 @@ while test "$1" != ""; do
         SPEEDTEST_OPTS="$SPEEDTEST_OPTS --testset rtree"
         CC_OPTS="$CC_OPTS -DSQLITE_ENABLE_RTREE"
         ;;
+    --persist)
+        SPEEDTEST_OPTS="$SPEEDTEST_OPTS --persist"
+        ;;
     --orm)
         SPEEDTEST_OPTS="$SPEEDTEST_OPTS --testset orm"
         ;;