LCOV - code coverage report
Current view: top level - model/relationship - relationship.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 66 68 97.1 %
Date: 2022-06-06 11:59:57 Functions: 0 0 -

          Line data    Source code
       1             : part of flutter_data;
       2             : 
       3             : /// A `Set` that models a relationship between one or more [DataModel] objects
       4             : /// and their a [DataModel] owner. Backed by a [GraphNotifier].
       5             : abstract class Relationship<E extends DataModel<E>, N> with EquatableMixin {
       6          11 :   @protected
       7             :   Relationship(Set<E>? models)
       8          29 :       : this._(models?.map((m) {
       9           9 :           if (m._key == null) {
      10           0 :             throw AssertionError(
      11           0 :                 'Model $m must be initialized to be included in this relationship');
      12             :           }
      13           9 :           return m._key!;
      14           9 :         }).toSet());
      15             : 
      16          11 :   Relationship._(this._uninitializedKeys);
      17             : 
      18           3 :   Relationship._remove() : _uninitializedKeys = {};
      19             : 
      20             :   String? _ownerKey;
      21             :   String? _name;
      22             :   String? _inverseName;
      23             : 
      24          11 :   RemoteAdapter<E> get _adapter =>
      25          44 :       internalRepositories[_internalType]!.remoteAdapter as RemoteAdapter<E>;
      26          44 :   GraphNotifier get _graph => _adapter.localAdapter.graph;
      27             : 
      28             :   final Set<String>? _uninitializedKeys;
      29          22 :   String get _internalType => DataHelpers.getType<E>();
      30             : 
      31          22 :   bool get isInitialized => _ownerKey != null;
      32             : 
      33             :   /// Initializes this relationship (typically when initializing the owner
      34             :   /// in [DataModel]) by supplying the owner, and related metadata.
      35          11 :   Relationship<E, N> initialize(
      36             :       {required final DataModel owner,
      37             :       required final String name,
      38             :       final String? inverseName}) {
      39          11 :     if (isInitialized) return this;
      40             : 
      41          22 :     _ownerKey = owner._key;
      42          11 :     _name = name;
      43          11 :     _inverseName = inverseName;
      44             : 
      45             :     // means it was omitted (remote-omitted, or loaded locally), so skip
      46          11 :     if (_uninitializedKeys == null) return this;
      47             : 
      48             :     // setting up from scratch, remove all and add keys
      49             : 
      50          30 :     _graph._removeEdges(_ownerKey!,
      51          20 :         metadata: _name!, inverseMetadata: _inverseName, notify: false);
      52             : 
      53             :     // in case node was removed during removeEdges
      54          30 :     _graph._addNode(_ownerKey!);
      55             : 
      56          20 :     _graph._addEdges(
      57          10 :       _ownerKey!,
      58          10 :       tos: _uninitializedKeys!,
      59          10 :       metadata: _name!,
      60          10 :       inverseMetadata: _inverseName,
      61             :       notify: false,
      62             :     );
      63          20 :     _uninitializedKeys!.clear();
      64             : 
      65             :     return this;
      66             :   }
      67             : 
      68             :   // implement collection-like methods
      69             : 
      70           5 :   bool _add(E value, {bool notify = true}) {
      71           5 :     if (_contains(value)) {
      72             :       return false;
      73             :     }
      74             : 
      75          20 :     _graph._addEdge(_ownerKey!, value._key!,
      76          10 :         metadata: _name!, inverseMetadata: _inverseName, notify: false);
      77             :     if (notify) {
      78           8 :       _graph._notify(
      79          12 :         [_ownerKey!, value._key!],
      80           4 :         metadata: _name,
      81             :         type: DataGraphEventType.addEdge,
      82             :       );
      83             :     }
      84             : 
      85             :     return true;
      86             :   }
      87             : 
      88           5 :   bool _contains(Object? element) {
      89          10 :     return _iterable.contains(element);
      90             :   }
      91             : 
      92           4 :   bool _remove(Object? value, {bool notify = true}) {
      93           8 :     assert(value is E);
      94             :     final model = value as E;
      95             : 
      96           8 :     _graph._removeEdge(
      97           4 :       _ownerKey!,
      98           4 :       model._key!,
      99           4 :       metadata: _name!,
     100           4 :       inverseMetadata: _inverseName,
     101             :       notify: false,
     102             :     );
     103             :     if (notify) {
     104           6 :       _graph._notify(
     105           9 :         [_ownerKey!, value._key!],
     106           3 :         metadata: _name,
     107             :         type: DataGraphEventType.removeEdge,
     108             :       );
     109             :     }
     110             :     return true;
     111             :   }
     112             : 
     113             :   // support methods
     114             : 
     115           9 :   Iterable<E> get _iterable {
     116          63 :     return _keys.map((key) => _adapter.localAdapter.findOne(key)).filterNulls;
     117             :   }
     118             : 
     119          11 :   Set<String> get _keys {
     120          11 :     if (!isInitialized) return {};
     121          55 :     return _graph._getEdge(_ownerKey!, metadata: _name!).toSet();
     122             :   }
     123             : 
     124           4 :   Set<Object> get _ids {
     125          25 :     return _keys.map((key) => _graph.getIdForKey(key)).filterNulls.toSet();
     126             :   }
     127             : 
     128           2 :   DelayedStateNotifier<DataGraphEvent> get _relationshipEventNotifier {
     129           8 :     return _adapter.graph.where((event) {
     130           4 :       return event.type.isEdge &&
     131           6 :           event.metadata == _name &&
     132           6 :           event.keys.containsFirst(_ownerKey!);
     133             :     });
     134             :   }
     135             : 
     136             :   DelayedStateNotifier<N> watch();
     137             : 
     138             :   /// This is used to make `json_serializable`'s `explicitToJson` transparent.
     139             :   ///
     140             :   /// For internal use. Does not return valid JSON.
     141           8 :   dynamic toJson() => this;
     142             : 
     143             :   /// Whether the relationship has a value.
     144           6 :   bool get isPresent => _iterable.isNotEmpty;
     145             : 
     146           5 :   @override
     147          20 :   List<Object?> get props => [_ownerKey, _name, _inverseName];
     148             : 
     149           4 :   @override
     150             :   String toString() {
     151             :     final keysWithoutId =
     152          23 :         _keys.where((k) => _graph.getIdForKey(k) == null).map((k) => '[$k]');
     153          12 :     return {..._ids, ...keysWithoutId}.join(', ');
     154             :   }
     155             : }
     156             : 
     157             : // annotation
     158             : 
     159             : class DataRelationship {
     160             :   final String? inverse;
     161             :   final bool serialize;
     162          34 :   const DataRelationship({this.inverse, this.serialize = true});
     163             : }

Generated by: LCOV version 1.15