]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add a way to remove the opfs-sahpool's persistent state from OPFS or unlink() an...
authorstephan <stephan@noemail.net>
Sun, 16 Jul 2023 17:51:43 +0000 (17:51 +0000)
committerstephan <stephan@noemail.net>
Sun, 16 Jul 2023 17:51:43 +0000 (17:51 +0000)
FossilOrigin-Name: 80982daac3c098033dbc249bb7a17ef84ae218d2d789f8644e7f4af18b553d24

ext/wasm/api/sqlite3-vfs-opfs-sahpool.js
manifest
manifest.uuid

index a19589aac94eba0dd44b4b5bccd49bdc178d1046..d7c5b198e0569fbc1aef91737d096e5e4afbdff8 100644 (file)
@@ -101,7 +101,7 @@ let isPromiseReady;
      does not have any effect if a pool already exists.
 
    - `directory`: Specifies the OPFS directory name in which to store
-     metadata for the `"opfs-sahpool"` sqlite3_vfs.  Only 1 instance
+     metadata for the `"opfs-sahpool"` sqlite3_vfs.  Only one instance
      of this VFS can be installed per JavaScript engine, and any two
      engines with the same storage directory name will collide with
      each other, leading to locking errors and the inability to
@@ -113,13 +113,16 @@ let isPromiseReady;
      unspecified but descriptive.  This option may contain multiple
      path elements, e.g. "foo/bar/baz", and they are created
      automatically.  In practice there should be no driving need to
-     change this.
+     change this. ACHTUNG: all files in this directory are assumed to
+     be managed by the VFS. Do not place other files in that
+     directory, as they may be deleted or otherwise modified by the
+     VFS.
 
 
-   API for the utility object passed on by this function's Promise, in
-   alphabetical order...
+   The API for the utility object passed on by this function's
+   Promise, in alphabetical order...
 
-- [async] addCapacity(n)
+- [async] number addCapacity(n)
 
   Adds `n` entries to the current pool. This change is persistent
   across sessions so should not be called automatically at each app
@@ -144,7 +147,7 @@ let isPromiseReady;
 
   Returns the number of files from the pool currently in use.
 
-- importDb(name, byteArray)
+- void importDb(name, byteArray)
 
   Imports the contents of an SQLite database, provided as a byte
   array, under the given name, overwriting any existing
@@ -161,6 +164,25 @@ let isPromiseReady;
   only remove currently-unused entries. It returns a Promise which
   resolves to the number of entries actually removed.
 
+- [async] boolean removeVfs()
+
+  Unregisters the opfs-sahpool VFS and removes its directory
+  from OPFS. After calling this, the VFS may no longer be used
+  and there is no way to re-add it aside from reloading the
+  current JavaScript context.
+
+  Results are undefined if a database is currently in use with this
+  VFS.
+
+  The returned Promise resolves to true if it performed the removal
+  and false if the VFS was not installed.
+
+  If the VFS has a multi-level directory, e.g. "/foo/bar/baz", _only_
+  the bottom-most level is removed because this VFS cannot know for
+  certain whether the higher-level directories contain data which
+  should be removed.
+
+
 - [async] number reserveMinimumCapacity(min)
 
   If the current capacity is less than `min`, the capacity is
@@ -174,7 +196,7 @@ let isPromiseReady;
   effects. Results are undefined if the file is currently in active
   use.
 
-- [async] wipeFiles()
+- [async] void wipeFiles()
 
   Clears all client-defined state of all SAHs and makes all of them
   available for re-use by the pool. Results are undefined if any such
