dbSync.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /**
  2. @module dbSync
  3. */
  4. const { ipcMain, ipcRenderer } = require('electron');
  5. /**
  6. * Sync IPC calls received from given window into given db table.
  7. * @param {Object} coll Db collection to save to.
  8. */
  9. exports.initializeListeners = function() {
  10. let log = require('./utils/logger').create('dbSync'),
  11. db = require('./db'),
  12. ipc = ipcMain;
  13. ipc.on('dbSync-add', (event, args) => {
  14. let collName = args.collName,
  15. coll = db.getCollection(`UI_${collName}`);
  16. log.trace('dbSync-add', collName, args._id);
  17. const _id = args._id;
  18. if (!coll.by('_id', _id)) {
  19. args.fields._id = _id;
  20. coll.insert(args.fields);
  21. }
  22. });
  23. ipc.on('dbSync-changed', (event, args) => {
  24. let collName = args.collName,
  25. coll = db.getCollection(`UI_${collName}`);
  26. log.trace('dbSync-changed', collName, args._id);
  27. const _id = args._id;
  28. const item = coll.by('_id', _id);
  29. if (item) {
  30. for (const k in args.fields) {
  31. if ({}.hasOwnProperty.call(args.fields, k)) {
  32. item[k] = args.fields[k];
  33. }
  34. }
  35. coll.update(item);
  36. } else {
  37. log.error('Item not found in db', _id);
  38. }
  39. });
  40. ipc.on('dbSync-removed', (event, args) => {
  41. let collName = args.collName,
  42. coll = db.getCollection(`UI_${collName}`);
  43. log.trace('dbSync-removed', collName, args._id);
  44. const _id = args._id;
  45. const item = coll.by('_id', _id);
  46. if (item) {
  47. coll.remove(item);
  48. } else {
  49. log.error('Item not found in db', _id);
  50. }
  51. });
  52. // Get all data (synchronous)
  53. ipc.on('dbSync-reloadSync', (event, args) => {
  54. let collName = args.collName,
  55. coll = db.getCollection(`UI_${collName}`),
  56. docs = coll.find();
  57. log.debug('dbSync-reloadSync, no. of docs:', collName, docs.length);
  58. docs = docs.map(doc => {
  59. const ret = {};
  60. for (const k in doc) {
  61. if (k !== 'meta' && k !== '$loki') {
  62. ret[k] = doc[k];
  63. }
  64. }
  65. return ret;
  66. });
  67. event.returnValue = docs;
  68. });
  69. };
  70. const syncDataFromBackend = function(coll) {
  71. const ipc = ipcRenderer;
  72. const collName = coll._name;
  73. console.debug('Load collection data from backend: ', collName);
  74. return new Promise((resolve, reject) => {
  75. const dataJson = ipc.sendSync('dbSync-reloadSync', {
  76. collName
  77. });
  78. try {
  79. let done = 0;
  80. coll.remove({});
  81. if (!dataJson.length) {
  82. resolve();
  83. }
  84. // we do inserts slowly, to avoid race conditions when it comes
  85. // to updating the UI
  86. dataJson.forEach(record => {
  87. Tracker.afterFlush(() => {
  88. try {
  89. // On Meteor startup if a record contains a redirect to about:blank
  90. // page, the application process crashes.
  91. if (
  92. _.isString(record.redirect) &&
  93. record.redirect.indexOf('//about:blank') > -1
  94. ) {
  95. record.redirect = null;
  96. }
  97. if (record._id) {
  98. coll.upsert(record._id, record);
  99. } else {
  100. coll.insert(record);
  101. }
  102. } catch (err) {
  103. console.error(err.toString());
  104. }
  105. done++;
  106. if (done >= dataJson.length) {
  107. resolve();
  108. }
  109. });
  110. });
  111. } catch (err) {
  112. reject(err);
  113. }
  114. });
  115. };
  116. exports.syncDataFromBackend = syncDataFromBackend;
  117. exports.frontendSyncInit = function(coll) {
  118. let ipc = ipcRenderer,
  119. syncDoneResolver;
  120. const collName = coll._name;
  121. coll.onceSynced = new Promise((resolve, reject) => {
  122. syncDoneResolver = resolve;
  123. });
  124. syncDataFromBackend(coll)
  125. .catch(err => {
  126. console.error(err.toString());
  127. })
  128. .then(() => {
  129. // start watching for changes
  130. coll.find().observeChanges({
  131. added(id, fields) {
  132. ipc.send('dbSync-add', {
  133. collName,
  134. _id: id,
  135. fields
  136. });
  137. },
  138. changed(id, fields) {
  139. ipc.send('dbSync-changed', {
  140. collName,
  141. _id: id,
  142. fields
  143. });
  144. },
  145. removed(id) {
  146. ipc.send('dbSync-removed', {
  147. collName,
  148. _id: id
  149. });
  150. }
  151. });
  152. console.debug('Sync collection data to backend started: ', collName);
  153. syncDoneResolver();
  154. });
  155. return coll;
  156. };