From 9efe139a396eba61c3069a58343aa837dde4a393 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Sat, 5 Nov 2022 21:11:06 +0100 Subject: [PATCH] #368 clean duplicate entries introduced before v1.7.1 --- lib/model/db/db_metadata_sqflite.dart | 2 +- lib/model/db/db_metadata_sqflite_upgrade.dart | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/model/db/db_metadata_sqflite.dart b/lib/model/db/db_metadata_sqflite.dart index 2bf986395..2e0e3e11d 100644 --- a/lib/model/db/db_metadata_sqflite.dart +++ b/lib/model/db/db_metadata_sqflite.dart @@ -100,7 +100,7 @@ class SqfliteMetadataDb implements MetadataDb { ')'); }, onUpgrade: MetadataDbUpgrader.upgradeDb, - version: 9, + version: 10, ); final maxIdRows = await _db.rawQuery('SELECT max(id) AS maxId FROM $entryTable'); diff --git a/lib/model/db/db_metadata_sqflite_upgrade.dart b/lib/model/db/db_metadata_sqflite_upgrade.dart index 489c6f5c7..5d38540a8 100644 --- a/lib/model/db/db_metadata_sqflite_upgrade.dart +++ b/lib/model/db/db_metadata_sqflite_upgrade.dart @@ -1,4 +1,5 @@ import 'package:aves/model/db/db_metadata_sqflite.dart'; +import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; import 'package:sqflite/sqflite.dart'; @@ -41,6 +42,9 @@ class MetadataDbUpgrader { case 8: await _upgradeFrom8(db); break; + case 9: + await _upgradeFrom9(db); + break; } oldVersion++; } @@ -334,4 +338,36 @@ class MetadataDbUpgrader { await db.execute('ALTER TABLE $newMetadataTable RENAME TO $metadataTable;'); }); } + + static Future _upgradeFrom9(Database db) async { + debugPrint('upgrading DB from v9'); + + // clean duplicates introduced before Aves v1.7.1 + final duplicatedContentIdRows = await db.query(entryTable, columns: ['contentId'], groupBy: 'contentId', having: 'COUNT(id) > 1 AND contentId IS NOT NULL'); + final duplicatedContentIds = duplicatedContentIdRows.map((row) => row['contentId'] as int?).whereNotNull().toSet(); + final duplicateIds = {}; + await Future.forEach(duplicatedContentIds, (contentId) async { + final rows = await db.query(entryTable, columns: ['id'], where: 'contentId = ?', whereArgs: [contentId]); + final ids = rows.map((row) => row['id'] as int?).whereNotNull().toList()..sort(); + if (ids.length > 1) { + ids.removeAt(0); + duplicateIds.addAll(ids); + } + }); + final batch = db.batch(); + const where = 'id = ?'; + const coverWhere = 'entryId = ?'; + duplicateIds.forEach((id) { + final whereArgs = [id]; + batch.delete(entryTable, where: where, whereArgs: whereArgs); + batch.delete(dateTakenTable, where: where, whereArgs: whereArgs); + batch.delete(metadataTable, where: where, whereArgs: whereArgs); + batch.delete(addressTable, where: where, whereArgs: whereArgs); + batch.delete(favouriteTable, where: where, whereArgs: whereArgs); + batch.delete(coverTable, where: coverWhere, whereArgs: whereArgs); + batch.delete(trashTable, where: where, whereArgs: whereArgs); + batch.delete(videoPlaybackTable, where: where, whereArgs: whereArgs); + }); + await batch.commit(noResult: true); + } }