]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Internal refactoring in opfs-sahpool. Move OPFS tests to the end of tester1.c-cpp.js.
authorstephan <stephan@noemail.net>
Wed, 19 Jul 2023 08:18:25 +0000 (08:18 +0000)
committerstephan <stephan@noemail.net>
Wed, 19 Jul 2023 08:18:25 +0000 (08:18 +0000)
FossilOrigin-Name: 6bd5a7413dd830ca41b587a2826fb599a2196fb0186646a2333500f950b3cf4d

ext/wasm/api/sqlite3-v-helper.js
ext/wasm/api/sqlite3-vfs-opfs-sahpool.js
ext/wasm/tester1.c-pp.js
manifest
manifest.uuid

index cc9747aa5bc44bcd1f57e59904947f72017c62c4..8ae1172cf65e3522f100ec31eeb5f6aa6998efc8 100644 (file)
@@ -100,7 +100,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
 
      ACHTUNG: because we cannot generically know how to transform JS
      exceptions into result codes, the installed functions do no
-     automatic catching of exceptions. It is critical, to avoid 
+     automatic catching of exceptions. It is critical, to avoid
      undefined behavior in the C layer, that methods mapped via
      this function do not throw. The exception, as it were, to that
      rule is...
index 7547c01a8e28584aafc4f32b224b23133dc676b7..322ac977a9d8f868b14479c594f7da2d37e17755 100644 (file)
@@ -89,7 +89,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
 
   const optionDefaults = Object.assign(Object.create(null),{
     name: 'opfs-sahpool',
-    directory: undefined,
+    directory: undefined /* derived from .name */,
     initialCapacity: 6,
     clearOnInit: false,
     verbosity: 2 /*3+ == everything, 2 == warnings+errors, 1 == errors only*/
@@ -390,6 +390,21 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       return rc;
     }
 
+    getFileForPtr(ptr){
+      return this.mapIdToFile.get(ptr);
+    }
+    setFileForPtr(ptr,file){
+      if(file) this.mapIdToFile.set(ptr, file);
+      else this.mapIdToFile.delete(ptr);
+    }
+
+    hasFilename(name){
+      return this.mapFilenameToSAH.has(name)
+    }
+
+    getSAHForPath(path){
+      return this.mapFilenameToSAH.get(path);
+    }
   }/*class OpfsSAHPool*/;
 
 
@@ -576,6 +591,13 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
      the default directory. If no directory is explicitly provided
      then a directory name is synthesized from the `name` option.
 
+     Peculiarities of this VFS:
+
+     - Paths given to it _must_ be absolute. Relative paths will not
+     be properly recognized. This is arguably a bug but correcting it
+     requires some hoop-jumping and memory allocation in routines
+     which should not be allocating.
+
 
      The API for the utility object passed on by this function's
      Promise, in alphabetical order...
@@ -673,7 +695,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       throw new Error("Just testing rejection.");
     }
     if(initPromises[vfsName]){
-      console.warn("Returning same OpfsSAHPool result",options,vfsName,initPromises[vfsName]);
+      //console.warn("Returning same OpfsSAHPool result",options,vfsName,initPromises[vfsName]);
       return initPromises[vfsName];
     }
     if(!globalThis.FileSystemHandle ||
@@ -699,13 +721,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
     const opfsVfs = new capi.sqlite3_vfs()
           .addOnDispose(()=>opfsIoMethods.dispose());
 
-    const promiseReject = (err)=>{
-      error("rejecting promise:",err);
-      opfsVfs.dispose();
-      initPromises[vfsName] = Promise.reject(err);
-      throw err;
-    };
-
     /* We fetch the default VFS so that we can inherit some
        methods from it. */
     const pDVfs = capi.sqlite3_vfs_find(null);
@@ -755,13 +770,13 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
           },
           xClose: function(pFile){
             thePool.storeErr();
-            const file = thePool.mapIdToFile.get(pFile);
+            const file = thePool.getFileForPtr(pFile);
             if(file) {
               try{
                 log(`xClose ${file.path}`);
                 if(file.sq3File) file.sq3File.dispose();
                 file.sah.flush();
-                thePool.mapIdToFile.delete(pFile);
+                thePool.setFileForPtr(pFile,0);
                 if(file.flags & capi.SQLITE_OPEN_DELETEONCLOSE){
                   thePool.deletePath(file.path);
                 }
@@ -780,7 +795,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
           },
           xFileSize: function(pFile,pSz64){
             log(`xFileSize`);
-            const file = thePool.mapIdToFile.get(pFile);
+            const file = thePool.getFileForPtr(pFile);
             const size = file.sah.getSize() - HEADER_OFFSET_DATA;
             //log(`xFileSize ${file.path} ${size}`);
             wasm.poke64(pSz64, BigInt(size));
@@ -789,14 +804,14 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
           xLock: function(pFile,lockType){
             log(`xLock ${lockType}`);
             thePool.storeErr();
-            const file = thePool.mapIdToFile.get(pFile);
+            const file = thePool.getFileForPtr(pFile);
             file.lockType = lockType;
             return 0;
           },
           xRead: function(pFile,pDest,n,offset64){
             log(`xRead ${n}@${offset64}`);
             thePool.storeErr();
-            const file = thePool.mapIdToFile.get(pFile);
+            const file = thePool.getFileForPtr(pFile);
             log(`xRead ${file.path} ${n} ${offset64}`);
             try {
               const nRead = file.sah.read(
@@ -819,7 +834,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
           xSync: function(pFile,flags){
             log(`xSync ${flags}`);
             thePool.storeErr();
-            const file = thePool.mapIdToFile.get(pFile);
+            const file = thePool.getFileForPtr(pFile);
             //log(`xSync ${file.path} ${flags}`);
             try{
               file.sah.flush();
@@ -832,7 +847,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
           xTruncate: function(pFile,sz64){
             log(`xTruncate ${sz64}`);
             thePool.storeErr();
-            const file = thePool.mapIdToFile.get(pFile);
+            const file = thePool.getFileForPtr(pFile);
             //log(`xTruncate ${file.path} ${iSize}`);
             try{
               file.sah.truncate(HEADER_OFFSET_DATA + Number(sz64));
@@ -844,13 +859,13 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
           },
           xUnlock: function(pFile,lockType){
             log('xUnlock');
-            const file = thePool.mapIdToFile.get(pFile);
+            const file = thePool.getFileForPtr(pFile);
             file.lockType = lockType;
             return 0;
           },
           xWrite: function(pFile,pSrc,n,offset64){
             thePool.storeErr();
-            const file = thePool.mapIdToFile.get(pFile);
+            const file = thePool.getFileForPtr(pFile);
             log(`xWrite ${file.path} ${n} ${offset64}`);
             try{
               const nBytes = file.sah.write(
@@ -870,13 +885,14 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
         */
         const vfsMethods = {
           xAccess: function(pVfs,zName,flags,pOut){
-            log(`xAccess ${wasm.cstrToJs(zName)}`);
+            //log(`xAccess ${wasm.cstrToJs(zName)}`);
             thePool.storeErr();
             try{
-              const name = this.getPath(zName);
-              wasm.poke32(pOut, thePool.mapFilenameToSAH.has(name) ? 1 : 0);
+              const name = thePool.getPath(zName);
+              wasm.poke32(pOut, thePool.hasFilename(name) ? 1 : 0);
             }catch(e){
-              /*ignored*/;
+              /*ignored*/
+              wasm.poke32(pOut, 0);
             }
             return 0;
           },
@@ -931,7 +947,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
               const path = (zName && wasm.peek8(zName))
                     ? thePool.getPath(zName)
                     : getRandomName();
-              let sah = thePool.mapFilenameToSAH.get(path);
+              let sah = thePool.getSAHForPath(path);
               if(!sah && (flags & capi.SQLITE_OPEN_CREATE)) {
                 // File not found so try to create it.
                 if(thePool.getFileCount() < thePool.getCapacity()) {
@@ -949,7 +965,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
               // Subsequent methods are only passed the file pointer, so
               // map the relevant info we need to that pointer.
               const file = {path, flags, sah};
-              thePool.mapIdToFile.set(pFile, file);
+              thePool.setFileForPtr(pFile, file);
               wasm.poke32(pOutFlags, flags);
               file.sq3File = new capi.sqlite3_file(pFile);
               file.sq3File.$pMethods = opfsIoMethods.pointer;
@@ -1020,6 +1036,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
         log("VFS initialized.");
         return poolUtil;
       });
-    }).catch(promiseReject);
+    }).catch((err)=>{
+      error("rejecting promise:",err);
+      opfsVfs.dispose();
+      return initPromises[vfsName] = Promise.reject(err);
+    });
   }/*installOpfsSAHPoolVfs()*/;
 }/*sqlite3ApiBootstrap.initializers*/);
index 27a8118e8d85c14cf9967a18bd1078996db02e1a..d1fbbb87df7bfc87cc0ac0d7548bb4804ab243f6 100644 (file)
@@ -2634,199 +2634,6 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
    }/*kvvfs sqlite3_js_vfs_create_file()*/)
   ;/* end kvvfs tests */
 
-  ////////////////////////////////////////////////////////////////////////
-  T.g('OPFS: Origin-Private File System',
-      (sqlite3)=>(sqlite3.capi.sqlite3_vfs_find("opfs")
-                  || 'requires "opfs" VFS'))
-    .t({
-      name: 'OPFS db sanity checks',
-      test: async function(sqlite3){
-        const filename = this.opfsDbFile = 'sqlite3-tester1.db';
-        const pVfs = this.opfsVfs = capi.sqlite3_vfs_find('opfs');
-        T.assert(pVfs);
-        const unlink = this.opfsUnlink =
-              (fn=filename)=>{wasm.sqlite3_wasm_vfs_unlink(pVfs,fn)};
-        unlink();
-        let db = new sqlite3.oo1.OpfsDb(filename);
-        try {
-          db.exec([
-            'create table p(a);',
-            'insert into p(a) values(1),(2),(3)'
-          ]);
-          T.assert(3 === db.selectValue('select count(*) from p'));
-          db.close();
-          db = new sqlite3.oo1.OpfsDb(filename);
-          db.exec('insert into p(a) values(4),(5),(6)');
-          T.assert(6 === db.selectValue('select count(*) from p'));
-          this.opfsDbExport = capi.sqlite3_js_db_export(db);
-          T.assert(this.opfsDbExport instanceof Uint8Array)
-            .assert(this.opfsDbExport.byteLength>0
-                    && 0===this.opfsDbExport.byteLength % 512);
-        }finally{
-          db.close();
-          unlink();
-        }
-      }
-    }/*OPFS db sanity checks*/)
-    .t({
-      name: 'OPFS export/import',
-      test: async function(sqlite3){
-        let db;
-        try {
-          const exp = this.opfsDbExport;
-          delete this.opfsDbExport;
-          capi.sqlite3_js_vfs_create_file("opfs", this.opfsDbFile, exp);
-          const db = new sqlite3.oo1.OpfsDb(this.opfsDbFile);
-          T.assert(6 === db.selectValue('select count(*) from p'));
-        }finally{
-          if(db) db.close();
-        }
-      }
-    }/*OPFS export/import*/)
-    .t({
-      name: 'OPFS utility APIs and sqlite3_js_vfs_create_file()',
-      test: async function(sqlite3){
-        const filename = this.opfsDbFile;
-        const pVfs = this.opfsVfs;
-        const unlink = this.opfsUnlink;
-        T.assert(filename && pVfs && !!unlink);
-        delete this.opfsDbFile;
-        delete this.opfsVfs;
-        delete this.opfsUnlink;
-        unlink();
-        // Sanity-test sqlite3_js_vfs_create_file()...
-        /**************************************************************
-           ATTENTION CLIENT-SIDE USERS: sqlite3.opfs is NOT intended
-           for client-side use. It is only for this project's own
-           internal use. Its APIs are subject to change or removal at
-           any time.
-        ***************************************************************/
-        const opfs = sqlite3.opfs;
-        const fSize = 1379;
-        let sh;
-        try{
-          T.assert(!(await opfs.entryExists(filename)));
-          capi.sqlite3_js_vfs_create_file(
-            pVfs, filename, null, fSize
-          );
-          T.assert(await opfs.entryExists(filename));
-          let fh = await opfs.rootDirectory.getFileHandle(filename);
-          sh = await fh.createSyncAccessHandle();
-          T.assert(fSize === await sh.getSize());
-          await sh.close();
-          sh = undefined;
-          unlink();
-          T.assert(!(await opfs.entryExists(filename)));
-
-          const ba = new Uint8Array([1,2,3,4,5]);
-          capi.sqlite3_js_vfs_create_file(
-            "opfs", filename, ba
-          );
-          T.assert(await opfs.entryExists(filename));
-          fh = await opfs.rootDirectory.getFileHandle(filename);
-          sh = await fh.createSyncAccessHandle();
-          T.assert(ba.byteLength === await sh.getSize());
-          await sh.close();
-          sh = undefined;
-          unlink();
-
-          T.mustThrowMatching(()=>{
-            capi.sqlite3_js_vfs_create_file(
-              "no-such-vfs", filename, ba
-            );
-          }, "SQLITE_NOTFOUND: Unknown sqlite3_vfs name: no-such-vfs");
-        }finally{
-          if(sh) await sh.close();
-          unlink();
-        }
-
-        // Some sanity checks of the opfs utility functions...
-        const testDir = '/sqlite3-opfs-'+opfs.randomFilename(12);
-        const aDir = testDir+'/test/dir';
-        T.assert(await opfs.mkdir(aDir), "mkdir failed")
-          .assert(await opfs.mkdir(aDir), "mkdir must pass if the dir exists")
-          .assert(!(await opfs.unlink(testDir+'/test')), "delete 1 should have failed (dir not empty)")
-          .assert((await opfs.unlink(testDir+'/test/dir')), "delete 2 failed")
-          .assert(!(await opfs.unlink(testDir+'/test/dir')),
-                  "delete 2b should have failed (dir already deleted)")
-          .assert((await opfs.unlink(testDir, true)), "delete 3 failed")
-          .assert(!(await opfs.entryExists(testDir)),
-                  "entryExists(",testDir,") should have failed");
-      }
-    }/*OPFS util sanity checks*/)
-  ;/* end OPFS tests */
-
-  ////////////////////////////////////////////////////////////////////////
-  T.g('OPFS SyncAccessHandle Pool VFS',
-      (sqlite3)=>(hasOpfs() || "requires OPFS APIs"))
-    .t({
-      name: 'SAH sanity checks',
-      test: async function(sqlite3){
-        T.assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name))
-          .assert(sqlite3.capi.sqlite3_js_vfs_list().indexOf(sahPoolConfig.name) < 0)
-        const inst = sqlite3.installOpfsSAHPoolVfs,
-              catcher = (e)=>{
-                error("Cannot load SAH pool VFS.",
-                      "This might not be a problem,",
-                      "depending on the environment.");
-                return false;
-              };
-        let u1, u2;
-        const P1 = inst(sahPoolConfig).then(u=>u1 = u).catch(catcher),
-              P2 = inst(sahPoolConfig).then(u=>u2 = u).catch(catcher);
-        await Promise.all([P1, P2]);
-        if(!P1) return;
-        T.assert(u1 === u2)
-          .assert(sahPoolConfig.name === u1.vfsName)
-          .assert(sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name))
-          .assert(u1.getCapacity() >= sahPoolConfig.initialCapacity
-                  /* If a test fails before we get to nuke the VFS, we
-                     can have more than the initial capacity on the next
-                     run. */)
-          .assert(u1.getCapacity() + 2 === (await u2.addCapacity(2)))
-          .assert(2 === (await u2.reduceCapacity(2)))
-          .assert(sqlite3.oo1.OpfsSAHPool.default instanceof Function)
-          .assert(sqlite3.oo1.OpfsSAHPool.default ===
-                  sqlite3.oo1.OpfsSAHPool[sahPoolConfig.name])
-          .assert(sqlite3.capi.sqlite3_js_vfs_list().indexOf(sahPoolConfig.name) >= 0);
-
-        T.assert(0 === u1.getFileCount());
-        const DbCtor = sqlite3.oo1.OpfsSAHPool.default;
-        const dbName = '/foo.db';
-        let db = new DbCtor(dbName);
-        T.assert(1 === u1.getFileCount());
-        db.exec([
-          'create table t(a);',
-          'insert into t(a) values(1),(2),(3)'
-        ]);
-        T.assert(1 === u1.getFileCount());
-        T.assert(3 === db.selectValue('select count(*) from t'));
-        db.close();
-        T.assert(1 === u1.getFileCount());
-        db = new DbCtor(dbName);
-        T.assert(1 === u1.getFileCount());
-        db.close();
-        T.assert(1 === u1.getFileCount())
-          .assert(true === u1.unlink(dbName))
-          .assert(false === u1.unlink(dbName))
-          .assert(0 === u1.getFileCount());
-
-        T.assert(true === await u2.removeVfs())
-          .assert(false === await u1.removeVfs())
-          .assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name));
-
-        let cErr, u3;
-        const conf2 = JSON.parse(JSON.stringify(sahPoolConfig));
-        conf2.$testThrowInInit = new Error("Testing throwing during init.");
-        conf2.name = sahPoolConfig.name+'-err';
-        const P3 = await inst(conf2).then(u=>u3 = u).catch((e)=>cErr=e);
-        T.assert(P3 === conf2.$testThrowInInit)
-          .assert(cErr === P3)
-          .assert(undefined === u3)
-          .assert(!sqlite3.capi.sqlite3_vfs_find(conf2.name));
-      }
-    }/*OPFS SAH Pool sanity checks*/)
-
   ////////////////////////////////////////////////////////////////////////
   T.g('Hook APIs')
     .t({
@@ -3096,6 +2903,200 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
       }
     })/*session API sanity tests*/
   ;/*end of session API group*/;
