Bladeren bron

[mob][photos] Migrate to sqlite_async(10)

ashilkn 1 jaar geleden
bovenliggende
commit
16d54645bc
1 gewijzigde bestanden met toevoegingen van 117 en 82 verwijderingen
  1. 117 82
      mobile/lib/db/device_files_db.dart

+ 117 - 82
mobile/lib/db/device_files_db.dart

@@ -22,61 +22,55 @@ extension DeviceFiles on FilesDB {
     ConflictAlgorithm conflictAlgorithm = ConflictAlgorithm.ignore,
   }) async {
     debugPrint("Inserting missing PathIDToLocalIDMapping");
-    final db = await database;
-    var batch = db.batch();
+    final parameterSets = <List<Object?>>[];
     int batchCounter = 0;
     for (MapEntry e in mappingToAdd.entries) {
       final String pathID = e.key;
       for (String localID in e.value) {
+        parameterSets.add([localID, pathID]);
+        batchCounter++;
+
         if (batchCounter == 400) {
-          await batch.commit(noResult: true);
-          batch = db.batch();
+          await _insertBatch(parameterSets, conflictAlgorithm);
+          parameterSets.clear();
           batchCounter = 0;
         }
-        batch.insert(
-          "device_files",
-          {
-            "id": localID,
-            "path_id": pathID,
-          },
-          conflictAlgorithm: conflictAlgorithm,
-        );
-        batchCounter++;
       }
     }
-    await batch.commit(noResult: true);
+    await _insertBatch(parameterSets, conflictAlgorithm);
+    parameterSets.clear();
+    batchCounter = 0;
   }
 
   Future<void> deletePathIDToLocalIDMapping(
     Map<String, Set<String>> mappingsToRemove,
   ) async {
     debugPrint("removing PathIDToLocalIDMapping");
-    final db = await database;
-    var batch = db.batch();
+    final parameterSets = <List<Object?>>[];
     int batchCounter = 0;
     for (MapEntry e in mappingsToRemove.entries) {
       final String pathID = e.key;
+
       for (String localID in e.value) {
+        parameterSets.add([localID, pathID]);
+        batchCounter++;
+
         if (batchCounter == 400) {
-          await batch.commit(noResult: true);
-          batch = db.batch();
+          await _deleteBatch(parameterSets);
+          parameterSets.clear();
           batchCounter = 0;
         }
-        batch.delete(
-          "device_files",
-          where: 'id = ? AND path_id = ?',
-          whereArgs: [localID, pathID],
-        );
-        batchCounter++;
       }
     }
-    await batch.commit(noResult: true);
+    await _deleteBatch(parameterSets);
+    parameterSets.clear();
+    batchCounter = 0;
   }
 
   Future<Map<String, int>> getDevicePathIDToImportedFileCount() async {
     try {
-      final db = await database;
-      final rows = await db.rawQuery(
+      final db = await sqliteAsyncDB;
+      final rows = await db.getAll(
         '''
       SELECT count(*) as count, path_id
       FROM device_files
@@ -96,8 +90,8 @@ extension DeviceFiles on FilesDB {
 
   Future<Map<String, Set<String>>> getDevicePathIDToLocalIDMap() async {
     try {
-      final db = await database;
-      final rows = await db.rawQuery(
+      final db = await sqliteAsyncDB;
+      final rows = await db.getAll(
         ''' SELECT id, path_id FROM device_files; ''',
       );
       final result = <String, Set<String>>{};
@@ -116,8 +110,8 @@ extension DeviceFiles on FilesDB {
   }
 
   Future<Set<String>> getDevicePathIDs() async {
-    final Database db = await database;
-    final rows = await db.rawQuery(
+    final db = await sqliteAsyncDB;
+    final rows = await db.getAll(
       '''
       SELECT id FROM device_collections
       ''',
@@ -133,34 +127,42 @@ extension DeviceFiles on FilesDB {
     List<LocalPathAsset> localPathAssets, {
     bool shouldAutoBackup = false,
   }) async {
-    final Database db = await database;
+    final db = await sqliteAsyncDB;
     final Map<String, Set<String>> pathIDToLocalIDsMap = {};
     try {
-      final batch = db.batch();
       final Set<String> existingPathIds = await getDevicePathIDs();
+      final parameterSetsForUpdate = <List<Object?>>[];
+      final parameterSetsForInsert = <List<Object?>>[];
       for (LocalPathAsset localPathAsset in localPathAssets) {
         if (localPathAsset.localIDs.isNotEmpty) {
           pathIDToLocalIDsMap[localPathAsset.pathID] = localPathAsset.localIDs;
         }
         if (existingPathIds.contains(localPathAsset.pathID)) {
-          batch.rawUpdate(
-            "UPDATE device_collections SET name = ? where id = "
-            "?",
-            [localPathAsset.pathName, localPathAsset.pathID],
-          );
+          parameterSetsForUpdate
+              .add([localPathAsset.pathName, localPathAsset.pathID]);
         } else if (localPathAsset.localIDs.isNotEmpty) {
-          batch.insert(
-            "device_collections",
-            {
-              "id": localPathAsset.pathID,
-              "name": localPathAsset.pathName,
-              "should_backup": shouldAutoBackup ? _sqlBoolTrue : _sqlBoolFalse,
-            },
-            conflictAlgorithm: ConflictAlgorithm.ignore,
-          );
+          parameterSetsForInsert.add([
+            localPathAsset.pathID,
+            localPathAsset.pathName,
+            shouldAutoBackup ? _sqlBoolTrue : _sqlBoolFalse,
+          ]);
         }
       }
-      await batch.commit(noResult: true);
+
+      await db.executeBatch(
+        '''
+        INSERT OR IGNORE INTO device_collections (id, name, should_backup) VALUES (?, ?, ?);
+      ''',
+        parameterSetsForInsert,
+      );
+
+      await db.executeBatch(
+        '''
+        UPDATE device_collections SET name = ? WHERE id = ?;
+      ''',
+        parameterSetsForUpdate,
+      );
+
       // add the mappings for localIDs
       if (pathIDToLocalIDsMap.isNotEmpty) {
         await insertPathIDToLocalIDMapping(pathIDToLocalIDsMap);
@@ -177,7 +179,7 @@ extension DeviceFiles on FilesDB {
   }) async {
     bool hasUpdated = false;
     try {
-      final Database db = await database;
+      final db = await sqliteAsyncDB;
       final Set<String> existingPathIds = await getDevicePathIDs();
       for (Tuple2<AssetPathEntity, String> tup in devicePathInfo) {
         final AssetPathEntity pathEntity = tup.item1;
@@ -185,35 +187,42 @@ extension DeviceFiles on FilesDB {
         final String localID = tup.item2;
         final bool shouldUpdate = existingPathIds.contains(pathEntity.id);
         if (shouldUpdate) {
-          final rowUpdated = await db.rawUpdate(
-            "UPDATE device_collections SET name = ?, cover_id = ?, count"
-            " = ? where id = ? AND (name != ? OR cover_id != ? OR count != ?)",
-            [
-              pathEntity.name,
-              localID,
-              assetCount,
-              pathEntity.id,
-              pathEntity.name,
-              localID,
-              assetCount,
-            ],
-          );
+          final rowUpdated = await db.writeTransaction((tx) async {
+            await tx.execute(
+              "UPDATE device_collections SET name = ?, cover_id = ?, count"
+              " = ? where id = ? AND (name != ? OR cover_id != ? OR count != ?)",
+              [
+                pathEntity.name,
+                localID,
+                assetCount,
+                pathEntity.id,
+                pathEntity.name,
+                localID,
+                assetCount,
+              ],
+            );
+            final result = await tx.get("SELECT changes();");
+            return result["changes()"] as int;
+          });
+
           if (rowUpdated > 0) {
             _logger.fine("Updated $rowUpdated rows for ${pathEntity.name}");
             hasUpdated = true;
           }
         } else {
           hasUpdated = true;
-          await db.insert(
-            "device_collections",
-            {
-              "id": pathEntity.id,
-              "name": pathEntity.name,
-              "count": assetCount,
-              "cover_id": localID,
-              "should_backup": shouldBackup ? _sqlBoolTrue : _sqlBoolFalse,
-            },
-            conflictAlgorithm: ConflictAlgorithm.ignore,
+          await db.execute(
+            '''
+            INSERT INTO device_collections (id, name, count, cover_id, should_backup) 
+            VALUES (?, ?, ?, ?, ?);
+          ''',
+            [
+              pathEntity.id,
+              pathEntity.name,
+              assetCount,
+              localID,
+              shouldBackup ? _sqlBoolTrue : _sqlBoolFalse,
+            ],
           );
         }
       }
@@ -231,15 +240,17 @@ extension DeviceFiles on FilesDB {
           // feature, where we delete files which are backed up. Deleting such
           // entries here result in us losing out on the information that
           // those folders were marked for automatic backup.
-          await db.delete(
-            "device_collections",
-            where: 'id = ? and should_backup = $_sqlBoolFalse ',
-            whereArgs: [pathID],
+          await db.execute(
+            '''
+            DELETE FROM device_collections WHERE id = ? AND should_backup = $_sqlBoolFalse;
+          ''',
+            [pathID],
           );
-          await db.delete(
-            "device_files",
-            where: 'path_id = ?',
-            whereArgs: [pathID],
+          await db.execute(
+            '''
+            DELETE FROM device_files WHERE path_id = ?;
+          ''',
+            [pathID],
           );
         }
       }
@@ -253,8 +264,8 @@ extension DeviceFiles on FilesDB {
   // getDeviceSyncCollectionIDs returns the collectionIDs for the
   // deviceCollections which are marked for auto-backup
   Future<Set<int>> getDeviceSyncCollectionIDs() async {
-    final Database db = await database;
-    final rows = await db.rawQuery(
+    final db = await sqliteAsyncDB;
+    final rows = await db.getAll(
       '''
       SELECT collection_id FROM device_collections where should_backup = 
       $_sqlBoolTrue 
@@ -447,4 +458,28 @@ extension DeviceFiles on FilesDB {
       return null;
     }
   }
+
+  Future<void> _insertBatch(
+    List<List<Object?>> parameterSets,
+    ConflictAlgorithm conflictAlgorithm,
+  ) async {
+    final db = await sqliteAsyncDB;
+    await db.executeBatch(
+      '''
+        INSERT OR ${conflictAlgorithm.name.toUpperCase()}
+        INTO device_files (id, path_id) VALUES (?, ?);
+      ''',
+      parameterSets,
+    );
+  }
+
+  Future<void> _deleteBatch(List<List<Object?>> parameterSets) async {
+    final db = await sqliteAsyncDB;
+    await db.executeBatch(
+      '''
+        DELETE FROM device_files WHERE id = ? AND path_id = ?;
+      ''',
+      parameterSets,
+    );
+  }
 }