@sqb/sqljs
Version:
SQB serialization extension for sql.js driver
66 lines (65 loc) • 2 kB
JavaScript
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();
}
}