@@ -271,6 +293,9 @@ sqlite3.installOpfsSAHPoolVfs = async function(options=Object.create(null)){
     vfsDir: options.directory || ".sqlite3-opfs-sahpool",
     /* Directory handle to this.vfsDir. */
     dirHandle: undefined,
+    /* Directory handle to this.dirHandle's parent dir. Needed
+       for a VFS-wipe op. */
+    parentDirHandle: undefined,
     /* Maps SAHs to their opaque file names. */
     mapSAHToName: new Map(),
     /* Maps client-side file names to SAHs. */
@@ -465,12 +490,15 @@ sqlite3.installOpfsSAHPoolVfs = async function(options=Object.create(null)){
     reset: async function(clearFiles){
       await isPromiseReady;
       let h = await navigator.storage.getDirectory();
+      let prev, prevName;
       for(const d of this.vfsDir.split('/')){
         if(d){
+          prev = h;
           h = await h.getDirectoryHandle(d,{create:true});
         }
       }
       this.dirHandle = h;
+      this.parentDirHandle = prev;
       this.releaseAccessHandles();
       await this.acquireAccessHandles(clearFiles);
     },
@@ -801,17 +829,11 @@ sqlite3.installOpfsSAHPoolVfs = async function(options=Object.create(null)){
   PoolUtil.reduceCapacity = async (n)=>SAHPool.reduceCapacity(n);
   PoolUtil.getCapacity = SAHPool.getCapacity.bind(SAHPool);
   PoolUtil.getActiveFileCount = SAHPool.getFileCount.bind(SAHPool);
-  /** If capacity is < min, increase capacity to min, else do
-      nothing. Resolves to the new capacity. */
   PoolUtil.reserveMinimumCapacity = async (min)=>{
     const c = SAHPool.getCapacity();
     return (c < min) ? SAHPool.addCapacity(min - c) : c;
   };
-  /**
-     Synchronously reads the contents of the given file into a
-     Uint8Array and returns it. This will throw if the given name is
-     not currently in active use or on I/O error.
-  */
+
   PoolUtil.exportFile = function(name){
     const sah = SAHPool.mapFilenameToSAH.get(name) || toss("File not found:",name);
     const n = sah.getSize() - HEADER_OFFSET_DATA;
@@ -820,21 +842,6 @@ sqlite3.installOpfsSAHPoolVfs = async function(options=Object.create(null)){
     return b;
   };
 
-  /**
-     The counterpart of exportFile(), this imports the contents of an
-     SQLite database, provided as a byte array, under the given name,
-     overwriting any existing content. Throws if the pool has no
-     available file slots, on I/O error, or if the input does not
-     appear to be a database. In the latter case, only a cursory
-     examination is made.
-
-     Note that this routine is _only_ for importing database files,
-     not arbitrary files, the reason being that this VFS will
-     automatically clean up any non-database files so importing them
-     is pointless.
-
-     Returns undefined.
-  */
   PoolUtil.importDb = function(name, bytes){
     const n = bytes.byteLength;
     if(n<512 || n%512!=0){
@@ -852,25 +859,28 @@ sqlite3.installOpfsSAHPoolVfs = async function(options=Object.create(null)){
     sah.write(bytes, {at: HEADER_OFFSET_DATA});
     SAHPool.setAssociatedPath(sah, name, capi.SQLITE_OPEN_MAIN_DB);
   };
-  /**
-     Clears all client-defined state of all SAHs and makes all of them
-     available for re-use by the pool. Results are undefined if any
-     such handles are currently in use, e.g. by an sqlite3 db.
-  */
-  PoolUtil.wipeFiles = async ()=>SAHPool.reset(true);
 
-  /**
-     If a virtual file exists with the given name, disassociates it
-     from the pool and returns true, else returns false without side
-     effects.
-  */
+  PoolUtil.wipeFiles = async ()=>SAHPool.reset(true);
   PoolUtil.unlink = (filename)=>SAHPool.deletePath(filename);
 
-  /**
-     PoolUtil TODOs:
-
-     - function to wipe out all traces of the VFS from storage.
-   */
+  PoolUtil.removeVfs = async function(){
+    if(!opfsVfs.pointer) return false;
+    capi.sqlite3_vfs_unregister(opfsVfs.pointer);
+    opfsVfs.dispose();
+    try{
+      SAHPool.releaseAccessHandles();
+      if(SAHPool.parentDirHandle){
+        await SAHPool.parentDirHandle.removeEntry(
+          SAHPool.dirHandle.name, {recursive: true}
+        );
+        SAHPool.dirHandle = SAHPool.parentDirHandle = undefined;
+      }
+    }catch(e){
+      warn("removeVfs() failed:",e);
+      /*but otherwise ignored*/
+    }
+    return true;
+  };
 
   return isPromiseReady = SAHPool.reset(!!options.clearOnInit).then(async ()=>{
     if(SAHPool.$error){
index 1e2c3ff6712b22612aefacd3fdaafd7c0e785239..c9f239f8bbad8a2bddaf8d8269a6fb974556f264 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Move\sSAH\spool\sconfiguration\soptions\sfrom\sthe\slibrary-level\sconfig\sto\sa\sconfig\spassed\sto\sthe\sVFS\sinstall\sroutine.\sExtend\sand\sdocument\sthe\sPoolUtil\sobject.
-D 2023-07-16T16:52:09.106
+C Add\sa\sway\sto\sremove\sthe\sopfs-sahpool's\spersistent\sstate\sfrom\sOPFS\sor\sunlink()\san\sindividual\sfile.\sDoc\scleanups.
+D 2023-07-16T17:51:43.068
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -502,7 +502,7 @@ F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b17386
 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 e5c202a9ecde9ef818536d3f5faf26c03a1a9f5192b1ddea8bdabf30d75ef487
-F ext/wasm/api/sqlite3-vfs-opfs-sahpool.js c19ccfc2995c0dcae00f13fe1be6fa436a39a3d629b6bf4208965ea78a50cab3
+F ext/wasm/api/sqlite3-vfs-opfs-sahpool.js fa2f08cb8a2f6ed4e87241872a005d68376330f688560cf214fb46d4bb8d4e77
 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 842d55b35a871ee5483cc5e0cf067a968362b4d61321f08c71aab5505c72f556
 F ext/wasm/api/sqlite3-wasm.c 12a096d8e58a0af0589142bae5a3c27a0c7e19846755a1a37d2c206352fbedda
 F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f
@@ -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 aa94c8abfbdfc4c7b36554c4b3ea90a5065e7e3f4294c64c8cbf688b4688300d
-R 76883f55e00ff0c4af4f43f15f164d03
+P d2ed99556fa1f40994c1c6bd90d1d5733bebc824b1ebfabe978fae9e18948437
+R 8239157f9b8eb58dfb7c9f17d6e6ac86
 U stephan
-Z fd9b47fd6c1916432a0f6dc613a90b88
+Z e36f1591c077277bbe10a5f210ace350
 # Remove this line to create a well-formed Fossil manifest.
index 9dc2139fb90b0195a00152c2f1a8cb425a8327a8..25f5cba9c5e77303fa58a5aa31d9e7056a47ac14 100644 (file)
@@ -1 +1 @@
-d2ed99556fa1f40994c1c6bd90d1d5733bebc824b1ebfabe978fae9e18948437
\ No newline at end of file
+80982daac3c098033dbc249bb7a17ef84ae218d2d789f8644e7f4af18b553d24
\ No newline at end of file