Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,7 @@ jspm_packages

# Optional REPL history
.node_repl_history

# Omit tests
dist/sqlite-async-test.js
dist/sqlite-async-test.d.ts
4 changes: 4 additions & 0 deletions .mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"spec": "src/**/*-test.ts",
"require": "ts-node/register"
}
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ Equivalent to the sqlite3 `Statement#all` method. Returns a promise that is reso

Equivalent to the sqlite3 `Statement#each` method. The per-row callback function is requied. Returns a promise that is resolved with the Statement instance.

## Contributors

- [Frank Hellwig](https://github.com/fhellwig) -- Author
- [Andy Peterson](https://github.com/ndp) -- Typescript

## License

MIT License
Expand Down
39 changes: 39 additions & 0 deletions dist/sqlite-async.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* This module provides a promise interface to the sqlite3 database module.
*/
import sqlite from 'sqlite3';
export type OpenMode = typeof sqlite.OPEN_READONLY | typeof sqlite.OPEN_READWRITE | typeof sqlite.OPEN_CREATE;
export interface RunResult {
lastID: number;
changes: number;
}
export declare class Database {
db: sqlite.Database | null;
filename: string;
static get OPEN_READONLY(): number;
static get OPEN_READWRITE(): number;
static get OPEN_CREATE(): number;
static get SQLITE3_VERSION(): string;
static open(filename: string, mode?: OpenMode): Promise<Database>;
open(filename: string, mode?: OpenMode): Promise<Database>;
on(evt: string, cb: (...args: any[]) => void): sqlite.Database;
close<Result>(fn?: (db: this) => Promise<Result>): Promise<Result | this>;
run(...args: any[]): Promise<RunResult>;
get(...args: any[]): Promise<unknown>;
all(...args: any[]): Promise<any[]>;
each(...args: any[]): Promise<number>;
exec(sql: string): Promise<this>;
transaction<T>(fn: (db: this) => T): Promise<T>;
prepare(...args: any[]): Promise<Statement>;
}
export declare class Statement {
statement: sqlite.Statement;
constructor(statement: sqlite.Statement);
bind(...args: any[]): Promise<unknown>;
reset(): Promise<unknown>;
finalize(): Promise<void>;
run(...args: any[]): Promise<RunResult>;
get(...args: any[]): Promise<any>;
all(...args: any[]): Promise<any[]>;
each(...args: any[]): Promise<number>;
}
318 changes: 318 additions & 0 deletions dist/sqlite-async.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,318 @@
"use strict";
/**
* This module provides a promise interface to the sqlite3 database module.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Statement = exports.Database = void 0;
const sqlite3_1 = __importDefault(require("sqlite3"));
//-----------------------------------------------------------------------------
// The Database class
//-----------------------------------------------------------------------------
class Database {
db;
filename;
static get OPEN_READONLY() {
return sqlite3_1.default.OPEN_READONLY;
}
static get OPEN_READWRITE() {
return sqlite3_1.default.OPEN_READWRITE;
}
static get OPEN_CREATE() {
return sqlite3_1.default.OPEN_CREATE;
}
static get SQLITE3_VERSION() {
return '5.0.11';
}
static open(filename, mode) {
let db = new Database();
return db.open(filename, mode);
}
open(filename, mode) {
if (typeof mode === 'undefined') {
mode = Database.OPEN_READWRITE | Database.OPEN_CREATE;
}
else if (typeof mode !== 'number') {
throw new TypeError('Database.open: mode is not a number');
}
return new Promise((resolve, reject) => {
if (this.db) {
return reject(new Error('Database.open: database is already open'));
}
let db = new sqlite3_1.default.Database(filename, mode, (err) => {
if (err) {
reject(err);
}
else {
this.db = db;
this.filename = filename;
resolve(this);
}
});
});
}
on(evt, cb) {
return this.db.on(evt, cb);
}
close(fn) {
if (!this.db) {
return Promise.reject(new Error('Database.close: database is not open'));
}
if (fn) {
return fn(this)
.then((result) => {
return this.close().then((_) => {
return result;
});
})
.catch((err) => {
return this.close().then((_) => {
return Promise.reject(err);
});
});
}
return new Promise((resolve, reject) => {
this.db.close((err) => {
if (err) {
reject(err);
}
else {
this.db = null;
resolve(this);
}
});
});
}
run(...args) {
return new Promise((resolve, reject) => {
if (!this.db) {
return reject(new Error('Database.run: database is not open'));
}
// Need a real function because 'this' is used.
const callback = function (err) {
if (err) {
reject(err);
}
else {
resolve({
lastID: this.lastID,
changes: this.changes
});
}
};
args.push(callback);
this.db.run.apply(this.db, args);
});
}
get(...args) {
return new Promise((resolve, reject) => {
if (!this.db) {
return reject(new Error('Database.get: database is not open'));
}
const callback = (err, row) => {
if (err) {
reject(err);
}
else {
resolve(row);
}
};
args.push(callback);
this.db.get.apply(this.db, args);
});
}
all(...args) {
return new Promise((resolve, reject) => {
if (!this.db) {
return reject(new Error('Database.all: database is not open'));
}
const callback = (err, rows) => {
if (err) {
reject(err);
}
else {
resolve(rows);
}
};
args.push(callback);
this.db.all.apply(this.db, args);
});
}
each(...args) {
if (args.length === 0 || typeof args[args.length - 1] !== 'function') {
throw TypeError('Database.each: last arg is not a function');
}
return new Promise((resolve, reject) => {
if (!this.db) {
return reject(new Error('Database.each: database is not open'));
}
const completeCallback = (err, nrows) => {
if (err) {
reject(err);
}
else {
resolve(nrows);
}
};
args.push(completeCallback);
this.db.each.apply(this.db, args);
});
}
exec(sql) {
return new Promise((resolve, reject) => {
if (!this.db) {
return reject(new Error('Database.exec: database is not open'));
}
this.db.exec(sql, (err) => {
if (err) {
reject(err);
}
else {
resolve(this);
}
});
});
}
async transaction(fn) {
await this.exec('BEGIN TRANSACTION');
try {
const result = await fn(this);
await this.exec('END TRANSACTION');
return result;
}
catch (e) {
await this.exec('ROLLBACK TRANSACTION');
throw e;
}
}
prepare(...args) {
return new Promise((resolve, reject) => {
if (!this.db) {
return reject(new Error('Database.prepare: database is not open'));
}
let statement;
const callback = (err) => {
if (err) {
reject(err);
}
else {
resolve(new Statement(statement));
}
};
args.push(callback);
statement = this.db.prepare.apply(this.db, args);
});
}
}
exports.Database = Database;
//-----------------------------------------------------------------------------
// The Statement class
//-----------------------------------------------------------------------------
class Statement {
statement;
constructor(statement) {
if (!(statement instanceof sqlite3_1.default.Statement)) {
throw new TypeError(`Statement: 'statement' is not a statement instance`);
}
this.statement = statement;
}
bind(...args) {
return new Promise((resolve, reject) => {
const callback = (err) => {
if (err) {
reject(err);
}
else {
resolve(this);
}
};
args.push(callback);
this.statement.bind.apply(this.statement, args);
});
}
reset() {
return new Promise((resolve, reject) => {
this.statement.reset((_) => {
resolve(this);
});
});
}
finalize() {
return new Promise((resolve, reject) => {
this.statement.finalize((err) => {
if (err) {
reject(err);
}
else {
resolve(); // can't use it anymore
}
});
});
}
run(...args) {
return new Promise((resolve, reject) => {
// Need a real function because 'this' is used.
const callback = function (err) {
if (err) {
reject(err);
}
else {
resolve({
lastID: this.lastID,
changes: this.changes
});
}
};
args.push(callback);
this.statement.run.apply(this.statement, args);
});
}
get(...args) {
return new Promise((resolve, reject) => {
const callback = (err, row) => {
if (err) {
reject(err);
}
else {
resolve(row);
}
};
args.push(callback);
this.statement.get.apply(this.statement, args);
});
}
all(...args) {
return new Promise((resolve, reject) => {
const callback = (err, rows) => {
if (err) {
reject(err);
}
else {
resolve(rows);
}
};
args.push(callback);
this.statement.all.apply(this.statement, args);
});
}
each(...args) {
if (args.length === 0 || typeof args[args.length - 1] !== 'function') {
throw TypeError('Statement.each: last arg is not a function');
}
return new Promise((resolve, reject) => {
const callback = (err, nrows) => {
if (err) {
reject(err);
}
else {
resolve(nrows);
}
};
args.push(callback);
this.statement.each.apply(this.statement, args);
});
}
}
exports.Statement = Statement;
Loading