UNPKG

@sqb/sqljs

Version:

SQB serialization extension for sql.js driver

66 lines (65 loc) 2 kB
import '@sqb/sqlite-dialect'; import fs from 'fs'; import path from 'path'; import promisify from 'putil-promisify'; import initSqlJs from 'sql.js'; import { SqljsConnection } from './sqljs-connection.js'; const dbCache = new Map(); export class SqljsAdapter { constructor() { this.driver = 'sqljs'; this.dialect = 'sqlite'; this.features = { cursor: true, // fetchAsString: [DataType.DATE, DataType.TIMESTAMP, DataType.TIMESTAMPTZ] }; } async connect(config) { if (!config.database) throw new Error('You must provide sqlite database file for sql.js driver'); let dbName = ''; let isMemory = false; const m = config.database.match(/^(:memory:)(\w+)?$/); if (m) { isMemory = true; dbName = config.database; } else { dbName = path.resolve(config.database); } let intlDb = dbCache.get(dbName); if (intlDb) { intlDb._refCount++; } else { const SQL = await initSqlJs(); if (isMemory) { intlDb = new SQL.Database(); intlDb._refCount = 0; } else { const buf = await promisify.fromCallback(cb => fs.readFile(dbName, cb)); intlDb = new SQL.Database(buf); intlDb._refCount = 1; } dbCache.set(dbName, intlDb); } const _intlDb = intlDb; return new SqljsConnection(_intlDb, () => { if (isMemory) return; if (--_intlDb._refCount <= 0) { _intlDb.close(); dbCache.delete(dbName); } }); } } export async function closeMemoryDatabase(name) { const memoryDbName = name || ':memory:'; const memDb = dbCache.get(memoryDbName); if (memDb) { dbCache.delete(memoryDbName); memDb.close(); } }