UNPKG

@megaorm/sqlite

Version:

This package provides a simple, high-level, unified API for interacting with SQLite databases.

207 lines 9.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SQLite = void 0; const sqlite3_1 = require("sqlite3"); const errors_1 = require("@megaorm/errors"); const errors_2 = require("@megaorm/errors"); const errors_3 = require("@megaorm/errors"); const errors_4 = require("@megaorm/errors"); const errors_5 = require("@megaorm/errors"); const errors_6 = require("@megaorm/errors"); const test_1 = require("@megaorm/test"); /** * SQLite driver responsible for creating SQLite connections. * @implements `MegaDriver` interface. * @example * * // Create a new SQLite driver using a file-based database * const driver = new SQLite('./database.sqlite'); * * // Create a new SQLite driver using an in-memory database * const driver = new SQLite(':memory:'); * * // Create connection * const connection = await driver.create(); * * // Execute your queries * const result = await connection.query(sql, values); * console.log(result); * * // Begin a transaction * await connection.beginTransaction(); * * // Commit transaction * await connection.commit(); * * // Rollback transaction * await connection.rollback(); * * @note * SQLite supports two types of databases: * 1. **File-based database**: The database is stored in a file on disk (e.g., `./database.sqlite`). Data is persisted. * 2. **In-memory database**: The database is stored entirely in memory and is not persisted to disk. When the connection is closed or the application stops, all data is lost. */ class SQLite { /** * Constructs a SQLite driver with the given options. * @param path SQLite database file path like `./database.sqlite`, or `:memory:` for an in-memory database. * @example * * // Create a new SQLite driver with a file-based database * const driver = new SQLite('./database.sqlite'); * * // Create a new SQLite driver with an in-memory database * const driver = new SQLite(':memory:'); * * @note * - **File-based databases** are persistent. You can use them for long-term storage * - **In-memory databases** are non-persistent. They are faster because they don't involve file I/O, but all data is lost when the connection is closed or the application stops. Useful for testing or temporary data storage. */ constructor(path) { if (!(0, test_1.isStr)(path)) { throw new errors_2.CreateConnectionError(`Invalid SQLite path: ${String(path)}`); } this.path = path; this.id = Symbol('SQLite'); } /** * Creates a new SQLite connection. * @returns A `Promise` that resolves with a new SQLite connection. * @throws `CreateConnectionError` If connection creation fails. * @example * * // Create a new SQLite driver * const driver = new SQLite(path); * * // Create connection * const connection = await driver.create(); * * // Execute your queries * const result = await connection.query(sql, values); * console.log(result); * * // Begin a transaction * await connection.beginTransaction(); * * // Commit transaction * await connection.commit(); * * // Rollback transaction * await connection.rollback(); * * @note * - When using `:memory:` as the path, SQLite creates an in-memory database that is non-persistent. * - For a file-based database, the path should point to a valid file location like `./database.sqlite` * - An in-memory database can be ideal for tests and temporary storage because you lose all data once the application ends. */ create() { return new Promise((resolve, reject) => { // Create connection using SQLite3 const db = new sqlite3_1.Database(this.path, (error) => { if ((0, test_1.isError)(error)) { return reject(new errors_2.CreateConnectionError(error.message)); } // Enable foreign key constraints db.run('PRAGMA foreign_keys = ON', undefined, (error) => { if ((0, test_1.isError)(error)) { return reject(new errors_2.CreateConnectionError(error.message)); } const sqlite = { id: Symbol('MegaConnection'), driver: this, query(sql, values) { return new Promise((resolve, reject) => { if (!(0, test_1.isStr)(sql)) { return reject(new errors_1.QueryError(`Invalid query: ${String(sql)}`)); } if ((0, test_1.isDefined)(values)) { if (!(0, test_1.isArr)(values)) { return reject(new errors_1.QueryError(`Invalid query values: ${String(values)}`)); } values.forEach((value) => { if (!(0, test_1.isNum)(value) && !(0, test_1.isStr)(value)) { return reject(new errors_1.QueryError(`Invalid query value: ${String(value)}`)); } }); } // Handle SELECT queries if (/^\s*SELECT/i.test(sql)) { return db.all(sql, values, (error, rows) => { if ((0, test_1.isError)(error)) { return reject(new errors_1.QueryError(error.message)); } return resolve(rows); }); } // Handle other query types db.run(sql, values, function (error) { if (error) return reject(new errors_1.QueryError(error.message)); // Handle INSERT queries if (/^\s*INSERT/i.test(sql)) { // Check if it was a single insert or bulk insert if (this.changes === 1) { return resolve(this.lastID); // Return the last inserted ID for single inserts } return resolve(undefined); // Return undefined for bulk insert } return resolve(undefined); }); }); }, close() { return new Promise((resolve, reject) => { db.close((error) => { if ((0, test_1.isError)(error)) { return reject(new errors_3.CloseConnectionError(error.message)); } const assign = (Error) => { return function reject() { return Promise.reject(new Error('Cannot perform further operations once the connection is closed')); }; }; // Reset sqlite.close = assign(errors_3.CloseConnectionError); sqlite.query = assign(errors_1.QueryError); sqlite.beginTransaction = assign(errors_4.BeginTransactionError); sqlite.commit = assign(errors_5.CommitTransactionError); sqlite.rollback = assign(errors_6.RollbackTransactionError); // Resolve resolve(); }); }); }, beginTransaction() { return new Promise((resolve, reject) => { return sqlite .query('BEGIN TRANSACTION;') .then(() => resolve()) .catch((error) => reject(new errors_4.BeginTransactionError(error.message))); }); }, commit() { return new Promise((resolve, reject) => { return sqlite .query('COMMIT;') .then(() => resolve()) .catch((error) => reject(new errors_5.CommitTransactionError(error.message))); }); }, rollback() { return new Promise((resolve, reject) => { return sqlite .query('ROLLBACK;') .then(() => resolve()) .catch((error) => reject(new errors_6.RollbackTransactionError(error.message))); }); }, }; // Resolve resolve(sqlite); }); }); }); } } exports.SQLite = SQLite; //# sourceMappingURL=index.js.map