+
+  ////////////////////////////////////////////////////////////////////////
+  T.g('OPFS: Origin-Private File System',
+      (sqlite3)=>(sqlite3.capi.sqlite3_vfs_find("opfs")
+                  || 'requires "opfs" VFS'))
+    .t({
+      name: 'OPFS db sanity checks',
+      test: async function(sqlite3){
+        const filename = this.opfsDbFile = 'sqlite3-tester1.db';
+        const pVfs = this.opfsVfs = capi.sqlite3_vfs_find('opfs');
+        T.assert(pVfs);
+        const unlink = this.opfsUnlink =
+              (fn=filename)=>{wasm.sqlite3_wasm_vfs_unlink(pVfs,fn)};
+        unlink();
+        let db = new sqlite3.oo1.OpfsDb(filename);
+        try {
+          db.exec([
+            'create table p(a);',
+            'insert into p(a) values(1),(2),(3)'
+          ]);
+          T.assert(3 === db.selectValue('select count(*) from p'));
+          db.close();
+          db = new sqlite3.oo1.OpfsDb(filename);
+          db.exec('insert into p(a) values(4),(5),(6)');
+          T.assert(6 === db.selectValue('select count(*) from p'));
+          this.opfsDbExport = capi.sqlite3_js_db_export(db);
+          T.assert(this.opfsDbExport instanceof Uint8Array)
+            .assert(this.opfsDbExport.byteLength>0
+                    && 0===this.opfsDbExport.byteLength % 512);
+        }finally{
+          db.close();
+          unlink();
+        }
+      }
+    }/*OPFS db sanity checks*/)
+    .t({
+      name: 'OPFS export/import',
+      test: async function(sqlite3){
+        let db;
+        try {
+          const exp = this.opfsDbExport;
+          delete this.opfsDbExport;
+          capi.sqlite3_js_vfs_create_file("opfs", this.opfsDbFile, exp);
+          const db = new sqlite3.oo1.OpfsDb(this.opfsDbFile);
+          T.assert(6 === db.selectValue('select count(*) from p'));
+        }finally{
+          if(db) db.close();
+        }
+      }
+    }/*OPFS export/import*/)
+    .t({
+      name: 'OPFS utility APIs and sqlite3_js_vfs_create_file()',
+      test: async function(sqlite3){
+        const filename = this.opfsDbFile;
+        const pVfs = this.opfsVfs;
+        const unlink = this.opfsUnlink;
+        T.assert(filename && pVfs && !!unlink);
+        delete this.opfsDbFile;
+        delete this.opfsVfs;
+        delete this.opfsUnlink;
+        unlink();
+        // Sanity-test sqlite3_js_vfs_create_file()...
+        /**************************************************************
+           ATTENTION CLIENT-SIDE USERS: sqlite3.opfs is NOT intended
+           for client-side use. It is only for this project's own
+           internal use. Its APIs are subject to change or removal at
+           any time.
+        ***************************************************************/
+        const opfs = sqlite3.opfs;
+        const fSize = 1379;
+        let sh;
+        try{
+          T.assert(!(await opfs.entryExists(filename)));
+          capi.sqlite3_js_vfs_create_file(
+            pVfs, filename, null, fSize
+          );
+          T.assert(await opfs.entryExists(filename));
+          let fh = await opfs.rootDirectory.getFileHandle(filename);
+          sh = await fh.createSyncAccessHandle();
+          T.assert(fSize === await sh.getSize());
+          await sh.close();
+          sh = undefined;
+          unlink();
+          T.assert(!(await opfs.entryExists(filename)));
+
+          const ba = new Uint8Array([1,2,3,4,5]);
+          capi.sqlite3_js_vfs_create_file(
+            "opfs", filename, ba
+          );
+          T.assert(await opfs.entryExists(filename));
+          fh = await opfs.rootDirectory.getFileHandle(filename);
+          sh = await fh.createSyncAccessHandle();
+          T.assert(ba.byteLength === await sh.getSize());
+          await sh.close();
+          sh = undefined;
+          unlink();
+
+          T.mustThrowMatching(()=>{
+            capi.sqlite3_js_vfs_create_file(
+              "no-such-vfs", filename, ba
+            );
+          }, "SQLITE_NOTFOUND: Unknown sqlite3_vfs name: no-such-vfs");
+        }finally{
+          if(sh) await sh.close();
+          unlink();
+        }
+
+        // Some sanity checks of the opfs utility functions...
+        const testDir = '/sqlite3-opfs-'+opfs.randomFilename(12);
+        const aDir = testDir+'/test/dir';
+        T.assert(await opfs.mkdir(aDir), "mkdir failed")
+          .assert(await opfs.mkdir(aDir), "mkdir must pass if the dir exists")
+          .assert(!(await opfs.unlink(testDir+'/test')), "delete 1 should have failed (dir not empty)")
+          .assert((await opfs.unlink(testDir+'/test/dir')), "delete 2 failed")
+          .assert(!(await opfs.unlink(testDir+'/test/dir')),
+                  "delete 2b should have failed (dir already deleted)")
+          .assert((await opfs.unlink(testDir, true)), "delete 3 failed")
+          .assert(!(await opfs.entryExists(testDir)),
+                  "entryExists(",testDir,") should have failed");
+      }
+    }/*OPFS util sanity checks*/)
+  ;/* end OPFS tests */
+
+  ////////////////////////////////////////////////////////////////////////
+  T.g('OPFS SyncAccessHandle Pool VFS',
+      (sqlite3)=>(hasOpfs() || "requires OPFS APIs"))
+    .t({
+      name: 'SAH sanity checks',
+      test: async function(sqlite3){
+        T.assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name))
+          .assert(sqlite3.capi.sqlite3_js_vfs_list().indexOf(sahPoolConfig.name) < 0)
+        const inst = sqlite3.installOpfsSAHPoolVfs,
+              catcher = (e)=>{
+                error("Cannot load SAH pool VFS.",
+                      "This might not be a problem,",
+                      "depending on the environment.");
+                return false;
+              };
+        let u1, u2;
+        const P1 = inst(sahPoolConfig).then(u=>u1 = u).catch(catcher),
+              P2 = inst(sahPoolConfig).then(u=>u2 = u).catch(catcher);
+        await Promise.all([P1, P2]);
+        if(!P1) return;
+        T.assert(u1 === u2)
+          .assert(sahPoolConfig.name === u1.vfsName)
+          .assert(sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name))
+          .assert(u1.getCapacity() >= sahPoolConfig.initialCapacity
+                  /* If a test fails before we get to nuke the VFS, we
+                     can have more than the initial capacity on the next
+                     run. */)
+          .assert(u1.getCapacity() + 2 === (await u2.addCapacity(2)))
+          .assert(2 === (await u2.reduceCapacity(2)))
+          .assert(sqlite3.oo1.OpfsSAHPool.default instanceof Function)
+          .assert(sqlite3.oo1.OpfsSAHPool.default ===
+                  sqlite3.oo1.OpfsSAHPool[sahPoolConfig.name])
+          .assert(sqlite3.capi.sqlite3_js_vfs_list().indexOf(sahPoolConfig.name) >= 0);
+
+        T.assert(0 === u1.getFileCount());
+        const DbCtor = sqlite3.oo1.OpfsSAHPool.default;
+        const dbName = '/foo.db';
+        let db = new DbCtor(dbName);
+        T.assert(1 === u1.getFileCount());
+        db.exec([
+          'create table t(a);',
+          'insert into t(a) values(1),(2),(3)'
+        ]);
+        T.assert(1 === u1.getFileCount());
+        T.assert(3 === db.selectValue('select count(*) from t'));
+        db.close();
+        T.assert(1 === u1.getFileCount());
+        db = new DbCtor(dbName);
+        T.assert(1 === u1.getFileCount());
+        db.close();
+        T.assert(1 === u1.getFileCount())
+          .assert(true === u1.unlink(dbName))
+          .assert(false === u1.unlink(dbName))
+          .assert(0 === u1.getFileCount());
+
+        T.assert(true === await u2.removeVfs())
+          .assert(false === await u1.removeVfs())
+          .assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name));
+
+        let cErr, u3;
+        const conf2 = JSON.parse(JSON.stringify(sahPoolConfig));
+        conf2.$testThrowInInit = new Error("Testing throwing during init.");
+        conf2.name = sahPoolConfig.name+'-err';
+        const P3 = await inst(conf2).then(u=>u3 = u).catch((e)=>cErr=e);
+        T.assert(P3 === conf2.$testThrowInInit)
+          .assert(cErr === P3)
+          .assert(undefined === u3)
+          .assert(!sqlite3.capi.sqlite3_vfs_find(conf2.name));
+      }
+    }/*OPFS SAH Pool sanity checks*/)
+
   ////////////////////////////////////////////////////////////////////////
   T.g('Bug Reports')
     .t({
index e7ddd646d85f00e40b7c26a8d90075c8afa5c0b4..a54d71323c43fd9c25dff97005561c99ba299827 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C More\sopfs-sahpool\stests.
-D 2023-07-18T19:47:19.982
+C Internal\srefactoring\sin\sopfs-sahpool.\sMove\sOPFS\stests\sto\sthe\send\sof\stester1.c-cpp.js.
+D 2023-07-19T08:18:25.901
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -501,8 +501,8 @@ F ext/wasm/api/sqlite3-api-prologue.js d747cbb379e13881c9edf39dce019cbbbae860c45
 F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec
 F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
 F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379
-F ext/wasm/api/sqlite3-v-helper.js fc9ed95433d943a65905d16b7ed51515ddb6667d2a2c5a711c7ce33b29d3be31
-F ext/wasm/api/sqlite3-vfs-opfs-sahpool.js a33b88beb55e0e19a8f9c3d37620e9aa58a0a32cacf7c398195d3d045d414815
+F ext/wasm/api/sqlite3-v-helper.js e4b7b27a8259e40407b3c16e42dd5df05b80726c609594cc23b1565dc2ad9ca2
+F ext/wasm/api/sqlite3-vfs-opfs-sahpool.js 9a8ba44b775b0e8faaffc8d877cfef0726713c2ca368e5776b59d9029f5ebf23
 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 4946af0d6fbd395aa39966562ca85900664605a5f0cc10fff50146dee527812c
 F ext/wasm/api/sqlite3-wasm.c 8867f1d41c112fb4a2cfe22ff224eccaf309fcdea266cee0ec554f85db72ef0f
 F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f
@@ -549,7 +549,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b
 F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
 F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
-F ext/wasm/tester1.c-pp.js f625ce01681956cfd895a834d8aeb68d59595200441628ac2e41adf48788d8c9
+F ext/wasm/tester1.c-pp.js a72fc43950ce26c1ad7cee47aa225dd18efdb92743cf616b2e114b4cd1cdf2dd
 F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1
 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d
 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
@@ -2044,8 +2044,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 9c8a73aff0f291e0c18072372e0d8961d3a05910489598d0d342227d99871954
-R 17462841136511130de69ca7a00ea9cc
+P 60713fa9c4627ef17e0b8778eee37913d2b930c5a06414721a00af30e1395090
+R b81da7c28422da4e0ac61aef8c2566f8
 U stephan
-Z c3c355ff206bb421832084a0cbc9cd73
+Z 2d92190e2a732ef23d4b23ca479d2da6
 # Remove this line to create a well-formed Fossil manifest.
index a80d58ffe9ec243b78c15e777cdbdcacc9966ab9..9aaea635b74583fd1c662fb2f756a866211d3bac 100644 (file)
@@ -1 +1 @@
-60713fa9c4627ef17e0b8778eee37913d2b930c5a06414721a00af30e1395090
\ No newline at end of file
+6bd5a7413dd830ca41b587a2826fb599a2196fb0186646a2333500f950b3cf4d
\ No newline at end of file