fix: merge algorithm

This commit is contained in:
J-Jamet
2025-10-27 16:34:38 +01:00
parent 62ab11cc56
commit 79777801e8

View File

@@ -433,6 +433,32 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
} }
} }
/**
* Return the real parent in database from a group defined as parent
* If the parent is null, simply return the root group
* Guaranteed that a return group is linked to the database tree through its ancestors
*/
private fun getAttachedParent(
group: GroupKDBX?
): GroupKDBX {
var realParent: GroupKDBX = database.rootGroup!!
group?.let { parent ->
val parentInDatabase = database.getGroupById(parent.nodeId)
if (parentInDatabase == null) {
realParent = GroupKDBX().apply {
updateWith(parent, updateParents = false)
}
database.addGroupTo(
realParent,
getAttachedParent(parent.parent)
)
} else {
realParent = parentInDatabase
}
}
return realParent
}
/** /**
* Utility method to merge a KDBX entry * Utility method to merge a KDBX entry
*/ */
@@ -443,10 +469,7 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
databaseToMerge.getEntryById(entryId)?.let { srcEntryToMerge -> databaseToMerge.getEntryById(entryId)?.let { srcEntryToMerge ->
// Retrieve parent in current database // Retrieve parent in current database
var parentEntryToMerge: GroupKDBX? = null val parentEntryToMerge: GroupKDBX = getAttachedParent(srcEntryToMerge.parent)
srcEntryToMerge.parent?.nodeId?.let {
parentEntryToMerge = database.getGroupById(it)
}
val entryToMerge = EntryKDBX().apply { val entryToMerge = EntryKDBX().apply {
updateWith(srcEntryToMerge, copyHistory = true, updateParents = false) updateWith(srcEntryToMerge, copyHistory = true, updateParents = false)
} }
@@ -478,8 +501,7 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
// If it's a deleted object, but another instance was updated // If it's a deleted object, but another instance was updated
// If entry parent to add exists and in current database // If entry parent to add exists and in current database
if ((deletedObject == null if ((deletedObject == null
|| deletedObject.deletionTime.isBefore(entryToMerge.lastModificationTime)) || deletedObject.deletionTime.isBefore(entryToMerge.lastModificationTime))) {
&& parentEntryToMerge != null) {
database.addEntryTo(entryToMerge, parentEntryToMerge) database.addEntryTo(entryToMerge, parentEntryToMerge)
} }
} else { } else {
@@ -490,25 +512,28 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
// Update entry with databaseEntryToMerge and merge history // Update entry with databaseEntryToMerge and merge history
addHistory(entry, entryToMerge) addHistory(entry, entryToMerge)
if (parentEntryToMerge == entry.parent) { if (parentEntryToMerge == entry.parent) {
// Update the current entry to keep modification
entry.updateWith(entryToMerge, copyHistory = true, updateParents = false) entry.updateWith(entryToMerge, copyHistory = true, updateParents = false)
} else { // Move the current entry to the verified location
database.removeEntryFrom(entry, entry.parent)
database.addEntryTo(entry, parentEntryToMerge)
} else {
// Remove the current entry and add the entry to merge to the correct location
database.removeEntryFrom(entry, entry.parent) database.removeEntryFrom(entry, entry.parent)
if (parentEntryToMerge != null) {
database.addEntryTo(entryToMerge, parentEntryToMerge) database.addEntryTo(entryToMerge, parentEntryToMerge)
} }
}
} else if (entry.lastModificationTime.isAfter(entryToMerge.lastModificationTime)) { } else if (entry.lastModificationTime.isAfter(entryToMerge.lastModificationTime)) {
// Don't touch the location but update the entry history
addHistory(entryToMerge, entry) addHistory(entryToMerge, entry)
} else if (entry.lastModificationTime.isEquals(entryToMerge.lastModificationTime)) { } else if (entry.lastModificationTime.isEquals(entryToMerge.lastModificationTime)) {
// If it's the same modification time, simply move entry to the right location // If it's the same modification time, simply move entry to the right location,
parentEntryToMerge?.let { // Current entry and entry to merge are normally the same
database.removeEntryFrom(entry, entry.parent) database.removeEntryFrom(entry, entry.parent)
database.addEntryTo(entryToMerge, parentEntryToMerge) database.addEntryTo(entryToMerge, parentEntryToMerge)
} }
} }
} }
} }
}
/** /**
* Utility method to merge an history from an [entryA] to an [entryB], * Utility method to merge an history from an [entryA] to an [entryB],
@@ -546,10 +571,7 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
databaseToMerge.getGroupById(groupId)?.let { srcGroupToMerge -> databaseToMerge.getGroupById(groupId)?.let { srcGroupToMerge ->
// Retrieve parent in current database // Retrieve parent in current database
var parentGroupToMerge: GroupKDBX? = null val parentGroupToMerge: GroupKDBX = getAttachedParent(srcGroupToMerge.parent)
srcGroupToMerge.parent?.nodeId?.let {
parentGroupToMerge = database.getGroupById(it)
}
val groupToMerge = GroupKDBX().apply { val groupToMerge = GroupKDBX().apply {
updateWith(srcGroupToMerge, updateParents = false) updateWith(srcGroupToMerge, updateParents = false)
} }
@@ -557,8 +579,7 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
if (group == null) { if (group == null) {
// If group parent to add exists and in current database // If group parent to add exists and in current database
if ((deletedObject == null if ((deletedObject == null
|| deletedObject.deletionTime.isBefore(groupToMerge.lastModificationTime)) || deletedObject.deletionTime.isBefore(groupToMerge.lastModificationTime))) {
&& parentGroupToMerge != null) {
database.addGroupTo(groupToMerge, parentGroupToMerge) database.addGroupTo(groupToMerge, parentGroupToMerge)
} }
} else { } else {
@@ -567,16 +588,16 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
// Merge by modification time // Merge by modification time
if (group.lastModificationTime.isBefore(groupToMerge.lastModificationTime)) { if (group.lastModificationTime.isBefore(groupToMerge.lastModificationTime)) {
if (parentGroupToMerge == group.parent) { if (parentGroupToMerge == group.parent) {
group.updateWith(groupToMerge, false) group.updateWith(groupToMerge, updateParents = false)
// Update the current group location to the verified one
database.removeGroupFrom(group, group.parent)
database.addGroupTo(group, parentGroupToMerge)
} else { } else {
database.removeGroupFrom(group, group.parent) database.removeGroupFrom(group, group.parent)
if (parentGroupToMerge != null) {
database.addGroupTo(groupToMerge, parentGroupToMerge) database.addGroupTo(groupToMerge, parentGroupToMerge)
} }
}
} else if (group.lastModificationTime.isEquals(groupToMerge.lastModificationTime)) { } else if (group.lastModificationTime.isEquals(groupToMerge.lastModificationTime)) {
// If it's the same modification time, simply move group to the right location // If it's the same modification time, simply move group to the right location
parentGroupToMerge?.let {
database.removeGroupFrom(group, group.parent) database.removeGroupFrom(group, group.parent)
database.addGroupTo(groupToMerge, parentGroupToMerge) database.addGroupTo(groupToMerge, parentGroupToMerge)
} }
@@ -584,4 +605,3 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
} }
} }
} }
}