@darlean/fs-persistence-suite
Version:
File System Persistence Suite that uses a physical or shared file system to persist data.
113 lines (112 loc) • 3.29 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Statement = exports.StatementPool = exports.SqliteDatabase = void 0;
/**
* This module provides a promise interface to the better-sqlite3 database module.
*
* Originally copied from https://www.npmjs.com/package/sqlite-async and then adjusted to have proper TS bindings
* and pooling.
*/
const utils_1 = require("@darlean/utils");
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
//-----------------------------------------------------------------------------
// The Database class
//-----------------------------------------------------------------------------
class SqliteDatabase {
open(filename, readonly) {
const db = new better_sqlite3_1.default(filename, { readonly });
this.db = db;
}
close() {
if (!this.db) {
throw new Error('Database.close: database is not open');
}
this.db.close();
this.db = undefined;
}
run(sql) {
this.db?.exec(sql);
}
prepare(sql) {
if (!this.db) {
throw new Error('Database.prepare: database is not open');
}
const pool = new StatementPool(this, sql);
const s = pool.obtain();
s.release();
return pool;
}
_prepare(pool, sql) {
if (!this.db) {
throw new Error('Database.prepare: database is not open');
}
const statement = this.db.prepare(sql);
return new Statement(pool, statement);
}
}
exports.SqliteDatabase = SqliteDatabase;
class StatementPool {
constructor(db, sql) {
this.finalizing = false;
this.used = 0;
this.db = db;
this.sql = sql;
this.statements = [];
}
obtain() {
this.used++;
if (this.statements.length === 0) {
const s = this.db._prepare(this, this.sql);
return s;
}
else {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return this.statements.pop();
}
}
release(value) {
try {
if (this.finalizing) {
// Do nothing
}
else {
this.statements.push(value);
}
}
finally {
this.used--;
}
}
async finalize() {
this.finalizing = true;
while (this.used > 0) {
await (0, utils_1.sleep)(1);
}
}
}
exports.StatementPool = StatementPool;
class Statement {
constructor(pool, statement) {
this.pool = pool;
this.statement = statement;
}
release() {
this.pool.release(this);
}
run(params) {
this.statement.run(params ?? []);
}
get(params) {
return this.statement.get(params ?? []);
}
all(params) {
return this.statement.all(params ?? []);
}
iterate(params) {
return this.statement.iterate(params ?? []);
}
}
exports.Statement = Statement;