LCOV - code coverage report
Current view: top level - repository - repository.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 32 34 94.1 %
Date: 2021-06-18 12:41:16 Functions: 0 0 -

          Line data    Source code
       1             : part of flutter_data;
       2             : 
       3             : /// Thin wrapper on the [RemoteAdapter] API
       4             : class Repository<T extends DataModel<T>> with _Lifecycle {
       5             :   final ProviderReference _ref;
       6           1 :   Repository(this._ref);
       7             : 
       8             :   var _isInit = false;
       9             : 
      10           2 :   String get _internalType => DataHelpers.getType<T>();
      11             : 
      12             :   final _adapters = <String, RemoteAdapter>{};
      13             : 
      14             :   /// Obtain the [RemoteAdapter] for this type.
      15           1 :   RemoteAdapter<T> get remoteAdapter =>
      16           3 :       _adapters[_internalType]! as RemoteAdapter<T>;
      17             : 
      18             :   /// Type for the [RemoteAdapter]
      19           0 :   @nonVirtual
      20           0 :   String get type => remoteAdapter.type;
      21             : 
      22             :   /// Initializes this [Repository]. Nothing will work without this.
      23             :   /// In standard scenarios this initialization is done by the framework.
      24             :   @mustCallSuper
      25           1 :   FutureOr<Repository<T>> initialize(
      26             :       {bool? remote,
      27             :       bool? verbose,
      28             :       required Map<String, RemoteAdapter> adapters}) async {
      29           1 :     if (isInitialized) return this;
      30           2 :     _adapters.addAll(adapters);
      31           3 :     await remoteAdapter.initialize(
      32             :       remote: remote,
      33             :       verbose: verbose,
      34             :       adapters: adapters,
      35           1 :       ref: _ref,
      36             :     );
      37           1 :     _isInit = true;
      38             :     return this;
      39             :   }
      40             : 
      41             :   /// Returns whether this [Repository] is initialized
      42             :   /// (when its underlying [RemoteAdapter] is).
      43           1 :   @override
      44           3 :   bool get isInitialized => _isInit && remoteAdapter.isInitialized;
      45             : 
      46             :   /// Disposes this [Repository] and everything that depends on it.
      47           1 :   @override
      48             :   void dispose() {
      49           1 :     if (isInitialized) {
      50           2 :       remoteAdapter.dispose();
      51           1 :       _isInit = false;
      52             :     }
      53             :   }
      54             : 
      55             :   // Public API
      56             : 
      57             :   /// Returns all models of type [T].
      58             :   ///
      59             :   /// If [_RemoteAdapter.shouldLoadRemoteAll] (function of [remote]) is `true`,
      60             :   /// it will initiate an HTTP call.
      61             :   /// Otherwise returns all models of type [T] in local storage.
      62             :   ///
      63             :   /// Arguments [params] and [headers] will be merged with
      64             :   /// [_RemoteAdapter.defaultParams] and [_RemoteAdapter.defaultHeaders], respectively.
      65             :   ///
      66             :   /// For local storage of type [T] to be synchronized to the exact resources
      67             :   /// returned from the remote source when using `findAll`, pass `syncLocal: true`.
      68             :   /// This call would, for example, reflect server-side resource deletions.
      69             :   /// The default is `syncLocal: false`.
      70             :   ///
      71             :   /// See also: [_RemoteAdapter.urlForFindAll], [_RemoteAdapter.methodForFindAll].
      72           1 :   Future<List<T>> findAll({
      73             :     bool? remote,
      74             :     Map<String, dynamic>? params,
      75             :     Map<String, String>? headers,
      76             :     bool? syncLocal,
      77             :     OnDataError<List<T>>? onError,
      78             :   }) {
      79           2 :     return remoteAdapter.findAll(
      80             :       remote: remote,
      81             :       params: params,
      82             :       headers: headers,
      83             :       syncLocal: syncLocal,
      84             :       onError: onError,
      85             :     );
      86             :   }
      87             : 
      88             :   /// Returns model of type [T] by [id].
      89             :   ///
      90             :   /// If [_RemoteAdapter.shouldLoadRemoteOne] (function of [remote]) is `true`,
      91             :   /// it will initiate an HTTP call.
      92             :   /// Otherwise returns model of type [T] and [id] in local storage.
      93             :   ///
      94             :   /// Arguments [params] and [headers] will be merged with
      95             :   /// [_RemoteAdapter.defaultParams] and [_RemoteAdapter.defaultHeaders], respectively.
      96             :   ///
      97             :   /// See also: [_RemoteAdapter.urlForFindOne], [_RemoteAdapter.methodForFindOne].
      98           1 :   Future<T?> findOne(
      99             :     final dynamic id, {
     100             :     bool? remote,
     101             :     Map<String, dynamic>? params,
     102             :     Map<String, String>? headers,
     103             :     OnDataError<T>? onError,
     104             :   }) {
     105           2 :     return remoteAdapter.findOne(
     106             :       id,
     107             :       remote: remote ?? true,
     108             :       params: params,
     109             :       headers: headers,
     110             :       onError: onError,
     111             :     );
     112             :   }
     113             : 
     114             :   /// Saves [model] of type [T].
     115             :   ///
     116             :   /// If [remote] is `true`, it will initiate an HTTP call.
     117             :   ///
     118             :   /// Always persists to local storage.
     119             :   ///
     120             :   /// Arguments [params] and [headers] will be merged with
     121             :   /// [_RemoteAdapter.defaultParams] and [_RemoteAdapter.defaultHeaders], respectively.
     122             :   ///
     123             :   /// See also: [_RemoteAdapter.urlForSave], [_RemoteAdapter.methodForSave].
     124           1 :   Future<T> save(
     125             :     T model, {
     126             :     bool? remote,
     127             :     Map<String, dynamic>? params,
     128             :     Map<String, String>? headers,
     129             :     OnData<T>? onSuccess,
     130             :     OnDataError<T>? onError,
     131             :   }) {
     132           2 :     return remoteAdapter.save(
     133             :       model,
     134             :       remote: remote,
     135             :       params: params,
     136             :       headers: headers,
     137             :       onSuccess: onSuccess,
     138             :       onError: onError,
     139             :     );
     140             :   }
     141             : 
     142             :   /// Deletes [model] of type [T].
     143             :   ///
     144             :   /// If [remote] is `true`, it will initiate an HTTP call.
     145             :   ///
     146             :   /// Always deletes from local storage.
     147             :   ///
     148             :   /// Arguments [params] and [headers] will be merged with
     149             :   /// [_RemoteAdapter.defaultParams] and [_RemoteAdapter.defaultHeaders], respectively.
     150             :   ///
     151             :   /// See also: [_RemoteAdapter.urlForDelete], [_RemoteAdapter.methodForDelete].
     152           1 :   Future<void> delete(
     153             :     dynamic model, {
     154             :     bool? remote,
     155             :     Map<String, dynamic>? params,
     156             :     Map<String, String>? headers,
     157             :     OnData<void>? onSuccess,
     158             :     OnDataError<void>? onError,
     159             :   }) {
     160           2 :     return remoteAdapter.delete(
     161             :       model,
     162             :       remote: remote,
     163             :       params: params,
     164             :       headers: headers,
     165             :       onSuccess: onSuccess,
     166             :       onError: onError,
     167             :     );
     168             :   }
     169             : 
     170             :   /// Deletes all models of type [T] in local storage.
     171             :   ///
     172             :   ///
     173             :   ///
     174             :   /// If you need to clear all models, use the
     175             :   /// `repositoryProviders` map exposed on your `main.data.dart`.
     176           3 :   Future<void> clear() => remoteAdapter.clear();
     177             : 
     178             :   // offline
     179             : 
     180             :   /// Gets a list of all pending [OfflineOperation]s for this type.
     181           1 :   Set<OfflineOperation<T>> get offlineOperations =>
     182           2 :       remoteAdapter.offlineOperations;
     183             : 
     184             :   // watchers
     185             : 
     186             :   /// Watches changes on all models of type [T] in local storage.
     187             :   ///
     188             :   /// When called, will in turn call [findAll] with [remote], [params],
     189             :   /// [headers], [syncLocal].
     190             :   ///
     191             :   /// If [syncLocal] is set to `false` but results still need to be filtered,
     192             :   /// use [filterLocal]. All data updates will be filtered through it.
     193           1 :   DataStateNotifier<List<T>> watchAll({
     194             :     bool? remote,
     195             :     Map<String, dynamic>? params,
     196             :     Map<String, String>? headers,
     197             :     bool? syncLocal,
     198             :     bool Function(T)? filterLocal,
     199             :   }) {
     200           2 :     return remoteAdapter.watchAll(
     201             :       remote: remote!,
     202             :       params: params,
     203             :       headers: headers,
     204             :       filterLocal: filterLocal,
     205             :       syncLocal: syncLocal,
     206             :     );
     207             :   }
     208             : 
     209             :   /// Watches changes on model of type [T] by [id] in local storage.
     210             :   ///
     211             :   /// Optionally [alsoWatch]es selected relationships of this model.
     212             :   ///
     213             :   /// Example: Watch `Book` with `id=1` and its `Author` relationship.
     214             :   ///
     215             :   /// ```
     216             :   /// bookRepository.watchOne('1', alsoWatch: (book) => [book.author]);
     217             :   /// ```
     218             :   ///
     219             :   /// When called, will in turn call [findAll] with [remote], [params], [headers].
     220           1 :   DataStateNotifier<T?> watchOne(
     221             :     dynamic id, {
     222             :     bool? remote,
     223             :     Map<String, dynamic>? params,
     224             :     Map<String, String>? headers,
     225             :     AlsoWatch<T>? alsoWatch,
     226             :   }) {
     227           2 :     return remoteAdapter.watchOne(
     228             :       id,
     229             :       remote: remote,
     230             :       params: params,
     231             :       headers: headers,
     232             :       alsoWatch: alsoWatch,
     233             :     );
     234             :   }
     235             : }
     236             : 
     237             : /// Annotation on a [DataModel] model to request a [Repository] be generated for it.
     238             : ///
     239             : /// Takes a list of [adapters] to be mixed into this [Repository].
     240             : /// Public methods of these [adapters] mixins will be made available in the repository
     241             : /// via extensions.
     242             : ///
     243             : /// A classic example is:
     244             : ///
     245             : /// ```
     246             : /// @JsonSerializable()
     247             : /// @DataRepository([JSONAPIAdapter])
     248             : /// class Todo with DataModel<Todo> {
     249             : ///   @override
     250             : ///   final int id;
     251             : ///   final String title;
     252             : ///   final bool completed;
     253             : ///
     254             : ///   Todo({this.id, this.title, this.completed = false});
     255             : /// }
     256             : ///```
     257             : class DataRepository {
     258             :   final List<Type> adapters;
     259             :   final bool remote;
     260           6 :   const DataRepository(this.adapters, {this.remote = true});
     261             : }

Generated by: LCOV version 1.15