From 8a5b24752048838c090dd84f7c89d2184c7e9590 Mon Sep 17 00:00:00 2001 From: Etienne Noel Date: Fri, 23 Jun 2023 13:41:25 -0700 Subject: [PATCH 1/3] Added comlink and a sqlite client that encapsulates the communication with the worker. --- demo/index.html | 3 ++ demo/sqlite.client.js | 26 +++++++++++++++++ package.json | 3 +- src/sqlite.client.mjs | 67 +++++++++++++++++++++++++++++++++++++++++++ src/sqlite.worker.mjs | 39 +++++++++++++++++++++++++ 5 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 demo/sqlite.client.js create mode 100644 src/sqlite.client.mjs create mode 100644 src/sqlite.worker.mjs diff --git a/demo/index.html b/demo/index.html index 814a7ce..c164185 100644 --- a/demo/index.html +++ b/demo/index.html @@ -5,6 +5,7 @@ SQLite Wasm Demo +

SQLite Wasm Demo

@@ -12,5 +13,7 @@

Main thread

Worker

+

Built-in Sqlite Client

+
diff --git a/demo/sqlite.client.js b/demo/sqlite.client.js new file mode 100644 index 0000000..2da35a5 --- /dev/null +++ b/demo/sqlite.client.js @@ -0,0 +1,26 @@ +import SqliteClient from '/src/sqlite.client.mjs'; + +const sqliteClient = new SqliteClient('/db.sqlite3', '/src/sqlite.worker.mjs'); + +await sqliteClient.init(); + +await sqliteClient.executeSql('CREATE TABLE IF NOT EXISTS t(a,b)'); + +for (let i = 20; i <= 25; ++i) { + await sqliteClient.executeSql('INSERT INTO t(a,b) VALUES (?,?)', [i, i * 2]); +} + +const rows = await sqliteClient.executeSql('SELECT a FROM t ORDER BY a LIMIT 3'); + +console.log(rows); + +document.getElementById('sqlite-client').innerHTML = + '' + + '' + + '' + + '' + + '' + + '' + + '' + + rows.map((row) => '').concat(); +'' + '
a
' + row[0] + '
'; diff --git a/package.json b/package.json index 937c6a0..8a49bc9 100644 --- a/package.json +++ b/package.json @@ -58,5 +58,6 @@ "prettier": "^2.8.8", "publint": "^0.1.12", "shx": "^0.3.4" - } + }, + "dependencies": {} } diff --git a/src/sqlite.client.mjs b/src/sqlite.client.mjs new file mode 100644 index 0000000..eabe87f --- /dev/null +++ b/src/sqlite.client.mjs @@ -0,0 +1,67 @@ +import * as Comlink from 'https://unpkg.com/comlink/dist/esm/comlink.mjs'; +const log = (...args) => console.log(...args); +const error = (...args) => console.error(...args); + +export default class SqliteClient { + sqliteWorker; + + dbFile = ''; + sqliteWorkerPath = ''; + + constructor(dbFile, sqliteWorkerPath) { + if (typeof dbFile !== 'string') { + return error( + "The 'dbFile' parameter passed to the SqliteClient constructor must be of type 'string'. Instead, you passed: '" + + typeof dbFile + + "'", + ); + } + + if (typeof sqliteWorkerPath !== 'string') { + return error( + "The 'sqliteWorkerPath' parameter passed to the SqliteClient constructor must be of type 'string'. Instead, you passed: '" + + typeof sqliteWorkerPath + + "'", + ); + } + + this.dbFile = dbFile; + this.sqliteWorkerPath = sqliteWorkerPath; + } + + async init() { + const SqliteWorker = Comlink.wrap( + new Worker(this.sqliteWorkerPath, { + type: 'module', + }), + ); + + this.sqliteWorker = await new SqliteWorker(); + + await this.sqliteWorker.init(this.dbFile); + } + + async executeSql(sqlStatement, bindParameters = []) { + if (typeof sqlStatement !== 'string') { + return error( + "The 'sqlStatement' parameter passed to the 'executeSql' method of the SqliteClient must be of type 'string'. Instead, you passed: '" + + typeof sqlStatement + + "'", + ); + } + + if (Array.isArray(bindParameters) === false) { + return error( + "The 'bindParameters' parameter passed to the 'executeSql' method of the SqliteClient must be of type 'array'. Instead, you passed: '" + + typeof bindParameters + + "'", + ); + } + + return new Promise(async resolve => { + await this.sqliteWorker.executeSql(sqlStatement, bindParameters, Comlink.proxy((rows) => { + return resolve(rows); + })); + }) + } +} diff --git a/src/sqlite.worker.mjs b/src/sqlite.worker.mjs new file mode 100644 index 0000000..504c615 --- /dev/null +++ b/src/sqlite.worker.mjs @@ -0,0 +1,39 @@ +import * as Comlink from "https://unpkg.com/comlink/dist/esm/comlink.mjs"; +import {default as sqlite3InitModule} from "../index.mjs" + +const log = (...args) => console.log(...args); +const error = (...args) => console.error(...args); + + + +class SqliteWorker { + db; + init(dbFile) { + return new Promise(resolve => { + sqlite3InitModule({ + print: log, + printErr: error, + }).then((sqlite3) => { + try { + this.db = new sqlite3.oo1.OpfsDb(dbFile); + } catch (err) { + error(err.name, err.message); + } + + return resolve(); + }); + }) + + } + + executeSql(sqlStatement, bindParameters, callback) { + return callback(this.db.exec({ + sql: sqlStatement, + bind: bindParameters, + returnValue: "resultRows", + rowMode: 'array', + })); + } +} + +Comlink.expose(SqliteWorker); \ No newline at end of file From e2a00a262ebaa295e2c738525b804ea6cbc50875 Mon Sep 17 00:00:00 2001 From: Etienne Noel Date: Mon, 26 Jun 2023 09:02:08 -0700 Subject: [PATCH 2/3] - Update after first round of comments. --- demo/index.html | 2 +- demo/{sqlite.client.js => sqlite-client.js} | 4 +- package-lock.json | 8 ++++ package.json | 4 +- src/{sqlite.client.mjs => sqlite-client.mjs} | 17 +++++---- src/sqlite-worker.mjs | 38 +++++++++++++++++++ src/sqlite.worker.mjs | 39 -------------------- 7 files changed, 63 insertions(+), 49 deletions(-) rename demo/{sqlite.client.js => sqlite-client.js} (87%) rename src/{sqlite.client.mjs => sqlite-client.mjs} (83%) create mode 100644 src/sqlite-worker.mjs delete mode 100644 src/sqlite.worker.mjs diff --git a/demo/index.html b/demo/index.html index c164185..ba86897 100644 --- a/demo/index.html +++ b/demo/index.html @@ -5,7 +5,7 @@ SQLite Wasm Demo - +

