fix: merge algorithm #2223

This commit is contained in:
J-Jamet
2025-10-27 18:51:19 +01:00
parent 79777801e8
commit d557e8b516
5 changed files with 27 additions and 33 deletions

View File

@@ -1,3 +1,6 @@
KeePassDX(4.2.2)
* Fix database merge algorithm #2223
KeePassDX(4.2.1) KeePassDX(4.2.1)
* Fix Magikeyboard autosearch #2233 * Fix Magikeyboard autosearch #2233
* Fix database merge #2223 * Fix database merge #2223

View File

@@ -11,8 +11,8 @@ android {
applicationId "com.kunzisoft.keepass" applicationId "com.kunzisoft.keepass"
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 35 targetSdkVersion 35
versionCode = 146 versionCode = 147
versionName = "4.2.1" versionName = "4.2.2"
multiDexEnabled true multiDexEnabled true
testApplicationId = "com.kunzisoft.keepass.tests" testApplicationId = "com.kunzisoft.keepass.tests"

View File

@@ -510,54 +510,46 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
// Merge by modification time // Merge by modification time
if (entry.lastModificationTime.isBefore(entryToMerge.lastModificationTime)) { if (entry.lastModificationTime.isBefore(entryToMerge.lastModificationTime)) {
// Update entry with databaseEntryToMerge and merge history // Update entry with databaseEntryToMerge and merge history
addHistory(entry, entryToMerge) entryToMerge.addHistoryFrom(entry)
if (parentEntryToMerge == entry.parent) { entry.updateWith(entryToMerge, copyHistory = true, updateParents = false)
// Update the current entry to keep modification // Move the current entry to the verified location
entry.updateWith(entryToMerge, copyHistory = true, updateParents = false) database.removeEntryFrom(entry, entry.parent)
// Move the current entry to the verified location database.addEntryTo(entry, parentEntryToMerge)
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.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 // Don't touch the location but update the entry history
addHistory(entryToMerge, entry) entry.addHistoryFrom(entryToMerge)
} 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,
// Current entry and entry to merge are normally the same // 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(entry, parentEntryToMerge)
} }
} }
} }
} }
/** /**
* Utility method to merge an history from an [entryA] to an [entryB], * Utility method to merge an history from an [entryA]
* [entryB] is modified
*/ */
private fun addHistory(entryA: EntryKDBX, entryB: EntryKDBX) { private fun EntryKDBX.addHistoryFrom(entryA: EntryKDBX) {
// Keep entry as history if already not present // Keep entry as history if already not present
entryA.history.forEach { history -> entryA.history.forEach { history ->
// If history not present // If history not present
if (!entryB.history.any { if (!this.history.any {
it.lastModificationTime == history.lastModificationTime it.lastModificationTime == history.lastModificationTime
}) { }) {
entryB.addEntryToHistory(history) this.addEntryToHistory(history)
} }
} }
// Last entry not present // Last entry not present
if (entryB.history.find { if (this.history.find {
it.lastModificationTime == entryA.lastModificationTime it.lastModificationTime == entryA.lastModificationTime
} == null) { } == null) {
val history = EntryKDBX().apply { val history = EntryKDBX().apply {
updateWith(entryA, copyHistory = false, updateParents = false) updateWith(entryA, copyHistory = false, updateParents = false)
parent = null parent = null
} }
entryB.addEntryToHistory(history) this.addEntryToHistory(history)
} }
} }
@@ -587,19 +579,16 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
mergeCustomData(group.customData, groupToMerge.customData) mergeCustomData(group.customData, groupToMerge.customData)
// Merge by modification time // Merge by modification time
if (group.lastModificationTime.isBefore(groupToMerge.lastModificationTime)) { if (group.lastModificationTime.isBefore(groupToMerge.lastModificationTime)) {
if (parentGroupToMerge == group.parent) { group.updateWith(groupToMerge, updateParents = false)
group.updateWith(groupToMerge, updateParents = false) // Update the current group location to the verified one
// Update the current group location to the verified one database.removeGroupFrom(group, group.parent)
database.removeGroupFrom(group, group.parent) database.addGroupTo(group, parentGroupToMerge)
database.addGroupTo(group, parentGroupToMerge) } else if (group.lastModificationTime.isAfter(group.lastModificationTime)) {
} else { // Don't touch the location
database.removeGroupFrom(group, group.parent)
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
database.removeGroupFrom(group, group.parent) database.removeGroupFrom(group, group.parent)
database.addGroupTo(groupToMerge, parentGroupToMerge) database.addGroupTo(group, parentGroupToMerge)
} }
} }
} }

View File

@@ -0,0 +1 @@
* Fix database merge algorithm #2223

View File

@@ -0,0 +1 @@
* Correction de l'algorithme de fusion des bases de données #2223