280 lines
No EOL
11 KiB
JavaScript
280 lines
No EOL
11 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.Database = void 0;
|
|
const Statement_1 = require("./Statement");
|
|
const migrate_1 = require("./utils/migrate");
|
|
const strings_1 = require("./utils/strings");
|
|
const format_error_1 = require("./utils/format-error");
|
|
/**
|
|
* Promisified wrapper for the sqlite3#Database interface.
|
|
*/
|
|
class Database {
|
|
constructor(config) {
|
|
this.config = config;
|
|
this.db = null;
|
|
}
|
|
/**
|
|
* Event handler when verbose mode is enabled.
|
|
* @see https://github.com/mapbox/node-sqlite3/wiki/Debugging
|
|
*/
|
|
on(event, listener) {
|
|
this.db.on(event, listener);
|
|
}
|
|
/**
|
|
* Returns the underlying sqlite3 Database instance
|
|
*/
|
|
getDatabaseInstance() {
|
|
return this.db;
|
|
}
|
|
/**
|
|
* Opens the database
|
|
*/
|
|
open() {
|
|
return new Promise((resolve, reject) => {
|
|
let { filename, mode, driver } = this.config;
|
|
// https://github.com/mapbox/node-sqlite3/wiki/API#new-sqlite3databasefilename-mode-callback
|
|
if (filename === null || filename === undefined) {
|
|
throw new Error('sqlite: filename cannot be null / undefined');
|
|
}
|
|
if (!driver) {
|
|
throw new Error('sqlite: driver is not defined');
|
|
}
|
|
if (mode) {
|
|
this.db = new driver(filename, mode, err => {
|
|
if (err) {
|
|
return reject((0, format_error_1.formatError)(err));
|
|
}
|
|
resolve();
|
|
});
|
|
}
|
|
else {
|
|
this.db = new driver(filename, err => {
|
|
if (err) {
|
|
return reject((0, format_error_1.formatError)(err));
|
|
}
|
|
resolve();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
/**
|
|
* Closes the database.
|
|
*/
|
|
close() {
|
|
return new Promise((resolve, reject) => {
|
|
this.db.close(err => {
|
|
if (err) {
|
|
return reject((0, format_error_1.formatError)(err));
|
|
}
|
|
resolve();
|
|
});
|
|
});
|
|
}
|
|
/**
|
|
* @see https://github.com/mapbox/node-sqlite3/wiki/API#databaseconfigureoption-value
|
|
*/
|
|
configure(option, value) {
|
|
this.db.configure(option, value);
|
|
}
|
|
/**
|
|
* Runs the SQL query with the specified parameters. It does not retrieve any result data.
|
|
* The function returns the Database object for which it was called to allow for function chaining.
|
|
*
|
|
* @param {string} sql The SQL query to run.
|
|
*
|
|
* @param {any} [params, ...] When the SQL statement contains placeholders, you
|
|
* can pass them in here. They will be bound to the statement before it is
|
|
* executed. There are three ways of passing bind parameters: directly in
|
|
* the function's arguments, as an array, and as an object for named
|
|
* parameters. This automatically sanitizes inputs.
|
|
*
|
|
* @see https://github.com/mapbox/node-sqlite3/wiki/API#databaserunsql-param--callback
|
|
*/
|
|
run(sql, ...params) {
|
|
return new Promise((resolve, reject) => {
|
|
const sqlObj = (0, strings_1.toSqlParams)(sql, params);
|
|
this.db.run(sqlObj.sql, ...sqlObj.params, function (err) {
|
|
if (err) {
|
|
return reject((0, format_error_1.formatError)(err));
|
|
}
|
|
resolve({
|
|
stmt: new Statement_1.Statement(this.stmt),
|
|
lastID: this.lastID,
|
|
changes: this.changes
|
|
});
|
|
});
|
|
});
|
|
}
|
|
/**
|
|
* Runs the SQL query with the specified parameters and resolves with
|
|
* with the first result row afterwards. If the result set is empty, returns undefined.
|
|
*
|
|
* The property names correspond to the column names of the result set.
|
|
* It is impossible to access them by column index; the only supported way is by column name.
|
|
*
|
|
* @param {string} sql The SQL query to run.
|
|
*
|
|
* @param {any} [params, ...] When the SQL statement contains placeholders, you
|
|
* can pass them in here. They will be bound to the statement before it is
|
|
* executed. There are three ways of passing bind parameters: directly in
|
|
* the function's arguments, as an array, and as an object for named
|
|
* parameters. This automatically sanitizes inputs.
|
|
*
|
|
* @see https://github.com/mapbox/node-sqlite3/wiki/API#databasegetsql-param--callback
|
|
*/
|
|
get(sql, ...params) {
|
|
return new Promise((resolve, reject) => {
|
|
const sqlObj = (0, strings_1.toSqlParams)(sql, params);
|
|
this.db.get(sqlObj.sql, ...sqlObj.params, (err, row) => {
|
|
if (err) {
|
|
return reject((0, format_error_1.formatError)(err));
|
|
}
|
|
resolve(row);
|
|
});
|
|
});
|
|
}
|
|
each(sql, ...params) {
|
|
return new Promise((resolve, reject) => {
|
|
const callback = params.pop();
|
|
if (!callback || typeof callback !== 'function') {
|
|
throw new Error('sqlite: Last param of Database#each() must be a callback function');
|
|
}
|
|
if (params.length > 0) {
|
|
const positional = params.pop();
|
|
if (typeof positional === 'function') {
|
|
throw new Error('sqlite: Database#each() should only have a single callback defined. See readme for usage.');
|
|
}
|
|
params.push(positional);
|
|
}
|
|
const sqlObj = (0, strings_1.toSqlParams)(sql, params);
|
|
this.db.each(sqlObj.sql, ...sqlObj.params, (err, row) => {
|
|
if (err) {
|
|
return callback((0, format_error_1.formatError)(err), null);
|
|
}
|
|
callback(null, row);
|
|
}, (err, count) => {
|
|
if (err) {
|
|
return reject((0, format_error_1.formatError)(err));
|
|
}
|
|
resolve(count);
|
|
});
|
|
});
|
|
}
|
|
/**
|
|
* Runs the SQL query with the specified parameters. The parameters are the same as the
|
|
* Database#run function, with the following differences:
|
|
*
|
|
* If the result set is empty, it will be an empty array, otherwise it will
|
|
* have an object for each result row which
|
|
* in turn contains the values of that row, like the Database#get function.
|
|
*
|
|
* Note that it first retrieves all result rows and stores them in memory.
|
|
* For queries that have potentially large result sets, use the Database#each
|
|
* function to retrieve all rows or Database#prepare followed by multiple
|
|
* Statement#get calls to retrieve a previously unknown amount of rows.
|
|
*
|
|
* @param {string} sql The SQL query to run.
|
|
*
|
|
* @param {any} [params, ...] When the SQL statement contains placeholders, you
|
|
* can pass them in here. They will be bound to the statement before it is
|
|
* executed. There are three ways of passing bind parameters: directly in
|
|
* the function's arguments, as an array, and as an object for named
|
|
* parameters. This automatically sanitizes inputs.
|
|
*
|
|
* @see https://github.com/mapbox/node-sqlite3/wiki/API#databaseallsql-param--callback
|
|
*/
|
|
all(sql, ...params) {
|
|
return new Promise((resolve, reject) => {
|
|
const sqlObj = (0, strings_1.toSqlParams)(sql, params);
|
|
this.db.all(sqlObj.sql, ...sqlObj.params, (err, rows) => {
|
|
if (err) {
|
|
return reject((0, format_error_1.formatError)(err));
|
|
}
|
|
resolve(rows);
|
|
});
|
|
});
|
|
}
|
|
/**
|
|
* Runs all SQL queries in the supplied string. No result rows are retrieved. If a query fails,
|
|
* no subsequent statements will be executed (wrap it in a transaction if you want all
|
|
* or none to be executed).
|
|
*
|
|
* Note: This function will only execute statements up to the first NULL byte.
|
|
* Comments are not allowed and will lead to runtime errors.
|
|
*
|
|
* @param {string} sql The SQL query to run.
|
|
* @see https://github.com/mapbox/node-sqlite3/wiki/API#databaseexecsql-callback
|
|
*/
|
|
exec(sql) {
|
|
return new Promise((resolve, reject) => {
|
|
const sqlObj = (0, strings_1.toSqlParams)(sql);
|
|
this.db.exec(sqlObj.sql, err => {
|
|
if (err) {
|
|
return reject((0, format_error_1.formatError)(err));
|
|
}
|
|
resolve();
|
|
});
|
|
});
|
|
}
|
|
/**
|
|
* Prepares the SQL statement and optionally binds the specified parameters.
|
|
* When bind parameters are supplied, they are bound to the prepared statement.
|
|
*
|
|
* @param {string} sql The SQL query to run.
|
|
* @param {any} [params, ...] When the SQL statement contains placeholders, you
|
|
* can pass them in here. They will be bound to the statement before it is
|
|
* executed. There are three ways of passing bind parameters: directly in
|
|
* the function's arguments, as an array, and as an object for named
|
|
* parameters. This automatically sanitizes inputs.
|
|
* @returns Promise<Statement> Statement object
|
|
*/
|
|
prepare(sql, ...params) {
|
|
return new Promise((resolve, reject) => {
|
|
const sqlObj = (0, strings_1.toSqlParams)(sql, params);
|
|
const stmt = this.db.prepare(sqlObj.sql, ...sqlObj.params, err => {
|
|
if (err) {
|
|
return reject(err);
|
|
}
|
|
resolve(new Statement_1.Statement(stmt));
|
|
});
|
|
});
|
|
}
|
|
/**
|
|
* Loads a compiled SQLite extension into the database connection object.
|
|
*
|
|
* @param {string} path Filename of the extension to load
|
|
*/
|
|
loadExtension(path) {
|
|
return new Promise((resolve, reject) => {
|
|
this.db.loadExtension(path, err => {
|
|
if (err) {
|
|
return reject((0, format_error_1.formatError)(err));
|
|
}
|
|
resolve();
|
|
});
|
|
});
|
|
}
|
|
/**
|
|
* Performs a database migration.
|
|
*/
|
|
async migrate(config) {
|
|
await (0, migrate_1.migrate)(this, config);
|
|
}
|
|
/**
|
|
* The methods underneath requires creative work to implement. PRs / proposals accepted!
|
|
*/
|
|
/*
|
|
* Unsure if serialize can be made into a promise.
|
|
*/
|
|
serialize() {
|
|
throw new Error('sqlite: Currently not implemented. Use getDatabaseInstance().serialize() instead.');
|
|
}
|
|
/*
|
|
* Unsure if parallelize can be made into a promise.
|
|
*/
|
|
parallelize() {
|
|
throw new Error('sqlite: Currently not implemented. Use getDatabaseInstance().parallelize() instead.');
|
|
}
|
|
}
|
|
exports.Database = Database;
|
|
//# sourceMappingURL=Database.js.map
|