const sqlite3 = require('sqlite3').verbose(); const fs = require('fs'); const location = process.env.SQLITE_DB_LOCATION || '/etc/todos/todo.db'; let db, dbAll, dbRun; function init() { const dirName = require('path').dirname(location); if (!fs.existsSync(dirName)) { fs.mkdirSync(dirName, { recursive: true }); } return new Promise((acc, rej) => { db = new sqlite3.Database(location, err => { if (err) return rej(err); if (process.env.NODE_ENV !== 'test') console.log(`Using sqlite database at ${location}`); db.run( 'CREATE TABLE IF NOT EXISTS todo_items (id varchar(36), name varchar(255), completed boolean)', (err, result) => { if (err) return rej(err); acc(); }, ); }); }); } async function teardown() { return new Promise((acc, rej) => { db.close(err => { if (err) rej(err); else acc(); }); }); } async function getItems() { return new Promise((acc, rej) => { db.all('SELECT * FROM todo_items', (err, rows) => { if (err) return rej(err); acc( rows.map(item => Object.assign({}, item, { completed: item.completed === 1, }), ), ); }); }); } async function getItem(id) { return new Promise((acc, rej) => { db.all('SELECT * FROM todo_items WHERE id=?', [id], (err, rows) => { if (err) return rej(err); acc( rows.map(item => Object.assign({}, item, { completed: item.completed === 1, }), )[0], ); }); }); } async function storeItem(item) { return new Promise((acc, rej) => { db.run( 'INSERT INTO todo_items (id, name, completed) VALUES (?, ?, ?)', [item.id, item.name, item.completed ? 1 : 0], err => { if (err) return rej(err); acc(); }, ); }); } async function updateItem(id, item) { return new Promise((acc, rej) => { db.run( 'UPDATE todo_items SET name=?, completed=? WHERE id = ?', [item.name, item.completed ? 1 : 0, id], err => { if (err) return rej(err); acc(); }, ); }); } async function removeItem(id) { return new Promise((acc, rej) => { db.run('DELETE FROM todo_items WHERE id = ?', [id], err => { if (err) return rej(err); acc(); }); }); } module.exports = { init, teardown, getItems, getItem, storeItem, updateItem, removeItem, };