const sqlite3 = require('sqlite3').verbose(); class sqlite3DB { constructor(databaseName, errorFunc = null) { if (!databaseName) { throw new Error('Database name is required.'); } this.errorFunc = errorFunc || (err => { console.error(`sql: ${err.SQL}\nerror: ${err.message}`); }); this.db = new sqlite3.Database(databaseName, (err) => { if (err) { console.error(`Failed to open database: ${err.message}`); } }); } runSql(sql, data, callback) { if (data == null) { data = undefined; } this.db.run(sql, data, (err) => { if (err) { err.SQL = sql; this.errorFunc(err); if (typeof callback === 'function') { callback(err); } } }); } runSerialize(sql, data, callback) { this.db.serialize(() => { this.runSql(sql, data, callback); }); } prepareSql(sql, callback) { return this.db.prepare(sql, (stmt, err) => { if (err) { err.SQL = sql; this.errorFunc(err); if (typeof callback === 'function') { callback(err); } return; } return stmt; }); } createTable(tableName, columnDefinitions, callback) { const columns = columnDefinitions.map(column => `${column.name} ${column.type}`).join(', '); const sql = `CREATE TABLE IF NOT EXISTS ${tableName} (${columns})`; this.db.serialize(() => { this.runSql(sql, null, callback); }); } insertData(tableName, data, callback) { 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})`; this.db.serialize(() => { const stmt = this.prepareSql(sql, callback); data.forEach((item) => { stmt.run(Object.values(item), (err) => { if (err) { err.SQL = sql; this.errorFunc(err); if (typeof callback === 'function') { callback(err); } } }); }); stmt.finalize((err) => { if(err) { err.SQL = sql; this.errorFunc(err); if (typeof callback === 'function') { callback(err); } } }); }); } selectData(tableName, columns, where, callback) { const sql = `SELECT ${columns} FROM ${tableName} ${where && typeof where !== 'function' ? ` WHERE ${where}` : ''}`; return this.db.all(sql, [], (err, rows) => { if (err) { err.SQL = sql; this.errorFunc(err); if (typeof callback === 'function') { callback(err); } } if (typeof callback === 'function') { callback(undefined, rows); } else { return rows; } }); } updateData(tableName, _data, where, callback) { var 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); this.runSql(sql, values, callback); } deleteData(tableName, where, callback) { const sql = `DELETE FROM ${tableName} ${where && typeof where !== 'function' ? ` WHERE ${where}` : ''}`; this.runSql(sql, callback); } closeConnection() { this.db.close((err) => { if (err) { err.SQL = 'ERROR close connection' this.errorFunc('ERROR db close', err); }}); } } module.exports = sqlite3DB;