Line data Source code
1 : import 'package:event_db/event_db.dart'; 2 : 3 : /// Represents a map of [GenericModel]s with functions to automatically 4 : /// retrieve and save them in a [DatabaseRepository] 5 : // TODO(vhcblade): BP-32 https://trello.com/c/uj0uS1cO/32-bp-32-add-test-for-genericmodelmap-in-eventdb 6 : class GenericModelMap<T extends GenericModel> { 7 : /// Maintains a [map] for the [T] models with their id as their key. 8 : /// 9 : /// [supplier] generates a new instance of [T] 10 : /// 11 : /// [repository] gives this the instance of the [DatabaseRepository] to be 12 : /// used in the automatic loading functions of this class. 13 : /// 14 : /// [defaultDatabaseName] is the database the [repository] will use. This can 15 : /// be overridden in all the loading functions of this class. 16 1 : GenericModelMap({ 17 : required this.repository, 18 : required this.supplier, 19 : this.defaultDatabaseName, 20 : }); 21 : 22 : /// The map of [GenericModel]s with their id as the key 23 : final Map<String, T> map = {}; 24 : 25 : /// Creates a new instance of [T], provided in the constructor 26 : final ModelConstructor<T> supplier; 27 : 28 : /// Returns the used [DatabaseRepository] for the various functions provided. 29 : final DatabaseRepository Function() repository; 30 : 31 : /// Used in the various functions if a databaseName is not specified for them. 32 : final String? defaultDatabaseName; 33 : 34 : /// Creates the [SpecificDatabase] using the [defaultDatabaseName] passed in 35 : /// the constructor. 36 : /// 37 : /// if [databaseName] is provided, it will use that rather than 38 : /// [defaultDatabaseName] 39 1 : SpecificDatabase specificDatabase([String? databaseName]) { 40 : assert( 41 2 : databaseName != null || defaultDatabaseName != null, 42 : 'At least one of defaultDatabaseName and databaseName needs to be ' 43 : 'provided', 44 : ); 45 4 : return SpecificDatabase(repository(), databaseName ?? defaultDatabaseName!); 46 : } 47 : 48 : /// Adds the given [models] to the [map] without adding them to the 49 : /// [repository]. It is assumed that these are already present. 50 1 : void addLoadedModels(Iterable<T> models) => 51 6 : map.addAll({for (final model in models) model.id!: model}); 52 : 53 : /// Removes the given [models] to the [map] without removing them from the 54 : /// [repository]. It is assumed that these have already been removed. 55 0 : void removeLoadedModels(Iterable<T> models) { 56 0 : final set = models.map((e) => e.id).toSet(); 57 0 : map.removeWhere((key, value) => set.contains(key)); 58 : } 59 : 60 : /// Loads all of the [T] models present in [repository] 61 : /// for the given database. 62 1 : Future<Iterable<T>> loadAll({String? databaseName}) async { 63 1 : final database = specificDatabase(databaseName); 64 2 : final models = await database.findAllModelsOfType(supplier); 65 1 : addLoadedModels(models); 66 : return models; 67 : } 68 : 69 : /// Loads all of the [T] models with the given [ids] in [repository] 70 : /// for the given database. 71 0 : Future<Iterable<T>> loadModelIds( 72 : Iterable<String> ids, { 73 : String? databaseName, 74 : }) async { 75 0 : final database = specificDatabase(databaseName); 76 : 77 0 : final loadedModels = await database.findModels<T>(ids); 78 0 : addLoadedModels(loadedModels); 79 : return loadedModels; 80 : } 81 : 82 : /// Adds the given [model] to the [map] and the given database in [repository] 83 1 : Future<T> addModel(T model, {String? databaseName}) async { 84 1 : final database = specificDatabase(databaseName); 85 : 86 1 : final newModel = await database.saveModel<T>(model); 87 2 : addLoadedModels([newModel]); 88 : 89 : return newModel; 90 : } 91 : 92 : /// Deletes the given [model] from the [map] and the given database in 93 : /// [repository] 94 0 : Future<bool> deleteModel(T model, {String? databaseName}) async { 95 0 : final database = specificDatabase(databaseName); 96 : 97 0 : final successful = await database.deleteModel<T>(model); 98 : if (successful) { 99 0 : removeLoadedModels([model]); 100 : } 101 : return successful; 102 : } 103 : 104 : /// Updates the given [model] to the [map] and the given database in 105 : /// [repository] 106 1 : Future<T> updateModel(T model, {String? databaseName}) async { 107 1 : final database = specificDatabase(databaseName); 108 : 109 1 : final newModel = await database.saveModel<T>(model); 110 2 : addLoadedModels([newModel]); 111 : return newModel; 112 : } 113 : }