Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 

252 Zeilen
5.3 KiB

  1. let util = require('util');
  2. const tableNames = require('./tableNames');
  3. module.exports = {
  4. db: null,
  5. file: '../../data/storage.db',
  6. buffer: [],
  7. processing: [],
  8. tables: {},
  9. init: async function (cbReady) {
  10. let sqlite = require('sqlite3').verbose();
  11. this.db = new sqlite.Database(this.file, this.onDbCreated.bind(this, cbReady));
  12. },
  13. onDbCreated: function (cbReady) {
  14. let db = this.db;
  15. let scope = this;
  16. db.serialize(function () {
  17. for (let t of tableNames) {
  18. db.run(`
  19. CREATE TABLE ${t} (key VARCHAR(50), value TEXT)
  20. `, scope.onTableCreated.bind(scope, t));
  21. }
  22. cbReady();
  23. }, this);
  24. },
  25. createTable: async function (tableName) {
  26. return new Promise(res => {
  27. this.db.run(`
  28. CREATE TABLE ${tableName} (key VARCHAR(50), value TEXT)
  29. `, res);
  30. });
  31. },
  32. onTableCreated: async function (table) {
  33. },
  34. //ent, field
  35. get: function (options) {
  36. let key = options.ent;
  37. let table = options.field;
  38. options.query = `SELECT * FROM ${table} WHERE key = '${key}' LIMIT 1`;
  39. this.db.get(options.query, this.done.bind(this, options));
  40. },
  41. getAsync: async function (options) {
  42. return await this.queue({
  43. type: 'get',
  44. options: options
  45. });
  46. },
  47. getAllAsync: async function (options) {
  48. return await this.queue({
  49. type: 'getAll',
  50. options: options
  51. });
  52. },
  53. delete: function (options) {
  54. let key = options.ent;
  55. let table = options.field;
  56. options.query = `DELETE FROM ${table} WHERE key = '${key}'`;
  57. this.db.run(options.query, this.done.bind(this, options));
  58. },
  59. deleteAsync: async function (options) {
  60. await this.queue({
  61. type: 'delete',
  62. options: options
  63. });
  64. },
  65. //ent, field, value
  66. set: function (options) {
  67. let key = options.ent;
  68. let table = options.field;
  69. this.db.get(`SELECT 1 FROM ${table} where key = '${key}'`, this.doesExist.bind(this, options));
  70. },
  71. doesExist: function (options, err, result) {
  72. let key = options.ent;
  73. let table = options.field;
  74. let query = `INSERT INTO ${table} (key, value) VALUES('${key}', '${options.value}')`;
  75. if (result)
  76. query = `UPDATE ${table} SET value = '${options.value}' WHERE key = '${key}'`;
  77. this.db.run(query, this.done.bind(this, options));
  78. },
  79. setAsync: async function (options) {
  80. await this.queue({
  81. type: 'set',
  82. options: options
  83. });
  84. },
  85. queue: async function (config) {
  86. let resolve = null;
  87. let promise = new Promise(function (res) {
  88. resolve = res;
  89. });
  90. this.buffer.push({
  91. resolve: resolve,
  92. config: config
  93. });
  94. this.process();
  95. return promise;
  96. },
  97. process: async function () {
  98. let next = this.buffer.splice(0, 1);
  99. if (!next.length)
  100. return;
  101. next = next[0];
  102. let config = next.config;
  103. let options = config.options;
  104. let res = null;
  105. try {
  106. if (config.type === 'get')
  107. res = await this.processGet(options);
  108. else if (config.type === 'getAll')
  109. res = await this.processGetAll(options);
  110. else if (config.type === 'set')
  111. await this.processSet(options);
  112. else if (config.type === 'delete')
  113. await this.processDelete(options);
  114. } catch (e) {
  115. _.log(e);
  116. this.buffer.splice(0, 0, next);
  117. setTimeout(this.process.bind(this), 10);
  118. return;
  119. }
  120. next.resolve(res);
  121. setTimeout(this.process.bind(this), 10);
  122. },
  123. processGet: async function (options) {
  124. const collate = options.ignoreCase ? 'COLLATE NOCASE' : '';
  125. const query = `SELECT * FROM ${options.table} WHERE key = '${options.key}' ${collate} LIMIT 1`;
  126. let res = await util.promisify(this.db.get.bind(this.db))(query);
  127. if (res) {
  128. res = res.value;
  129. if (options.clean) {
  130. res = res
  131. .split('`')
  132. .join('\'')
  133. .replace(/''+/g, '\'');
  134. }
  135. if (!options.noParse)
  136. res = JSON.parse(res);
  137. } else if (!options.noParse && !options.noDefault)
  138. res = options.isArray ? [] : {};
  139. return res;
  140. },
  141. processGetAll: async function (options) {
  142. let res = await util.promisify(this.db.all.bind(this.db))(`SELECT * FROM ${options.table}`);
  143. if (res) {
  144. if (options.clean) {
  145. res.forEach(r => {
  146. r.value = r.value
  147. .split('`')
  148. .join('\'')
  149. .replace(/''+/g, '\'');
  150. });
  151. }
  152. if (!options.noParse) {
  153. if (!res)
  154. res = options.isArray ? [] : {};
  155. else {
  156. res.forEach(r => {
  157. r.value = JSON.parse(r.value);
  158. });
  159. }
  160. }
  161. } else if (!options.noParse && !options.noDefault)
  162. res = options.isArray ? [] : {};
  163. return res;
  164. },
  165. processSet: async function (options) {
  166. let table = options.table;
  167. let key = options.key;
  168. let value = options.value;
  169. if (options.serialize)
  170. value = JSON.stringify(value);
  171. //Clean single quotes
  172. if (value.split) {
  173. value = value
  174. .split('\'')
  175. .join('`');
  176. }
  177. let exists = await util.promisify(this.db.get.bind(this.db))(`SELECT * FROM ${table} WHERE key = '${key}' LIMIT 1`);
  178. let query = `INSERT INTO ${table} (key, value) VALUES('${key}', '${value}')`;
  179. if (exists)
  180. query = `UPDATE ${table} SET value = '${value}' WHERE key = '${key}'`;
  181. await util.promisify(this.db.run.bind(this.db))(query);
  182. },
  183. processDelete: async function (options) {
  184. let table = options.table;
  185. let key = options.key;
  186. let query = `DELETE FROM ${table} WHERE key = '${key}'`;
  187. await util.promisify(this.db.run.bind(this.db))(query);
  188. },
  189. done: function (options, err, result) {
  190. result = result || {
  191. value: null
  192. };
  193. if (options.callback)
  194. options.callback(result.value);
  195. }
  196. };