فهرست منبع

Add migration script for fixing badCreationTime

Neeraj Gupta 2 سال پیش
والد
کامیت
792710a19d
3فایلهای تغییر یافته به همراه105 افزوده شده و 2 حذف شده
  1. 1 0
      lib/db/file_updation_db.dart
  2. 42 0
      lib/db/files_db.dart
  3. 62 2
      lib/services/local_file_update_service.dart

+ 1 - 0
lib/db/file_updation_db.dart

@@ -16,6 +16,7 @@ class FileUpdationDB {
   static const columnReason = 'reason';
   static const columnReason = 'reason';
   static const missingLocation = 'missing_location';
   static const missingLocation = 'missing_location';
   static const modificationTimeUpdated = 'modificationTimeUpdated';
   static const modificationTimeUpdated = 'modificationTimeUpdated';
+  static const badCreationTime = 'badCreationTime';
 
 
   // SQL code to create the database table
   // SQL code to create the database table
   static List<String> _createTable() {
   static List<String> _createTable() {

+ 42 - 0
lib/db/files_db.dart

@@ -1259,6 +1259,28 @@ class FilesDB {
     return result;
     return result;
   }
   }
 
 
+  Future<Map<int, File>> getFilesFromGeneratedIDs(List<int> ids) async {
+    final result = <int, File>{};
+    if (ids.isEmpty) {
+      return result;
+    }
+    String inParam = "";
+    for (final id in ids) {
+      inParam += "'" + id.toString() + "',";
+    }
+    inParam = inParam.substring(0, inParam.length - 1);
+    final db = await instance.database;
+    final results = await db.query(
+      filesTable,
+      where: '$columnGeneratedID IN ($inParam)',
+    );
+    final files = convertToFiles(results);
+    for (final file in files) {
+      result[file.generatedID] = file;
+    }
+    return result;
+  }
+
   Future<Map<int, List<File>>> getAllFilesGroupByCollectionID(
   Future<Map<int, List<File>>> getAllFilesGroupByCollectionID(
     List<int> ids,
     List<int> ids,
   ) async {
   ) async {
@@ -1312,6 +1334,26 @@ class FilesDB {
     return files;
     return files;
   }
   }
 
 
+  Future<List<String>> getGeneratedIDForFilesOlderThan(
+    int cutOffTime,
+    int ownerID,
+  ) async {
+    final db = await instance.database;
+    final rows = await db.query(
+      filesTable,
+      columns: [columnGeneratedID],
+      distinct: true,
+      where:
+          '$columnCreationTime <= ? AND  ($columnOwnerID IS NULL OR $columnOwnerID = ?)',
+      whereArgs: [cutOffTime, ownerID],
+    );
+    final result = <String>[];
+    for (final row in rows) {
+      result.add(row[columnGeneratedID].toString());
+    }
+    return result;
+  }
+
   Future<List<File>> getAllFilesFromDB(Set<int> collectionsToIgnore) async {
   Future<List<File>> getAllFilesFromDB(Set<int> collectionsToIgnore) async {
     final db = await instance.database;
     final db = await instance.database;
     final List<Map<String, dynamic>> result = await db.query(filesTable);
     final List<Map<String, dynamic>> result = await db.query(filesTable);

+ 62 - 2
lib/services/local_file_update_service.dart

@@ -6,9 +6,13 @@ import 'dart:io';
 
 
 import 'package:flutter/foundation.dart';
 import 'package:flutter/foundation.dart';
 import 'package:logging/logging.dart';
 import 'package:logging/logging.dart';
+import 'package:photos/core/configuration.dart';
+import 'package:photos/core/constants.dart';
 import 'package:photos/db/file_updation_db.dart';
 import 'package:photos/db/file_updation_db.dart';
 import 'package:photos/db/files_db.dart';
 import 'package:photos/db/files_db.dart';
+import 'package:photos/extensions/stop_watch.dart';
 import 'package:photos/models/file.dart' as ente;
 import 'package:photos/models/file.dart' as ente;
+import 'package:photos/services/files_service.dart';
 import 'package:photos/utils/file_uploader_util.dart';
 import 'package:photos/utils/file_uploader_util.dart';
 import 'package:photos/utils/file_util.dart';
 import 'package:photos/utils/file_util.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 import 'package:shared_preferences/shared_preferences.dart';
@@ -21,6 +25,9 @@ class LocalFileUpdateService {
   Logger _logger;
   Logger _logger;
   static const isLocationMigrationComplete = "fm_isLocationMigrationComplete";
   static const isLocationMigrationComplete = "fm_isLocationMigrationComplete";
   static const isLocalImportDone = "fm_IsLocalImportDone";
   static const isLocalImportDone = "fm_IsLocalImportDone";
+  static const isBadCreationTimeImportDone = 'fm_badCreationTime';
+  static const isBadCreationTimeMigrationComplete =
+      'fm_badCreationTimeCompleted';
   Completer<void> _existingMigration;
   Completer<void> _existingMigration;
 
 
   LocalFileUpdateService._privateConstructor() {
   LocalFileUpdateService._privateConstructor() {
@@ -35,8 +42,8 @@ class LocalFileUpdateService {
   static LocalFileUpdateService instance =
   static LocalFileUpdateService instance =
       LocalFileUpdateService._privateConstructor();
       LocalFileUpdateService._privateConstructor();
 
 
-  bool isLocationMigrationCompleted() {
-    return _prefs.get(isLocationMigrationComplete) ?? false;
+  bool isBadCreationMigrationCompleted() {
+    return _prefs.get(isBadCreationTimeMigrationComplete) ?? false;
   }
   }
 
 
   Future<void> markUpdatedFilesForReUpload() async {
   Future<void> markUpdatedFilesForReUpload() async {
@@ -47,6 +54,9 @@ class LocalFileUpdateService {
     _existingMigration = Completer<void>();
     _existingMigration = Completer<void>();
     try {
     try {
       await _markFilesWhichAreActuallyUpdated();
       await _markFilesWhichAreActuallyUpdated();
+      if (Platform.isAndroid) {
+        await _migrationForFixingBadCreationTime();
+      }
     } catch (e, s) {
     } catch (e, s) {
       _logger.severe('failed to perform migration', e, s);
       _logger.severe('failed to perform migration', e, s);
     } finally {
     } finally {
@@ -141,4 +151,54 @@ class LocalFileUpdateService {
     }
     }
     return mediaUploadData;
     return mediaUploadData;
   }
   }
+
+  Future<void> _migrationForFixingBadCreationTime() async {
+    if (_prefs.containsKey(isBadCreationTimeMigrationComplete)) {
+      return;
+    }
+    await _importFilesWithBadCreationTime();
+    const int singleRunLimit = 100;
+    try {
+      final generatedIDs =
+          await _fileUpdationDB.getLocalIDsForPotentialReUpload(
+        singleRunLimit,
+        FileUpdationDB.badCreationTime,
+      );
+      if (generatedIDs.isNotEmpty) {
+        final List<int> genIdIntList =
+            generatedIDs.map((e) => int.tryParse(e)).toList();
+        final filesWithBadTime =
+            await FilesDB.instance.getFilesFromGeneratedIDs(genIdIntList);
+        await FilesService.instance.bulkEditTime(
+            filesWithBadTime.values.toList(), EditTimeSource.fileName);
+      } else {
+        // everything is done
+        await _prefs.setBool(isBadCreationTimeMigrationComplete, true);
+      }
+      await _fileUpdationDB.deleteByLocalIDs(
+        generatedIDs,
+        FileUpdationDB.badCreationTime,
+      );
+    } catch (e) {
+      _logger.severe("Failed to fix bad creationTime", e);
+    }
+  }
+
+  Future<void> _importFilesWithBadCreationTime() async {
+    if (_prefs.containsKey(isBadCreationTimeImportDone) ||
+        !Platform.isAndroid) {
+      return;
+    }
+    _logger.info('_importFilesWithBadCreationTime');
+    final EnteWatch watch = EnteWatch("_importFilesWithBadCreationTime");
+    final int ownerID = Configuration.instance.getUserID();
+    final filesGeneratedID = await FilesDB.instance
+        .getGeneratedIDForFilesOlderThan(jan011981Time, ownerID);
+    await _fileUpdationDB.insertMultiple(
+      filesGeneratedID,
+      FileUpdationDB.badCreationTime,
+    );
+    watch.log("imported ${filesGeneratedID.length} files");
+    _prefs.setBool(isBadCreationTimeImportDone, true);
+  }
 }
 }