LCOV - code coverage report
Current view: top level - model - data_model.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 40 40 100.0 %
Date: 2022-07-06 18:09:45 Functions: 0 0 -

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

Generated by: LCOV version 1.15