const betterSqlite3 = require('better-sqlite3'); class betterSqlite3DB { constructor(databaseName, errorFunc = undefined) { if (!databaseName) { throw new Error('Database name is required.'); } this.errorFunc = errorFunc === null ? undefined : (errorFunc || (() => { console.error(`DB error: ${this.err.code} - sql: ${this.err.sql} - data: ${this.err.data}`); })); this.err = {}; this.info = null; this.db = new betterSqlite3(databaseName, { }); } runStmt(stmt, data = [], func = undefined, throwError = false) { try { if (typeof func === 'function') { this.info = func(stmt); } else { this.info = stmt.run(data); } this.err.err = null; this.err.sql = null; this.err.data = null; return true; // No error occurred } catch (err) { this.err.code = err.code !== undefined ? err.code : 'none err code'; this.err.sql = stmt.source; this.err.data = data; if (this.errorFunc) { this.errorFunc(); } if (throwError) { throw err; } return false; // Return the error if it occurred } } runSql(sql, data = [], func = undefined, throwError = false) { const stmt = this.db.prepare(sql); return this.runStmt(stmt, data, func, throwError); } createTable(tableName, columnDefinitions) { const columns = columnDefinitions.map(column => `${column.name} ${column.type}`).join(', '); const sql = `CREATE TABLE IF NOT EXISTS ${tableName} (${columns})`; this.db.exec(sql); } insertData(tableName, data) { if (!Array.isArray(data)) { data = [data]; } const columns = Object.keys(data[0]).join(', '); const values = Object.keys(data[0]).map(() => '?').join(', '); const sql = `INSERT INTO ${tableName} (${columns}) VALUES (${values})`; const stmt = this.db.prepare(sql); try { this.db.transaction(() => { data.forEach(item => this.runStmt(stmt, Object.values(item), undefined, true)); })(); } catch (err) { return false; } return true; } selectData(tableName, columns, where) { const sql = `SELECT ${columns ? columns : '*'} FROM ${tableName} ${where && typeof where !== 'function' ? ` WHERE ${where}` : ''}`; return this.runSql(sql, where, (stmt) => { return stmt.all(); }); } updateData(tableName, _data, where) { let data = null; if (Array.isArray(_data)) { data = _data[0]; } else { data = _data; } const columns = Object.keys(data).map((values) => { return `${values}=?`; }).join(', '); const sql = `UPDATE ${tableName} SET ${columns} ${where && typeof where !== 'function' ? ` WHERE ${where}` : ''}`; const values = Object.values(data); return this.runSql(sql, values); } deleteData(tableName, where) { const sql = `DELETE FROM ${tableName} ${where && typeof where !== 'function' ? ` WHERE ${where}` : ''}`; return this.runSql(sql); } closeConnection() { this.db.close(); } runInTransaction(callback) { try { this.db.transaction(callback)(); } catch (err) { return err; } } } module.exports = betterSqlite3DB;