]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Incremental work on kvvfs v2.
authorstephan <stephan@noemail.net>
Sat, 22 Nov 2025 07:35:36 +0000 (07:35 +0000)
committerstephan <stephan@noemail.net>
Sat, 22 Nov 2025 07:35:36 +0000 (07:35 +0000)
FossilOrigin-Name: 60d61cf383b63b25dcfbf8da9539aaec253b6618ec83403f6690b7a32c13363d

ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js
manifest
manifest.uuid
src/os_kv.c

index 05de2c40e555fcd889f7b6fa515838ff7210f2e0..8e907e3e36e9ff1aadff2d21ed691106452d8746 100644 (file)
@@ -47,6 +47,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
   const warn = function(){
     sqlite3.config.warn("kvvfs:", ...arguments);
   };
+  const error = function(){
+    sqlite3.config.error("kvvfs:", ...arguments);
+  };
 
   /**
      Implementation of JS's Storage interface for use as backing store
@@ -302,6 +305,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
     const pVfs = new capi.sqlite3_vfs(kvvfsMethods.$pVfs);
     const pIoDb = new capi.sqlite3_io_methods(kvvfsMethods.$pIoDb);
     const pIoJrnl = new capi.sqlite3_io_methods(kvvfsMethods.$pIoJrnl);
+    const recordHandler = Object.create(null);
     /**
        Implementations for members of the object referred to by
        sqlite3__wasm_kvvfs_methods(). We swap out the native
@@ -327,6 +331,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
                 astack = wasm.scopedAllocPush();
           try{
             const store = storageForZClass(zClass);
+            if( !store ) return -1;
+            if( 0 ){
+              debug("xRcrdRead", nBuf, zClass, wasm.cstrToJs(zClass),
+                    wasm.cstrToJs(zKey), store);
+            }
             const zXKey = keyForStorage(store, zClass, zKey);
             if(!zXKey) return -3/*OOM*/;
             const jV = store.s.getItem(wasm.cstrToJs(zXKey));
@@ -347,10 +356,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
             wasm.heap8u().copyWithin(
               Number(zBuf), Number(zV), wasm.ptr.addn(zV, nBuf,- 1)
             );
-            wasm.poke(wasm.ptr.add(zBuf, nBuf, -1), 0);
+            wasm.poke(wasm.ptr.add(zBuf, nBuf), 0);
             return nBuf - 1;
           }catch(e){
-            sqlite3.config.error("kvrecordRead()",e);
+            error("kvrecordRead()",e);
             return -2;
           }finally{
             pstack.restore(stack);
@@ -370,7 +379,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
             );
             return 0;
           }catch(e){
-            sqlite3.config.error("kvrecordWrite()",e);
+            error("kvrecordWrite()",e);
             return capi.SQLITE_IOERR;
           }finally{
             pstack.restore(stack);
@@ -386,7 +395,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
             store.s.removeItem(wasm.cstrToJs(zXKey));
             return 0;
           }catch(e){
-            sqlite3.config.error("kvrecordDelete()",e);
+            error("kvrecordDelete()",e);
             return capi.SQLITE_IOERR;
           }finally{
             pstack.restore(stack);
@@ -450,59 +459,75 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
             return capi.SQLITE_ERROR;
           }
         }/*xOpen()*/,
