Skip to content

Instantly share code, notes, and snippets.

@trvswgnr
Created January 2, 2024 00:15
Show Gist options
  • Save trvswgnr/6119eb31270ce2a52bb7d1f72bf8c8a4 to your computer and use it in GitHub Desktop.
Save trvswgnr/6119eb31270ce2a52bb7d1f72bf8c8a4 to your computer and use it in GitHub Desktop.
npm sqlite3 db promises
import sqlite3 from "sqlite3";
export class Database {
private db: sqlite3.Database;
constructor(path: string) {
this.db = new sqlite3.Database(path);
}
public static open(path: string): Database {
return new Database(path);
}
public async exec(sql: string): Promise<void> {
return new Promise((resolve, reject) => {
this.db.exec(sql, (err) => {
if (err) return reject(err);
return resolve();
});
});
}
public async prepare<T, X = SQLQueryBindings>(sql: string): Promise<Statement<T>> {
return new Promise((resolve, reject) => {
const stmt: sqlite3.Statement = this.db.prepare(sql, (err) => {
if (err) return reject(err);
return resolve(new Statement(stmt));
});
});
}
public async query<T, U = SQLQueryBindings>(
sql: string,
...params: U[]
): Promise<Statement<T>> {
return this.prepare(sql);
}
public async close(): Promise<void> {
return new Promise((resolve, reject) => {
this.db.close((err) => {
if (err) return reject(err);
return resolve();
});
});
}
public async transaction<T>(
fn: (...args: any[]) => Promise<T>
): Promise<(x: any) => Promise<T>> {
return async (...x: any[]) =>
new Promise((resolve, reject) => {
this.db.serialize(() => {
this.db.run("BEGIN TRANSACTION");
try {
fn(...x).then((result) => {
this.db.run("COMMIT");
resolve(result);
});
} catch (err) {
this.db.run("ROLLBACK");
reject(err);
}
});
});
}
}
export class Statement<T = unknown> {
private stmt: sqlite3.Statement;
constructor(stmt: sqlite3.Statement) {
this.stmt = stmt;
}
public async run(...params: any[]): Promise<void> {
return new Promise((resolve, reject) => {
this.stmt.run(params, (err) => {
if (err) return reject(err);
return resolve();
});
});
}
public async finalize(): Promise<void> {
return new Promise((resolve, reject) => {
this.stmt.finalize((err) => {
if (err) return reject(err);
return resolve();
});
});
}
public async all(...params: any[]): Promise<any[]> {
return new Promise((resolve, reject) => {
this.stmt.all(params, (err, rows) => {
if (err) return reject(err);
return resolve(rows);
});
});
}
public async get(...params: any[]): Promise<T> {
return new Promise((resolve, reject) => {
this.stmt.get(params, (err, row) => {
if (err) return reject(err);
return resolve(row as T);
});
});
}
}
export type SQLQueryBindings =
| string
| bigint
| TypedArray
| number
| boolean
| null
| Record<string, string | bigint | TypedArray | number | boolean | null>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment