|
|
const sqlite3 = require("sqlite3").verbose();
function generateId() { const buffer = Buffer.alloc(18); buffer.writeUInt32BE(Date.now() / (2 ** 32), 0); buffer.writeUInt32BE(Date.now() % (2 ** 32), 4); for (let i = 8; i < 18; ++i) { buffer[i] = Math.floor(Math.random() * 255); }
return buffer.slice(2).toString("hex"); }
class SQLite3Repository { constructor(path) { this.db = new sqlite3.Database(path); }
/** * @returns {Promise<void>} */ setup() { return new Promise((resolve, reject) => { this.db.run(SQL_TABLE_BIKE, (err) => { if (err != null) { reject(err); }
this.db.run(SQL_TABLE_PROGRAM, (err) => { if (err != null) { reject(err); }
this.db.run(SQL_TABLE_WORKOUT, (err) => { if (err != null) { reject(err); }
this.db.run(SQL_TABLE_MEASUREMENT, (err) => { if (err != null) { reject(err); }
resolve(); }); }); }); }); }); }
insert(obj, table, params) { if (!params.includes("id")) { params.push("id"); obj = {...obj, id: table.charAt(0).toUpperCase() + generateId(0, -1)}; } let id = obj.id;
return new Promise((resolve, reject) => { const query = `INSERT INTO ${table} (${params.join(", ")}) VALUES (${params.map(p => ':'+p).join(", ")});`; const values = params.map(p => obj[p]); this.db.run(query, values, (err) => { if (err != null) { return reject(err); }
resolve(id); }); }); }
update(obj, table, key, keys) { return new Promise((resolve, reject) => { const query = `UPDATE ${table} SET ${keys.map(k => `${k}=:${k}`).join(" AND ")} WHERE ${key}=:${key}`; const values = [ ...keys.map(k => obj[k]), obj[key], ]; this.db.run(query, values, function(err) { if (err != null) { return reject(err); }
resolve(); }); }); }
delete(obj, table, key) { return new Promise((resolve, reject) => { const query = `DELETE FROM ${table} WHERE ${key}=:${key};` this.db.run(query, [obj[key]], function(err) { if (err != null) { return reject(err); }
resolve(this.changes); }); }); }
findOne(table, match) { return this.find(table, match).then(res => res[0] || null) }
find(table, match) { return new Promise((resolve, reject) => { const keys = Object.keys(match).filter(k => match[k] != null); const params = keys.map(k => match[k]); const query = `SELECT * FROM ${table}${keys.length > 0 ? ` WHERE ${keys.map(k => `${k}=:${k}`).join(" AND ")}` : ""};`; this.db.all(query, params, function(err, rows) { if (err != null) { return reject(err); }
resolve(rows); }); }); }
findBike(id) { return this.findOne("bike", {id}); }
listBikes() { return this.find("bike", {}); }
insertBike(bike) { return this.insert(bike, "bike", ["name", "driver", "connect", "maxLevel"]); }
updateBike(bike) { return this.update(bike, "bike", "id", ["name"]); }
deleteBike(bike) { return this.delete(bike, "bike", "id"); }
findProgram(id) { return this.findOne("program", {id}); }
listPrograms() { return this.find("program", {}); }
insertProgram(program) { return this.insert(program, "program", ["name", "cpm", "warmupMin", "warmupCpm"]); }
updateProgram(program) { return this.update(program, "program", "id", ["name"]); }
deleteProgram(program) { return this.delete(program, "program", "id"); }
findWorkout(id) { return this.findOne("workout", {id}).then(d => ({...d, date: new Date(d.date)})); }
listWorkouts({programId, bikeId} = {}) { return this.find("workout", {programId, bikeId}).then(l => l.map(d => ({...d, date: new Date(d.date)}))); }
insertWorkout(workout) { return this.insert(workout, "workout", ["bikeId","programId","date"]); }
deleteWorkout(workout) { return this.delete(workout, "workout", "id"); }
findMeasurement(id) { return this.findOne("measurement", {id}); }
listMeasurements(workoutId) { return this.find("measurement", {workoutId}); }
insertMeasurement(measurement) { return this.insert(measurement, "measurement", ["workoutId","minutes","seconds","speed","rpm","distance","calories","pulse","watt","level"]); }
deleteMeasurement(measurement) { return this.delete(measurement, "measurement", "id"); }
deleteMeasurements({workoutId}) { return this.delete({workoutId}, "measurement", "workoutId"); } }
const SQL_TABLE_BIKE = `
CREATE TABLE IF NOT EXISTS bike ( id CHAR(32) PRIMARY KEY, name VARCHAR(255) NOT NULL, driver VARCHAR(255) NOT NULL, connect VARCHAR(255) NOT NULL, maxLevel INT ); `;
const SQL_TABLE_PROGRAM = `
CREATE TABLE IF NOT EXISTS program ( id CHAR(32) PRIMARY KEY, name VARCHAR(255) NOT NULL, cpm INT NOT NULL, warmupMin INT NOT NULL, warmupCpm INT NOT NULL ); `;
const SQL_TABLE_WORKOUT = `
CREATE TABLE IF NOT EXISTS workout ( id CHAR(32) PRIMARY KEY, bikeId INT NOT NULL, programId INT NOT NULL, date DATETIME NOT NULL ); `;
const SQL_TABLE_MEASUREMENT = `
CREATE TABLE IF NOT EXISTS measurement ( id CHAR(32) PRIMARY KEY, workoutId INT NOT NULL, minutes INT, seconds INT, speed REAL, rpm REAL, distance REAL, calories REAL, pulse INT, watt REAL, level INT ); `;
module.exports = SQLite3Repository;
|