LCOV - code coverage report
Current view: top level - repository - remote_adapter_serialization.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 55 55 100.0 %
Date: 2022-06-06 11:59:57 Functions: 0 0 -

          Line data    Source code
       1             : part of flutter_data;
       2             : 
       3             : mixin _RemoteAdapterSerialization<T extends DataModel<T>> on _RemoteAdapter<T> {
       4             :   @override
       5           7 :   Future<Map<String, dynamic>> serialize(T model,
       6             :       {bool withRelationships = true}) async {
       7             :     final map =
       8          14 :         localAdapter.serialize(model, withRelationships: withRelationships);
       9             : 
      10             :     // essentially converts keys to IDs
      11          28 :     for (final key in localAdapter.relationshipMetas.keys) {
      12          14 :       if (map[key] is Iterable) {
      13          14 :         map[key] = (map[key] as Iterable)
      14          15 :             .map((k) => graph.getIdForKey(k.toString()))
      15           7 :             .filterNulls
      16           7 :             .toList();
      17           7 :       } else if (map[key] != null) {
      18          10 :         map[key] = graph.getIdForKey(map[key].toString());
      19             :       }
      20          14 :       if (map[key] == null) map.remove(key);
      21             :     }
      22             :     return map;
      23             :   }
      24             : 
      25             :   @override
      26           7 :   Future<DeserializedData<T>> deserialize(Object? data) async {
      27          21 :     final result = DeserializedData<T>([], included: []);
      28             : 
      29           4 :     Future<Object?> _processIdAndAddInclude(id, RemoteAdapter? adapter) async {
      30           4 :       if (id is Map && adapter != null) {
      31           6 :         final data = await adapter.deserialize(id as Map<String, dynamic>);
      32           3 :         result.included
      33           6 :           ..add(data.model as DataModel<DataModel>)
      34           6 :           ..addAll(data.included);
      35           6 :         id = data.model!.id;
      36             :       }
      37             :       if (id != null && adapter != null) {
      38          12 :         return graph.getKeyForId(adapter.internalType, id,
      39           8 :             keyIfAbsent: DataHelpers.generateKey(adapter.internalType));
      40             :       }
      41             :       return null;
      42             :     }
      43             : 
      44           7 :     if (data == null || data == '') {
      45             :       return result;
      46             :     }
      47             : 
      48             :     // since data is not null, touch local storage
      49          14 :     localAdapter._touchLocalStorage();
      50             : 
      51           7 :     if (data is Map<String, dynamic>) {
      52           7 :       data = [data];
      53             :     }
      54             : 
      55           7 :     if (data is Iterable) {
      56          14 :       for (final map in data) {
      57           7 :         final mapIn = Map<String, dynamic>.from(map as Map);
      58           7 :         final mapOut = <String, dynamic>{};
      59             : 
      60          14 :         final relationships = localAdapter.relationshipMetas;
      61             : 
      62             :         // - process includes
      63             :         // - transform ids into keys to pass to the local deserializer
      64          14 :         for (final mapKey in mapIn.keys) {
      65           7 :           final metadata = relationships[mapKey];
      66             : 
      67             :           if (metadata != null) {
      68           5 :             final relType = metadata.type;
      69             : 
      70          10 :             if (metadata.serialize == false) {
      71             :               continue;
      72             :             }
      73             : 
      74          10 :             if (metadata.kind == 'BelongsTo') {
      75           4 :               final key = await _processIdAndAddInclude(
      76           6 :                   mapIn[mapKey], adapters[relType]!);
      77           2 :               if (key != null) mapOut[mapKey] = key;
      78             :             }
      79             : 
      80          10 :             if (metadata.kind == 'HasMany') {
      81           8 :               mapOut[mapKey] = [
      82           8 :                 for (final id in (mapIn[mapKey] as Iterable))
      83          12 :                   await _processIdAndAddInclude(id, adapters[relType]!)
      84           4 :               ].filterNulls;
      85             :             }
      86             :           } else {
      87             :             // regular field mapping
      88          14 :             mapOut[mapKey] = mapIn[mapKey];
      89             :           }
      90             :         }
      91             : 
      92          14 :         final model = localAdapter.deserialize(mapOut);
      93          14 :         result.models.add(model);
      94             :       }
      95             :     }
      96             : 
      97             :     return result;
      98             :   }
      99             : }
     100             : 
     101             : /// A utility class used to return deserialized main [models] AND [included] models.
     102             : class DeserializedData<T extends DataModel<T>> {
     103           7 :   const DeserializedData(this.models, {this.included = const []});
     104             :   final List<T> models;
     105             :   final List<DataModel> included;
     106          21 :   T? get model => models.singleOrNull;
     107             : 
     108           5 :   void _log(RemoteAdapter adapter, DataRequestLabel label) {
     109          20 :     adapter.log(label, '${models.toShortLog()} fetched from remote');
     110          16 :     final groupedIncluded = included.groupListsBy((m) => m._remoteAdapter.type);
     111           7 :     for (final e in groupedIncluded.entries) {
     112           4 :       if (e.value.isNotEmpty) {
     113          10 :         adapter.log(label, '  - with ${e.key} ${e.value.toShortLog()} ');
     114             :       }
     115             :     }
     116             :   }
     117             : }

Generated by: LCOV version 1.15