mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	refactored "sync" table to "entity_changes"
This commit is contained in:
		| @@ -1,4 +1,4 @@ | |||||||
| const syncTableService = require('../../src/services/sync_table'); | const syncTableService = require('../../src/services/entity_changes.js'); | ||||||
|  |  | ||||||
| // options has not been filled so far which caused problems with clean-slate sync. | // options has not been filled so far which caused problems with clean-slate sync. | ||||||
| module.exports = async () => await syncTableService.fillAllSyncRows(); | module.exports = async () => await syncTableService.fillAllSyncRows(); | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| const syncTableService = require('../../src/services/sync_table'); | const syncTableService = require('../../src/services/entity_changes.js'); | ||||||
|  |  | ||||||
| module.exports = async () => { | module.exports = async () => { | ||||||
|     await syncTableService.fillAllSyncRows(); |     await syncTableService.fillAllSyncRows(); | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								db/migrations/0163__rename_sync_to_entity_changes.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								db/migrations/0163__rename_sync_to_entity_changes.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | ALTER TABLE sync RENAME TO entity_changes; | ||||||
| @@ -102,11 +102,6 @@ class Attribute extends Entity { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // cannot be static! |  | ||||||
|     updatePojo(pojo) { |  | ||||||
|         delete pojo.__note; // FIXME: probably note necessary anymore |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     createClone(type, name, value, isInheritable) { |     createClone(type, name, value, isInheritable) { | ||||||
|         return new Attribute({ |         return new Attribute({ | ||||||
|             noteId: this.noteId, |             noteId: this.noteId, | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ const protectedSessionService = require('../services/protected_session'); | |||||||
| const sql = require('../services/sql'); | const sql = require('../services/sql'); | ||||||
| const utils = require('../services/utils'); | const utils = require('../services/utils'); | ||||||
| const dateUtils = require('../services/date_utils'); | const dateUtils = require('../services/date_utils'); | ||||||
| const syncTableService = require('../services/sync_table'); | const entityChangesService = require('../services/entity_changes.js'); | ||||||
|  |  | ||||||
| const LABEL = 'label'; | const LABEL = 'label'; | ||||||
| const LABEL_DEFINITION = 'label-definition'; | const LABEL_DEFINITION = 'label-definition'; | ||||||
| @@ -154,7 +154,7 @@ class Note extends Entity { | |||||||
|  |  | ||||||
|         sql.upsert("note_contents", "noteId", pojo); |         sql.upsert("note_contents", "noteId", pojo); | ||||||
|  |  | ||||||
|         syncTableService.addNoteContentSync(this.noteId); |         entityChangesService.addNoteContentSync(this.noteId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     setJsonContent(content) { |     setJsonContent(content) { | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ const protectedSessionService = require('../services/protected_session'); | |||||||
| const utils = require('../services/utils'); | const utils = require('../services/utils'); | ||||||
| const sql = require('../services/sql'); | const sql = require('../services/sql'); | ||||||
| const dateUtils = require('../services/date_utils'); | const dateUtils = require('../services/date_utils'); | ||||||
| const syncTableService = require('../services/sync_table'); | const entityChangesService = require('../services/entity_changes.js'); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * NoteRevision represents snapshot of note's title and content at some point in the past. It's used for seamless note versioning. |  * NoteRevision represents snapshot of note's title and content at some point in the past. It's used for seamless note versioning. | ||||||
| @@ -126,7 +126,7 @@ class NoteRevision extends Entity { | |||||||
|  |  | ||||||
|         sql.upsert("note_revision_contents", "noteRevisionId", pojo); |         sql.upsert("note_revision_contents", "noteRevisionId", pojo); | ||||||
|  |  | ||||||
|         syncTableService.addNoteRevisionContentSync(this.noteRevisionId); |         entityChangesService.addNoteRevisionContentSync(this.noteRevisionId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     beforeSaving() { |     beforeSaving() { | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ export default class AdvancedOptions { | |||||||
|         $("#options-advanced").html(TPL); |         $("#options-advanced").html(TPL); | ||||||
|  |  | ||||||
|         this.$forceFullSyncButton = $("#force-full-sync-button"); |         this.$forceFullSyncButton = $("#force-full-sync-button"); | ||||||
|         this.$fillSyncRowsButton = $("#fill-sync-rows-button"); |         this.$fillEntityChangesButton = $("#fill-sync-rows-button"); | ||||||
|         this.$anonymizeButton = $("#anonymize-button"); |         this.$anonymizeButton = $("#anonymize-button"); | ||||||
|         this.$backupDatabaseButton = $("#backup-database-button"); |         this.$backupDatabaseButton = $("#backup-database-button"); | ||||||
|         this.$vacuumDatabaseButton = $("#vacuum-database-button"); |         this.$vacuumDatabaseButton = $("#vacuum-database-button"); | ||||||
| @@ -53,7 +53,7 @@ export default class AdvancedOptions { | |||||||
|             toastService.showMessage("Full sync triggered"); |             toastService.showMessage("Full sync triggered"); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         this.$fillSyncRowsButton.on('click', async () => { |         this.$fillEntityChangesButton.on('click', async () => { | ||||||
|             await server.post('sync/fill-sync-rows'); |             await server.post('sync/fill-sync-rows'); | ||||||
|  |  | ||||||
|             toastService.showMessage("Sync rows filled successfully"); |             toastService.showMessage("Sync rows filled successfully"); | ||||||
|   | |||||||
| @@ -72,7 +72,7 @@ export default class Entrypoints extends Component { | |||||||
|             isProtected: todayNote.isProtected |             isProtected: todayNote.isProtected | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         await ws.waitForMaxKnownSyncId(); |         await ws.waitForMaxKnownEntityChangeId(); | ||||||
|  |  | ||||||
|         await appContext.tabManager.openTabWithNote(note.noteId, true); |         await appContext.tabManager.openTabWithNote(note.noteId, true); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -67,7 +67,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain | |||||||
|      * @return {Promise<void>} |      * @return {Promise<void>} | ||||||
|      */ |      */ | ||||||
|     this.activateNewNote = async notePath => { |     this.activateNewNote = async notePath => { | ||||||
|         await ws.waitForMaxKnownSyncId(); |         await ws.waitForMaxKnownEntityChangeId(); | ||||||
|  |  | ||||||
|         await appContext.tabManager.getActiveTabContext().setNote(notePath); |         await appContext.tabManager.getActiveTabContext().setNote(notePath); | ||||||
|         appContext.triggerEvent('focusAndSelectTitle'); |         appContext.triggerEvent('focusAndSelectTitle'); | ||||||
| @@ -152,7 +152,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain | |||||||
|  |  | ||||||
|         if (ret.success) { |         if (ret.success) { | ||||||
|             // wait until all the changes done in the script has been synced to frontend before continuing |             // wait until all the changes done in the script has been synced to frontend before continuing | ||||||
|             await ws.waitForSyncId(ret.maxSyncId); |             await ws.waitForEntityChangeId(ret.maxEntityChangeId); | ||||||
|  |  | ||||||
|             return ret.executionResult; |             return ret.executionResult; | ||||||
|         } |         } | ||||||
| @@ -402,7 +402,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain | |||||||
|      * |      * | ||||||
|      * @method |      * @method | ||||||
|      */ |      */ | ||||||
|     this.waitUntilSynced = ws.waitForMaxKnownSyncId; |     this.waitUntilSynced = ws.waitForMaxKnownEntityChangeId; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * This will refresh all currently opened notes which have included note specified in the parameter |      * This will refresh all currently opened notes which have included note specified in the parameter | ||||||
|   | |||||||
| @@ -49,7 +49,7 @@ async function createNote(parentNoteId, options = {}) { | |||||||
|         window.cutToNote.removeSelection(); |         window.cutToNote.removeSelection(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     await ws.waitForMaxKnownSyncId(); |     await ws.waitForMaxKnownEntityChangeId(); | ||||||
|  |  | ||||||
|     if (options.activate) { |     if (options.activate) { | ||||||
|         const activeTabContext = appContext.tabManager.getActiveTabContext(); |         const activeTabContext = appContext.tabManager.getActiveTabContext(); | ||||||
| @@ -91,7 +91,7 @@ function parseSelectedHtml(selectedHtml) { | |||||||
| async function duplicateNote(noteId, parentNoteId) { | async function duplicateNote(noteId, parentNoteId) { | ||||||
|     const {note} = await server.post(`notes/${noteId}/duplicate/${parentNoteId}`); |     const {note} = await server.post(`notes/${noteId}/duplicate/${parentNoteId}`); | ||||||
|  |  | ||||||
|     await ws.waitForMaxKnownSyncId(); |     await ws.waitForMaxKnownEntityChangeId(); | ||||||
|  |  | ||||||
|     await appContext.tabManager.activateOrOpenNote(note.noteId); |     await appContext.tabManager.activateOrOpenNote(note.noteId); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -45,7 +45,7 @@ async function remove(url, sourceId) { | |||||||
| let i = 1; | let i = 1; | ||||||
| const reqResolves = {}; | const reqResolves = {}; | ||||||
|  |  | ||||||
| let maxKnownSyncId = 0; | let maxKnownEntityChangeId = 0; | ||||||
|  |  | ||||||
| async function call(method, url, data, headers = {}) { | async function call(method, url, data, headers = {}) { | ||||||
|     let resp; |     let resp; | ||||||
| @@ -82,10 +82,10 @@ async function call(method, url, data, headers = {}) { | |||||||
|         console.log(`${method} ${url} took ${end - start}ms`); |         console.log(`${method} ${url} took ${end - start}ms`); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const maxSyncIdStr = resp.headers['trilium-max-sync-id']; |     const maxEntityChangeIdStr = resp.headers['trilium-max-entity-change-id']; | ||||||
|  |  | ||||||
|     if (maxSyncIdStr && maxSyncIdStr.trim()) { |     if (maxEntityChangeIdStr && maxEntityChangeIdStr.trim()) { | ||||||
|         maxKnownSyncId = Math.max(maxKnownSyncId, parseInt(maxSyncIdStr)); |         maxKnownEntityChangeId = Math.max(maxKnownEntityChangeId, parseInt(maxEntityChangeIdStr)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return resp.body; |     return resp.body; | ||||||
| @@ -160,5 +160,5 @@ export default { | |||||||
|     ajax, |     ajax, | ||||||
|     // don't remove, used from CKEditor image upload! |     // don't remove, used from CKEditor image upload! | ||||||
|     getHeaders, |     getHeaders, | ||||||
|     getMaxKnownSyncId: () => maxKnownSyncId |     getMaxKnownEntityChangeId: () => maxKnownEntityChangeId | ||||||
| }; | }; | ||||||
| @@ -13,8 +13,8 @@ const $outstandingSyncsCount = $("#outstanding-syncs-count"); | |||||||
| const messageHandlers = []; | const messageHandlers = []; | ||||||
|  |  | ||||||
| let ws; | let ws; | ||||||
| let lastAcceptedSyncId = window.glob.maxSyncIdAtLoad; | let lastAcceptedEntityChangeId = window.glob.maxEntityChangeIdAtLoad; | ||||||
| let lastProcessedSyncId = window.glob.maxSyncIdAtLoad; | let lastProcessedEntityChangeId = window.glob.maxEntityChangeIdAtLoad; | ||||||
| let lastPingTs; | let lastPingTs; | ||||||
| let syncDataQueue = []; | let syncDataQueue = []; | ||||||
|  |  | ||||||
| @@ -38,13 +38,12 @@ function subscribeToMessages(messageHandler) { | |||||||
| // used to serialize sync operations | // used to serialize sync operations | ||||||
| let consumeQueuePromise = null; | let consumeQueuePromise = null; | ||||||
|  |  | ||||||
| // most sync events are sent twice - once immediatelly after finishing the transaction and once during the scheduled ping | // to make sure each change event is processed only once. Not clear if this is still necessary | ||||||
| // but we want to process only once | const processedEntityChangeIds = new Set(); | ||||||
| const processedSyncIds = new Set(); |  | ||||||
|  |  | ||||||
| function logRows(syncRows) { | function logRows(syncRows) { | ||||||
|     const filteredRows = syncRows.filter(row => |     const filteredRows = syncRows.filter(row => | ||||||
|         !processedSyncIds.has(row.id) |         !processedEntityChangeIds.has(row.id) | ||||||
|         && row.entityName !== 'recent_notes' |         && row.entityName !== 'recent_notes' | ||||||
|         && (row.entityName !== 'options' || row.entityId !== 'openTabs')); |         && (row.entityName !== 'options' || row.entityId !== 'openTabs')); | ||||||
|  |  | ||||||
| @@ -71,8 +70,8 @@ async function handleMessage(event) { | |||||||
|  |  | ||||||
|             syncDataQueue.push(...syncRows); |             syncDataQueue.push(...syncRows); | ||||||
|  |  | ||||||
|             // we set lastAcceptedSyncId even before sync processing and send ping so that backend can start sending more updates |             // we set lastAcceptedEntityChangeId even before sync processing and send ping so that backend can start sending more updates | ||||||
|             lastAcceptedSyncId = Math.max(lastAcceptedSyncId, syncRows[syncRows.length - 1].id); |             lastAcceptedEntityChangeId = Math.max(lastAcceptedEntityChangeId, syncRows[syncRows.length - 1].id); | ||||||
|             sendPing(); |             sendPing(); | ||||||
|  |  | ||||||
|             // first wait for all the preceding consumers to finish |             // first wait for all the preceding consumers to finish | ||||||
| @@ -100,38 +99,38 @@ async function handleMessage(event) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| let syncIdReachedListeners = []; | let entityChangeIdReachedListeners = []; | ||||||
|  |  | ||||||
| function waitForSyncId(desiredSyncId) { | function waitForEntityChangeId(desiredEntityChangeId) { | ||||||
|     if (desiredSyncId <= lastProcessedSyncId) { |     if (desiredEntityChangeId <= lastProcessedEntityChangeId) { | ||||||
|         return Promise.resolve(); |         return Promise.resolve(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     console.debug("Waiting for", desiredSyncId, 'current is', lastProcessedSyncId); |     console.debug("Waiting for", desiredEntityChangeId, 'current is', lastProcessedEntityChangeId); | ||||||
|  |  | ||||||
|     return new Promise((res, rej) => { |     return new Promise((res, rej) => { | ||||||
|         syncIdReachedListeners.push({ |         entityChangeIdReachedListeners.push({ | ||||||
|             desiredSyncId, |             desiredEntityChangeId: desiredEntityChangeId, | ||||||
|             resolvePromise: res, |             resolvePromise: res, | ||||||
|             start: Date.now() |             start: Date.now() | ||||||
|         }) |         }) | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| function waitForMaxKnownSyncId() { | function waitForMaxKnownEntityChangeId() { | ||||||
|     return waitForSyncId(server.getMaxKnownSyncId()); |     return waitForEntityChangeId(server.getMaxKnownEntityChangeId()); | ||||||
| } | } | ||||||
|  |  | ||||||
| function checkSyncIdListeners() { | function checkEntityChangeIdListeners() { | ||||||
|     syncIdReachedListeners |     entityChangeIdReachedListeners | ||||||
|         .filter(l => l.desiredSyncId <= lastProcessedSyncId) |         .filter(l => l.desiredEntityChangeId <= lastProcessedEntityChangeId) | ||||||
|         .forEach(l => l.resolvePromise()); |         .forEach(l => l.resolvePromise()); | ||||||
|  |  | ||||||
|     syncIdReachedListeners = syncIdReachedListeners |     entityChangeIdReachedListeners = entityChangeIdReachedListeners | ||||||
|         .filter(l => l.desiredSyncId > lastProcessedSyncId); |         .filter(l => l.desiredEntityChangeId > lastProcessedEntityChangeId); | ||||||
|  |  | ||||||
|     syncIdReachedListeners.filter(l => Date.now() > l.start - 60000) |     entityChangeIdReachedListeners.filter(l => Date.now() > l.start - 60000) | ||||||
|         .forEach(l => console.log(`Waiting for syncId ${l.desiredSyncId} while current is ${lastProcessedSyncId} for ${Math.floor((Date.now() - l.start) / 1000)}s`)); |         .forEach(l => console.log(`Waiting for entityChangeId ${l.desiredEntityChangeId} while current is ${lastProcessedEntityChangeId} for ${Math.floor((Date.now() - l.start) / 1000)}s`)); | ||||||
| } | } | ||||||
|  |  | ||||||
| async function runSafely(syncHandler, syncData) { | async function runSafely(syncHandler, syncData) { | ||||||
| @@ -143,18 +142,12 @@ async function runSafely(syncHandler, syncData) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * TODO: we should rethink the fact that each sync row is sent twice (once at the end of transaction, once periodically) |  | ||||||
|  *       and we keep both lastProcessedSyncId and processedSyncIds |  | ||||||
|  *       it even seems incorrect that when transaction sync rows are received, we incorrectly increase lastProcessedSyncId |  | ||||||
|  *       and then some syncs might lost (or are *all* sync rows sent from transactions?) |  | ||||||
|  */ |  | ||||||
| async function consumeSyncData() { | async function consumeSyncData() { | ||||||
|     if (syncDataQueue.length > 0) { |     if (syncDataQueue.length > 0) { | ||||||
|         const allSyncRows = syncDataQueue; |         const allSyncRows = syncDataQueue; | ||||||
|         syncDataQueue = []; |         syncDataQueue = []; | ||||||
|  |  | ||||||
|         const nonProcessedSyncRows = allSyncRows.filter(sync => !processedSyncIds.has(sync.id)); |         const nonProcessedSyncRows = allSyncRows.filter(sync => !processedEntityChangeIds.has(sync.id)); | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
|             await utils.timeLimit(processSyncRows(nonProcessedSyncRows), 5000); |             await utils.timeLimit(processSyncRows(nonProcessedSyncRows), 5000); | ||||||
| @@ -167,13 +160,13 @@ async function consumeSyncData() { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         for (const syncRow of nonProcessedSyncRows) { |         for (const syncRow of nonProcessedSyncRows) { | ||||||
|             processedSyncIds.add(syncRow.id); |             processedEntityChangeIds.add(syncRow.id); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         lastProcessedSyncId = Math.max(lastProcessedSyncId, allSyncRows[allSyncRows.length - 1].id); |         lastProcessedEntityChangeId = Math.max(lastProcessedEntityChangeId, allSyncRows[allSyncRows.length - 1].id); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     checkSyncIdListeners(); |     checkEntityChangeIdListeners(); | ||||||
| } | } | ||||||
|  |  | ||||||
| function connectWebSocket() { | function connectWebSocket() { | ||||||
| @@ -198,7 +191,7 @@ async function sendPing() { | |||||||
|     if (ws.readyState === ws.OPEN) { |     if (ws.readyState === ws.OPEN) { | ||||||
|         ws.send(JSON.stringify({ |         ws.send(JSON.stringify({ | ||||||
|             type: 'ping', |             type: 'ping', | ||||||
|             lastSyncId: lastAcceptedSyncId |             lastEntityChangeId: lastAcceptedEntityChangeId | ||||||
|         })); |         })); | ||||||
|     } |     } | ||||||
|     else if (ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) { |     else if (ws.readyState === ws.CLOSED || ws.readyState === ws.CLOSING) { | ||||||
| @@ -394,6 +387,6 @@ async function processSyncRows(syncRows) { | |||||||
| export default { | export default { | ||||||
|     logError, |     logError, | ||||||
|     subscribeToMessages, |     subscribeToMessages, | ||||||
|     waitForSyncId, |     waitForEntityChangeId, | ||||||
|     waitForMaxKnownSyncId |     waitForMaxKnownEntityChangeId | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|  |  | ||||||
| const sql = require('../../services/sql'); | const sql = require('../../services/sql'); | ||||||
| const utils = require('../../services/utils'); | const utils = require('../../services/utils'); | ||||||
| const syncTableService = require('../../services/sync_table'); | const entityChangesService = require('../../services/entity_changes.js'); | ||||||
| const treeService = require('../../services/tree'); | const treeService = require('../../services/tree'); | ||||||
| const noteService = require('../../services/notes'); | const noteService = require('../../services/notes'); | ||||||
| const repository = require('../../services/repository'); | const repository = require('../../services/repository'); | ||||||
| @@ -66,7 +66,7 @@ function moveBranchBeforeNote(req) { | |||||||
|     sql.execute("UPDATE branches SET notePosition = notePosition + 10 WHERE parentNoteId = ? AND notePosition >= ? AND isDeleted = 0", |     sql.execute("UPDATE branches SET notePosition = notePosition + 10 WHERE parentNoteId = ? AND notePosition >= ? AND isDeleted = 0", | ||||||
|         [beforeNote.parentNoteId, beforeNote.notePosition]); |         [beforeNote.parentNoteId, beforeNote.notePosition]); | ||||||
|  |  | ||||||
|     syncTableService.addNoteReorderingSync(beforeNote.parentNoteId); |     entityChangesService.addNoteReorderingSync(beforeNote.parentNoteId); | ||||||
|  |  | ||||||
|     if (branchToMove.parentNoteId === beforeNote.parentNoteId) { |     if (branchToMove.parentNoteId === beforeNote.parentNoteId) { | ||||||
|         branchToMove.notePosition = beforeNote.notePosition; |         branchToMove.notePosition = beforeNote.notePosition; | ||||||
| @@ -100,7 +100,7 @@ function moveBranchAfterNote(req) { | |||||||
|     sql.execute("UPDATE branches SET notePosition = notePosition + 10 WHERE parentNoteId = ? AND notePosition > ? AND isDeleted = 0", |     sql.execute("UPDATE branches SET notePosition = notePosition + 10 WHERE parentNoteId = ? AND notePosition > ? AND isDeleted = 0", | ||||||
|         [afterNote.parentNoteId, afterNote.notePosition]); |         [afterNote.parentNoteId, afterNote.notePosition]); | ||||||
|  |  | ||||||
|     syncTableService.addNoteReorderingSync(afterNote.parentNoteId); |     entityChangesService.addNoteReorderingSync(afterNote.parentNoteId); | ||||||
|  |  | ||||||
|     const movedNotePosition = afterNote.notePosition + 10; |     const movedNotePosition = afterNote.notePosition + 10; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -49,7 +49,7 @@ function loginSync(req) { | |||||||
|  |  | ||||||
|     return { |     return { | ||||||
|         sourceId: sourceIdService.getCurrentSourceId(), |         sourceId: sourceIdService.getCurrentSourceId(), | ||||||
|         maxSyncId: sql.getValue("SELECT COALESCE(MAX(id), 0) FROM sync WHERE isSynced = 1") |         maxEntityChangeId: sql.getValue("SELECT COALESCE(MAX(id), 0) FROM entity_changes WHERE isSynced = 1") | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ function exec(req) { | |||||||
|         return { |         return { | ||||||
|             success: true, |             success: true, | ||||||
|             executionResult: result, |             executionResult: result, | ||||||
|             maxSyncId: syncService.getMaxSyncId() |             maxEntityChangeId: syncService.getMaxEntityChangeId() | ||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
|     catch (e) { |     catch (e) { | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|  |  | ||||||
| const syncService = require('../../services/sync'); | const syncService = require('../../services/sync'); | ||||||
| const syncUpdateService = require('../../services/sync_update'); | const syncUpdateService = require('../../services/sync_update'); | ||||||
| const syncTableService = require('../../services/sync_table'); | const entityChangesService = require('../../services/entity_changes.js'); | ||||||
| const sql = require('../../services/sql'); | const sql = require('../../services/sql'); | ||||||
| const sqlInit = require('../../services/sql_init'); | const sqlInit = require('../../services/sql_init'); | ||||||
| const optionService = require('../../services/options'); | const optionService = require('../../services/options'); | ||||||
| @@ -50,7 +50,7 @@ function getStats() { | |||||||
| function checkSync() { | function checkSync() { | ||||||
|     return { |     return { | ||||||
|         entityHashes: contentHashService.getEntityHashes(), |         entityHashes: contentHashService.getEntityHashes(), | ||||||
|         maxSyncId: sql.getValue('SELECT COALESCE(MAX(id), 0) FROM sync WHERE isSynced = 1') |         maxEntityChangeId: sql.getValue('SELECT COALESCE(MAX(id), 0) FROM entity_changes WHERE isSynced = 1') | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -60,8 +60,8 @@ function syncNow() { | |||||||
|     return syncService.sync(); |     return syncService.sync(); | ||||||
| } | } | ||||||
|  |  | ||||||
| function fillSyncRows() { | function fillEntityChanges() { | ||||||
|     syncTableService.fillAllSyncRows(); |     entityChangesService.fillAllEntityChanges(); | ||||||
|  |  | ||||||
|     log.info("Sync rows have been filled."); |     log.info("Sync rows have been filled."); | ||||||
| } | } | ||||||
| @@ -82,32 +82,32 @@ function forceNoteSync(req) { | |||||||
|     const now = dateUtils.utcNowDateTime(); |     const now = dateUtils.utcNowDateTime(); | ||||||
|  |  | ||||||
|     sql.execute(`UPDATE notes SET utcDateModified = ? WHERE noteId = ?`, [now, noteId]); |     sql.execute(`UPDATE notes SET utcDateModified = ? WHERE noteId = ?`, [now, noteId]); | ||||||
|     syncTableService.addNoteSync(noteId); |     entityChangesService.addNoteSync(noteId); | ||||||
|  |  | ||||||
|     sql.execute(`UPDATE note_contents SET utcDateModified = ? WHERE noteId = ?`, [now, noteId]); |     sql.execute(`UPDATE note_contents SET utcDateModified = ? WHERE noteId = ?`, [now, noteId]); | ||||||
|     syncTableService.addNoteContentSync(noteId); |     entityChangesService.addNoteContentSync(noteId); | ||||||
|  |  | ||||||
|     for (const branchId of sql.getColumn("SELECT branchId FROM branches WHERE noteId = ?", [noteId])) { |     for (const branchId of sql.getColumn("SELECT branchId FROM branches WHERE noteId = ?", [noteId])) { | ||||||
|         sql.execute(`UPDATE branches SET utcDateModified = ? WHERE branchId = ?`, [now, branchId]); |         sql.execute(`UPDATE branches SET utcDateModified = ? WHERE branchId = ?`, [now, branchId]); | ||||||
|  |  | ||||||
|         syncTableService.addBranchSync(branchId); |         entityChangesService.addBranchSync(branchId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     for (const attributeId of sql.getColumn("SELECT attributeId FROM attributes WHERE noteId = ?", [noteId])) { |     for (const attributeId of sql.getColumn("SELECT attributeId FROM attributes WHERE noteId = ?", [noteId])) { | ||||||
|         sql.execute(`UPDATE attributes SET utcDateModified = ? WHERE attributeId = ?`, [now, attributeId]); |         sql.execute(`UPDATE attributes SET utcDateModified = ? WHERE attributeId = ?`, [now, attributeId]); | ||||||
|  |  | ||||||
|         syncTableService.addAttributeSync(attributeId); |         entityChangesService.addAttributeSync(attributeId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     for (const noteRevisionId of sql.getColumn("SELECT noteRevisionId FROM note_revisions WHERE noteId = ?", [noteId])) { |     for (const noteRevisionId of sql.getColumn("SELECT noteRevisionId FROM note_revisions WHERE noteId = ?", [noteId])) { | ||||||
|         sql.execute(`UPDATE note_revisions SET utcDateModified = ? WHERE noteRevisionId = ?`, [now, noteRevisionId]); |         sql.execute(`UPDATE note_revisions SET utcDateModified = ? WHERE noteRevisionId = ?`, [now, noteRevisionId]); | ||||||
|         syncTableService.addNoteRevisionSync(noteRevisionId); |         entityChangesService.addNoteRevisionSync(noteRevisionId); | ||||||
|  |  | ||||||
|         sql.execute(`UPDATE note_revision_contents SET utcDateModified = ? WHERE noteRevisionId = ?`, [now, noteRevisionId]); |         sql.execute(`UPDATE note_revision_contents SET utcDateModified = ? WHERE noteRevisionId = ?`, [now, noteRevisionId]); | ||||||
|         syncTableService.addNoteRevisionContentSync(noteRevisionId); |         entityChangesService.addNoteRevisionContentSync(noteRevisionId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     syncTableService.addRecentNoteSync(noteId); |     entityChangesService.addRecentNoteSync(noteId); | ||||||
|  |  | ||||||
|     log.info("Forcing note sync for " + noteId); |     log.info("Forcing note sync for " + noteId); | ||||||
|  |  | ||||||
| @@ -118,17 +118,17 @@ function forceNoteSync(req) { | |||||||
| function getChanged(req) { | function getChanged(req) { | ||||||
|     const startTime = Date.now(); |     const startTime = Date.now(); | ||||||
|  |  | ||||||
|     const lastSyncId = parseInt(req.query.lastSyncId); |     const lastEntityChangeId = parseInt(req.query.lastEntityChangedId); | ||||||
|  |  | ||||||
|     const syncs = sql.getRows("SELECT * FROM sync WHERE isSynced = 1 AND id > ? LIMIT 1000", [lastSyncId]); |     const entityChanges = sql.getRows("SELECT * FROM entity_changes WHERE isSynced = 1 AND id > ? LIMIT 1000", [lastEntityChangeId]); | ||||||
|  |  | ||||||
|     const ret = { |     const ret = { | ||||||
|         syncs: syncService.getSyncRecords(syncs), |         syncs: syncService.getEntityChangesRecords(entityChanges), | ||||||
|         maxSyncId: sql.getValue('SELECT COALESCE(MAX(id), 0) FROM sync WHERE isSynced = 1') |         maxEntityChangeId: sql.getValue('SELECT COALESCE(MAX(id), 0) FROM entity_changes WHERE isSynced = 1') | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     if (ret.syncs.length > 0) { |     if (ret.syncs.length > 0) { | ||||||
|         log.info(`Returning ${ret.syncs.length} sync records in ${Date.now() - startTime}ms`); |         log.info(`Returning ${ret.syncs.length} entity changes in ${Date.now() - startTime}ms`); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return ret; |     return ret; | ||||||
| @@ -155,14 +155,14 @@ function queueSector(req) { | |||||||
|  |  | ||||||
|     const entityPrimaryKey = entityConstructor.getEntityFromEntityName(entityName).primaryKeyName; |     const entityPrimaryKey = entityConstructor.getEntityFromEntityName(entityName).primaryKeyName; | ||||||
|  |  | ||||||
|     syncTableService.addEntitySyncsForSector(entityName, entityPrimaryKey, sector); |     entityChangesService.addEntityChangesForSector(entityName, entityPrimaryKey, sector); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|     testSync, |     testSync, | ||||||
|     checkSync, |     checkSync, | ||||||
|     syncNow, |     syncNow, | ||||||
|     fillSyncRows, |     fillEntityChanges, | ||||||
|     forceFullSync, |     forceFullSync, | ||||||
|     forceNoteSync, |     forceNoteSync, | ||||||
|     getChanged, |     getChanged, | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ function index(req, res) { | |||||||
|         treeFontSize: parseInt(options.treeFontSize), |         treeFontSize: parseInt(options.treeFontSize), | ||||||
|         detailFontSize: parseInt(options.detailFontSize), |         detailFontSize: parseInt(options.detailFontSize), | ||||||
|         sourceId: sourceIdService.generateSourceId(), |         sourceId: sourceIdService.generateSourceId(), | ||||||
|         maxSyncIdAtLoad: sql.getValue("SELECT COALESCE(MAX(id), 0) FROM sync"), |         maxEntityChangeIdAtLoad: sql.getValue("SELECT COALESCE(MAX(id), 0) FROM entity_changes"), | ||||||
|         instanceName: config.General ? config.General.instanceName : null, |         instanceName: config.General ? config.General.instanceName : null, | ||||||
|         appCssNoteIds: getAppCssNoteIds(), |         appCssNoteIds: getAppCssNoteIds(), | ||||||
|         isDev: env.isDev(), |         isDev: env.isDev(), | ||||||
|   | |||||||
| @@ -45,7 +45,7 @@ const auth = require('../services/auth'); | |||||||
| const cls = require('../services/cls'); | const cls = require('../services/cls'); | ||||||
| const sql = require('../services/sql'); | const sql = require('../services/sql'); | ||||||
| const protectedSessionService = require('../services/protected_session'); | const protectedSessionService = require('../services/protected_session'); | ||||||
| const syncTableService = require('../services/sync_table'); | const entityChangesService = require('../services/entity_changes.js'); | ||||||
| const csurf = require('csurf'); | const csurf = require('csurf'); | ||||||
|  |  | ||||||
| const csrfMiddleware = csurf({ | const csrfMiddleware = csurf({ | ||||||
| @@ -54,7 +54,7 @@ const csrfMiddleware = csurf({ | |||||||
| }); | }); | ||||||
|  |  | ||||||
| function apiResultHandler(req, res, result) { | function apiResultHandler(req, res, result) { | ||||||
|     res.setHeader('trilium-max-sync-id', syncTableService.getMaxSyncId()); |     res.setHeader('trilium-max-entity-change-id', entityChangesService.getMaxEntityChangeId()); | ||||||
|  |  | ||||||
|     // if it's an array and first element is integer then we consider this to be [statusCode, response] format |     // if it's an array and first element is integer then we consider this to be [statusCode, response] format | ||||||
|     if (Array.isArray(result) && result.length > 0 && Number.isInteger(result[0])) { |     if (Array.isArray(result) && result.length > 0 && Number.isInteger(result[0])) { | ||||||
| @@ -205,7 +205,7 @@ function register(app) { | |||||||
|  |  | ||||||
|     apiRoute(POST, '/api/sync/test', syncApiRoute.testSync); |     apiRoute(POST, '/api/sync/test', syncApiRoute.testSync); | ||||||
|     apiRoute(POST, '/api/sync/now', syncApiRoute.syncNow); |     apiRoute(POST, '/api/sync/now', syncApiRoute.syncNow); | ||||||
|     apiRoute(POST, '/api/sync/fill-sync-rows', syncApiRoute.fillSyncRows); |     apiRoute(POST, '/api/sync/fill-sync-rows', syncApiRoute.fillEntityChanges); | ||||||
|     apiRoute(POST, '/api/sync/force-full-sync', syncApiRoute.forceFullSync); |     apiRoute(POST, '/api/sync/force-full-sync', syncApiRoute.forceFullSync); | ||||||
|     apiRoute(POST, '/api/sync/force-note-sync/:noteId', syncApiRoute.forceNoteSync); |     apiRoute(POST, '/api/sync/force-note-sync/:noteId', syncApiRoute.forceNoteSync); | ||||||
|     route(GET, '/api/sync/check', [auth.checkApiAuth], syncApiRoute.checkSync, apiResultHandler); |     route(GET, '/api/sync/check', [auth.checkApiAuth], syncApiRoute.checkSync, apiResultHandler); | ||||||
|   | |||||||
| @@ -4,8 +4,8 @@ const build = require('./build'); | |||||||
| const packageJson = require('../../package'); | const packageJson = require('../../package'); | ||||||
| const {TRILIUM_DATA_DIR} = require('./data_dir'); | const {TRILIUM_DATA_DIR} = require('./data_dir'); | ||||||
|  |  | ||||||
| const APP_DB_VERSION = 162; | const APP_DB_VERSION = 163; | ||||||
| const SYNC_VERSION = 14; | const SYNC_VERSION = 15; | ||||||
| const CLIPPER_PROTOCOL_VERSION = "1.0"; | const CLIPPER_PROTOCOL_VERSION = "1.0"; | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| "use strict"; | "use strict"; | ||||||
|  |  | ||||||
| const sql = require('./sql'); | const sql = require('./sql'); | ||||||
| const syncTable = require('./sync_table'); | const syncTable = require('./entity_changes.js'); | ||||||
| const treeService = require('./tree'); | const treeService = require('./tree'); | ||||||
| const noteService = require('./notes'); | const noteService = require('./notes'); | ||||||
| const repository = require('./repository'); | const repository = require('./repository'); | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ const ws = require('./ws.js'); | |||||||
| const syncMutexService = require('./sync_mutex'); | const syncMutexService = require('./sync_mutex'); | ||||||
| const repository = require('./repository'); | const repository = require('./repository'); | ||||||
| const cls = require('./cls'); | const cls = require('./cls'); | ||||||
| const syncTableService = require('./sync_table'); | const entityChangesService = require('./entity_changes.js'); | ||||||
| const optionsService = require('./options'); | const optionsService = require('./options'); | ||||||
| const Branch = require('../entities/branch'); | const Branch = require('../entities/branch'); | ||||||
| const dateUtils = require('./date_utils'); | const dateUtils = require('./date_utils'); | ||||||
| @@ -300,7 +300,7 @@ class ConsistencyChecks { | |||||||
|                             utcDateModified: dateUtils.utcNowDateTime() |                             utcDateModified: dateUtils.utcNowDateTime() | ||||||
|                         }); |                         }); | ||||||
|  |  | ||||||
|                         syncTableService.addNoteContentSync(noteId); |                         entityChangesService.addNoteContentSync(noteId); | ||||||
|                     } |                     } | ||||||
|                     else { |                     else { | ||||||
|                         // empty string might be wrong choice for some note types but it's a best guess |                         // empty string might be wrong choice for some note types but it's a best guess | ||||||
| @@ -566,7 +566,7 @@ class ConsistencyChecks { | |||||||
|           sync.id IS NULL AND ` + (entityName === 'options' ? 'options.isSynced = 1' : '1'), |           sync.id IS NULL AND ` + (entityName === 'options' ? 'options.isSynced = 1' : '1'), | ||||||
|             ({entityId}) => { |             ({entityId}) => { | ||||||
|                 if (this.autoFix) { |                 if (this.autoFix) { | ||||||
|                     syncTableService.addEntitySync(entityName, entityId); |                     entityChangesService.addEntityChange(entityName, entityId); | ||||||
|  |  | ||||||
|                     logFix(`Created missing sync record for entityName=${entityName}, entityId=${entityId}`); |                     logFix(`Created missing sync record for entityName=${entityName}, entityId=${entityId}`); | ||||||
|                 } else { |                 } else { | ||||||
| @@ -585,7 +585,7 @@ class ConsistencyChecks { | |||||||
|               AND ${key} IS NULL`, |               AND ${key} IS NULL`, | ||||||
|                 ({id, entityId}) => { |                 ({id, entityId}) => { | ||||||
|                     if (this.autoFix) { |                     if (this.autoFix) { | ||||||
|                         sql.execute("DELETE FROM sync WHERE entityName = ? AND entityId = ?", [entityName, entityId]); |                         sql.execute("DELETE FROM entity_changes WHERE entityName = ? AND entityId = ?", [entityName, entityId]); | ||||||
|  |  | ||||||
|                         logFix(`Deleted extra sync record id=${id}, entityName=${entityName}, entityId=${entityId}`); |                         logFix(`Deleted extra sync record id=${id}, entityName=${entityName}, entityId=${entityId}`); | ||||||
|                     } else { |                     } else { | ||||||
|   | |||||||
| @@ -1,16 +1,12 @@ | |||||||
| /** |  | ||||||
|  * TODO: rename "sync" table to something like "changelog" since it now also contains rows which are not synced (isSynced=false) |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| const sql = require('./sql'); | const sql = require('./sql'); | ||||||
| const sourceIdService = require('./source_id'); | const sourceIdService = require('./source_id'); | ||||||
| const dateUtils = require('./date_utils'); | const dateUtils = require('./date_utils'); | ||||||
| const log = require('./log'); | const log = require('./log'); | ||||||
| const cls = require('./cls'); | const cls = require('./cls'); | ||||||
| 
 | 
 | ||||||
| let maxSyncId = 0; | let maxEntityChangeId = 0; | ||||||
| 
 | 
 | ||||||
| function insertEntitySync(entityName, entityId, sourceId = null, isSynced = true) { | function insertEntityChange(entityName, entityId, sourceId = null, isSynced = true) { | ||||||
|     const sync = { |     const sync = { | ||||||
|         entityName: entityName, |         entityName: entityName, | ||||||
|         entityId: entityId, |         entityId: entityId, | ||||||
| @@ -21,18 +17,18 @@ function insertEntitySync(entityName, entityId, sourceId = null, isSynced = true | |||||||
| 
 | 
 | ||||||
|     sync.id = sql.replace("sync", sync); |     sync.id = sql.replace("sync", sync); | ||||||
| 
 | 
 | ||||||
|     maxSyncId = Math.max(maxSyncId, sync.id); |     maxEntityChangeId = Math.max(maxEntityChangeId, sync.id); | ||||||
| 
 | 
 | ||||||
|     return sync; |     return sync; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function addEntitySync(entityName, entityId, sourceId, isSynced) { | function addEntityChange(entityName, entityId, sourceId, isSynced) { | ||||||
|     const sync = insertEntitySync(entityName, entityId, sourceId, isSynced); |     const sync = insertEntityChange(entityName, entityId, sourceId, isSynced); | ||||||
| 
 | 
 | ||||||
|     cls.addSyncRow(sync); |     cls.addSyncRow(sync); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function addEntitySyncsForSector(entityName, entityPrimaryKey, sector) { | function addEntityChangesForSector(entityName, entityPrimaryKey, sector) { | ||||||
|     const startTime = Date.now(); |     const startTime = Date.now(); | ||||||
| 
 | 
 | ||||||
|     sql.transactional(() => { |     sql.transactional(() => { | ||||||
| @@ -47,7 +43,7 @@ function addEntitySyncsForSector(entityName, entityPrimaryKey, sector) { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             insertEntitySync(entityName, entityId, 'content-check', true); |             insertEntityChange(entityName, entityId, 'content-check', true); | ||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
| @@ -57,12 +53,12 @@ function addEntitySyncsForSector(entityName, entityPrimaryKey, sector) { | |||||||
| function cleanupSyncRowsForMissingEntities(entityName, entityPrimaryKey) { | function cleanupSyncRowsForMissingEntities(entityName, entityPrimaryKey) { | ||||||
|     sql.execute(` |     sql.execute(` | ||||||
|       DELETE  |       DELETE  | ||||||
|       FROM sync  |       FROM entity_changes  | ||||||
|       WHERE sync.entityName = '${entityName}'  |       WHERE sync.entityName = '${entityName}'  | ||||||
|         AND sync.entityId NOT IN (SELECT ${entityPrimaryKey} FROM ${entityName})`);
 |         AND sync.entityId NOT IN (SELECT ${entityPrimaryKey} FROM ${entityName})`);
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function fillSyncRows(entityName, entityPrimaryKey, condition = '') { | function fillEntityChanges(entityName, entityPrimaryKey, condition = '') { | ||||||
|     try { |     try { | ||||||
|         cleanupSyncRowsForMissingEntities(entityName, entityPrimaryKey); |         cleanupSyncRowsForMissingEntities(entityName, entityPrimaryKey); | ||||||
| 
 | 
 | ||||||
| @@ -72,7 +68,7 @@ function fillSyncRows(entityName, entityPrimaryKey, condition = '') { | |||||||
|         let createdCount = 0; |         let createdCount = 0; | ||||||
| 
 | 
 | ||||||
|         for (const entityId of entityIds) { |         for (const entityId of entityIds) { | ||||||
|             const existingRows = sql.getValue("SELECT COUNT(1) FROM sync WHERE entityName = ? AND entityId = ?", [entityName, entityId]); |             const existingRows = sql.getValue("SELECT COUNT(1) FROM entity_changes WHERE entityName = ? AND entityId = ?", [entityName, entityId]); | ||||||
| 
 | 
 | ||||||
|             // we don't want to replace existing entities (which would effectively cause full resync)
 |             // we don't want to replace existing entities (which would effectively cause full resync)
 | ||||||
|             if (existingRows === 0) { |             if (existingRows === 0) { | ||||||
| @@ -99,35 +95,35 @@ function fillSyncRows(entityName, entityPrimaryKey, condition = '') { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function fillAllSyncRows() { | function fillAllEntityChanges() { | ||||||
|     sql.transactional(() => { |     sql.transactional(() => { | ||||||
|         sql.execute("DELETE FROM sync"); |         sql.execute("DELETE FROM entity_changes"); | ||||||
| 
 | 
 | ||||||
|         fillSyncRows("notes", "noteId"); |         fillEntityChanges("notes", "noteId"); | ||||||
|         fillSyncRows("note_contents", "noteId"); |         fillEntityChanges("note_contents", "noteId"); | ||||||
|         fillSyncRows("branches", "branchId"); |         fillEntityChanges("branches", "branchId"); | ||||||
|         fillSyncRows("note_revisions", "noteRevisionId"); |         fillEntityChanges("note_revisions", "noteRevisionId"); | ||||||
|         fillSyncRows("note_revision_contents", "noteRevisionId"); |         fillEntityChanges("note_revision_contents", "noteRevisionId"); | ||||||
|         fillSyncRows("recent_notes", "noteId"); |         fillEntityChanges("recent_notes", "noteId"); | ||||||
|         fillSyncRows("attributes", "attributeId"); |         fillEntityChanges("attributes", "attributeId"); | ||||||
|         fillSyncRows("api_tokens", "apiTokenId"); |         fillEntityChanges("api_tokens", "apiTokenId"); | ||||||
|         fillSyncRows("options", "name", 'isSynced = 1'); |         fillEntityChanges("options", "name", 'isSynced = 1'); | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = { | ||||||
|     addNoteSync: (noteId, sourceId) => addEntitySync("notes", noteId, sourceId), |     addNoteSync: (noteId, sourceId) => addEntityChange("notes", noteId, sourceId), | ||||||
|     addNoteContentSync: (noteId, sourceId) => addEntitySync("note_contents", noteId, sourceId), |     addNoteContentSync: (noteId, sourceId) => addEntityChange("note_contents", noteId, sourceId), | ||||||
|     addBranchSync: (branchId, sourceId) => addEntitySync("branches", branchId, sourceId), |     addBranchSync: (branchId, sourceId) => addEntityChange("branches", branchId, sourceId), | ||||||
|     addNoteReorderingSync: (parentNoteId, sourceId) => addEntitySync("note_reordering", parentNoteId, sourceId), |     addNoteReorderingSync: (parentNoteId, sourceId) => addEntityChange("note_reordering", parentNoteId, sourceId), | ||||||
|     addNoteRevisionSync: (noteRevisionId, sourceId) => addEntitySync("note_revisions", noteRevisionId, sourceId), |     addNoteRevisionSync: (noteRevisionId, sourceId) => addEntityChange("note_revisions", noteRevisionId, sourceId), | ||||||
|     addNoteRevisionContentSync: (noteRevisionId, sourceId) => addEntitySync("note_revision_contents", noteRevisionId, sourceId), |     addNoteRevisionContentSync: (noteRevisionId, sourceId) => addEntityChange("note_revision_contents", noteRevisionId, sourceId), | ||||||
|     addOptionsSync: (name, sourceId, isSynced) => addEntitySync("options", name, sourceId, isSynced), |     addOptionsSync: (name, sourceId, isSynced) => addEntityChange("options", name, sourceId, isSynced), | ||||||
|     addRecentNoteSync: (noteId, sourceId) => addEntitySync("recent_notes", noteId, sourceId), |     addRecentNoteSync: (noteId, sourceId) => addEntityChange("recent_notes", noteId, sourceId), | ||||||
|     addAttributeSync: (attributeId, sourceId) => addEntitySync("attributes", attributeId, sourceId), |     addAttributeSync: (attributeId, sourceId) => addEntityChange("attributes", attributeId, sourceId), | ||||||
|     addApiTokenSync: (apiTokenId, sourceId) => addEntitySync("api_tokens", apiTokenId, sourceId), |     addApiTokenSync: (apiTokenId, sourceId) => addEntityChange("api_tokens", apiTokenId, sourceId), | ||||||
|     addEntitySync, |     addEntityChange, | ||||||
|     fillAllSyncRows, |     fillAllEntityChanges, | ||||||
|     addEntitySyncsForSector, |     addEntityChangesForSector, | ||||||
|     getMaxSyncId: () => maxSyncId |     getMaxEntityChangeId: () => maxEntityChangeId | ||||||
| }; | }; | ||||||
| @@ -31,7 +31,7 @@ function load() { | |||||||
| } | } | ||||||
|  |  | ||||||
| eventService.subscribe([eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED, eventService.ENTITY_SYNCED],  ({entityName, entity}) => { | eventService.subscribe([eventService.ENTITY_CHANGED, eventService.ENTITY_DELETED, eventService.ENTITY_SYNCED],  ({entityName, entity}) => { | ||||||
|     // note that entity can also be just POJO without methods if coming from sync |     // note that entity can also be just POJO without methods if coming FROM entity_changes | ||||||
|  |  | ||||||
|     if (!noteCache.loaded) { |     if (!noteCache.loaded) { | ||||||
|         return; |         return; | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ const sql = require('./sql'); | |||||||
| const sqlInit = require('./sql_init'); | const sqlInit = require('./sql_init'); | ||||||
| const optionService = require('./options'); | const optionService = require('./options'); | ||||||
| const dateUtils = require('./date_utils'); | const dateUtils = require('./date_utils'); | ||||||
| const syncTableService = require('./sync_table'); | const entityChangesService = require('./entity_changes.js'); | ||||||
| const eventService = require('./events'); | const eventService = require('./events'); | ||||||
| const repository = require('./repository'); | const repository = require('./repository'); | ||||||
| const cls = require('../services/cls'); | const cls = require('../services/cls'); | ||||||
| @@ -159,7 +159,7 @@ function createNewNoteWithTarget(target, targetBranchId, params) { | |||||||
|  |  | ||||||
|         const retObject = createNewNote(params); |         const retObject = createNewNote(params); | ||||||
|  |  | ||||||
|         syncTableService.addNoteReorderingSync(params.parentNoteId); |         entityChangesService.addNoteReorderingSync(params.parentNoteId); | ||||||
|  |  | ||||||
|         return retObject; |         return retObject; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| "use strict"; | "use strict"; | ||||||
|  |  | ||||||
| const sql = require('./sql'); | const sql = require('./sql'); | ||||||
| const syncTableService = require('../services/sync_table'); | const entityChangesService = require('./entity_changes.js'); | ||||||
| const eventService = require('./events'); | const eventService = require('./events'); | ||||||
| const cls = require('./cls'); | const cls = require('./cls'); | ||||||
| const entityConstructor = require('../entities/entity_constructor'); | const entityConstructor = require('../entities/entity_constructor'); | ||||||
| @@ -119,7 +119,7 @@ function updateEntity(entity) { | |||||||
|         if (entity.isChanged) { |         if (entity.isChanged) { | ||||||
|             const isSynced = entityName !== 'options' || entity.isSynced; |             const isSynced = entityName !== 'options' || entity.isSynced; | ||||||
|  |  | ||||||
|             syncTableService.addEntitySync(entityName, primaryKey, null, isSynced); |             entityChangesService.addEntityChange(entityName, primaryKey, null, isSynced); | ||||||
|  |  | ||||||
|             if (!cls.isEntityEventsDisabled()) { |             if (!cls.isEntityEventsDisabled()) { | ||||||
|                 const eventPayload = { |                 const eventPayload = { | ||||||
|   | |||||||
| @@ -64,7 +64,7 @@ async function setupSyncFromSyncServer(syncServerHost, syncProxy, username, pass | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     try { |     try { | ||||||
|         log.info("Getting document options from sync server."); |         log.info("Getting document options FROM entity_changes server."); | ||||||
|  |  | ||||||
|         // response is expected to contain documentId and documentSecret options |         // response is expected to contain documentId and documentSecret options | ||||||
|         const resp = await request.exec({ |         const resp = await request.exec({ | ||||||
|   | |||||||
| @@ -84,8 +84,6 @@ async function createInitialDatabase(username, password, theme) { | |||||||
|     const zipImportService = require("./import/zip"); |     const zipImportService = require("./import/zip"); | ||||||
|     await zipImportService.importZip(dummyTaskContext, demoFile, rootNote); |     await zipImportService.importZip(dummyTaskContext, demoFile, rootNote); | ||||||
|  |  | ||||||
|     require('./sync_table').fillAllSyncRows(); |  | ||||||
|  |  | ||||||
|     sql.transactional(() => { |     sql.transactional(() => { | ||||||
|         const startNoteId = sql.getValue("SELECT noteId FROM branches WHERE parentNoteId = 'root' AND isDeleted = 0 ORDER BY notePosition"); |         const startNoteId = sql.getValue("SELECT noteId FROM branches WHERE parentNoteId = 'root' AND isDeleted = 0 ORDER BY notePosition"); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ const syncMutexService = require('./sync_mutex'); | |||||||
| const cls = require('./cls'); | const cls = require('./cls'); | ||||||
| const request = require('./request'); | const request = require('./request'); | ||||||
| const ws = require('./ws'); | const ws = require('./ws'); | ||||||
| const syncTableService = require('./sync_table'); | const entityChangesService = require('./entity_changes.js'); | ||||||
| const entityConstructor = require('../entities/entity_constructor'); | const entityConstructor = require('../entities/entity_constructor'); | ||||||
|  |  | ||||||
| let proxyToggle = true; | let proxyToggle = true; | ||||||
| @@ -113,10 +113,10 @@ async function doLogin() { | |||||||
|  |  | ||||||
|     // this is important in a scenario where we setup the sync by manually copying the document |     // this is important in a scenario where we setup the sync by manually copying the document | ||||||
|     // lastSyncedPull then could be pretty off for the newly cloned client |     // lastSyncedPull then could be pretty off for the newly cloned client | ||||||
|     if (lastSyncedPull > resp.maxSyncId) { |     if (lastSyncedPull > resp.maxEntityChangeId) { | ||||||
|         log.info(`Lowering last synced pull from ${lastSyncedPull} to ${resp.maxSyncId}`); |         log.info(`Lowering last synced pull from ${lastSyncedPull} to ${resp.maxEntityChangeId}`); | ||||||
|  |  | ||||||
|         setLastSyncedPull(resp.maxSyncId); |         setLastSyncedPull(resp.maxEntityChangeId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return syncContext; |     return syncContext; | ||||||
| @@ -127,7 +127,7 @@ async function pullSync(syncContext) { | |||||||
|  |  | ||||||
|     while (true) { |     while (true) { | ||||||
|         const lastSyncedPull = getLastSyncedPull(); |         const lastSyncedPull = getLastSyncedPull(); | ||||||
|         const changesUri = '/api/sync/changed?lastSyncId=' + lastSyncedPull; |         const changesUri = '/api/sync/changed?lastEntityChangeId=' + lastSyncedPull; | ||||||
|  |  | ||||||
|         const startDate = Date.now(); |         const startDate = Date.now(); | ||||||
|  |  | ||||||
| @@ -135,7 +135,7 @@ async function pullSync(syncContext) { | |||||||
|  |  | ||||||
|         const pulledDate = Date.now(); |         const pulledDate = Date.now(); | ||||||
|  |  | ||||||
|         stats.outstandingPulls = resp.maxSyncId - lastSyncedPull; |         stats.outstandingPulls = resp.maxEntityChangeId - lastSyncedPull; | ||||||
|  |  | ||||||
|         if (stats.outstandingPulls < 0) { |         if (stats.outstandingPulls < 0) { | ||||||
|             stats.outstandingPulls = 0; |             stats.outstandingPulls = 0; | ||||||
| @@ -159,13 +159,13 @@ async function pullSync(syncContext) { | |||||||
|                     syncUpdateService.updateEntity(sync, entity, syncContext.sourceId); |                     syncUpdateService.updateEntity(sync, entity, syncContext.sourceId); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 stats.outstandingPulls = resp.maxSyncId - sync.id; |                 stats.outstandingPulls = resp.maxEntityChangeId - sync.id; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             setLastSyncedPull(rows[rows.length - 1].sync.id); |             setLastSyncedPull(rows[rows.length - 1].sync.id); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         log.info(`Pulled ${rows.length} changes starting at syncId=${lastSyncedPull} in ${pulledDate - startDate}ms and applied them in ${Date.now() - pulledDate}ms, ${stats.outstandingPulls} outstanding pulls`); |         log.info(`Pulled ${rows.length} changes starting at entityChangeId=${lastSyncedPull} in ${pulledDate - startDate}ms and applied them in ${Date.now() - pulledDate}ms, ${stats.outstandingPulls} outstanding pulls`); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (atLeastOnePullApplied) { |     if (atLeastOnePullApplied) { | ||||||
| @@ -179,7 +179,7 @@ async function pushSync(syncContext) { | |||||||
|     let lastSyncedPush = getLastSyncedPush(); |     let lastSyncedPush = getLastSyncedPush(); | ||||||
|  |  | ||||||
|     while (true) { |     while (true) { | ||||||
|         const syncs = sql.getRows('SELECT * FROM sync WHERE isSynced = 1 AND id > ? LIMIT 1000', [lastSyncedPush]); |         const syncs = sql.getRows('SELECT * FROM entity_changes WHERE isSynced = 1 AND id > ? LIMIT 1000', [lastSyncedPush]); | ||||||
|  |  | ||||||
|         if (syncs.length === 0) { |         if (syncs.length === 0) { | ||||||
|             log.info("Nothing to push"); |             log.info("Nothing to push"); | ||||||
| @@ -209,7 +209,7 @@ async function pushSync(syncContext) { | |||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         const syncRecords = getSyncRecords(filteredSyncs); |         const syncRecords = getEntityChangesRecords(filteredSyncs); | ||||||
|         const startDate = new Date(); |         const startDate = new Date(); | ||||||
|  |  | ||||||
|         await syncRequest(syncContext, 'PUT', '/api/sync/update', { |         await syncRequest(syncContext, 'PUT', '/api/sync/update', { | ||||||
| @@ -233,13 +233,13 @@ async function checkContentHash(syncContext) { | |||||||
|     const resp = await syncRequest(syncContext, 'GET', '/api/sync/check'); |     const resp = await syncRequest(syncContext, 'GET', '/api/sync/check'); | ||||||
|     const lastSyncedPullId = getLastSyncedPull(); |     const lastSyncedPullId = getLastSyncedPull(); | ||||||
|  |  | ||||||
|     if (lastSyncedPullId < resp.maxSyncId) { |     if (lastSyncedPullId < resp.maxEntityChangeId) { | ||||||
|         log.info(`There are some outstanding pulls (${lastSyncedPullId} vs. ${resp.maxSyncId}), skipping content check.`); |         log.info(`There are some outstanding pulls (${lastSyncedPullId} vs. ${resp.maxEntityChangeId}), skipping content check.`); | ||||||
|  |  | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const notPushedSyncs = sql.getValue("SELECT EXISTS(SELECT 1 FROM sync WHERE isSynced = 1 AND id > ?)", [getLastSyncedPush()]); |     const notPushedSyncs = sql.getValue("SELECT EXISTS(SELECT 1 FROM entity_changes WHERE isSynced = 1 AND id > ?)", [getLastSyncedPush()]); | ||||||
|  |  | ||||||
|     if (notPushedSyncs) { |     if (notPushedSyncs) { | ||||||
|         log.info(`There's ${notPushedSyncs} outstanding pushes, skipping content check.`); |         log.info(`There's ${notPushedSyncs} outstanding pushes, skipping content check.`); | ||||||
| @@ -252,7 +252,7 @@ async function checkContentHash(syncContext) { | |||||||
|     for (const {entityName, sector} of failedChecks) { |     for (const {entityName, sector} of failedChecks) { | ||||||
|         const entityPrimaryKey = entityConstructor.getEntityFromEntityName(entityName).primaryKeyName; |         const entityPrimaryKey = entityConstructor.getEntityFromEntityName(entityName).primaryKeyName; | ||||||
|  |  | ||||||
|         syncTableService.addEntitySyncsForSector(entityName, entityPrimaryKey, sector); |         entityChangesService.addEntityChangesForSector(entityName, entityPrimaryKey, sector); | ||||||
|  |  | ||||||
|         await syncRequest(syncContext, 'POST', `/api/sync/queue-sector/${entityName}/${sector}`); |         await syncRequest(syncContext, 'POST', `/api/sync/queue-sector/${entityName}/${sector}`); | ||||||
|     } |     } | ||||||
| @@ -287,7 +287,7 @@ const primaryKeys = { | |||||||
|     "attributes": "attributeId" |     "attributes": "attributeId" | ||||||
| }; | }; | ||||||
|  |  | ||||||
| function getEntityRow(entityName, entityId) { | function getEntityChangeRow(entityName, entityId) { | ||||||
|     if (entityName === 'note_reordering') { |     if (entityName === 'note_reordering') { | ||||||
|         return sql.getMap("SELECT branchId, notePosition FROM branches WHERE parentNoteId = ? AND isDeleted = 0", [entityId]); |         return sql.getMap("SELECT branchId, notePosition FROM branches WHERE parentNoteId = ? AND isDeleted = 0", [entityId]); | ||||||
|     } |     } | ||||||
| @@ -316,20 +316,20 @@ function getEntityRow(entityName, entityId) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function getSyncRecords(syncs) { | function getEntityChangesRecords(entityChanges) { | ||||||
|     const records = []; |     const records = []; | ||||||
|     let length = 0; |     let length = 0; | ||||||
|  |  | ||||||
|     for (const sync of syncs) { |     for (const entityChange of entityChanges) { | ||||||
|         const entity = getEntityRow(sync.entityName, sync.entityId); |         const entity = getEntityChangeRow(entityChange.entityName, entityChange.entityId); | ||||||
|  |  | ||||||
|         if (sync.entityName === 'options' && !entity.isSynced) { |         if (entityChange.entityName === 'options' && !entity.isSynced) { | ||||||
|             records.push({sync}); |             records.push({entityChange}); | ||||||
|  |  | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         const record = { sync, entity }; |         const record = { entityChange, entity }; | ||||||
|  |  | ||||||
|         records.push(record); |         records.push(record); | ||||||
|  |  | ||||||
| @@ -347,8 +347,8 @@ function getLastSyncedPull() { | |||||||
|     return parseInt(optionService.getOption('lastSyncedPull')); |     return parseInt(optionService.getOption('lastSyncedPull')); | ||||||
| } | } | ||||||
|  |  | ||||||
| function setLastSyncedPull(syncId) { | function setLastSyncedPull(entityChangeId) { | ||||||
|     optionService.setOption('lastSyncedPull', syncId); |     optionService.setOption('lastSyncedPull', entityChangeId); | ||||||
| } | } | ||||||
|  |  | ||||||
| function getLastSyncedPush() { | function getLastSyncedPush() { | ||||||
| @@ -363,12 +363,12 @@ function updatePushStats() { | |||||||
|     if (syncOptions.isSyncSetup()) { |     if (syncOptions.isSyncSetup()) { | ||||||
|         const lastSyncedPush = optionService.getOption('lastSyncedPush'); |         const lastSyncedPush = optionService.getOption('lastSyncedPush'); | ||||||
|  |  | ||||||
|         stats.outstandingPushes = sql.getValue("SELECT COUNT(1) FROM sync WHERE isSynced = 1 AND id > ?", [lastSyncedPush]); |         stats.outstandingPushes = sql.getValue("SELECT COUNT(1) FROM entity_changes WHERE isSynced = 1 AND id > ?", [lastSyncedPush]); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| function getMaxSyncId() { | function getMaxEntityChangeId() { | ||||||
|     return sql.getValue('SELECT COALESCE(MAX(id), 0) FROM sync'); |     return sql.getValue('SELECT COALESCE(MAX(id), 0) FROM entity_changes'); | ||||||
| } | } | ||||||
|  |  | ||||||
| sqlInit.dbReady.then(() => { | sqlInit.dbReady.then(() => { | ||||||
| @@ -383,7 +383,7 @@ sqlInit.dbReady.then(() => { | |||||||
| module.exports = { | module.exports = { | ||||||
|     sync, |     sync, | ||||||
|     login, |     login, | ||||||
|     getSyncRecords, |     getEntityChangesRecords, | ||||||
|     stats, |     stats, | ||||||
|     getMaxSyncId |     getMaxEntityChangeId | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| const sql = require('./sql'); | const sql = require('./sql'); | ||||||
| const log = require('./log'); | const log = require('./log'); | ||||||
| const syncTableService = require('./sync_table'); | const entityChangesService = require('./entity_changes.js'); | ||||||
| const eventService = require('./events'); | const eventService = require('./events'); | ||||||
|  |  | ||||||
| function updateEntity(sync, entity, sourceId) { | function updateEntity(sync, entity, sourceId) { | ||||||
| @@ -86,7 +86,7 @@ function updateNote(remoteEntity, sourceId) { | |||||||
|         sql.transactional(() => { |         sql.transactional(() => { | ||||||
|             sql.replace("notes", remoteEntity); |             sql.replace("notes", remoteEntity); | ||||||
|  |  | ||||||
|             syncTableService.addNoteSync(remoteEntity.noteId, sourceId); |             entityChangesService.addNoteSync(remoteEntity.noteId, sourceId); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         return true; |         return true; | ||||||
| @@ -104,7 +104,7 @@ function updateNoteContent(remoteEntity, sourceId) { | |||||||
|         sql.transactional(() => { |         sql.transactional(() => { | ||||||
|             sql.replace("note_contents", remoteEntity); |             sql.replace("note_contents", remoteEntity); | ||||||
|  |  | ||||||
|             syncTableService.addNoteContentSync(remoteEntity.noteId, sourceId); |             entityChangesService.addNoteContentSync(remoteEntity.noteId, sourceId); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         return true; |         return true; | ||||||
| @@ -126,7 +126,7 @@ function updateBranch(remoteEntity, sourceId) { | |||||||
|  |  | ||||||
|             sql.replace('branches', remoteEntity); |             sql.replace('branches', remoteEntity); | ||||||
|  |  | ||||||
|             syncTableService.addBranchSync(remoteEntity.branchId, sourceId); |             entityChangesService.addBranchSync(remoteEntity.branchId, sourceId); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         return true; |         return true; | ||||||
| @@ -142,7 +142,7 @@ function updateNoteRevision(remoteEntity, sourceId) { | |||||||
|         if (shouldWeUpdateEntity(localEntity, remoteEntity)) { |         if (shouldWeUpdateEntity(localEntity, remoteEntity)) { | ||||||
|             sql.replace('note_revisions', remoteEntity); |             sql.replace('note_revisions', remoteEntity); | ||||||
|  |  | ||||||
|             syncTableService.addNoteRevisionSync(remoteEntity.noteRevisionId, sourceId); |             entityChangesService.addNoteRevisionSync(remoteEntity.noteRevisionId, sourceId); | ||||||
|  |  | ||||||
|             log.info("Update/sync note revision " + remoteEntity.noteRevisionId); |             log.info("Update/sync note revision " + remoteEntity.noteRevisionId); | ||||||
|         } |         } | ||||||
| @@ -158,7 +158,7 @@ function updateNoteRevisionContent(remoteEntity, sourceId) { | |||||||
|  |  | ||||||
|             sql.replace('note_revision_contents', remoteEntity); |             sql.replace('note_revision_contents', remoteEntity); | ||||||
|  |  | ||||||
|             syncTableService.addNoteRevisionContentSync(remoteEntity.noteRevisionId, sourceId); |             entityChangesService.addNoteRevisionContentSync(remoteEntity.noteRevisionId, sourceId); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         return true; |         return true; | ||||||
| @@ -173,7 +173,7 @@ function updateNoteReordering(entityId, remote, sourceId) { | |||||||
|             sql.execute("UPDATE branches SET notePosition = ? WHERE branchId = ?", [remote[key], key]); |             sql.execute("UPDATE branches SET notePosition = ? WHERE branchId = ?", [remote[key], key]); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         syncTableService.addNoteReorderingSync(entityId, sourceId); |         entityChangesService.addNoteReorderingSync(entityId, sourceId); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     return true; |     return true; | ||||||
| @@ -190,7 +190,7 @@ function updateOptions(remoteEntity, sourceId) { | |||||||
|         sql.transactional(() => { |         sql.transactional(() => { | ||||||
|             sql.replace('options', remoteEntity); |             sql.replace('options', remoteEntity); | ||||||
|  |  | ||||||
|             syncTableService.addOptionsSync(remoteEntity.name, sourceId, true); |             entityChangesService.addOptionsSync(remoteEntity.name, sourceId, true); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         return true; |         return true; | ||||||
| @@ -206,7 +206,7 @@ function updateRecentNotes(remoteEntity, sourceId) { | |||||||
|         sql.transactional(() => { |         sql.transactional(() => { | ||||||
|             sql.replace('recent_notes', remoteEntity); |             sql.replace('recent_notes', remoteEntity); | ||||||
|  |  | ||||||
|             syncTableService.addRecentNoteSync(remoteEntity.noteId, sourceId); |             entityChangesService.addRecentNoteSync(remoteEntity.noteId, sourceId); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         return true; |         return true; | ||||||
| @@ -222,7 +222,7 @@ function updateAttribute(remoteEntity, sourceId) { | |||||||
|         sql.transactional(() => { |         sql.transactional(() => { | ||||||
|             sql.replace("attributes", remoteEntity); |             sql.replace("attributes", remoteEntity); | ||||||
|  |  | ||||||
|             syncTableService.addAttributeSync(remoteEntity.attributeId, sourceId); |             entityChangesService.addAttributeSync(remoteEntity.attributeId, sourceId); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         return true; |         return true; | ||||||
| @@ -238,7 +238,7 @@ function updateApiToken(entity, sourceId) { | |||||||
|         sql.transactional(() => { |         sql.transactional(() => { | ||||||
|             sql.replace("api_tokens", entity); |             sql.replace("api_tokens", entity); | ||||||
|  |  | ||||||
|             syncTableService.addApiTokenSync(entity.apiTokenId, sourceId); |             entityChangesService.addApiTokenSync(entity.apiTokenId, sourceId); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         return true; |         return true; | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| const sql = require('./sql'); | const sql = require('./sql'); | ||||||
| const repository = require('./repository'); | const repository = require('./repository'); | ||||||
| const Branch = require('../entities/branch'); | const Branch = require('../entities/branch'); | ||||||
| const syncTableService = require('./sync_table'); | const entityChangesService = require('./entity_changes.js'); | ||||||
| const protectedSessionService = require('./protected_session'); | const protectedSessionService = require('./protected_session'); | ||||||
|  |  | ||||||
| function getNotes(noteIds) { | function getNotes(noteIds) { | ||||||
| @@ -138,7 +138,7 @@ function sortNotesAlphabetically(parentNoteId, directoriesFirst = false) { | |||||||
|             position += 10; |             position += 10; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         syncTableService.addNoteReorderingSync(parentNoteId); |         entityChangesService.addNoteReorderingSync(parentNoteId); | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -47,7 +47,7 @@ | |||||||
|     window.glob = { |     window.glob = { | ||||||
|         activeDialog: null, |         activeDialog: null, | ||||||
|         sourceId: '<%= sourceId %>', |         sourceId: '<%= sourceId %>', | ||||||
|         maxSyncIdAtLoad: <%= maxSyncIdAtLoad %>, |         maxEntityChangeIdAtLoad: <%= maxEntityChangeIdAtLoad %>, | ||||||
|         instanceName: '<%= instanceName %>', |         instanceName: '<%= instanceName %>', | ||||||
|         csrfToken: '<%= csrfToken %>', |         csrfToken: '<%= csrfToken %>', | ||||||
|         isDev: <%= isDev %>, |         isDev: <%= isDev %>, | ||||||
|   | |||||||
| @@ -111,7 +111,7 @@ | |||||||
|     window.glob = { |     window.glob = { | ||||||
|         activeDialog: null, |         activeDialog: null, | ||||||
|         sourceId: '<%= sourceId %>', |         sourceId: '<%= sourceId %>', | ||||||
|         maxSyncIdAtLoad: <%= maxSyncIdAtLoad %>, |         maxEntityChangeIdAtLoad: <%= maxEntityChangeIdAtLoad %>, | ||||||
|         instanceName: '<%= instanceName %>', |         instanceName: '<%= instanceName %>', | ||||||
|         csrfToken: '<%= csrfToken %>', |         csrfToken: '<%= csrfToken %>', | ||||||
|         isDev: <%= isDev %>, |         isDev: <%= isDev %>, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user