|
|
@ -1,18 +1,21 @@ |
|
|
|
// Add type declarations for external modules
|
|
|
|
declare module '@jlongster/sql.js'; |
|
|
|
declare module 'absurd-sql'; |
|
|
|
declare module 'absurd-sql/dist/indexeddb-backend'; |
|
|
|
declare module "@jlongster/sql.js"; |
|
|
|
declare module "absurd-sql"; |
|
|
|
declare module "absurd-sql/dist/indexeddb-backend"; |
|
|
|
|
|
|
|
import initSqlJs from '@jlongster/sql.js'; |
|
|
|
import { SQLiteFS } from 'absurd-sql'; |
|
|
|
import IndexedDBBackend from 'absurd-sql/dist/indexeddb-backend'; |
|
|
|
import initSqlJs from "@jlongster/sql.js"; |
|
|
|
import { SQLiteFS } from "absurd-sql"; |
|
|
|
import IndexedDBBackend from "absurd-sql/dist/indexeddb-backend"; |
|
|
|
|
|
|
|
import { runMigrations } from '../db-sql/migration'; |
|
|
|
import type { QueryExecResult } from '../interfaces/database'; |
|
|
|
import { runMigrations } from "../db-sql/migration"; |
|
|
|
import type { QueryExecResult } from "../interfaces/database"; |
|
|
|
|
|
|
|
interface SQLDatabase { |
|
|
|
exec: (sql: string, params?: any[]) => Promise<QueryExecResult[]>; |
|
|
|
run: (sql: string, params?: any[]) => Promise<{ changes: number; lastId?: number }>; |
|
|
|
run: ( |
|
|
|
sql: string, |
|
|
|
params?: any[], |
|
|
|
) => Promise<{ changes: number; lastId?: number }>; |
|
|
|
} |
|
|
|
|
|
|
|
class DatabaseService { |
|
|
@ -62,34 +65,39 @@ class DatabaseService { |
|
|
|
|
|
|
|
const SQL = await initSqlJs({ |
|
|
|
locateFile: (file: string) => { |
|
|
|
return new URL(`/node_modules/@jlongster/sql.js/dist/${file}`, import.meta.url).href; |
|
|
|
} |
|
|
|
return new URL( |
|
|
|
`/node_modules/@jlongster/sql.js/dist/${file}`, |
|
|
|
import.meta.url, |
|
|
|
).href; |
|
|
|
}, |
|
|
|
}); |
|
|
|
|
|
|
|
let sqlFS = new SQLiteFS(SQL.FS, new IndexedDBBackend()); |
|
|
|
const sqlFS = new SQLiteFS(SQL.FS, new IndexedDBBackend()); |
|
|
|
SQL.register_for_idb(sqlFS); |
|
|
|
|
|
|
|
SQL.FS.mkdir('/sql'); |
|
|
|
SQL.FS.mount(sqlFS, {}, '/sql'); |
|
|
|
SQL.FS.mkdir("/sql"); |
|
|
|
SQL.FS.mount(sqlFS, {}, "/sql"); |
|
|
|
|
|
|
|
const path = '/sql/db.sqlite'; |
|
|
|
if (typeof SharedArrayBuffer === 'undefined') { |
|
|
|
let stream = SQL.FS.open(path, 'a+'); |
|
|
|
const path = "/sql/db.sqlite"; |
|
|
|
if (typeof SharedArrayBuffer === "undefined") { |
|
|
|
const stream = SQL.FS.open(path, "a+"); |
|
|
|
await stream.node.contents.readIfFallback(); |
|
|
|
SQL.FS.close(stream); |
|
|
|
} |
|
|
|
|
|
|
|
this.db = new SQL.Database(path, { filename: true }); |
|
|
|
if (!this.db) { |
|
|
|
throw new Error('The database initialization failed. We recommend you restart or reinstall.'); |
|
|
|
throw new Error( |
|
|
|
"The database initialization failed. We recommend you restart or reinstall.", |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
await this.db.exec(`PRAGMA journal_mode=MEMORY;`); |
|
|
|
const sqlExec = this.db.exec.bind(this.db); |
|
|
|
|
|
|
|
|
|
|
|
// Run migrations
|
|
|
|
await runMigrations(sqlExec); |
|
|
|
|
|
|
|
|
|
|
|
this.initialized = true; |
|
|
|
} |
|
|
|
|
|
|
@ -108,13 +116,20 @@ class DatabaseService { |
|
|
|
|
|
|
|
// If initialized but no db, something went wrong
|
|
|
|
if (!this.db) { |
|
|
|
console.error(`Database not properly initialized after await waitForInitialization() - initialized flag is true but db is null`); |
|
|
|
throw new Error(`The database could not be initialized. We recommend you restart or reinstall.`); |
|
|
|
console.error( |
|
|
|
`Database not properly initialized after await waitForInitialization() - initialized flag is true but db is null`, |
|
|
|
); |
|
|
|
throw new Error( |
|
|
|
`The database could not be initialized. We recommend you restart or reinstall.`, |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Used for inserts, updates, and deletes
|
|
|
|
async run(sql: string, params: any[] = []): Promise<{ changes: number; lastId?: number }> { |
|
|
|
async run( |
|
|
|
sql: string, |
|
|
|
params: any[] = [], |
|
|
|
): Promise<{ changes: number; lastId?: number }> { |
|
|
|
await this.waitForInitialization(); |
|
|
|
return this.db!.run(sql, params); |
|
|
|
} |
|
|
@ -141,4 +156,4 @@ class DatabaseService { |
|
|
|
// Create a singleton instance
|
|
|
|
const databaseService = DatabaseService.getInstance(); |
|
|
|
|
|
|
|
export default databaseService; |
|
|
|
export default databaseService; |
|
|
|