lib/persistence.js

  1. /**
  2. * @file Persistence layer
  3. * @author Antonio Olmo Titos <a@olmo-titos.info>
  4. * @exports lib/persistence
  5. */
  6. // Configuration:
  7. const CONFIG = require('../config');
  8. // External packages:
  9. const PROCESS = require('process'),
  10. SQLITE = require('sqlite3');
  11. // Internal packages:
  12. const LOGGING = require('./logging'),
  13. UTIL = require('./util');
  14. // Variables:
  15. var connection;
  16. /**
  17. * Terminate the DB connection (gracefully)
  18. */
  19. const wrapUp = function() {
  20. connection.close();
  21. LOGGING.info(`connection to DB file closed`);
  22. PROCESS.exit();
  23. };
  24. /**
  25. * Run a query and retrieve a set of rows from the DB
  26. * @param {String} query - the SQL query
  27. * @param {String} params - (optional; variable length) values to interpolate in the query
  28. * @returns {Array} the resulting rows
  29. */
  30. const retrieveRows = function(query, ...params) {
  31. return new Promise(function(resolve, reject) {
  32. connection.all(query, params, function(err, rows) {
  33. if (err)
  34. reject(err);
  35. else
  36. resolve(rows);
  37. });
  38. });
  39. };
  40. /**
  41. * Set up persistence
  42. */
  43. const setUp = function() {
  44. if (connection)
  45. LOGGING.warn(`“persistence.setUp()” called more than once`);
  46. else {
  47. if (CONFIG.debug)
  48. SQLITE.verbose();
  49. // @TODO: handle issues.
  50. connection = new SQLITE.Database(CONFIG.db, SQLITE.OPEN_READWRITE);
  51. connection.exec('PRAGMA foreign_keys = ON;');
  52. LOGGING.info(`persistence linked to file “${CONFIG.db}”`);
  53. PROCESS.on('SIGINT', wrapUp);
  54. // Export more stuff:
  55. exports.TYPE_PERSON = 'people';
  56. exports.TYPE_MEETING = 'meetings';
  57. exports.TYPE_LOCATION = 'locations';
  58. // exports.createEntity = createEntity;
  59. exports.listEntities = listEntities;
  60. exports.findEntity = findEntity;
  61. }
  62. };
  63. // const createEntity = function(type) {
  64. // return new Promise(function(resolve, reject) {
  65. // if (exports.TYPE_PERSON === type)
  66. // retrieveRows(`INSERT INTO ${type} VALUES;`).then(function(rows) {
  67. // resolve(rows);
  68. // }).catch(function(err) {
  69. // LOGGING.debug(`“persistence.listEntities()” error: ${err}`);
  70. // reject(err);
  71. // });
  72. // else if (exports.TYPE_MEETING === type)
  73. // ;
  74. // else if (exports.TYPE_LOCATION === type)
  75. // ;
  76. // else
  77. // reject();
  78. // });
  79. // };
  80. /**
  81. * Return all entities of a given type
  82. * @param {String} type - type; use constants of the form <code>persistence.TYPE_*</code>
  83. * @returns {Array} all entities of that type
  84. */
  85. const listEntities = function(type) {
  86. return new Promise(function(resolve, reject) {
  87. if (exports.TYPE_PERSON === type || exports.TYPE_MEETING === type || exports.TYPE_LOCATION === type) {
  88. retrieveRows(`SELECT * FROM ${type} ORDER BY name;`).then(function(rows) {
  89. UTIL.processData(rows);
  90. resolve(rows);
  91. }).catch(function(err) {
  92. LOGGING.warn(`“persistence.listEntities()” error: ${err}`);
  93. reject(err);
  94. });
  95. } else
  96. reject();
  97. });
  98. };
  99. /**
  100. * Return all entities with a given ID (should be unique)
  101. * @param {String} id - name of the desired ID
  102. * @returns {Promise} found entities
  103. */
  104. const findEntity = function(id) {
  105. LOGGING.dir(id);
  106. return new Promise(function(resolve, reject) {
  107. const normalisedID = UTIL.normaliseID(id);
  108. if (normalisedID) {
  109. const queries = [
  110. retrieveRows(`SELECT * FROM people WHERE name LIKE ?;`, id),
  111. retrieveRows(`SELECT * FROM meetings WHERE name LIKE ?;`, id),
  112. retrieveRows(`SELECT * FROM locations WHERE name LIKE ?;`, id)
  113. ];
  114. const result = Promise.all(queries);
  115. result.then(function(rows) {
  116. const people = rows[0],
  117. meetings = rows[1],
  118. locations = rows[2];
  119. if (1 === people.length && 0 === meetings.length && 0 === locations.length)
  120. resolve({type: exports.TYPE_PERSON, data: people[0]});
  121. else if (0 === people.length && 1 === meetings.length && 0 === locations.length)
  122. resolve({type: exports.TYPE_MEETING, data: meetings[0]});
  123. else if (0 === people.length && 0 === meetings.length && 1 === locations.length)
  124. resolve({type: exports.TYPE_LOCATION, data: locations[0]});
  125. else if (people.length + meetings.length + locations.length > 1)
  126. reject('more than one entity');
  127. else
  128. reject('foo');
  129. });
  130. result.catch(function(err) {
  131. reject(`“persistence.findEntity()” error: ${err}`);
  132. });
  133. } else
  134. reject('wrong');
  135. });
  136. };
  137. // Export stuff:
  138. exports.setUp = setUp;