mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-04 05:28:59 +01:00 
			
		
		
		
	sync fix, #4288
This commit is contained in:
		
							parent
							
								
									be918628c3
								
							
						
					
					
						commit
						9f726304aa
					
				@ -208,6 +208,7 @@ class Becca {
 | 
			
		||||
        return this.etapiTokens[etapiTokenId];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @returns {AbstractBeccaEntity|null} */
 | 
			
		||||
    getEntity(entityName, entityId) {
 | 
			
		||||
        if (!entityName || !entityId) {
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
@ -18,31 +18,11 @@ let becca = null;
 | 
			
		||||
class AbstractBeccaEntity {
 | 
			
		||||
    /** @protected */
 | 
			
		||||
    beforeSaving() {
 | 
			
		||||
        this.generateIdIfNecessary();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @protected */
 | 
			
		||||
    generateIdIfNecessary() {
 | 
			
		||||
        if (!this[this.constructor.primaryKeyName]) {
 | 
			
		||||
            this[this.constructor.primaryKeyName] = utils.newEntityId();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @protected */
 | 
			
		||||
    generateHash(isDeleted = false) {
 | 
			
		||||
        let contentToHash = "";
 | 
			
		||||
 | 
			
		||||
        for (const propertyName of this.constructor.hashedProperties) {
 | 
			
		||||
            contentToHash += `|${this[propertyName]}`;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (isDeleted) {
 | 
			
		||||
            contentToHash += "|deleted";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return utils.hash(contentToHash).substr(0, 10);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @protected */
 | 
			
		||||
    getUtcDateChanged() {
 | 
			
		||||
        return this.utcDateModified || this.utcDateCreated;
 | 
			
		||||
@ -61,7 +41,7 @@ class AbstractBeccaEntity {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @protected */
 | 
			
		||||
    putEntityChange(isDeleted = false) {
 | 
			
		||||
    putEntityChange(isDeleted) {
 | 
			
		||||
        entityChangesService.putEntityChange({
 | 
			
		||||
            entityName: this.constructor.entityName,
 | 
			
		||||
            entityId: this[this.constructor.primaryKeyName],
 | 
			
		||||
@ -72,11 +52,37 @@ class AbstractBeccaEntity {
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @protected
 | 
			
		||||
     * @returns {string}
 | 
			
		||||
     */
 | 
			
		||||
    generateHash(isDeleted) {
 | 
			
		||||
        let contentToHash = "";
 | 
			
		||||
 | 
			
		||||
        for (const propertyName of this.constructor.hashedProperties) {
 | 
			
		||||
            contentToHash += `|${this[propertyName]}`;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (isDeleted) {
 | 
			
		||||
            contentToHash += "|deleted";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return utils.hash(contentToHash).substr(0, 10);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** @protected */
 | 
			
		||||
    getPojoToSave() {
 | 
			
		||||
        return this.getPojo();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @protected
 | 
			
		||||
     * @abstract
 | 
			
		||||
     */
 | 
			
		||||
    getPojo() {
 | 
			
		||||
        throw new Error(`Unimplemented getPojo() for entity '${this.constructor.name}'`)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Saves entity - executes SQL, but doesn't commit the transaction on its own
 | 
			
		||||
     *
 | 
			
		||||
@ -88,9 +94,7 @@ class AbstractBeccaEntity {
 | 
			
		||||
 | 
			
		||||
        const isNewEntity = !this[primaryKeyName];
 | 
			
		||||
 | 
			
		||||
        if (this.beforeSaving) {
 | 
			
		||||
            this.beforeSaving(opts);
 | 
			
		||||
        }
 | 
			
		||||
        this.beforeSaving(opts);
 | 
			
		||||
 | 
			
		||||
        const pojo = this.getPojoToSave();
 | 
			
		||||
 | 
			
		||||
@ -101,7 +105,7 @@ class AbstractBeccaEntity {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.putEntityChange(false);
 | 
			
		||||
            this.putEntityChange(!!this.isDeleted);
 | 
			
		||||
 | 
			
		||||
            if (!cls.isEntityEventsDisabled()) {
 | 
			
		||||
                const eventPayload = {
 | 
			
		||||
 | 
			
		||||
@ -20,8 +20,7 @@ const attachmentRoleToNoteTypeMapping = {
 | 
			
		||||
class BAttachment extends AbstractBeccaEntity {
 | 
			
		||||
    static get entityName() { return "attachments"; }
 | 
			
		||||
    static get primaryKeyName() { return "attachmentId"; }
 | 
			
		||||
    static get hashedProperties() { return ["attachmentId", "ownerId", "role", "mime", "title", "blobId",
 | 
			
		||||
                                            "utcDateScheduledForErasureSince", "utcDateModified"]; }
 | 
			
		||||
    static get hashedProperties() { return ["attachmentId", "ownerId", "role", "mime", "title", "blobId", "utcDateScheduledForErasureSince"]; }
 | 
			
		||||
 | 
			
		||||
    constructor(row) {
 | 
			
		||||
        super();
 | 
			
		||||
 | 
			
		||||
@ -148,12 +148,13 @@ function fillEntityChanges(entityName, entityPrimaryKey, condition = '') {
 | 
			
		||||
                const entity = becca.getEntity(entityName, entityId);
 | 
			
		||||
 | 
			
		||||
                if (entity) {
 | 
			
		||||
                    ec.hash = entity.generateHash() || "|deleted";
 | 
			
		||||
                    ec.hash = entity.generateHash();
 | 
			
		||||
                    ec.utcDateChanged = entity.getUtcDateChanged() || dateUtils.utcNowDateTime();
 | 
			
		||||
                    ec.isSynced = entityName !== 'options' || !!entity.isSynced;
 | 
			
		||||
                } else {
 | 
			
		||||
                    // entity might be null (not present in becca) when it's deleted
 | 
			
		||||
                    // FIXME: hacky, not sure if it might cause some problems
 | 
			
		||||
                    // this will produce different hash value than when entity is being deleted since then
 | 
			
		||||
                    // all normal hashed attributes are being used. Sync should recover from that, though.
 | 
			
		||||
                    ec.hash = "deleted";
 | 
			
		||||
                    ec.utcDateChanged = dateUtils.utcNowDateTime();
 | 
			
		||||
                    ec.isSynced = true; // deletable (the ones with isDeleted) entities are synced
 | 
			
		||||
 | 
			
		||||
@ -456,7 +456,7 @@ async function importZip(taskContext, fileBuffer, importRootNote) {
 | 
			
		||||
                position: attachmentMeta.position
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            attachment.setContent(content);
 | 
			
		||||
            attachment.setContent(content, { forceSave: true });
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -106,7 +106,7 @@ function updateNormalEntity(remoteEC, remoteEntityRow, instanceId, updateContext
 | 
			
		||||
        updateContext.updated[remoteEC.entityName] = updateContext.updated[remoteEC.entityName] || [];
 | 
			
		||||
        updateContext.updated[remoteEC.entityName].push(remoteEC.entityId);
 | 
			
		||||
 | 
			
		||||
        if (!localEC || localEC.utcDateChanged < remoteEC.utcDateChanged) {
 | 
			
		||||
        if (!localEC || localEC.utcDateChanged < remoteEC.utcDateChanged || localEC.hash !== remoteEC.hash) {
 | 
			
		||||
            entityChangesService.putEntityChangeWithInstanceId(remoteEC, instanceId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user