SQLite Wasm Demo

diff --git a/demo/sqlite.client.js b/demo/sqlite-client.js similarity index 87% rename from demo/sqlite.client.js rename to demo/sqlite-client.js index 2da35a5..5130ff7 100644 --- a/demo/sqlite.client.js +++ b/demo/sqlite-client.js @@ -10,7 +10,9 @@ for (let i = 20; i <= 25; ++i) { await sqliteClient.executeSql('INSERT INTO t(a,b) VALUES (?,?)', [i, i * 2]); } -const rows = await sqliteClient.executeSql('SELECT a FROM t ORDER BY a LIMIT 3'); +const rows = await sqliteClient.executeSql( + 'SELECT a FROM t ORDER BY a LIMIT 3', +); console.log(rows); diff --git a/package-lock.json b/package-lock.json index 9369f53..6720503 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "@sqlite.org/sqlite-wasm", "version": "3.42.0-build1", "license": "Apache-2.0", + "dependencies": { + "comlink": "^4.4.1" + }, "bin": { "sqlite-wasm": "bin/index.js" }, @@ -249,6 +252,11 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/comlink": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/comlink/-/comlink-4.4.1.tgz", + "integrity": "sha512-+1dlx0aY5Jo1vHy/tSsIGpSkN4tS9rZSW8FIhG0JH/crs9wwweswIo/POr451r7bZww3hFbPAKnTpimzL/mm4Q==" + }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", diff --git a/package.json b/package.json index 8a49bc9..eb54ea8 100644 --- a/package.json +++ b/package.json @@ -59,5 +59,7 @@ "publint": "^0.1.12", "shx": "^0.3.4" }, - "dependencies": {} + "dependencies": { + "comlink": "^4.4.1" + } } diff --git a/src/sqlite.client.mjs b/src/sqlite-client.mjs similarity index 83% rename from src/sqlite.client.mjs rename to src/sqlite-client.mjs index eabe87f..a30ad13 100644 --- a/src/sqlite.client.mjs +++ b/src/sqlite-client.mjs @@ -1,4 +1,3 @@ -import * as Comlink from 'https://unpkg.com/comlink/dist/esm/comlink.mjs'; const log = (...args) => console.log(...args); const error = (...args) => console.error(...args); @@ -50,7 +49,7 @@ export default class SqliteClient { ); } - if (Array.isArray(bindParameters) === false) { + if (!Array.isArray(bindParameters)) { return error( "The 'bindParameters' parameter passed to the 'executeSql' method of the SqliteClient must be of type 'array'. Instead, you passed: '" + typeof bindParameters + @@ -58,10 +57,14 @@ export default class SqliteClient { ); } - return new Promise(async resolve => { - await this.sqliteWorker.executeSql(sqlStatement, bindParameters, Comlink.proxy((rows) => { - return resolve(rows); - })); - }) + return new Promise(async (resolve) => { + await this.sqliteWorker.executeSql( + sqlStatement, + bindParameters, + Comlink.proxy((rows) => { + return resolve(rows); + }), + ); + }); } } diff --git a/src/sqlite-worker.mjs b/src/sqlite-worker.mjs new file mode 100644 index 0000000..62150a2 --- /dev/null +++ b/src/sqlite-worker.mjs @@ -0,0 +1,38 @@ +import * as Comlink from 'https://unpkg.com/comlink/dist/esm/comlink.mjs'; +import { default as sqlite3InitModule } from '../index.mjs'; + +const log = (...args) => console.log(...args); +const error = (...args) => console.error(...args); + +class SqliteWorker { + db; + init(dbFile) { + return new Promise((resolve) => { + sqlite3InitModule({ + print: log, + printErr: error, + }).then((sqlite3) => { + try { + this.db = new sqlite3.oo1.OpfsDb(dbFile); + } catch (err) { + error(err.name, err.message); + } + + return resolve(); + }); + }); + } + + executeSql(sqlStatement, bindParameters, callback) { + return callback( + this.db.exec({ + sql: sqlStatement, + bind: bindParameters, + returnValue: 'resultRows', + rowMode: 'array', + }), + ); + } +} + +Comlink.expose(SqliteWorker); diff --git a/src/sqlite.worker.mjs b/src/sqlite.worker.mjs deleted file mode 100644 index 504c615..0000000 --- a/src/sqlite.worker.mjs +++ /dev/null @@ -1,39 +0,0 @@ -import * as Comlink from "https://unpkg.com/comlink/dist/esm/comlink.mjs"; -import {default as sqlite3InitModule} from "../index.mjs" - -const log = (...args) => console.log(...args); -const error = (...args) => console.error(...args); - - - -class SqliteWorker { - db; - init(dbFile) { - return new Promise(resolve => { - sqlite3InitModule({ - print: log, - printErr: error, - }).then((sqlite3) => { - try { - this.db = new sqlite3.oo1.OpfsDb(dbFile); - } catch (err) { - error(err.name, err.message); - } - - return resolve(); - }); - }) - - } - - executeSql(sqlStatement, bindParameters, callback) { - return callback(this.db.exec({ - sql: sqlStatement, - bind: bindParameters, - returnValue: "resultRows", - rowMode: 'array', - })); - } -} - -Comlink.expose(SqliteWorker); \ No newline at end of file From b0d63977bd3ea8d5c3ae74f8483004d090b87e9b Mon Sep 17 00:00:00 2001 From: Thomas Steiner Date: Fri, 30 Jun 2023 16:34:26 +0200 Subject: [PATCH 3/3] Apply suggestions from code review --- demo/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/index.html b/demo/index.html index ba86897..6a57a0e 100644 --- a/demo/index.html +++ b/demo/index.html @@ -13,7 +13,7 @@

Main thread

Worker

-

Built-in Sqlite Client

+

Built-in SQLite Client