You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

227 lines
5.2 KiB

5 years ago
  1. const sqlite3 = require("sqlite3").verbose();
  2. class SQLite3Repository {
  3. constructor(path) {
  4. this.db = new sqlite3.Database(path);
  5. }
  6. /**
  7. * @returns {Promise<void>}
  8. */
  9. setup() {
  10. return new Promise((resolve, reject) => {
  11. this.db.run(SQL_TABLE_BIKE, (err) => {
  12. if (err != null) {
  13. reject(err);
  14. }
  15. this.db.run(SQL_TABLE_PROGRAM, (err) => {
  16. if (err != null) {
  17. reject(err);
  18. }
  19. this.db.run(SQL_TABLE_WORKOUT, (err) => {
  20. if (err != null) {
  21. reject(err);
  22. }
  23. this.db.run(SQL_TABLE_MEASUREMENT, (err) => {
  24. if (err != null) {
  25. reject(err);
  26. }
  27. resolve();
  28. });
  29. });
  30. });
  31. });
  32. });
  33. }
  34. insert(obj, table, params) {
  35. return new Promise((resolve, reject) => {
  36. const query = `INSERT INTO ${table} (${params.join(", ")}) VALUES (${params.map(p => ':'+p).join(", ")});`;
  37. const values = params.map(p => obj[p]);
  38. this.db.run(query, values, function(err) {
  39. if (err != null) {
  40. return reject(err);
  41. }
  42. resolve(this.lastID);
  43. });
  44. });
  45. }
  46. update(obj, table, key, keys) {
  47. return new Promise((resolve, reject) => {
  48. const query = `UPDATE ${table} SET ${keys.map(k => `${k}=:${k}`).join(" AND ")} WHERE ${key}=:${key}`;
  49. const values = [
  50. ...keys.map(k => obj[k]),
  51. obj[key],
  52. ];
  53. this.db.run(query, values, function(err) {
  54. if (err != null) {
  55. return reject(err);
  56. }
  57. resolve();
  58. });
  59. });
  60. }
  61. delete(obj, table, key) {
  62. return new Promise((resolve, reject) => {
  63. const query = `DELETE FROM ${table} WHERE ${key}=:${key};`
  64. this.db.run(query, [obj[key]], function(err) {
  65. if (err != null) {
  66. return reject(err);
  67. }
  68. resolve(this.changes);
  69. });
  70. });
  71. }
  72. findOne(table, match) {
  73. return this.find(table, match).then(res => res[0] || null)
  74. }
  75. find(table, match) {
  76. return new Promise((resolve, reject) => {
  77. const keys = Object.keys(match).filter(k => match[k] != null);
  78. const params = keys.map(k => match[k]);
  79. const query = `SELECT * FROM ${table}${keys.length > 0 ? ` WHERE ${keys.map(k => `${k}=:${k}`).join(" AND ")}` : ""};`;
  80. this.db.all(query, params, function(err, rows) {
  81. if (err != null) {
  82. return reject(err);
  83. }
  84. resolve(rows);
  85. });
  86. });
  87. }
  88. findBike(id) {
  89. return this.findOne("bike", {id});
  90. }
  91. listBikes() {
  92. return this.find("bike", {});
  93. }
  94. insertBike(bike) {
  95. return this.insert(bike, "bike", ["name", "driver", "connect", "maxLevel"]);
  96. }
  97. updateBike(bike) {
  98. return this.update(bike, "bike", "id", ["name"]);
  99. }
  100. deleteBike(bike) {
  101. return this.delete(bike, "bike", "id");
  102. }
  103. findProgram(id) {
  104. return this.findOne("program", {id});
  105. }
  106. listPrograms() {
  107. return this.find("program", {});
  108. }
  109. insertProgram(program) {
  110. return this.insert(program, "program", ["name", "cpm", "warmupMin", "warmupCpm"]);
  111. }
  112. updateProgram(program) {
  113. return this.update(program, "program", "id", ["name"]);
  114. }
  115. deleteProgram(program) {
  116. return this.delete(program, "program", "id");
  117. }
  118. findWorkout(id) {
  119. return this.findOne("workout", {id}).then(d => ({...d, date: new Date(d.date)}));
  120. }
  121. listWorkouts({programId, bikeId} = {}) {
  122. return this.find("workout", {programId, bikeId}).then(l => l.map(d => ({...d, date: new Date(d.date)})));
  123. }
  124. insertWorkout(workout) {
  125. return this.insert(workout, "workout", ["bikeId","programId","date"]);
  126. }
  127. deleteWorkout(workout) {
  128. return this.delete(workout, "workout", "id");
  129. }
  130. findMeasurement(id) {
  131. return this.findOne("measurement", {id});
  132. }
  133. listMeasurements(workoutId) {
  134. return this.find("measurement", {workoutId});
  135. }
  136. insertMeasurement(measurement) {
  137. return this.insert(measurement, "measurement", ["workoutId","minutes","seconds","speed","rpm","distance","calories","pulse","watt","level"]);
  138. }
  139. deleteMeasurement(measurement) {
  140. return this.delete(measurement, "measurement", "id");
  141. }
  142. deleteMeasurements({workoutId}) {
  143. return this.delete({workoutId}, "measurement", "workoutId");
  144. }
  145. }
  146. const SQL_TABLE_BIKE = `
  147. CREATE TABLE IF NOT EXISTS bike (
  148. id INTEGER PRIMARY KEY,
  149. name VARCHAR(255) NOT NULL,
  150. driver VARCHAR(255) NOT NULL,
  151. connect VARCHAR(255) NOT NULL,
  152. maxLevel INT
  153. );
  154. `;
  155. const SQL_TABLE_PROGRAM = `
  156. CREATE TABLE IF NOT EXISTS program (
  157. id INTEGER PRIMARY KEY,
  158. name VARCHAR(255) NOT NULL,
  159. cpm INT NOT NULL,
  160. warmupMin INT NOT NULL,
  161. warmupCpm INT NOT NULL
  162. );
  163. `;
  164. const SQL_TABLE_WORKOUT = `
  165. CREATE TABLE IF NOT EXISTS workout (
  166. id INTEGER PRIMARY KEY,
  167. bikeId INT NOT NULL,
  168. programId INT NOT NULL,
  169. date DATETIME NOT NULL
  170. );
  171. `;
  172. const SQL_TABLE_MEASUREMENT = `
  173. CREATE TABLE IF NOT EXISTS measurement (
  174. id INTEGER PRIMARY KEY,
  175. workoutId INT NOT NULL,
  176. minutes INT,
  177. seconds INT,
  178. speed REAL,
  179. rpm REAL,
  180. distance REAL,
  181. calories REAL,
  182. pulse INT,
  183. watt REAL,
  184. level INT
  185. );
  186. `;
  187. module.exports = SQLite3Repository;