]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add a kvvfs vtab for inspecting the storage state. This is for testing and my own...
authorstephan <stephan@noemail.net>
Sat, 29 Nov 2025 16:41:27 +0000 (16:41 +0000)
committerstephan <stephan@noemail.net>
Sat, 29 Nov 2025 16:41:27 +0000 (16:41 +0000)
FossilOrigin-Name: eaff2e8b7f63575e85fb9be800a2c59163e402d6a25fc6a955b9df15afe13b92

ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js
ext/wasm/api/sqlite3-vtab-helper.c-pp.js
ext/wasm/tester1.c-pp.js
manifest
manifest.uuid

index 9a7867a48a4cd2a8fcac5ad0064ebd786672777e..5c6cb9302f94661afc5a52a8ad62c319d7b0da0a 100644 (file)
@@ -97,7 +97,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
 
   if( !pKvvfs ) return /* nothing to do */;
   if( 0 ){
-    /* This working would be our proverbial holy grail. */
+    /* This working would be our proverbial holy grail, in that it
+       would allow us to eliminate the current default VFS, which
+       relies on POSIX I/O APIs. Eliminating that dependency would get
+       us one giant step closer to creating wasi-sdk builds. */
     capi.sqlite3_vfs_register(pKvvfs, 1);
   }
 
@@ -466,6 +469,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
   const jsKeyForStorage = (store,zClass,zKey)=>
         wasm.cstrToJs(zKeyForStorage(store, zClass, zKey));
 
+  const storageGetDbSize = (store)=>+store.storage.getItem(store.keyPrefix + "sz");
+
   /**
      sqlite3_file pointers => objects, each of which has:
 
@@ -1434,6 +1439,159 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
     };
   }/*sqlite3.oo1.JsStorageDb*/
 
+  if( sqlite3.__isUnderTest && sqlite3.vtab ){
+    /**
+       An eponymous vtab for inspecting the kvvfs state.  This is only
+       intended for use in testing and development, not part of the
+       public API.
+    */
+    const cols = Object.assign(Object.create(null),{
+      rowid:       {type: 'INTEGER'},
+      name:        {type: 'TEXT'},
+      nRef:        {type: 'INTEGER'},
+      nOpen:       {type: 'INTEGER'},
+      isTransient: {type: 'INTEGER'},
+      dbSize:      {type: 'INTEGER'}
+    });
+    Object.keys(cols).forEach((v,i)=>cols[v].colId = i);
+
+    const VT = sqlite3.vtab;
+    const cursorState = function(cursor){
+      return ((cursor instanceof capi.sqlite3_vtab_cursor)
+       ? cursor
+       : VT.xCursor.get(cursor)
+      ).vTabState
+        ??= Object.assign(Object.create(null),{
+          rowid: 0,
+          names: Object.keys(cache.storagePool)
+            .filter(v=>!cache.rxJournalSuffix.test(v)),
+          row: function(){
+            return cache.storagePool[this.names[this.rowid]];
+          }
+        });
+    };
+
+    const dbg = 1 ? ()=>{} : (...args)=>debug("vtab",...args);
+
+    const theModule = function f(){
+      return f.mod ??= new sqlite3.capi.sqlite3_module().setupModule({
+        catchExceptions: true,
+        methods: {
+          xConnect: function(pDb, pAux, argc, argv, ppVtab, pzErr){
+            dbg("xConnect");
+            try{
+              const xcol = [];
+              Object.keys(cols).forEach((k)=>{
+                xcol.push(k+" "+cols[k].type);
+              });
+              const rc = capi.sqlite3_declare_vtab(
+                pDb, "CREATE TABLE ignored("+xcol.join(',')+")"
+              );
+              if(0===rc){
+                const t = VT.xVtab.create(ppVtab);
+                util.assert(
+                  (t === VT.xVtab.get(wasm.peekPtr(ppVtab))),
+                  "output pointer check failed"
+                );
+              }
+              return rc;
+            }catch(e){
+              return VT.xErrror('xConnect', e, capi.SQLITE_ERROR);
+            }
+          },
+          xCreate: wasm.ptr.null, // eponymous only
+          xDisconnect: function(pVtab){
+            dbg("xDisconnect",...arguments);
+            VT.xVtab.dispose(pVtab);
+            return 0;
+          },
+          xOpen: function(pVtab, ppCursor){
+            dbg("xOpen",...arguments);
+            VT.xCursor.create(ppCursor);
+            return 0;
+          },
+          xClose: function(pCursor){
+            dbg("xClose",...arguments);
+            const c = VT.xCursor.unget(pCursor);
+            delete c.vTabState;
+            c.dispose();
+            return 0;
+          },
+          xNext: function(pCursor){
+            dbg("xNext",...arguments);
+            const c = VT.xCursor.get(pCursor);
+            ++cursorState(c).rowid;
+            return 0;
+          },
+          xColumn: function(pCursor, pCtx, iCol){
+            dbg("xColumn",...arguments);
+            //const c = VT.xCursor.get(pCursor);
+            const st = cursorState(pCursor);
+            const store = st.row();
+            util.assert(store, "Unexpected xColumn call");
+            switch(iCol){
+              case cols.rowid.colId:
+                capi.sqlite3_result_int(pCtx, st.rowid);
+                break;
+              case cols.name.colId:
+                capi.sqlite3_result_text(pCtx, store.jzClass, -1, capi.SQLITE_TRANSIENT);
+                break;
+              case cols.nRef.colId:
+                capi.sqlite3_result_int(pCtx, store.refc);
+                break;
+              case cols.nOpen.colId:
+                capi.sqlite3_result_int(pCtx, store.files.length);
+                break;
+              case cols.isTransient.colId:
+                capi.sqlite3_result_int(pCtx, !!store.deleteAtRefc0);
+                break;
+              case cols.dbSize.colId:
+                capi.sqlite3_result_int(pCtx, storageGetDbSize(store));
+                break;
+              default:
+                capi.sqlite3_result_error(pCtx, "Invalid column id: "+iCol);
+                return capi.SQLITE_RANGE;
+            }
+            return 0;
+          },
+          xRowid: function(pCursor, ppRowid64){
+            dbg("xRowid",...arguments);
+            const st = cursorState(pCursor);
+            VT.xRowid(ppRowid64, st.rowid);
+            return 0;
+          },
+          xEof: function(pCursor){
+            dbg("xEof",...arguments);
+            const st = cursorState(pCursor);
+            return !st.row();
+          },
+          xFilter: function(pCursor, idxNum, idxCStr,
+                            argc, argv/* [sqlite3_value* ...] */){
+            dbg("xFilter",...arguments);
+            const st = cursorState(pCursor);
+            st.rowid = 0;
+            return 0;
+          },
+          xBestIndex: function(pVtab, pIdxInfo){
+            dbg("xBestIndex",...arguments);
+            //const t = VT.xVtab.get(pVtab);
+            const pii = new capi.sqlite3_index_info(pIdxInfo);
+            pii.$estimatedRows = cache.storagePool.size;
+            pii.$estimatedCost = 1.0;
+            pii.dispose();
+            return 0;
+          }
+        }
+      })/*setupModule*/;
+    }/*theModule()*/;
+
+    sqlite3.kvvfs.create_module = function(pDb, name="sqlite_kvvfs"){
+      return capi.sqlite3_create_module(pDb, name, theModule(),
+                                        wasm.ptr.null);
+    };
+
+  }/* virtual table */
+
 })/*globalThis.sqlite3ApiBootstrap.initializers*/;
 //#savepoint rollback
 //#endif not omit-kvvfs
