LCOV - code coverage report
Current view: top level - repository - hive_local_adapter.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 48 63 76.2 %
Date: 2022-05-06 22:54:19 Functions: 0 0 -

          Line data    Source code
       1             : part of flutter_data;
       2             : 
       3             : /// Hive implementation of [LocalAdapter] and Hive's [TypeAdapter].
       4             : // ignore: must_be_immutable
       5             : abstract class HiveLocalAdapter<T extends DataModel<T>> extends LocalAdapter<T>
       6             :     with TypeAdapter<T> {
       7           1 :   HiveLocalAdapter(Reader read)
       8           2 :       : _hiveLocalStorage = read(hiveLocalStorageProvider),
       9           1 :         super(read);
      10             : 
      11             :   final HiveLocalStorage _hiveLocalStorage;
      12             : 
      13             :   final _hiveAdapterNs = '_adapter_hive';
      14           3 :   String get _hiveAdapterKey => 'key'.namespaceWith(_hiveAdapterNs);
      15             : 
      16           2 :   String get _internalType => DataHelpers.getType<T>();
      17             : 
      18             :   @protected
      19             :   @visibleForTesting
      20             :   Box<T>? box;
      21             : 
      22             :   @override
      23           1 :   Future<HiveLocalAdapter<T>> initialize() async {
      24           1 :     if (isInitialized) return this;
      25             : 
      26           4 :     if (!_hiveLocalStorage.hive.isBoxOpen(_internalType)) {
      27           4 :       if (!_hiveLocalStorage.hive.isAdapterRegistered(typeId)) {
      28           0 :         _hiveLocalStorage.hive.registerAdapter(this);
      29             :       }
      30           2 :       if (_hiveLocalStorage.clear) {
      31           0 :         await _hiveLocalStorage.deleteBox(_internalType);
      32             :       }
      33             :     }
      34             : 
      35             :     try {
      36           5 :       box = await _hiveLocalStorage.openBox<T>(_internalType);
      37             :     } catch (e, stackTrace) {
      38           0 :       print('[flutter_data] Box failed to open:\n$stackTrace');
      39             :     }
      40             : 
      41             :     return this;
      42             :   }
      43             : 
      44           1 :   @override
      45           2 :   bool get isInitialized => box?.isOpen ?? false;
      46             : 
      47           1 :   @override
      48             :   void dispose() {
      49           2 :     box?.close();
      50             :   }
      51             : 
      52             :   // protected API
      53             : 
      54           1 :   @override
      55             :   List<T>? findAll() {
      56           1 :     if (_isLocalStorageTouched) {
      57           3 :       return box!.values.toImmutableList();
      58             :     }
      59             :     return null;
      60             :   }
      61             : 
      62           1 :   @override
      63           2 :   T? findOne(String? key) => box!.get(key);
      64             : 
      65             :   @override
      66           1 :   Future<T> save(String key, T model, {bool notify = true}) async {
      67           1 :     _touchLocalStorage();
      68             : 
      69           2 :     final keyExisted = box!.containsKey(key);
      70           2 :     final save = box!.put(key, model);
      71             :     if (notify) {
      72           2 :       graph._notify(
      73           1 :         [key],
      74             :         type: keyExisted
      75             :             ? DataGraphEventType.updateNode
      76             :             : DataGraphEventType.addNode,
      77             :       );
      78             :     }
      79             : 
      80           1 :     await save;
      81             :     return model;
      82             :   }
      83             : 
      84             :   @override
      85           1 :   Future<void> delete(String key) async {
      86           2 :     final delete = box!.delete(key); // delete in bg
      87             :     // id will become orphan & purged
      88           2 :     graph.removeKey(key);
      89           1 :     await delete;
      90             :   }
      91             : 
      92             :   @override
      93           1 :   Future<void> clear() async {
      94           3 :     await box!.clear();
      95             :   }
      96             : 
      97             :   // Touching local storage means the box has received data;
      98             :   // this is used to know whether `findAll` should return
      99             :   // null, or its models (possibly empty)
     100             : 
     101             :   // _boxMetadata: {
     102             :   //   '_boxMetadata:touched': ['_'],
     103             :   // }
     104             : 
     105           1 :   @override
     106             :   bool get _isLocalStorageTouched {
     107           2 :     return graph._hasEdge('_boxMetadata', metadata: '_boxMetadata:touched');
     108             :   }
     109             : 
     110           1 :   @override
     111             :   void _touchLocalStorage() {
     112           2 :     graph._addEdge('_boxMetadata', '_',
     113             :         metadata: '_boxMetadata:touched', addNode: true, notify: false);
     114             :   }
     115             : 
     116             :   // hive adapter
     117             : 
     118           1 :   @override
     119             :   int get typeId {
     120             :     // _adapter_hive:key: {
     121             :     //   '_adapter_hive:posts': ['_adapter_hive:1'],
     122             :     //   '_adapter_hive:comments': ['_adapter_hive:2'],
     123             :     //   '_adapter_hive:houses': ['_adapter_hive:3'],
     124             :     // }
     125             : 
     126             :     final _typesNode =
     127           3 :         graph._getNode(_hiveAdapterKey, orAdd: true, notify: false)!;
     128             : 
     129           4 :     final edge = _typesNode[_internalType.namespaceWith(_hiveAdapterNs)];
     130             : 
     131           1 :     if (edge != null && edge.isNotEmpty) {
     132             :       // first is of format: _adapter_hive:1
     133           1 :       return int.parse(edge.first.denamespace());
     134             :     }
     135             : 
     136             :     // get namespaced indices
     137           1 :     final index = _typesNode.values
     138             :             // denamespace and parse single
     139           5 :             .map((e) => int.parse(e.first.denamespace()))
     140             :             // find max
     141           2 :             .fold(0, math.max) +
     142             :         1;
     143             : 
     144           2 :     graph._addEdge(
     145           4 :         _hiveAdapterKey, index.toString().namespaceWith(_hiveAdapterNs),
     146           3 :         metadata: _internalType.namespaceWith(_hiveAdapterNs), notify: false);
     147             :     return index;
     148             :   }
     149             : 
     150           0 :   @override
     151             :   T read(reader) {
     152             :     // read attributes (no relationships stored)
     153           0 :     final total = reader.readByte();
     154           0 :     final map = <String, dynamic>{
     155           0 :       for (var i = 0; i < total; i++) reader.read().toString(): reader.read(),
     156             :     };
     157             : 
     158           0 :     final model = deserialize(map);
     159             :     return model;
     160             :   }
     161             : 
     162           0 :   @override
     163             :   void write(writer, T obj) {
     164           0 :     final _map = serialize(obj, withRelationships: false);
     165             : 
     166           0 :     final keys = _map.keys;
     167           0 :     writer.writeByte(keys.length);
     168           0 :     for (final k in keys) {
     169           0 :       writer.write(k);
     170           0 :       writer.write(_map[k]);
     171             :     }
     172             :   }
     173             : }

Generated by: LCOV version 1.15