fix sync bug

This commit is contained in:
zadam 2023-10-18 09:37:36 +02:00
parent b764761e58
commit d5271c17e3

View File

@ -68,44 +68,29 @@ function updateEntity(remoteEC, remoteEntityRow, instanceId, updateContext) {
function updateNormalEntity(remoteEC, remoteEntityRow, instanceId, updateContext) { function updateNormalEntity(remoteEC, remoteEntityRow, instanceId, updateContext) {
const localEC = sql.getRow(`SELECT * FROM entity_changes WHERE entityName = ? AND entityId = ?`, [remoteEC.entityName, remoteEC.entityId]); const localEC = sql.getRow(`SELECT * FROM entity_changes WHERE entityName = ? AND entityId = ?`, [remoteEC.entityName, remoteEC.entityId]);
if (!localEC?.isErased && remoteEC.isErased) {
eraseEntity(remoteEC, instanceId);
updateContext.erased++;
return true;
} else if (localEC?.isErased && !remoteEC.isErased) {
// on this side, we can't unerase the entity, so force the entity to be erased on the other side.
entityChangesService.putEntityChangeForOtherInstances(localEC);
return false;
} else if (localEC?.isErased && remoteEC.isErased) {
updateContext.alreadyErased++;
return false;
}
if (!localEC || localEC.utcDateChanged <= remoteEC.utcDateChanged) { if (!localEC || localEC.utcDateChanged <= remoteEC.utcDateChanged) {
if (!remoteEntityRow) { if (remoteEC.isErased) {
throw new Error(`Empty entity row for: ${JSON.stringify(remoteEC)}`); if (localEC?.isErased) {
} eraseEntity(remoteEC); // make sure it's erased anyway
updateContext.alreadyErased++;
if (remoteEC.entityName === 'blobs' && remoteEntityRow.content !== null) { return false; // we won't save entitychange in this case
// we always use a Buffer object which is different from normal saving - there we use a simple string type for } else {
// "string notes". The problem is that in general, it's not possible to detect whether a blob content eraseEntity(remoteEC);
// is string note or note (syncs can arrive out of order) updateContext.erased++;
remoteEntityRow.content = Buffer.from(remoteEntityRow.content, 'base64');
if (remoteEntityRow.content.byteLength === 0) {
// there seems to be a bug which causes empty buffer to be stored as NULL which is then picked up as inconsistency
// (possibly not a problem anymore with the newer better-sqlite3)
remoteEntityRow.content = "";
} }
} else {
if (!remoteEntityRow) {
throw new Error(`Empty entity row for: ${JSON.stringify(remoteEC)}`);
}
preProcessContent(remoteEC, remoteEntityRow);
sql.replace(remoteEC.entityName, remoteEntityRow);
updateContext.updated[remoteEC.entityName] = updateContext.updated[remoteEC.entityName] || [];
updateContext.updated[remoteEC.entityName].push(remoteEC.entityId);
} }
sql.replace(remoteEC.entityName, remoteEntityRow);
updateContext.updated[remoteEC.entityName] = updateContext.updated[remoteEC.entityName] || [];
updateContext.updated[remoteEC.entityName].push(remoteEC.entityId);
if (!localEC || localEC.utcDateChanged < remoteEC.utcDateChanged || localEC.hash !== remoteEC.hash) { if (!localEC || localEC.utcDateChanged < remoteEC.utcDateChanged || localEC.hash !== remoteEC.hash) {
entityChangesService.putEntityChangeWithInstanceId(remoteEC, instanceId); entityChangesService.putEntityChangeWithInstanceId(remoteEC, instanceId);
} }
@ -121,6 +106,21 @@ function updateNormalEntity(remoteEC, remoteEntityRow, instanceId, updateContext
return false; return false;
} }
function preProcessContent(remoteEC, remoteEntityRow) {
if (remoteEC.entityName === 'blobs' && remoteEntityRow.content !== null) {
// we always use a Buffer object which is different from normal saving - there we use a simple string type for
// "string notes". The problem is that in general, it's not possible to detect whether a blob content
// is string note or note (syncs can arrive out of order)
remoteEntityRow.content = Buffer.from(remoteEntityRow.content, 'base64');
if (remoteEntityRow.content.byteLength === 0) {
// there seems to be a bug which causes empty buffer to be stored as NULL which is then picked up as inconsistency
// (possibly not a problem anymore with the newer better-sqlite3)
remoteEntityRow.content = "";
}
}
}
function updateNoteReordering(remoteEC, remoteEntityRow, instanceId) { function updateNoteReordering(remoteEC, remoteEntityRow, instanceId) {
if (!remoteEntityRow) { if (!remoteEntityRow) {
throw new Error(`Empty note_reordering body for: ${JSON.stringify(remoteEC)}`); throw new Error(`Empty note_reordering body for: ${JSON.stringify(remoteEC)}`);
@ -135,7 +135,7 @@ function updateNoteReordering(remoteEC, remoteEntityRow, instanceId) {
return true; return true;
} }
function eraseEntity(entityChange, instanceId) { function eraseEntity(entityChange) {
const {entityName, entityId} = entityChange; const {entityName, entityId} = entityChange;
const entityNames = [ const entityNames = [
@ -155,8 +155,6 @@ function eraseEntity(entityChange, instanceId) {
const primaryKeyName = entityConstructor.getEntityFromEntityName(entityName).primaryKeyName; const primaryKeyName = entityConstructor.getEntityFromEntityName(entityName).primaryKeyName;
sql.execute(`DELETE FROM ${entityName} WHERE ${primaryKeyName} = ?`, [entityId]); sql.execute(`DELETE FROM ${entityName} WHERE ${primaryKeyName} = ?`, [entityId]);
entityChangesService.putEntityChangeWithInstanceId(entityChange, instanceId);
} }
function logUpdateContext(updateContext) { function logUpdateContext(updateContext) {