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

          Line data    Source code
       1             : part of flutter_data;
       2             : 
       3             : /// A mixin to "tag" and ensure the implementation of an [id] getter
       4             : /// in data classes managed through Flutter Data.
       5             : ///
       6             : /// It contains private state and methods to track the model's identity.
       7             : abstract class DataModel<T extends DataModel<T>> {
       8             :   Object? get id;
       9             : 
      10          11 :   DataModel() {
      11          33 :     final repository = internalRepositories[_internalType];
      12             :     if (repository != null) {
      13          33 :       repository.remoteAdapter.localAdapter.initModel(
      14             :         this,
      15          22 :         onModelInitialized: repository.remoteAdapter.onModelInitialized,
      16             :       );
      17             :     }
      18             :   }
      19             : 
      20             :   String? _key;
      21          22 :   String get _internalType => DataHelpers.getType<T>();
      22          11 :   T get _this => this as T;
      23             : 
      24             :   /// Exposes this type's [RemoteAdapter]
      25          11 :   RemoteAdapter<T> get _remoteAdapter =>
      26          44 :       internalRepositories[_internalType]!.remoteAdapter as RemoteAdapter<T>;
      27             : 
      28             :   // data model helpers
      29             : 
      30             :   /// Returns a model's `_key` private attribute.
      31             :   ///
      32             :   /// Useful for testing, debugging or usage in [RemoteAdapter] subclasses.
      33          14 :   static String keyFor(DataModel model) => model._key!;
      34             : 
      35             :   /// Returns a model's non-null relationships.
      36           1 :   static Map<String, Relationship> relationshipsFor<T extends DataModel<T>>(
      37             :       T model) {
      38           1 :     return {
      39             :       for (final meta
      40           4 :           in model._remoteAdapter.localAdapter.relationshipMetas.values)
      41           6 :         if (meta.instance(model) != null) meta.name: meta.instance(model)!,
      42             :     };
      43             :   }
      44             : 
      45             :   /// Returns a model [RemoteAdapter]
      46           4 :   static RemoteAdapter adapterFor(DataModel model) => model._remoteAdapter;
      47             : 
      48             :   /// Apply [model]'s key to [applyTo].
      49           4 :   static DataModel withKeyOf(DataModel model,
      50             :       {required DataModel applyTo, bool force = false}) {
      51             :     final _this = applyTo;
      52          12 :     if (model._key != _this._key) {
      53             :       DataModel oldModel;
      54             :       DataModel newModel;
      55             : 
      56             :       // if the passed-in model has no ID
      57             :       // then treat the original as prevalent
      58          12 :       if (force == false && model.id == null && _this.id != null) {
      59             :         oldModel = model;
      60             :         newModel = _this;
      61             :       } else {
      62             :         // in all other cases, treat the passed-in
      63             :         // model as prevalent
      64             :         oldModel = _this;
      65             :         newModel = model;
      66             :       }
      67             : 
      68           4 :       final oldKey = oldModel._key;
      69          12 :       if (_this._key != newModel._key) {
      70           4 :         _this._key = newModel._key;
      71             :       }
      72          12 :       if (_this._key != oldModel._key) {
      73           6 :         oldModel._key = _this._key;
      74           9 :         _this._remoteAdapter.graph.removeKey(oldKey!);
      75             :       }
      76             : 
      77           4 :       if (oldModel.id != null) {
      78           2 :         _this._remoteAdapter.graph
      79           3 :             .removeId(_this._internalType, oldModel.id!, notify: false);
      80           5 :         _this._remoteAdapter.graph.getKeyForId(_this._internalType, oldModel.id,
      81           1 :             keyIfAbsent: _this._key);
      82             :       }
      83             :     }
      84             :     return _this;
      85             :   }
      86             : }
      87             : 
      88             : /// Extension that adds syntax-sugar to data classes,
      89             : /// linking them to common [Repository] methods such as
      90             : /// [save] and [delete].
      91             : extension DataModelExtension<T extends DataModel<T>> on DataModel<T> {
      92             :   /// Copy identity (internal key) from an old model to a new one
      93             :   /// to signal they are the same.
      94             :   ///
      95             :   /// **Only makes sense to use if model is immutable and has no ID!**
      96             :   ///
      97             :   /// ```
      98             :   /// final walter = Person(name: 'Walter');
      99             :   /// person.copyWith(age: 56).withKeyOf(walter);
     100             :   /// ```
     101             :   ///
     102             :   /// [force] will set [model]'s key even if its `id` is null.
     103           4 :   T withKeyOf(T model, {bool force = false}) {
     104           4 :     return DataModel.withKeyOf(model, applyTo: this, force: force) as T;
     105             :   }
     106             : 
     107             :   /// Saves this model through a call equivalent to [Repository.save].
     108             :   ///
     109             :   /// Usage: `await post.save()`, `author.save(remote: false, params: {'a': 'x'})`.
     110           6 :   Future<T> save({
     111             :     bool? remote,
     112             :     Map<String, dynamic>? params,
     113             :     Map<String, String>? headers,
     114             :     OnSuccessOne<T>? onSuccess,
     115             :     OnErrorOne<T>? onError,
     116             :   }) async {
     117          18 :     return await _remoteAdapter.save(
     118           6 :       _this,
     119             :       remote: remote,
     120             :       params: params,
     121             :       headers: headers,
     122             :       onSuccess: onSuccess,
     123             :       onError: onError,
     124             :     );
     125             :   }
     126             : 
     127             :   /// Deletes this model through a call equivalent to [Repository.delete].
     128           3 :   Future<T?> delete({
     129             :     bool? remote,
     130             :     Map<String, dynamic>? params,
     131             :     Map<String, String>? headers,
     132             :     OnSuccessOne<T>? onSuccess,
     133             :     OnErrorOne<T>? onError,
     134             :   }) async {
     135           9 :     return await _remoteAdapter.delete(
     136             :       this,
     137             :       remote: remote,
     138             :       params: params,
     139             :       headers: headers,
     140             :       onSuccess: onSuccess,
     141             :       onError: onError,
     142             :     );
     143             :   }
     144             : 
     145             :   /// Reload this model through a call equivalent to [Repository.findOne].
     146             :   /// with the current object/[id]
     147           1 :   Future<T?> reload({
     148             :     bool? remote,
     149             :     Map<String, dynamic>? params,
     150             :     Map<String, String>? headers,
     151             :     bool? background,
     152             :     DataRequestLabel? label,
     153             :   }) async {
     154           3 :     return await _remoteAdapter.findOne(
     155             :       this,
     156             :       remote: remote,
     157             :       params: params,
     158             :       headers: headers,
     159             :       background: background,
     160             :       label: label,
     161             :     );
     162             :   }
     163             : 
     164             :   // locals
     165             : 
     166             :   /// Saves this model to local storage.
     167          40 :   T saveLocal() => _remoteAdapter.saveLocal(_this);
     168             : 
     169             :   /// Deletes this model from local storage.
     170           4 :   void deleteLocal() => _remoteAdapter.deleteLocal(_this);
     171             : 
     172             :   /// Reload model from local storage.
     173           0 :   T? reloadLocal() => _remoteAdapter.localAdapter.findOne(_key);
     174             : }

Generated by: LCOV version 1.15