accountConfig.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. const db = require('../database.js');
  2. const TABLE_NAME = "accountConfig";
  3. function AccountConfigManager() {
  4. }
  5. AccountConfigManager.prototype.defaultForAccount = function(id, cb) {
  6. var self = this;
  7. db.database.queryFirst(TABLE_NAME, { accountId: id, serviceId: null, deviceId: null }, (err, result) => {
  8. cb(result ? self.fromDb(result) : null);
  9. });
  10. };
  11. AccountConfigManager.prototype.fromAccountId = function(id, cb) {
  12. var self = this;
  13. db.database.query(TABLE_NAME, { accountId: id }, (err, result) => {
  14. if (!result)
  15. cb(null);
  16. let accConfigs = [];
  17. result.forEach((res) => {
  18. accConfigs.push(self.fromDb(res));
  19. });
  20. cb(accConfigs);
  21. });
  22. };
  23. AccountConfigManager.prototype.addToConfig = function(accountId, service, device, newConfig, now, cb) {
  24. var self = this;
  25. db.database.query(TABLE_NAME, { accountId: accountId }, (err, result) => {
  26. // Lazy create config for [ service, device ]
  27. if (result)
  28. for (var i =0, nbResults = result.length; i < nbResults; i++) {
  29. if (result[i].serviceId === service && result[i].deviceId === device) {
  30. let conf = self.fromDb(result[i]);
  31. conf.merge(newConfig, now);
  32. self.save(conf, cb);
  33. return;
  34. }
  35. }
  36. let conf = new AccountConfigWrapper();
  37. conf.accountId = accountId;
  38. conf.serviceId = service;
  39. conf.deviceId = device;
  40. conf.merge(newConfig, now);
  41. self.save(conf, cb);
  42. });
  43. };
  44. AccountConfigManager.prototype.fromAccountIdAndVersion = function(id, v, cb) {
  45. var self = this;
  46. db.database.query(TABLE_NAME, { accountId: id }, (err, result) => {
  47. if (!result)
  48. cb(null);
  49. for (var i =0, nbConfig = result.length; i < nbConfig; i++) {
  50. if (result[i].modified > v) {
  51. var configs = [];
  52. for (i =0; i < nbConfig; i++) {
  53. configs.push(self.fromDb(result[i]));
  54. }
  55. cb(configs);
  56. return;
  57. }
  58. }
  59. cb(null);
  60. });
  61. };
  62. AccountConfigManager.prototype.newConfigFor = function(account) {
  63. var conf = new AccountConfigWrapper();
  64. conf.dirty = true;
  65. conf.accountId = account.id;
  66. return conf;
  67. };
  68. AccountConfig.prototype.addService = function(serviceType, serviceName, serviceId) {
  69. if (!this.services[serviceType])
  70. this.services[serviceType] = {};
  71. this.services[serviceType][serviceId] = serviceName;
  72. };
  73. AccountConfig.prototype.merge = function(configBlob) {
  74. let modified = false;
  75. if (configBlob["emojiProvider"] !== undefined && configBlob["emojiProvider"] !== this.emojiProvider) {
  76. this.emojiProvider = configBlob["emojiProvider"];
  77. modified = true;
  78. }
  79. if (configBlob["displayAvatar"] !== undefined && configBlob["displayAvatar"] !== this.displayAvatar) {
  80. this.displayAvatar = configBlob["displayAvatar"];
  81. modified = true;
  82. }
  83. return modified;
  84. };
  85. AccountConfigManager.prototype.fromId = function(id, cb) {
  86. var self = this;
  87. db.database.queryFirst(TABLE_NAME, { id: id }, (err, result) => {
  88. cb(self.fromDb(result));
  89. });
  90. };
  91. AccountConfigManager.prototype.fromDb = function(dbResult) {
  92. if (!dbResult)
  93. return null;
  94. return new AccountConfigWrapper(dbResult);
  95. };
  96. function AccountConfigWrapper(dbResult) {
  97. this.id;
  98. this.accountId;
  99. this.serviceId; // Can be null, or a serviceId
  100. this.deviceId; // Can be null, or a deviceId
  101. this.config = new AccountConfig();
  102. this.modified; // modified ts
  103. if (dbResult) {
  104. this.id = dbResult.id;
  105. this.accountId = dbResult.accountId;
  106. this.serviceId = dbResult.serviceId;
  107. this.deviceId = dbResult.deviceId;
  108. this.config.fromDb(dbResult.config);
  109. this.modified = dbResult.modified;
  110. this.dirty = false;
  111. } else {
  112. this.id = null;
  113. this.accountId = null;
  114. this.serviceId = null;
  115. this.deviceId = null;
  116. this.modified = Date.now();
  117. this.dirty = true;
  118. }
  119. }
  120. AccountConfigWrapper.prototype.toDb = function() {
  121. return {
  122. accountId: this.accountId,
  123. serviceId: this.serviceId,
  124. deviceId: this.deviceId,
  125. config: this.config.toDb(),
  126. modified: this.modified
  127. };
  128. };
  129. AccountConfigWrapper.prototype.merge = function(configBlob, now) {
  130. if (this.config.merge(configBlob)) {
  131. this.edit(now);
  132. return true;
  133. }
  134. return false;
  135. };
  136. AccountConfigManager.prototype.save = function(account, cb) {
  137. if (!account.id) {
  138. // insert and save id
  139. var data = account.toDb();
  140. data.id = null;
  141. db.database.insert(TABLE_NAME, data, (newId) => {
  142. account.id = newId;
  143. account.dirty = false;
  144. if (cb) cb(account);
  145. });
  146. } else if (account.dirty) {
  147. // update
  148. db.database.update(TABLE_NAME, account.id, account.toDb(), () => {
  149. account.dirty = false;
  150. if (cb) cb(account);
  151. });
  152. } else {
  153. // not changed
  154. if (cb) cb(account);
  155. }
  156. };
  157. AccountConfigWrapper.prototype.expose = function() {
  158. return {
  159. service: this.serviceId,
  160. device: this.deviceId,
  161. config: this.config.toDb()
  162. };
  163. };
  164. AccountConfigWrapper.prototype.edit = function(now) {
  165. this.dirty = true;
  166. this.modified = Math.max(this.modified, now || Date.now());
  167. return this;
  168. };
  169. function AccountConfig() {
  170. this.services = {};
  171. }
  172. AccountConfig.prototype.toDb = function() {
  173. return JSON.stringify({
  174. services: this.services,
  175. emojiProvider: this.emojiProvider,
  176. displayAvatar: this.displayAvatar
  177. });
  178. };
  179. AccountConfig.prototype.fromDb = function(dbObj) {
  180. dbObj = JSON.parse(dbObj);
  181. this.services = dbObj.services || [];
  182. this.emojiProvider = dbObj.emojiProvider;
  183. this.displayAvatar = dbObj.displayAvatar;
  184. };
  185. module.exports.accountConfigManager = new AccountConfigManager();
  186. module.exports.updateTable = function(dbObject, currentVersion, cb) {
  187. if (!currentVersion) {
  188. console.info("Creating table " +TABLE_NAME);
  189. dbObject.run('CREATE TABLE IF NOT EXISTS `' +TABLE_NAME +'` ('
  190. +"`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
  191. +"`accountId` STRING NOT NULL,"
  192. +"`serviceId` STRING,"
  193. +"`deviceId` STRING,"
  194. +"`config` STRING NOT NULL,"
  195. +"`modified` INT NOT NULL"
  196. +');CREATE INDEX accconfigbyaccount ON ' +TABLE_NAME +'(accountId); CREATE UNIQUE INDEX accconfigUniq ON ' +TABLE_NAME +'(accountId, serviceId, deviceId)', cb);
  197. //TODO permanent login token array
  198. } else {
  199. cb(null);
  200. }
  201. };