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.
 
 
 

254 regels
5.3 KiB

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