add full sync

This commit is contained in:
shenlong-tanwen
2024-09-02 02:16:47 +05:30
parent 877c3b028b
commit e81b61c98b
30 changed files with 333 additions and 179 deletions
@@ -1,9 +1,7 @@
import 'dart:io';
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
// ignore: depend_on_referenced_packages
import 'package:drift_dev/api/migrations.dart';
import 'package:drift_flutter/drift_flutter.dart';
import 'package:flutter/foundation.dart';
import 'package:immich_mobile/domain/entities/album.entity.dart';
import 'package:immich_mobile/domain/entities/local_asset.entity.dart';
@@ -11,54 +9,17 @@ import 'package:immich_mobile/domain/entities/log.entity.dart';
import 'package:immich_mobile/domain/entities/remote_asset.entity.dart';
import 'package:immich_mobile/domain/entities/store.entity.dart';
import 'package:immich_mobile/domain/entities/user.entity.dart';
import 'package:immich_mobile/domain/interfaces/database.interface.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
import 'package:sqlite3/sqlite3.dart';
import 'package:sqlite3_flutter_libs/sqlite3_flutter_libs.dart';
import 'database.repository.drift.dart';
@DriftDatabase(tables: [Logs, Store, LocalAlbum, LocalAsset, User, RemoteAsset])
class DriftDatabaseRepository extends $DriftDatabaseRepository
implements IDatabaseRepository<GeneratedDatabase> {
DriftDatabaseRepository() : super(_openConnection());
static LazyDatabase _openConnection() {
return LazyDatabase(() async {
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'db.sqlite'));
// Work around limitations on old Android versions
// https://github.com/simolus3/sqlite3.dart/tree/main/sqlite3_flutter_libs#problems-on-android-6
if (Platform.isAndroid) {
await applyWorkaroundToOpenSqlite3OnOldAndroidVersions();
}
// Make sqlite3 pick a more suitable location for temporary files - the
// one from the system may be inaccessible due to sandboxing.
// https://github.com/simolus3/moor/issues/876#issuecomment-710013503
final cachebase = (await getTemporaryDirectory()).path;
// We can't access /tmp on Android, which sqlite3 would try by default.
// Explicitly tell it about the correct temporary directory.
sqlite3.tempDirectory = cachebase;
return NativeDatabase.createInBackground(file);
});
}
@override
GeneratedDatabase init() => this;
class DriftDatabaseRepository extends $DriftDatabaseRepository {
DriftDatabaseRepository([QueryExecutor? executor])
: super(executor ?? driftDatabase(name: 'db'));
@override
int get schemaVersion => 1;
@override
// ignore: no-empty-block
void migrateDB() {
// Migrations are handled automatically using the migrator field
}
@override
MigrationStrategy get migration => MigrationStrategy(
onCreate: (m) => m.createAll(),
@@ -13,8 +13,8 @@ class LogDriftRepository implements ILogRepository {
const LogDriftRepository(this.db);
@override
Future<List<LogMessage>> fetchLogs() async {
return await db.managers.logs.map((l) => l.toModel()).get();
Future<List<LogMessage>> fetchAll() async {
return await db.managers.logs.map(_toModel).get();
}
@override
@@ -82,15 +82,13 @@ class LogDriftRepository implements ILogRepository {
}
}
extension _LogToLogMessage on Log {
LogMessage toModel() {
return LogMessage(
content: content,
createdAt: createdAt,
level: level,
error: error,
logger: logger,
stack: stack,
);
}
LogMessage _toModel(Log log) {
return LogMessage(
content: log.content,
createdAt: log.createdAt,
level: log.level,
error: log.error,
logger: log.logger,
stack: log.stack,
);
}
@@ -0,0 +1,44 @@
import 'package:drift/drift.dart';
import 'package:immich_mobile/domain/entities/remote_asset.entity.drift.dart';
import 'package:immich_mobile/domain/interfaces/remote_asset.interface.dart';
import 'package:immich_mobile/domain/models/asset/remote_asset.model.dart';
import 'package:immich_mobile/domain/repositories/database.repository.dart';
import 'package:immich_mobile/utils/mixins/log_context.mixin.dart';
class RemoteAssetDriftRepository
with LogContext
implements IRemoteAssetRepository {
final DriftDatabaseRepository _db;
const RemoteAssetDriftRepository(this._db);
@override
Future<bool> addAll(Iterable<RemoteAsset> assets) async {
try {
await _db.batch((batch) => batch.insertAllOnConflictUpdate(
_db.remoteAsset,
assets.map(_toEntity),
));
return true;
} catch (e, s) {
log.severe("Cannot insert remote assets into table", e, s);
return false;
}
}
}
RemoteAssetCompanion _toEntity(RemoteAsset asset) {
return RemoteAssetCompanion.insert(
name: asset.name,
checksum: asset.checksum,
height: Value(asset.height),
width: Value(asset.width),
type: asset.type,
createdTime: asset.createdTime,
remoteId: asset.remoteId,
duration: Value(asset.duration),
modifiedTime: Value(asset.modifiedTime),
livePhotoVideoId: Value(asset.livePhotoVideoId),
);
}
@@ -63,7 +63,7 @@ class StoreDriftRepository with LogContext implements IStoreRepository {
@override
FutureOr<void> clearStore() async {
await db.managers.store.delete();
;
}
FutureOr<T?> _getValueFromStoreData<T, U>(
@@ -13,15 +13,15 @@ class UserDriftRepository with LogContext implements IUserRepository {
const UserDriftRepository(this.db);
@override
FutureOr<User?> getUser(String userId) async {
FutureOr<User?> fetch(String userId) async {
return await db.managers.user
.filter((f) => f.id.equals(userId))
.map((u) => u.toModel())
.map(_toModel)
.getSingleOrNull();
}
@override
FutureOr<bool> insertUser(User user) async {
FutureOr<bool> add(User user) async {
try {
await db.into(db.user).insertOnConflictUpdate(
UserCompanion.insert(
@@ -46,20 +46,18 @@ class UserDriftRepository with LogContext implements IUserRepository {
}
}
extension _UserDataToUser on UserData {
User toModel() {
return User(
id: id,
email: email,
avatarColor: avatarColor,
inTimeline: inTimeline,
isAdmin: isAdmin,
memoryEnabled: memoryEnabled,
name: name,
profileImagePath: profileImagePath,
quotaSizeInBytes: quotaSizeInBytes,
quotaUsageInBytes: quotaUsageInBytes,
updatedAt: updatedAt,
);
}
User _toModel(UserData user) {
return User(
id: user.id,
email: user.email,
avatarColor: user.avatarColor,
inTimeline: user.inTimeline,
isAdmin: user.isAdmin,
memoryEnabled: user.memoryEnabled,
name: user.name,
profileImagePath: user.profileImagePath,
quotaSizeInBytes: user.quotaSizeInBytes,
quotaUsageInBytes: user.quotaUsageInBytes,
updatedAt: user.updatedAt,
);
}