Files
roaauto/frontend/src/db/database.js

58 lines
1.5 KiB
JavaScript

import SQLiteESMFactory from '@journeyapps/wa-sqlite/dist/wa-sqlite.mjs'
import * as SQLite from '@journeyapps/wa-sqlite'
import { SCHEMA_SQL } from './schema.js'
let db = null
let sqlite3 = null
const tableListeners = new Map()
let initPromise = null
export function initDatabase() {
if (initPromise) return initPromise
initPromise = _init()
return initPromise
}
async function _init() {
const module = await SQLiteESMFactory()
sqlite3 = SQLite.Factory(module)
db = await sqlite3.open_v2(':memory:')
for (const sql of SCHEMA_SQL.split(';').filter(s => s.trim())) {
await sqlite3.exec(db, sql)
}
return db
}
export function notifyTableChanged(table) {
tableListeners.get(table)?.forEach(cb => cb())
}
export function onTableChange(table, cb) {
if (!tableListeners.has(table)) tableListeners.set(table, new Set())
tableListeners.get(table).add(cb)
return () => tableListeners.get(table).delete(cb)
}
export async function execSQL(sql, params = []) {
if (!db) throw new Error('DB not initialized')
const results = []
if (params.length === 0) {
await sqlite3.exec(db, sql, (row, cols) => {
results.push(Object.fromEntries(cols.map((c, i) => [c, row[i]])))
})
} else {
for await (const stmt of sqlite3.statements(db, sql)) {
sqlite3.bind_collection(stmt, params)
const cols = sqlite3.column_names(stmt)
while ((await sqlite3.step(stmt)) === SQLite.SQLITE_ROW) {
results.push(Object.fromEntries(cols.map((c, i) => [c, sqlite3.column(stmt, i)])))
}
}
}
return results
}