2018-03-13 01:40:43 +02:00
|
|
|
const BaseModel = require('lib/BaseModel.js');
|
|
|
|
const Mutex = require('async-mutex').Mutex;
|
|
|
|
|
|
|
|
class ItemChange extends BaseModel {
|
|
|
|
static tableName() {
|
|
|
|
return 'item_changes';
|
|
|
|
}
|
|
|
|
|
|
|
|
static modelType() {
|
|
|
|
return BaseModel.TYPE_ITEM_CHANGE;
|
|
|
|
}
|
|
|
|
|
2019-05-06 22:35:29 +02:00
|
|
|
static async add(itemType, itemId, type, changeSource = null, beforeChangeItemJson = null) {
|
|
|
|
if (changeSource === null) changeSource = ItemChange.SOURCE_UNSPECIFIED;
|
|
|
|
if (!beforeChangeItemJson) beforeChangeItemJson = '';
|
|
|
|
|
2018-03-15 20:08:46 +02:00
|
|
|
ItemChange.saveCalls_.push(true);
|
|
|
|
|
|
|
|
// Using a mutex so that records can be added to the database in the
|
|
|
|
// background, without making the UI wait.
|
2018-03-13 01:40:43 +02:00
|
|
|
const release = await ItemChange.addChangeMutex_.acquire();
|
|
|
|
|
|
|
|
try {
|
2019-07-29 15:43:53 +02:00
|
|
|
await this.db().transactionExecBatch([{ sql: 'DELETE FROM item_changes WHERE item_id = ?', params: [itemId] }, { sql: 'INSERT INTO item_changes (item_type, item_id, type, source, created_time, before_change_item) VALUES (?, ?, ?, ?, ?, ?)', params: [itemType, itemId, type, changeSource, Date.now(), beforeChangeItemJson] }]);
|
2018-03-13 01:40:43 +02:00
|
|
|
} finally {
|
|
|
|
release();
|
2018-03-15 20:08:46 +02:00
|
|
|
ItemChange.saveCalls_.pop();
|
2018-03-13 01:40:43 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-13 18:05:07 +02:00
|
|
|
static async lastChangeId() {
|
|
|
|
const row = await this.db().selectOne('SELECT max(id) as max_id FROM item_changes');
|
|
|
|
return row && row.max_id ? row.max_id : 0;
|
|
|
|
}
|
|
|
|
|
2018-03-15 20:08:46 +02:00
|
|
|
// Because item changes are recorded in the background, this function
|
|
|
|
// can be used for synchronous code, in particular when unit testing.
|
|
|
|
static async waitForAllSaved() {
|
2019-09-13 00:16:42 +02:00
|
|
|
return new Promise((resolve) => {
|
2018-03-15 20:08:46 +02:00
|
|
|
const iid = setInterval(() => {
|
|
|
|
if (!ItemChange.saveCalls_.length) {
|
|
|
|
clearInterval(iid);
|
|
|
|
resolve();
|
|
|
|
}
|
|
|
|
}, 100);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-01-14 21:11:54 +02:00
|
|
|
static async deleteOldChanges(lowestChangeId) {
|
|
|
|
if (!lowestChangeId) return;
|
|
|
|
return this.db().exec('DELETE FROM item_changes WHERE id <= ?', [lowestChangeId]);
|
|
|
|
}
|
2018-03-13 01:40:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ItemChange.addChangeMutex_ = new Mutex();
|
2018-03-15 20:08:46 +02:00
|
|
|
ItemChange.saveCalls_ = [];
|
2018-03-13 01:40:43 +02:00
|
|
|
|
|
|
|
ItemChange.TYPE_CREATE = 1;
|
|
|
|
ItemChange.TYPE_UPDATE = 2;
|
|
|
|
ItemChange.TYPE_DELETE = 3;
|
|
|
|
|
2019-05-06 22:35:29 +02:00
|
|
|
ItemChange.SOURCE_UNSPECIFIED = 1;
|
|
|
|
ItemChange.SOURCE_SYNC = 2;
|
2019-05-28 19:10:21 +02:00
|
|
|
ItemChange.SOURCE_DECRYPTION = 2;
|
2019-05-06 22:35:29 +02:00
|
|
|
|
2019-07-29 15:43:53 +02:00
|
|
|
module.exports = ItemChange;
|