-//#if nope
-        xAccess:function(pProtoVfs, zPath, flags, pResOut){
-          /* Triggering an abort() via xClose(), but we'll need a working
-             xAccess() if we want to use kvvfs as the default vfs. */
+
+        xDelete: function(pVfs, zName, iSyncFlag){
           try{
-            let drc = 0;
-            const jzName = wasm.cstrToJs(zPath);
-            const s = cache.jzClassToStorage[jzName];
-            debug("xAccess", jzName, s);
-            if( s ){
-              if( 0 && !jzName.endsWith("-journal") ){
-                drc = 1;
-              }else{
-                const zKey = jzName.endsWith("-journal")
-                      ? cache.zKeyJrnl
-                      : cache.zKeySz;
-                drc = sqlite3_kvvfs_methods.override.recordHandler
-                  .xRcrdRead(zPath, zKey, wasm.ptr.null, 0);
+            if( 0 ){
+              util.assert(zName, "null zName?");
+              const jzName = wasm.cstrToJs(zName);
+              const s = cache.jzClassToStorage[jzName];
+              debug("xDelete", jzName, s);
+              if( cache.rxJournalSuffix.test(jzName) ){
+                recordHandler.xRcrdDelete(zName, cache.zKeyJrnl);
               }
+              return 0;
             }
-            wasm.poke32(pResOut, drc>0 ? 1 : 0);
-            return 0;
+            return originalMethods.vfs.xDelete(pVfs, zName, iSyncFlag);
           }catch(e){
-            warn("xAccess",e);
+            warn("xDelete",e);
             return capi.SQLITE_ERROR;
           }
-        }/*xAccess*/,
-        xDelete: function(pVfs, zName, iSyncFlag){
+        },
+
+        xAccess:function(pProtoVfs, zPath, flags, pResOut){
           try{
-            // Triggering an abort() via xClose()
-            util.assert(zName, "null zName?");
-            const jzName = wasm.cstrToJs(zName);
-            const s = cache.jzClassToStorage[jzName];
-            debug("xDelete", jzName, s);
-            if( s ){
-              if( jzName.endsWith("-journal") ){
-                const zKey = cache.zKeyJrnl;
-                util.assert(zKey, "Missing cache.zKeyJrnl");
-                sqlite3_kvvfs_methods.override.recordHandler
-                  .xRcrdDelete(zName, zKey);
-              }else{
-                drc = 1;
-                delete cache.jzClassToStorage[jzName];
+            if( 0 ){
+              const jzName = wasm.cstrToJs(zPath);
+              const s = cache.jzClassToStorage[jzName];
+              debug("xAccess", jzName, s);
+              let drc = 1;
+              wasm.poke32(pResOut, 0);
+              if( s ){
+                /* This block is _somehow_ triggering an
+                   abort() via xClose(). */
+                if(0) debug("cache.zKeyJrnl...",wasm.cstrToJs(cache.zKeyJrnl),
+                      wasm.cstrToJs(cache.zKeySz));
+                drc = recordHandler.xRcrdRead(
+                  zPath,
+                  jzName.endsWith("-journal")
+                    ? cache.zKeyJrnl
+                    : cache.zKeySz,
+                  wasm.ptr.null, 0
+                );
+                debug("xAccess", jzName, drc, pResOut);
+                if( drc>0 ){
+                  wasm.poke32(
+                    pResOut, 1
+                    /* This poke is triggering an abort via xClose().
+                       If we poke 0 then no problem... except that
+                       xAccess() doesn't report the truth. Same effect
+                       if we move that to the native impl
+                       os_kv.c:kvvfsAccess(). */
+                  );
+                }
               }
               return 0;
-            }else{
-              return originalMethods.vfs.xDelete(pVfs, zName, iSyncFlag);
             }
+            const rc = originalMethods.vfs.xAccess(
+              pProtoVfs, zPath, flags, pResOut
+              /* This one is only valid for local/session storage */
+            );
+            if( 0 && 0===rc ){
+              debug("xAccess pResOut", wasm.peek32(pResOut));
+            }
+            return rc;
           }catch(e){
-            warn("xDelete",e);
+            error('xAccess',e);
             return capi.SQLITE_ERROR;
           }
         },
+
+//#if nope
         xFullPathname: function(pVfs, zPath, nOut, zOut){},
         xDlOpen: function(pVfs, zFilename){},
         xSleep: function(pVfs,usec){},
@@ -544,8 +569,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
                 delete s.s;
                 delete s.refc;
               }
-              h.f.dispose();
               originalIoMethods(h.f).xClose(pFile);
+              h.f.dispose();
             }else{
               /* Can happen if xOpen fails */
             }
@@ -594,10 +619,13 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
     }/*sqlite3_kvvfs_methods.override*/;
 
     const ov = sqlite3_kvvfs_methods.override;
-    debug("pVfs and friends", pVfs, pIoDb, pIoJrnl);
+    debug("pVfs and friends", pVfs, pIoDb, pIoJrnl,
+          kvvfsMethods, capi.sqlite3_file.structInfo,
+          KVVfsFile.structInfo);
     try {
       for(const e of Object.entries(ov.recordHandler)){
         // Overwrite kvvfsMethods's callbacks
+        recordHandler[e[0]] = e[1];
         kvvfsMethods[kvvfsMethods.memberKey(e[0])] =
           wasm.installFunction(kvvfsMethods.memberSignature(e[0]), e[1]);
       }
@@ -612,12 +640,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       }
       for(const e of Object.entries(ov.ioDb)){
         // Similar treatment for pVfs.$pIoDb a.k.a. pIoDb...
-        const k = e[0], f = e[1], km = pIoDb.memberKey(k),
-              member = pIoDb.structInfo.members[k]
-              || util.toss("Missing pIoDb.structInfo[",k,"]");
+        const k = e[0], f = e[1], km = pIoDb.memberKey(k);
         originalMethods.ioDb[k] = wasm.functionEntry(pIoDb[km])
           || util.toss("Missing native pIoDb[",km,"]");
-        pIoDb[km] = wasm.installFunction(member.signature, f);
+        pIoDb[km] = wasm.installFunction(pIoDb.memberSignature(k), f);
       }
       for(const e of Object.entries(ov.ioJrnl)){
         // Similar treatment for pVfs.$pIoJrnl a.k.a. pIoJrnl...
@@ -628,8 +654,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
           /* use pIoDb's copy */
           pIoJrnl[km] = pIoDb[km] || util.toss("Missing copied pIoDb[",km,"]");
         }else{
-          const member = pIoJrnl.structInfo.members[k]
-                || util.toss("Missing pIoJrnl.structInfo[",k,"]");
           pIoJrnl[km] = wasm.installFunction(pIoJrnl.memberSignature(k), f);
         }
       }
index b47629356bd38d8d3593454813f0207c659a799d..bce3dbeea0ca90fa0a0bdc13729490b614a39cc7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Factor\sKVVfsFile::zName\sback\sout.\sRemove\sthe\sextraneous\spart\sof\sthe\sstorage\skeys\sfor\snon-local/non-session\sstorage.
-D 2025-11-22T05:37:21.474
+C Incremental\swork\son\skvvfs\sv2.
+D 2025-11-22T07:35:36.321
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -600,7 +600,7 @@ 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 a0835218719d0ec6bfc79ec29d44d2028ef98a7c1b1aeee75f4338f5d3eb337c
+F ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js f6eeaeccd0a6e1fd3fe58dba8e09954a32f8f7097fae4c00e519d91a72c7be1d
 F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 26cb41d5a62f46a106b6371eb00fef02de3cdbfaa51338ba087a45f53028e0d0
 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js aa330fa0e8ef35cbd92eb0d52e05fbaa07e61540c5cb164e693c82428ce1d763
 F ext/wasm/api/sqlite3-vtab-helper.c-pp.js 9097074724172e31e56ce20ccd7482259cf72a76124213cbc9469d757676da86
@@ -717,7 +717,7 @@ F src/notify.c 57c2d1a2805d6dee32acd5d250d928ab94e02d76369ae057dee7d445fd64e878
 F src/os.c 509452169d5ea739723e213b8e2481cf0e587f0e88579a912d200db5269f5f6d
 F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
-F src/os_kv.c 59f41c1ac47f9d1f89d3c04eb08b7f91e14e903d2b44e10a29e803ee353553a1
+F src/os_kv.c f11812682d83d125fb25c34db44d3091e4171662e087080ad2067203cc0606aa
 F src/os_setup.h 8efc64eda6a6c2f221387eefc2e7e45fd5a3d5c8337a7a83519ba4fbd2957ae2
 F src/os_unix.c 7945ede1e85b2d1b910e1b4af9ba342e964b1e30e79f4176480a60736445cb36
 F src/os_win.c a89b501fc195085c7d6c9eec7f5bd782625e94bb2a96b000f4d009703df1083f
@@ -2178,8 +2178,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 3f9ff9873303c3900dd3cba6e922bfb8cdb1f595353b692796b62e3025013517
-R 3850965b51b022600461307bc9bfa402
+P d2bf96d68c6cb2ae68558722edb22192fb1dbbf08fefdb2fd0a4827688e082a8
+R edd2150137694760800c3d7cae9ac6f3
 U stephan
-Z 2898a867b93493236c621da268e3979f
+Z 821185e1e7c2969ce068a864d05b8e47
 # Remove this line to create a well-formed Fossil manifest.
index 28409835c272dd54d81ba72602bb9b99585558f1..3f7d6d560ec98698fb4a5bec3138a716866a650d 100644 (file)
@@ -1 +1 @@
-d2bf96d68c6cb2ae68558722edb22192fb1dbbf08fefdb2fd0a4827688e082a8
+60d61cf383b63b25dcfbf8da9539aaec253b6618ec83403f6690b7a32c13363d
index 337cf1b0a930e63ae7c01ed6be2e2e5c5ca0ff4c..feb3536f4c96094c84e33610fda07adb69f71da6 100644 (file)
@@ -918,6 +918,20 @@ static int kvvfsAccess(
   int *pResOut
 ){
   SQLITE_KV_LOG(("xAccess(\"%s\")\n", zPath));
+#if 0 && defined(SQLITE_WASM)
+  /*
+  ** Bug somewhere: if this method sets *pResOut to non-0 then
+  ** xClose() is abort()ing via free(). The symptoms are the same
+  ** whether we set *pResOut from here or from JS.
+  */
+  if( 0==sqlite3_strglob("*-journal", zPath) ){
+    *pResOut =
+      sqlite3KvvfsMethods.xRcrdRead(zPath, "jrnl", 0, 0)>0;
+  }else{
+    *pResOut =
+      sqlite3KvvfsMethods.xRcrdRead(zPath, "sz", 0, 0)>0;
+  }
+#else
   if( strcmp(zPath, "local-journal")==0 ){
     *pResOut =
       sqlite3KvvfsMethods.xRcrdRead("local", "jrnl", 0, 0)>0;
@@ -937,6 +951,8 @@ static int kvvfsAccess(
   {
     *pResOut = 0;
   }
+  /*all current JS tests avoid triggering: assert( *pResOut == 0 ); */
+#endif
   SQLITE_KV_LOG(("xAccess returns %d\n",*pResOut));
   return SQLITE_OK;
 }