extract CachedKeyValueRepository
parent
932302c5ab
commit
19fbc11c33
|
|
@ -0,0 +1,37 @@
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
// ignore: depend_on_referenced_packages
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
|
abstract class CachedKeyValueRepository<K extends Enum, S> {
|
||||||
|
CachedKeyValueRepository(this._snapshot);
|
||||||
|
|
||||||
|
S _snapshot;
|
||||||
|
S get snapshot => _snapshot;
|
||||||
|
@protected
|
||||||
|
set snapshot(S value) => _snapshot = value;
|
||||||
|
|
||||||
|
List<K> get keys;
|
||||||
|
|
||||||
|
Object decodeValue(K key, String raw);
|
||||||
|
|
||||||
|
S buildSnapshot(Map<K, Object> overrides);
|
||||||
|
|
||||||
|
Selectable<({String key, String value})> selectable();
|
||||||
|
|
||||||
|
Future<void> refresh() async => _snapshot = _build(await selectable().get());
|
||||||
|
|
||||||
|
Stream<S> watchSnapshot() => selectable().watch().map((rows) => _snapshot = _build(rows));
|
||||||
|
|
||||||
|
S _build(List<({String key, String value})> rows) {
|
||||||
|
final overrides = <K, Object>{};
|
||||||
|
for (final row in rows) {
|
||||||
|
final key = keys.firstWhereOrNull((k) => k.name == row.key);
|
||||||
|
if (key == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
overrides[key] = decodeValue(key, row.value);
|
||||||
|
}
|
||||||
|
return buildSnapshot(overrides);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:immich_mobile/domain/models/config/app_config.dart';
|
import 'package:immich_mobile/domain/models/config/app_config.dart';
|
||||||
import 'package:immich_mobile/domain/models/settings_key.dart';
|
import 'package:immich_mobile/domain/models/settings_key.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/settings.entity.drift.dart';
|
import 'package:immich_mobile/infrastructure/entities/settings.entity.drift.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/cached_key_value_repository.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||||
|
|
||||||
class SettingsRepository extends DriftDatabaseRepository {
|
class SettingsRepository extends CachedKeyValueRepository<SettingsKey, AppConfig> {
|
||||||
final Drift _db;
|
final Drift _db;
|
||||||
|
|
||||||
SettingsRepository._(this._db) : super(_db);
|
SettingsRepository._(this._db) : super(const .new());
|
||||||
|
|
||||||
static SettingsRepository? _instance;
|
static SettingsRepository? _instance;
|
||||||
|
|
||||||
|
|
@ -20,9 +20,6 @@ class SettingsRepository extends DriftDatabaseRepository {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppConfig _appConfig = const .new();
|
|
||||||
AppConfig get appConfig => _appConfig;
|
|
||||||
|
|
||||||
static Future<SettingsRepository> ensureInitialized(Drift db) async {
|
static Future<SettingsRepository> ensureInitialized(Drift db) async {
|
||||||
if (_instance == null) {
|
if (_instance == null) {
|
||||||
final instance = SettingsRepository._(db);
|
final instance = SettingsRepository._(db);
|
||||||
|
|
@ -32,7 +29,20 @@ class SettingsRepository extends DriftDatabaseRepository {
|
||||||
return _instance!;
|
return _instance!;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> refresh() async => _applyOverrides(await _db.select(_db.settingsEntity).get());
|
@override
|
||||||
|
List<SettingsKey> get keys => SettingsKey.values;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Object decodeValue(SettingsKey key, String raw) => key.decode(raw);
|
||||||
|
|
||||||
|
@override
|
||||||
|
AppConfig buildSnapshot(Map<SettingsKey, Object> overrides) => AppConfig.fromEntries(overrides);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Selectable<({String key, String value})> selectable() =>
|
||||||
|
_db.select(_db.settingsEntity).map((row) => (key: row.key, value: row.value));
|
||||||
|
|
||||||
|
AppConfig get appConfig => snapshot;
|
||||||
|
|
||||||
Future<void> clear(Iterable<SettingsKey> keys) async {
|
Future<void> clear(Iterable<SettingsKey> keys) async {
|
||||||
if (keys.isEmpty) {
|
if (keys.isEmpty) {
|
||||||
|
|
@ -42,13 +52,15 @@ class SettingsRepository extends DriftDatabaseRepository {
|
||||||
final names = keys.map((key) => key.name).toList();
|
final names = keys.map((key) => key.name).toList();
|
||||||
await (_db.delete(_db.settingsEntity)..where((row) => row.key.isIn(names))).go();
|
await (_db.delete(_db.settingsEntity)..where((row) => row.key.isIn(names))).go();
|
||||||
|
|
||||||
|
var config = snapshot;
|
||||||
for (final key in keys) {
|
for (final key in keys) {
|
||||||
_appConfig = _appConfig.write(key, defaultConfig.read(key));
|
config = config.write(key, defaultConfig.read(key));
|
||||||
}
|
}
|
||||||
|
snapshot = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> write<T extends Object, U extends T>(SettingsKey<T> key, U value) async {
|
Future<void> write<T extends Object, U extends T>(SettingsKey<T> key, U value) async {
|
||||||
if (value == _appConfig.read(key)) {
|
if (value == snapshot.read(key)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,24 +73,8 @@ class SettingsRepository extends DriftDatabaseRepository {
|
||||||
.insertOnConflictUpdate(
|
.insertOnConflictUpdate(
|
||||||
SettingsEntityCompanion.insert(key: key.name, value: key.encode(value), updatedAt: Value(DateTime.now())),
|
SettingsEntityCompanion.insert(key: key.name, value: key.encode(value), updatedAt: Value(DateTime.now())),
|
||||||
);
|
);
|
||||||
_appConfig = _appConfig.write(key, value);
|
snapshot = snapshot.write(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<AppConfig> watchConfig() => _db.select(_db.settingsEntity).watch().map((rows) {
|
Stream<AppConfig> watchConfig() => watchSnapshot();
|
||||||
_applyOverrides(rows);
|
|
||||||
return _appConfig;
|
|
||||||
});
|
|
||||||
|
|
||||||
void _applyOverrides(List<SettingsEntityData> rows) {
|
|
||||||
_appConfig = AppConfig.fromEntries(
|
|
||||||
rows.fold({}, (overrides, row) {
|
|
||||||
final metadataKey = SettingsKey.values.firstWhereOrNull((key) => key.name == row.key);
|
|
||||||
if (metadataKey == null) {
|
|
||||||
return overrides;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {...overrides, metadataKey: metadataKey.decode(row.value)};
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue