This commit is contained in:
Neeraj Gupta 2022-08-01 16:35:16 +05:30
parent 3fdb422c64
commit 6429820485
No known key found for this signature in database
GPG key ID: 3C5A1684DC1729E1
4 changed files with 50 additions and 27 deletions

View file

@ -12,16 +12,18 @@ class FilesMigrationDB {
static final Logger _logger = Logger((FilesMigrationDB).toString());
static const tableName = 're_upload_tracker';
static const columnLocalID = 'local_id';
static const _columnLocalID = 'local_id';
static const _columnReason = 'reason';
static const missingLocation = 'missing_location';
static const modificationTimeUpdated = 'modificationTimeUpdated';
// SQL code to create the database table
static List<String> _createTable() {
return [
'''
CREATE TABLE $tableName (
$columnLocalID TEXT NOT NULL,
UNIQUE($columnLocalID)
$_columnLocalID TEXT NOT NULL,
UNIQUE($_columnLocalID)
);
''',
];
@ -71,7 +73,10 @@ class FilesMigrationDB {
await db.delete(tableName);
}
Future<void> insertMultiple(List<String> fileLocalIDs) async {
Future<void> insertMultiple(
List<String> fileLocalIDs, {
String reason,
}) async {
final startTime = DateTime.now();
final db = await instance.database;
var batch = db.batch();
@ -84,7 +89,7 @@ class FilesMigrationDB {
}
batch.insert(
tableName,
_getRowForReUploadTable(localID),
_getRowForReUploadTable(localID, reason),
conflictAlgorithm: ConflictAlgorithm.replace,
);
batchCounter++;
@ -110,24 +115,36 @@ class FilesMigrationDB {
final db = await instance.database;
return await db.delete(
tableName,
where: '$columnLocalID IN (${localIDs.join(', ')})',
where: '$_columnLocalID IN (${localIDs.join(', ')})',
);
}
Future<List<String>> getLocalIDsForPotentialReUpload(int limit) async {
Future<List<String>> getLocalIDsForPotentialReUpload(
int limit,
String reason,
) async {
final db = await instance.database;
final rows = await db.query(tableName, limit: limit);
String whereClause = '$_columnReason = $reason';
if (_columnReason == missingLocation) {
whereClause = '($_columnReason = $reason OR $_columnReason IS NULL';
}
final rows = await db.query(
tableName,
limit: limit,
where: whereClause,
);
final result = <String>[];
for (final row in rows) {
result.add(row[columnLocalID]);
result.add(row[_columnLocalID]);
}
return result;
}
Map<String, dynamic> _getRowForReUploadTable(String localID) {
Map<String, dynamic> _getRowForReUploadTable(String localID, String reason) {
assert(localID != null);
final row = <String, dynamic>{};
row[columnLocalID] = localID;
row[_columnLocalID] = localID;
row[_columnReason] = reason;
return row;
}
}

View file

@ -19,7 +19,7 @@ import 'package:photos/services/app_lifecycle_service.dart';
import 'package:photos/services/billing_service.dart';
import 'package:photos/services/collections_service.dart';
import 'package:photos/services/feature_flag_service.dart';
import 'package:photos/services/file_migration_service.dart';
import 'package:photos/services/local_file_update_service.dart';
import 'package:photos/services/local_sync_service.dart';
import 'package:photos/services/memories_service.dart';
import 'package:photos/services/notification_service.dart';
@ -140,7 +140,7 @@ Future<void> _init(bool isBackground, {String via = ''}) async {
await SyncService.instance.init();
await MemoriesService.instance.init();
await LocalSettings.instance.init();
await FileMigrationService.instance.init();
await LocalFileUpdateService.instance.init();
if (Platform.isIOS) {
PushService.instance.init().then((_) {
FirebaseMessaging.onBackgroundMessage(

View file

@ -10,7 +10,7 @@ import 'package:shared_preferences/shared_preferences.dart';
// LocalFileUpdateService tracks all the potential local file IDs which have
// changed/modified on the device and needed to be uploaded again.
class FileMigrationService {
class LocalFileUpdateService {
FilesDB _filesDB;
FilesMigrationDB _filesMigrationDB;
SharedPreferences _prefs;
@ -19,8 +19,8 @@ class FileMigrationService {
static const isLocalImportDone = "fm_IsLocalImportDone";
Completer<void> _existingMigration;
FileMigrationService._privateConstructor() {
_logger = Logger((FileMigrationService).toString());
LocalFileUpdateService._privateConstructor() {
_logger = Logger((LocalFileUpdateService).toString());
_filesDB = FilesDB.instance;
_filesMigrationDB = FilesMigrationDB.instance;
}
@ -29,8 +29,8 @@ class FileMigrationService {
_prefs = await SharedPreferences.getInstance();
}
static FileMigrationService instance =
FileMigrationService._privateConstructor();
static LocalFileUpdateService instance =
LocalFileUpdateService._privateConstructor();
Future<bool> _markLocationMigrationAsCompleted() async {
_logger.info('marking migration as completed');
@ -41,7 +41,7 @@ class FileMigrationService {
return _prefs.get(isLocationMigrationComplete) ?? false;
}
Future<void> runMigration() async {
Future<void> markUpdatedFilesForReUpload() async {
if (_existingMigration != null) {
_logger.info("migration is already in progress, skipping");
return _existingMigration.future;
@ -74,8 +74,11 @@ class FileMigrationService {
bool hasData = true;
const int limitInBatch = 100;
while (hasData) {
var localIDsToProcess = await _filesMigrationDB
.getLocalIDsForPotentialReUpload(limitInBatch);
var localIDsToProcess =
await _filesMigrationDB.getLocalIDsForPotentialReUpload(
limitInBatch,
FilesMigrationDB.missingLocation,
);
if (localIDsToProcess.isEmpty) {
hasData = false;
} else {
@ -130,12 +133,15 @@ class FileMigrationService {
final sTime = DateTime.now().microsecondsSinceEpoch;
_logger.info('importing files without location info');
var fileLocalIDs = await _filesDB.getLocalFilesBackedUpWithoutLocation();
await _filesMigrationDB.insertMultiple(fileLocalIDs);
await _filesMigrationDB.insertMultiple(
fileLocalIDs,
reason: FilesMigrationDB.missingLocation,
);
final eTime = DateTime.now().microsecondsSinceEpoch;
final d = Duration(microseconds: eTime - sTime);
_logger.info(
'importing completed, total files count ${fileLocalIDs.length} and took ${d.inSeconds.toString()} seconds',
);
_prefs.setBool(isLocalImportDone, true);
await _prefs.setBool(isLocalImportDone, true);
}
}

View file

@ -17,8 +17,8 @@ import 'package:photos/models/file_type.dart';
import 'package:photos/services/app_lifecycle_service.dart';
import 'package:photos/services/collections_service.dart';
import 'package:photos/services/feature_flag_service.dart';
import 'package:photos/services/file_migration_service.dart';
import 'package:photos/services/ignored_files_service.dart';
import 'package:photos/services/local_file_update_service.dart';
import 'package:photos/services/local_sync_service.dart';
import 'package:photos/services/trash_sync_service.dart';
import 'package:photos/utils/diff_fetcher.dart';
@ -32,8 +32,8 @@ class RemoteSyncService {
final _uploader = FileUploader.instance;
final _collectionsService = CollectionsService.instance;
final _diffFetcher = DiffFetcher();
final FileMigrationService _fileMigrationService =
FileMigrationService.instance;
final LocalFileUpdateService _localFileUpdateService =
LocalFileUpdateService.instance;
int _completedUploads = 0;
SharedPreferences _prefs;
Completer<void> _existingSync;
@ -135,7 +135,7 @@ class RemoteSyncService {
await _markReSyncAsDone();
}
if (FeatureFlagService.instance.enableMissingLocationMigration()) {
_fileMigrationService.runMigration();
_localFileUpdateService.markUpdatedFilesForReUpload();
}
}