From 640af757230eadad60d7b9c4677353caed8057fe Mon Sep 17 00:00:00 2001 From: James Long Date: Mon, 23 Aug 2021 23:28:55 -0400 Subject: [PATCH] Only close file if all open handles are closed --- README.md | 2 +- package.json | 2 +- src/sqlite-file.js | 36 ++++++++++++++++++++++++------------ 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 636ed40..0462cd6 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ It implements a backend for [sql.js](https://github.com/sql-js/sql.js/) (sqlite3 It basically stores a whole database into another database. Which is absurd. -[See the demo](https://priceless-keller-d097e5.netlify.app/). You can also view an entire app using this [here](https://app-next.actualbudget.com/). +[See the demo](https://priceless-keller-d097e5.netlify.app/). You can also view an entire app using this [here](https://app-next.actualbudget.com/?wtf_source=absurd). You should also read [this blog post](https://jlongster.com/future-sql-web) which explains the project in great detail. diff --git a/package.json b/package.json index ffe086d..f9ad4b9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "absurd-sql", - "version": "0.0.52", + "version": "0.0.53", "main": "./dist/index.js", "scripts": { "build": "rm -rf dist && rollup -c rollup.config.js", diff --git a/src/sqlite-file.js b/src/sqlite-file.js index 74337e1..3504e8b 100644 --- a/src/sqlite-file.js +++ b/src/sqlite-file.js @@ -110,6 +110,7 @@ export class File { this.meta = meta; this._metaDirty = false; this.writeLock = false; + this.openHandles = 0; } bufferChunks(chunks) { @@ -120,27 +121,38 @@ export class File { } open() { - this.ops.open(); - let meta = this.ops.readMeta(); + this.openHandles++; - // It's possible that `setattr` has already been called if opening - // the file in a mode that truncates it to 0 - if (this.meta == null) { - if (meta == null) { - // New file + // Don't open the file again if it's already open + if (this.openHandles === 1) { + this.ops.open(); + let meta = this.ops.readMeta(); - meta = { size: 0 }; - } + // It's possible that `setattr` has already been called if opening + // the file in a mode that truncates it to 0 + if (this.meta == null) { + if (meta == null) { + // New file - this.meta = meta; + meta = { size: 0 }; + } + + this.meta = meta; + } } - return meta; + return this.meta; } close() { this.fsync(); - this.ops.close(); + + this.openHandles = Math.max(this.openHandles - 1, 0); + + // Only close it if there are no existing open handles + if (this.openHandles === 0) { + this.ops.close(); + } } delete() {