index 4c2338fc5a4c2b07eca91eaa09cb4eaef9532a23..80f4bfac23afad6929ef49ab79f5ca5ad11cc121 100644 (file)
@@ -172,10 +172,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
          Works like unget() plus it calls dispose() on the
          StructType object.
       */
-      dispose: (pCObj)=>{
-        const o = __xWrap(pCObj,true);
-        if(o) o.dispose();
-      }
+      dispose: (pCObj)=>__xWrap(pCObj,true)?.dispose?.()
     });
   };
 
index 4056d54780794ddaf395d8739e272f0282fe9b86..b7d4afe15298ea583ce0dbd4f6bed0af155604af 100644 (file)
@@ -2631,7 +2631,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
           .assert(wasm.isPtr(tmplMod.$xRowid))
           .assert(wasm.isPtr(tmplMod.$xCreate))
           .assert(tmplMod.$xCreate === tmplMod.$xConnect,
-                  "setup() must make these equivalent and "+
+                  "setupModule() must make these equivalent and "+
                   "installMethods() must avoid re-compiling identical functions");
         tmplMod.$xCreate = wasm.ptr.null /* make tmplMod eponymous-only */;
         let rc = capi.sqlite3_create_module(
@@ -3265,12 +3265,30 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
           db.close();
           const after = JSON.stringify(counts);
           T.assert( before===after, "Expecting no events after unlistening." );
+          sqlite3.kvvfs.unlink(filename);
         }finally{
           db?.close?.();
         }
-
       }
