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

Generated by: LCOV version 1.15