First pass to manage deleted objects

This commit is contained in:
J-Jamet
2022-01-04 16:06:39 +01:00
parent 56efb20ffa
commit 5c75c6c7d3
3 changed files with 89 additions and 51 deletions

View File

@@ -144,6 +144,7 @@ class Database {
fun removeCustomIcon(customIcon: IconImageCustom) {
iconDrawableFactory.clearFromCache(customIcon)
iconsManager.removeCustomIcon(binaryCache, customIcon.uuid)
mDatabaseKDBX?.addDeletedObject(customIcon.uuid)
}
fun updateCustomIcon(customIcon: IconImageCustom) {
@@ -1030,6 +1031,9 @@ class Database {
}
fun deleteEntry(entry: Entry) {
entry.entryKDBX?.id?.let { entryId ->
mDatabaseKDBX?.addDeletedObject(entryId)
}
entry.parent?.let {
removeEntryFrom(entry, it)
}
@@ -1045,6 +1049,9 @@ class Database {
},
object : NodeHandler<Group>() {
override fun operate(node: Group): Boolean {
node.groupKDBX?.id?.let { groupId ->
mDatabaseKDBX?.addDeletedObject(groupId)
}
node.parent?.let {
removeGroupFrom(node, it)
}

View File

@@ -42,6 +42,7 @@ import com.kunzisoft.keepass.database.element.entry.FieldReferencesEngine
import com.kunzisoft.keepass.database.element.group.GroupKDBX
import com.kunzisoft.keepass.database.element.icon.IconImageCustom
import com.kunzisoft.keepass.database.element.icon.IconImageStandard
import com.kunzisoft.keepass.database.element.node.NodeId
import com.kunzisoft.keepass.database.element.node.NodeIdUUID
import com.kunzisoft.keepass.database.element.node.NodeVersioned
import com.kunzisoft.keepass.database.element.security.MemoryProtectionConfig
@@ -754,17 +755,16 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
return false
}
fun getDeletedObject(id: UUID): DeletedObject? {
return deletedObjects.find { it.uuid == id }
fun getDeletedObject(nodeId: NodeId<UUID>): DeletedObject? {
return deletedObjects.find { it.uuid == nodeId.id }
}
fun addDeletedObject(deletedObject: DeletedObject) {
this.deletedObjects.add(deletedObject)
}
override fun removeGroupFrom(groupToRemove: GroupKDBX, parent: GroupKDBX?) {
super.removeGroupFrom(groupToRemove, parent)
addDeletedObject(DeletedObject(groupToRemove.id))
fun addDeletedObject(objectId: UUID) {
addDeletedObject(DeletedObject(objectId))
}
override fun addEntryTo(newEntry: EntryKDBX, parent: GroupKDBX?) {
@@ -779,7 +779,6 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
override fun removeEntryFrom(entryToRemove: EntryKDBX, parent: GroupKDBX?) {
super.removeEntryFrom(entryToRemove, parent)
addDeletedObject(DeletedObject(entryToRemove.id))
mFieldReferenceEngine.clear()
}

View File

@@ -29,15 +29,11 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
}
// TODO Merge icons and attachments
// TODO Fix Recycle bin
databaseToMerge.rootGroup?.doForEachChild(
object : NodeHandler<EntryKDBX>() {
override fun operate(node: EntryKDBX): Boolean {
val entryId = node.nodeId
databaseToMerge.getEntryById(entryId)?.let {
mergeEntry(database.getEntryById(entryId), it)
}
mergeEntry(node, databaseToMerge)
return true
}
},
@@ -45,61 +41,97 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
override fun operate(node: GroupKDBX): Boolean {
val groupId = node.nodeId
databaseToMerge.getGroupById(groupId)?.let {
mergeGroup(database.getGroupById(groupId), it)
mergeGroup(node, databaseToMerge)
}
return true
}
}
)
databaseToMerge.deletedObjects.forEach { deletedObject ->
val deletedObjectId = deletedObject.uuid
val databaseEntry = database.getEntryById(deletedObjectId)
val databaseGroup = database.getGroupById(deletedObjectId)
if (databaseEntry != null
&& deletedObject.getDeletionTime().date
.after(databaseEntry.lastModificationTime.date)) {
database.removeEntryFrom(databaseEntry, databaseEntry.parent)
}
if (databaseGroup != null
&& deletedObject.getDeletionTime().date
.after(databaseGroup.lastModificationTime.date)) {
database.removeGroupFrom(databaseGroup, databaseGroup.parent)
}
// TODO Remove icon
}
}
private fun mergeEntry(databaseEntry: EntryKDBX?, databaseEntryToMerge: EntryKDBX) {
// Retrieve parent in current database
var parentEntry: GroupKDBX? = null
databaseEntryToMerge.parent?.nodeId?.let {
parentEntry = database.getGroupById(it)
}
private fun mergeEntry(node: EntryKDBX, databaseToMerge: DatabaseKDBX) {
val entryId = node.nodeId
val databaseEntryToMerge = databaseToMerge.getEntryById(entryId)
val databaseEntry = database.getEntryById(entryId)
val deletedObject = database.getDeletedObject(entryId)
if (databaseEntry == null) {
// TODO if it's not a deleted object
// If entry parent to add exists and in current database
if (parentEntry != null) {
database.addEntryTo(databaseEntryToMerge, parentEntry)
if (databaseEntryToMerge != null) {
// Retrieve parent in current database
var parentEntry: GroupKDBX? = null
databaseEntryToMerge.parent?.nodeId?.let {
parentEntry = database.getGroupById(it)
}
} else if (databaseEntry.lastModificationTime.date
.before(databaseEntryToMerge.lastModificationTime.date)
) {
// Update entry with databaseEntryToMerge and merge history
database.removeEntryFrom(databaseEntry, databaseEntry.parent)
val newDatabaseEntry = EntryKDBX().apply {
updateWith(databaseEntryToMerge)
// TODO history =
}
if (parentEntry != null) {
database.addEntryTo(newDatabaseEntry, parentEntry)
if (databaseEntry == null) {
// If it's a deleted object, but another instance was updated
// If entry parent to add exists and in current database
if (deletedObject == null
|| deletedObject.getDeletionTime().date
.before(databaseEntryToMerge.lastModificationTime.date)
|| parentEntry != null) {
database.addEntryTo(databaseEntryToMerge, parentEntry)
}
} else if (databaseEntry.lastModificationTime.date
.before(databaseEntryToMerge.lastModificationTime.date)
) {
// Update entry with databaseEntryToMerge and merge history
database.removeEntryFrom(databaseEntry, databaseEntry.parent)
val newDatabaseEntry = EntryKDBX().apply {
updateWith(databaseEntryToMerge)
// TODO history =
}
if (parentEntry != null) {
database.addEntryTo(newDatabaseEntry, parentEntry)
}
}
}
}
private fun mergeGroup(databaseGroup: GroupKDBX?, databaseGroupToMerge: GroupKDBX) {
// Retrieve parent in current database
var parentGroup: GroupKDBX? = null
databaseGroupToMerge.parent?.nodeId?.let {
parentGroup = database.getGroupById(it)
}
private fun mergeGroup(node: GroupKDBX, databaseToMerge: DatabaseKDBX) {
val groupId = node.nodeId
val databaseGroupToMerge = databaseToMerge.getGroupById(groupId)
val databaseGroup = database.getGroupById(groupId)
val deletedObject = database.getDeletedObject(groupId)
if (databaseGroup == null) {
// TODO if it's not a deleted object
// If group parent to add exists and in current database
if (parentGroup != null) {
database.addGroupTo(databaseGroupToMerge, parentGroup)
if (databaseGroupToMerge != null) {
// Retrieve parent in current database
var parentGroup: GroupKDBX? = null
databaseGroupToMerge.parent?.nodeId?.let {
parentGroup = database.getGroupById(it)
}
} else if (databaseGroup.lastModificationTime.date
.before(databaseGroupToMerge.lastModificationTime.date)
) {
database.removeGroupFrom(databaseGroup, databaseGroup.parent)
if (parentGroup != null) {
database.addGroupTo(databaseGroupToMerge, parentGroup)
if (databaseGroup == null) {
// If group parent to add exists and in current database
if (deletedObject == null
|| deletedObject.getDeletionTime().date
.before(databaseGroupToMerge.lastModificationTime.date)
|| parentGroup != null) {
database.addGroupTo(databaseGroupToMerge, parentGroup)
}
} else if (databaseGroup.lastModificationTime.date
.before(databaseGroupToMerge.lastModificationTime.date)
) {
database.removeGroupFrom(databaseGroup, databaseGroup.parent)
if (parentGroup != null) {
database.addGroupTo(databaseGroupToMerge, parentGroup)
}
}
}
}