-    })/*kvvfs listeners
+    })/*kvvfs listeners */
+    .t({
+      name: 'kvvfs vtab',
+      predicate: (sqlite3)=>!!sqlite3.kvvfs.create_module,
+      test: function(sqlite3){
+        const kvvfs = sqlite3.kvvfs;
+        const db = new sqlite3.oo1.DB();
+        try{
+          kvvfs.create_module(db);
+          /*db.exec([
+            "create virtual table vt using kvvfs()"
+          ]);*/
+          let rc = db.selectObjects("select * from sqlite_kvvfs");
+          console.log("vtab rc", rc);
+        }finally{
+          db.close();
+        }
+      }
+    })/* kvvfs vtab */
 //#if enable-see
     .t({
       name: 'kvvfs SEE encryption in sessionStorage',
index b9ba6731a4a18acfd61db4b0fff2c1011397ba45..b1271a14aa7b5ce17b27d8a39e9de6a7fbabdf2a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\strunk\sinto\sthe\skvvfs-v2\sbranch.
-D 2025-11-28T22:17:02.501
+C Add\sa\skvvfs\svtab\sfor\sinspecting\sthe\sstorage\sstate.\sThis\sis\sfor\stesting\sand\smy\sown\sedification,\snot\spart\sof\sthe\spublic\sAPI.
+D 2025-11-29T16:41:27.823
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -600,10 +600,10 @@ F ext/wasm/api/sqlite3-api-worker1.c-pp.js 1041dd645e8e821c082b628cd8d9acf70c667
 F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
 F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966
 F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d
-F ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js e08a013432aeb5e38f043829d8fa3dca06e124c117294d4c0a23db69138ae5b1
+F ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js 3f65769166670f2bd044374958f8eeb43b9fae8179ef58506acee38cb435de54
 F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js a2eea6442556867b589e04107796c6e1d04a472219529eeb45b7cd221d7d048b
 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 88ce2078267a2d1af57525a32d896295f4a8db7664de0e17e82dc9ff006ed8d3
-F ext/wasm/api/sqlite3-vtab-helper.c-pp.js 9097074724172e31e56ce20ccd7482259cf72a76124213cbc9469d757676da86
+F ext/wasm/api/sqlite3-vtab-helper.c-pp.js 366596d8ff73d4cefb938bbe95bc839d503c3fab6c8335ce4bf52f0d8a7dee81
 F ext/wasm/api/sqlite3-wasm.c 1d6f8f3486f4f9a21db597f84a015fe9bb7c111652ce6beacdaceb0d162617ff
 F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bda1c75bd674a92a0e27cc2f3d46dbbf21e422413f8046814515a0bd7409328a
 F ext/wasm/api/sqlite3-worker1.c-pp.js 802d69ead8c38dc1be52c83afbfc77e757da8a91a2e159e7ed3ecda8b8dba2e7
@@ -625,7 +625,7 @@ F ext/wasm/demo-worker1.js 08720227e98fa5b44761cf6e219269cee3e9dd0421d8d91459535
 F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f
 F ext/wasm/fiddle/fiddle-worker.js 7798af02e672e088ff192716f80626c8895e19301a65b8af6d5d12b2d13d2451
 F ext/wasm/fiddle/fiddle.js 84fd75967e0af8b69d3dd849818342227d0f81d13db92e0dcbc63649b31a4893
-F ext/wasm/fiddle/index.c-pp.html 72c7e5517217960b3809648429ea396a7cbad0ffb2c92f6a2f5703abecb27317 w ext/wasm/fiddle/index.html
+F ext/wasm/fiddle/index.c-pp.html 72c7e5517217960b3809648429ea396a7cbad0ffb2c92f6a2f5703abecb27317
 F ext/wasm/index-dist.html db23748044e286773f2768eec287669501703b5d5f72755e8db73607dc54d290
 F ext/wasm/index.html 54e27db740695ab2cb296e02d42c4c66b3f11b65797340d19fa6590f5b287da1
 F ext/wasm/jaccwabyt/jaccwabyt.js 4e2b797dc170851c9c530c3567679f4aa509eec0fab73b466d945b00b356574b
@@ -647,7 +647,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
 F ext/wasm/tester1-worker.c-pp.html 0e432ec2c0d99cd470484337066e8d27e7aee4641d97115338f7d962bf7b081a
 F ext/wasm/tester1.c-pp.html 52d88fe2c6f21a046030a36410b4839b632f4424028197a45a3d5669ea724ddb
-F ext/wasm/tester1.c-pp.js f7a2aa456af7b713772d2750c0b9e7693fb2ddbfa152faf0d41a4ef9121ac57b
+F ext/wasm/tester1.c-pp.js 05bb1099472d410b8b5b822af0f362ec565c617eea924d5f53a3b643fc1466d8
 F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e
 F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88
 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
@@ -2180,8 +2180,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 5ec20ebe057af297f5e0ccc0d7184ab0ed720f91db0f470a7cf827df0f2aa530 4384c9a108b58a0b8c38c51678aad871f088358b9bff3922299cc7ddb3d247ce
-R 6acef3505b89c0d3fbc9ed9322f624c8
+P 0e1a6ca0f1123da680918027b16608bf87593a9d91f7b1f3fc0c3a454185740d
+R 2aee549605fa5886143a182c3a989cec
 U stephan
-Z f3d7f6b7a89a18464041eaff89f54170
+Z db62e7bb06a82ac76e6e3341ca1c99a3
 # Remove this line to create a well-formed Fossil manifest.
index 20074f8777cd27d3accd23371d73b526d0b45818..9f0211379b2f0477c3210aa58aabe82189f3f8d2 100644 (file)
@@ -1 +1 @@
-0e1a6ca0f1123da680918027b16608bf87593a9d91f7b1f3fc0c3a454185740d
+eaff2e8b7f63575e85fb9be800a2c59163e402d6a25fc6a955b9df15afe13b92