refactored "sync" table to "entity_changes" - more changes

This commit is contained in:
zadam 2020-08-02 23:43:39 +02:00
parent 864271d5ef
commit 7900622f38
13 changed files with 93 additions and 92 deletions

View File

@ -66,7 +66,7 @@ class Note extends Entity {
* part of Note entity with it's own sync. Reasons behind this hybrid design has been: * part of Note entity with it's own sync. Reasons behind this hybrid design has been:
* *
* - content can be quite large and it's not necessary to load it / fill memory for any note access even if we don't need a content, especially for bulk operations like search * - content can be quite large and it's not necessary to load it / fill memory for any note access even if we don't need a content, especially for bulk operations like search
* - changes in the note metadata or title should not trigger note content sync (so we keep separate utcDateModified and sync rows) * - changes in the note metadata or title should not trigger note content sync (so we keep separate utcDateModified and entity changes records)
* - but to the user note content and title changes are one and the same - single dateModified (so all changes must go through Note and content is not a separate entity) * - but to the user note content and title changes are one and the same - single dateModified (so all changes must go through Note and content is not a separate entity)
*/ */
@ -154,7 +154,7 @@ class Note extends Entity {
sql.upsert("note_contents", "noteId", pojo); sql.upsert("note_contents", "noteId", pojo);
entityChangesService.addNoteContentSync(this.noteId); entityChangesService.addNoteContentEntityChange(this.noteId);
} }
setJsonContent(content) { setJsonContent(content) {

View File

@ -126,7 +126,7 @@ class NoteRevision extends Entity {
sql.upsert("note_revision_contents", "noteRevisionId", pojo); sql.upsert("note_revision_contents", "noteRevisionId", pojo);
entityChangesService.addNoteRevisionContentSync(this.noteRevisionId); entityChangesService.addNoteRevisionContentEntityChange(this.noteRevisionId);
} }
beforeSaving() { beforeSaving() {

View File

@ -8,7 +8,7 @@ const TPL = `
<br/> <br/>
<br/> <br/>
<button id="fill-sync-rows-button" class="btn">Fill sync rows</button> <button id="fill-entity-changes-button" class="btn">Fill entity changes records</button>
<br/> <br/>
<br/> <br/>
@ -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.$fillEntityChangesButton = $("#fill-sync-rows-button"); this.$fillEntityChangesButton = $("#fill-entity-changes-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");
@ -54,7 +54,7 @@ export default class AdvancedOptions {
}); });
this.$fillEntityChangesButton.on('click', async () => { this.$fillEntityChangesButton.on('click', async () => {
await server.post('sync/fill-sync-rows'); await server.post('sync/fill-entity-changes');
toastService.showMessage("Sync rows filled successfully"); toastService.showMessage("Sync rows filled successfully");
}); });

View File

@ -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]);
entityChangesService.addNoteReorderingSync(beforeNote.parentNoteId); entityChangesService.addNoteReorderingEntityChange(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]);
entityChangesService.addNoteReorderingSync(afterNote.parentNoteId); entityChangesService.addNoteReorderingEntityChange(afterNote.parentNoteId);
const movedNotePosition = afterNote.notePosition + 10; const movedNotePosition = afterNote.notePosition + 10;

View File

@ -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]);
entityChangesService.addNoteSync(noteId); entityChangesService.addNoteEntityChange(noteId);
sql.execute(`UPDATE note_contents SET utcDateModified = ? WHERE noteId = ?`, [now, noteId]); sql.execute(`UPDATE note_contents SET utcDateModified = ? WHERE noteId = ?`, [now, noteId]);
entityChangesService.addNoteContentSync(noteId); entityChangesService.addNoteContentEntityChange(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]);
entityChangesService.addBranchSync(branchId); entityChangesService.addBranchEntityChange(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]);
entityChangesService.addAttributeSync(attributeId); entityChangesService.addAttributeEntityChange(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]);
entityChangesService.addNoteRevisionSync(noteRevisionId); entityChangesService.addNoteRevisionEntityChange(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]);
entityChangesService.addNoteRevisionContentSync(noteRevisionId); entityChangesService.addNoteRevisionContentEntityChange(noteRevisionId);
} }
entityChangesService.addRecentNoteSync(noteId); entityChangesService.addRecentNoteEntityChange(noteId);
log.info("Forcing note sync for " + noteId); log.info("Forcing note sync for " + noteId);
@ -123,12 +123,12 @@ function getChanged(req) {
const entityChanges = sql.getRows("SELECT * FROM entity_changes WHERE isSynced = 1 AND id > ? LIMIT 1000", [lastEntityChangeId]); const entityChanges = sql.getRows("SELECT * FROM entity_changes WHERE isSynced = 1 AND id > ? LIMIT 1000", [lastEntityChangeId]);
const ret = { const ret = {
syncs: syncService.getEntityChangesRecords(entityChanges), entityChanges: syncService.getEntityChangesRecords(entityChanges),
maxEntityChangeId: sql.getValue('SELECT COALESCE(MAX(id), 0) FROM entity_changes WHERE isSynced = 1') maxEntityChangeId: sql.getValue('SELECT COALESCE(MAX(id), 0) FROM entity_changes WHERE isSynced = 1')
}; };
if (ret.syncs.length > 0) { if (ret.entityChanges.length > 0) {
log.info(`Returning ${ret.syncs.length} entity changes in ${Date.now() - startTime}ms`); log.info(`Returning ${ret.entityChanges.length} entity changes in ${Date.now() - startTime}ms`);
} }
return ret; return ret;

View File

@ -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.fillEntityChanges); apiRoute(POST, '/api/sync/fill-entity-changes', 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);

View File

@ -1,7 +1,7 @@
"use strict"; "use strict";
const sql = require('./sql'); const sql = require('./sql');
const syncTable = require('./entity_changes.js'); const eventChangesService = 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');
@ -90,7 +90,7 @@ function cloneNoteAfter(noteId, afterBranchId) {
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]);
syncTable.addNoteReorderingSync(afterNote.parentNoteId); eventChangesService.addNoteReorderingEntityChange(afterNote.parentNoteId);
const branch = new Branch({ const branch = new Branch({
noteId: noteId, noteId: noteId,

View File

@ -300,7 +300,7 @@ class ConsistencyChecks {
utcDateModified: dateUtils.utcNowDateTime() utcDateModified: dateUtils.utcNowDateTime()
}); });
entityChangesService.addNoteContentSync(noteId); entityChangesService.addNoteContentEntityChange(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
@ -343,14 +343,14 @@ class ConsistencyChecks {
// we always fix this issue because there does not seem to be a good way to prevent it. // we always fix this issue because there does not seem to be a good way to prevent it.
// Scenario in which this can happen: // Scenario in which this can happen:
// 1. user on instance A deletes the note (sync for notes is created, but not for note_contents) and is later erased // 1. user on instance A deletes the note (sync for notes is created, but not for note_contents) and is later erased
// 2. instance B gets synced from instance A, note is updated because of sync row for notes, // 2. instance B gets synced from instance A, note is updated because of entity change for notes,
// but note_contents is not because erasion does not create sync rows // but note_contents is not because erasion does not create entity change rows
// 3. therefore note.isErased = true, but note_contents.content remains not updated and not erased. // 3. therefore note.isErased = true, but note_contents.content remains not updated and not erased.
// //
// Considered solutions: // Considered solutions:
// - don't sync erased notes - this might prevent syncing also of the isDeleted flag and note would continue // - don't sync erased notes - this might prevent syncing also of the isDeleted flag and note would continue
// to exist on the other instance // to exist on the other instance
// - create sync rows for erased event - this would be a problem for undeletion since erasion might happen // - create entity changes for erased event - this would be a problem for undeletion since erasion might happen
// on one instance after undelete and thus would win even though there's no user action behind it // on one instance after undelete and thus would win even though there's no user action behind it
// //
// So instead we just fix such cases afterwards here. // So instead we just fix such cases afterwards here.
@ -555,22 +555,23 @@ class ConsistencyChecks {
}); });
} }
runSyncRowChecks(entityName, key) { runEntityChangeChecks(entityName, key) {
this.findAndFixIssues(` this.findAndFixIssues(`
SELECT SELECT
${key} as entityId ${key} as entityId
FROM FROM
${entityName} ${entityName}
LEFT JOIN sync ON sync.entityName = '${entityName}' AND entityId = ${key} LEFT JOIN entity_changes ON entity_changes.entityName = '${entityName}'
AND entity_changes.entityId = ${key}
WHERE WHERE
sync.id IS NULL AND ` + (entityName === 'options' ? 'options.isSynced = 1' : '1'), entity_changes.id IS NULL AND ` + (entityName === 'options' ? 'options.isSynced = 1' : '1'),
({entityId}) => { ({entityId}) => {
if (this.autoFix) { if (this.autoFix) {
entityChangesService.addEntityChange(entityName, entityId); entityChangesService.addEntityChange(entityName, entityId);
logFix(`Created missing sync record for entityName=${entityName}, entityId=${entityId}`); logFix(`Created missing entity change for entityName=${entityName}, entityId=${entityId}`);
} else { } else {
logError(`Missing sync record for entityName=${entityName}, entityId=${entityId}`); logError(`Missing entity change for entityName=${entityName}, entityId=${entityId}`);
} }
}); });
@ -578,31 +579,31 @@ class ConsistencyChecks {
SELECT SELECT
id, entityId id, entityId
FROM FROM
sync entity_changes
LEFT JOIN ${entityName} ON entityId = ${key} LEFT JOIN ${entityName} ON entityId = ${key}
WHERE WHERE
sync.entityName = '${entityName}' entity_changes.entityName = '${entityName}'
AND ${key} IS NULL`, AND ${key} IS NULL`,
({id, entityId}) => { ({id, entityId}) => {
if (this.autoFix) { if (this.autoFix) {
sql.execute("DELETE FROM entity_changes 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 entity change id=${id}, entityName=${entityName}, entityId=${entityId}`);
} else { } else {
logError(`Unrecognized sync record id=${id}, entityName=${entityName}, entityId=${entityId}`); logError(`Unrecognized entity change id=${id}, entityName=${entityName}, entityId=${entityId}`);
} }
}); });
} }
findSyncRowsIssues() { findEntityChangeIssues() {
this.runSyncRowChecks("notes", "noteId"); this.runEntityChangeChecks("notes", "noteId");
this.runSyncRowChecks("note_contents", "noteId"); this.runEntityChangeChecks("note_contents", "noteId");
this.runSyncRowChecks("note_revisions", "noteRevisionId"); this.runEntityChangeChecks("note_revisions", "noteRevisionId");
this.runSyncRowChecks("branches", "branchId"); this.runEntityChangeChecks("branches", "branchId");
this.runSyncRowChecks("recent_notes", "noteId"); this.runEntityChangeChecks("recent_notes", "noteId");
this.runSyncRowChecks("attributes", "attributeId"); this.runEntityChangeChecks("attributes", "attributeId");
this.runSyncRowChecks("api_tokens", "apiTokenId"); this.runEntityChangeChecks("api_tokens", "apiTokenId");
this.runSyncRowChecks("options", "name"); this.runEntityChangeChecks("options", "name");
} }
findWronglyNamedAttributes() { findWronglyNamedAttributes() {
@ -653,7 +654,7 @@ class ConsistencyChecks {
this.findLogicIssues(); this.findLogicIssues();
this.findSyncRowsIssues(); this.findEntityChangeIssues();
this.findWronglyNamedAttributes(); this.findWronglyNamedAttributes();

View File

@ -7,7 +7,7 @@ const cls = require('./cls');
let maxEntityChangeId = 0; let maxEntityChangeId = 0;
function insertEntityChange(entityName, entityId, sourceId = null, isSynced = true) { function insertEntityChange(entityName, entityId, sourceId = null, isSynced = true) {
const sync = { const entityChange = {
entityName: entityName, entityName: entityName,
entityId: entityId, entityId: entityId,
utcSyncDate: dateUtils.utcNowDateTime(), utcSyncDate: dateUtils.utcNowDateTime(),
@ -15,11 +15,11 @@ function insertEntityChange(entityName, entityId, sourceId = null, isSynced = tr
isSynced: isSynced ? 1 : 0 isSynced: isSynced ? 1 : 0
}; };
sync.id = sql.replace("sync", sync); entityChange.id = sql.replace("entity_changes", entityChange);
maxEntityChangeId = Math.max(maxEntityChangeId, sync.id); maxEntityChangeId = Math.max(maxEntityChangeId, entityChange.id);
return sync; return entityChange;
} }
function addEntityChange(entityName, entityId, sourceId, isSynced) { function addEntityChange(entityName, entityId, sourceId, isSynced) {
@ -85,13 +85,13 @@ function fillEntityChanges(entityName, entityPrimaryKey, condition = '') {
} }
if (createdCount > 0) { if (createdCount > 0) {
log.info(`Created ${createdCount} missing sync records for ${entityName}.`); log.info(`Created ${createdCount} missing entity changes for ${entityName}.`);
} }
} }
catch (e) { catch (e) {
// this is to fix migration from 0.30 to 0.32, can be removed later // this is to fix migration from 0.30 to 0.32, can be removed later
// see https://github.com/zadam/trilium/issues/557 // see https://github.com/zadam/trilium/issues/557
log.error(`Filling sync rows failed for ${entityName} ${entityPrimaryKey} with error "${e.message}", continuing`); log.error(`Filling entity changes failed for ${entityName} ${entityPrimaryKey} with error "${e.message}", continuing`);
} }
} }
@ -112,16 +112,16 @@ function fillAllEntityChanges() {
} }
module.exports = { module.exports = {
addNoteSync: (noteId, sourceId) => addEntityChange("notes", noteId, sourceId), addNoteEntityChange: (noteId, sourceId) => addEntityChange("notes", noteId, sourceId),
addNoteContentSync: (noteId, sourceId) => addEntityChange("note_contents", noteId, sourceId), addNoteContentEntityChange: (noteId, sourceId) => addEntityChange("note_contents", noteId, sourceId),
addBranchSync: (branchId, sourceId) => addEntityChange("branches", branchId, sourceId), addBranchEntityChange: (branchId, sourceId) => addEntityChange("branches", branchId, sourceId),
addNoteReorderingSync: (parentNoteId, sourceId) => addEntityChange("note_reordering", parentNoteId, sourceId), addNoteReorderingEntityChange: (parentNoteId, sourceId) => addEntityChange("note_reordering", parentNoteId, sourceId),
addNoteRevisionSync: (noteRevisionId, sourceId) => addEntityChange("note_revisions", noteRevisionId, sourceId), addNoteRevisionEntityChange: (noteRevisionId, sourceId) => addEntityChange("note_revisions", noteRevisionId, sourceId),
addNoteRevisionContentSync: (noteRevisionId, sourceId) => addEntityChange("note_revision_contents", noteRevisionId, sourceId), addNoteRevisionContentEntityChange: (noteRevisionId, sourceId) => addEntityChange("note_revision_contents", noteRevisionId, sourceId),
addOptionsSync: (name, sourceId, isSynced) => addEntityChange("options", name, sourceId, isSynced), addOptionEntityChange: (name, sourceId, isSynced) => addEntityChange("options", name, sourceId, isSynced),
addRecentNoteSync: (noteId, sourceId) => addEntityChange("recent_notes", noteId, sourceId), addRecentNoteEntityChange: (noteId, sourceId) => addEntityChange("recent_notes", noteId, sourceId),
addAttributeSync: (attributeId, sourceId) => addEntityChange("attributes", attributeId, sourceId), addAttributeEntityChange: (attributeId, sourceId) => addEntityChange("attributes", attributeId, sourceId),
addApiTokenSync: (apiTokenId, sourceId) => addEntityChange("api_tokens", apiTokenId, sourceId), addApiTokenEntityChange: (apiTokenId, sourceId) => addEntityChange("api_tokens", apiTokenId, sourceId),
addEntityChange, addEntityChange,
fillAllEntityChanges, fillAllEntityChanges,
addEntityChangesForSector, addEntityChangesForSector,

View File

@ -159,7 +159,7 @@ function createNewNoteWithTarget(target, targetBranchId, params) {
const retObject = createNewNote(params); const retObject = createNewNote(params);
entityChangesService.addNoteReorderingSync(params.parentNoteId); entityChangesService.addNoteReorderingEntityChange(params.parentNoteId);
return retObject; return retObject;
} }

View File

@ -141,31 +141,31 @@ async function pullSync(syncContext) {
stats.outstandingPulls = 0; stats.outstandingPulls = 0;
} }
const rows = resp.syncs; const {entityChanges} = resp;
if (rows.length === 0) { if (entityChanges.length === 0) {
break; break;
} }
sql.transactional(() => { sql.transactional(() => {
for (const {sync, entity} of rows) { for (const {entityChange, entity} of entityChanges) {
if (!sourceIdService.isLocalSourceId(sync.sourceId)) { if (!sourceIdService.isLocalSourceId(entityChange.sourceId)) {
if (!atLeastOnePullApplied && sync.entity !== 'recent_notes') { // send only for first if (!atLeastOnePullApplied && entityChange.entity !== 'recent_notes') { // send only for first
ws.syncPullInProgress(); ws.syncPullInProgress();
atLeastOnePullApplied = true; atLeastOnePullApplied = true;
} }
syncUpdateService.updateEntity(sync, entity, syncContext.sourceId); syncUpdateService.updateEntity(entityChange, entity, syncContext.sourceId);
} }
stats.outstandingPulls = resp.maxEntityChangeId - sync.id; stats.outstandingPulls = resp.maxEntityChangeId - entityChange.id;
} }
setLastSyncedPull(rows[rows.length - 1].sync.id); setLastSyncedPull(entityChanges[entityChanges.length - 1].entityChange.id);
}); });
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`); log.info(`Pulled ${entityChanges.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,20 +179,20 @@ async function pushSync(syncContext) {
let lastSyncedPush = getLastSyncedPush(); let lastSyncedPush = getLastSyncedPush();
while (true) { while (true) {
const syncs = sql.getRows('SELECT * FROM entity_changes WHERE isSynced = 1 AND id > ? LIMIT 1000', [lastSyncedPush]); const entityChanges = sql.getRows('SELECT * FROM entity_changes WHERE isSynced = 1 AND id > ? LIMIT 1000', [lastSyncedPush]);
if (syncs.length === 0) { if (entityChanges.length === 0) {
log.info("Nothing to push"); log.info("Nothing to push");
break; break;
} }
const filteredSyncs = syncs.filter(sync => { const filteredEntityChanges = entityChanges.filter(entityChange => {
if (sync.sourceId === syncContext.sourceId) { if (entityChange.sourceId === syncContext.sourceId) {
// this may set lastSyncedPush beyond what's actually sent (because of size limit) // this may set lastSyncedPush beyond what's actually sent (because of size limit)
// so this is applied to the database only if there's no actual update // so this is applied to the database only if there's no actual update
// TODO: it would be better to simplify this somehow // TODO: it would be better to simplify this somehow
lastSyncedPush = sync.id; lastSyncedPush = entityChange.id;
return false; return false;
} }
@ -201,25 +201,25 @@ async function pushSync(syncContext) {
} }
}); });
if (filteredSyncs.length === 0) { if (filteredEntityChanges.length === 0) {
// there still might be more syncs (because of batch limit), just all from current batch // there still might be more sync changes (because of batch limit), just all from current batch
// has been filtered out // has been filtered out
setLastSyncedPush(lastSyncedPush); setLastSyncedPush(lastSyncedPush);
continue; continue;
} }
const syncRecords = getEntityChangesRecords(filteredSyncs); const entityChangesRecords = getEntityChangesRecords(filteredEntityChanges);
const startDate = new Date(); const startDate = new Date();
await syncRequest(syncContext, 'PUT', '/api/sync/update', { await syncRequest(syncContext, 'PUT', '/api/sync/update', {
sourceId: sourceIdService.getCurrentSourceId(), sourceId: sourceIdService.getCurrentSourceId(),
entities: syncRecords entities: entityChangesRecords
}); });
log.info(`Pushing ${syncRecords.length} syncs in ` + (Date.now() - startDate.getTime()) + "ms"); log.info(`Pushing ${entityChangesRecords.length} sync changes in ` + (Date.now() - startDate.getTime()) + "ms");
lastSyncedPush = syncRecords[syncRecords.length - 1].sync.id; lastSyncedPush = entityChangesRecords[entityChangesRecords.length - 1].entityChange.id;
setLastSyncedPush(lastSyncedPush); setLastSyncedPush(lastSyncedPush);
} }

View File

@ -86,7 +86,7 @@ function updateNote(remoteEntity, sourceId) {
sql.transactional(() => { sql.transactional(() => {
sql.replace("notes", remoteEntity); sql.replace("notes", remoteEntity);
entityChangesService.addNoteSync(remoteEntity.noteId, sourceId); entityChangesService.addNoteEntityChange(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);
entityChangesService.addNoteContentSync(remoteEntity.noteId, sourceId); entityChangesService.addNoteContentEntityChange(remoteEntity.noteId, sourceId);
}); });
return true; return true;
@ -126,7 +126,7 @@ function updateBranch(remoteEntity, sourceId) {
sql.replace('branches', remoteEntity); sql.replace('branches', remoteEntity);
entityChangesService.addBranchSync(remoteEntity.branchId, sourceId); entityChangesService.addBranchEntityChange(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);
entityChangesService.addNoteRevisionSync(remoteEntity.noteRevisionId, sourceId); entityChangesService.addNoteRevisionEntityChange(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);
entityChangesService.addNoteRevisionContentSync(remoteEntity.noteRevisionId, sourceId); entityChangesService.addNoteRevisionContentEntityChange(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]);
} }
entityChangesService.addNoteReorderingSync(entityId, sourceId); entityChangesService.addNoteReorderingEntityChange(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);
entityChangesService.addOptionsSync(remoteEntity.name, sourceId, true); entityChangesService.addOptionEntityChange(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);
entityChangesService.addRecentNoteSync(remoteEntity.noteId, sourceId); entityChangesService.addRecentNoteEntityChange(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);
entityChangesService.addAttributeSync(remoteEntity.attributeId, sourceId); entityChangesService.addAttributeEntityChange(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);
entityChangesService.addApiTokenSync(entity.apiTokenId, sourceId); entityChangesService.addApiTokenEntityChange(entity.apiTokenId, sourceId);
}); });
return true; return true;

View File

@ -138,7 +138,7 @@ function sortNotesAlphabetically(parentNoteId, directoriesFirst = false) {
position += 10; position += 10;
} }
entityChangesService.addNoteReorderingSync(parentNoteId); entityChangesService.addNoteReorderingEntityChange(parentNoteId);
}); });
} }