Line data Source code
1 : part of flutter_data; 2 : 3 : /// An adapter interface to access local storage. 4 : /// 5 : /// Identity in this layer is enforced by keys. 6 : /// 7 : /// See also: [HiveLocalAdapter] 8 : abstract class LocalAdapter<T extends DataModel<T>> with _Lifecycle { 9 1 : @protected 10 2 : LocalAdapter(Reader read) : graph = read(graphNotifierProvider); 11 : 12 : @protected 13 : final GraphNotifier graph; 14 : 15 : FutureOr<LocalAdapter<T>> initialize(); 16 : 17 : // protected API 18 : 19 : /// Returns all models of type [T] in local storage. 20 : List<T>? findAll(); 21 : 22 : /// Finds model of type [T] by [key] in local storage. 23 : T? findOne(String? key); 24 : 25 : /// Saves model of type [T] with [key] in local storage. 26 : /// 27 : /// By default notifies this modification to the associated [GraphNotifier]. 28 : @protected 29 : @visibleForTesting 30 : Future<T> save(String key, T model, {bool notify = true}); 31 : 32 : /// Deletes model of type [T] with [key] from local storage. 33 : /// 34 : /// By default notifies this modification to the associated [GraphNotifier]. 35 : @protected 36 : @visibleForTesting 37 : Future<void> delete(String key); 38 : 39 : /// Deletes all models of type [T] in local storage. 40 : @protected 41 : @visibleForTesting 42 : Future<void> clear(); 43 : 44 : // public abstract methods 45 : 46 : Map<String, dynamic> serialize(T model, {bool withRelationships = true}); 47 : 48 : T deserialize(Map<String, dynamic> map); 49 : 50 : Map<String, Map<String, Object?>> relationshipsFor([T model]); 51 : 52 : // helpers 53 : 54 1 : Map<String, dynamic> transformSerialize(Map<String, dynamic> map, 55 : {bool withRelationships = true}) { 56 3 : for (final e in relationshipsFor().entries) { 57 1 : final key = e.key; 58 : if (withRelationships) { 59 3 : final ignored = e.value['serialize'] == 'false'; 60 1 : if (ignored) map.remove(key); 61 : 62 2 : if (map[key] is HasMany) { 63 3 : map[key] = (map[key] as HasMany).keys; 64 2 : } else if (map[key] is BelongsTo) { 65 3 : map[key] = map[key].key; 66 : } 67 : 68 2 : if (map[key] == null) map.remove(key); 69 : } else { 70 1 : map.remove(key); 71 : } 72 : } 73 : return map; 74 : } 75 : 76 1 : Map<String, dynamic> transformDeserialize(Map<String, dynamic> map) { 77 1 : map = Map<String, dynamic>.from(map); 78 3 : for (final e in relationshipsFor().entries) { 79 1 : final key = e.key; 80 2 : final keyset = map[key] is Iterable 81 2 : ? {...(map[key] as Iterable)} 82 3 : : {if (map[key] != null) map[key].toString()}; 83 3 : final ignored = e.value['serialize'] == 'false'; 84 2 : map[key] = { 85 1 : '_': (map.containsKey(key) && !ignored) ? keyset : null, 86 : }; 87 : } 88 : return map; 89 : } 90 : 91 : // private 92 : 93 : // ignore: unused_element 94 : bool get _isLocalStorageTouched; 95 : 96 : void _touchLocalStorage(); 97 : }