$_getPrefetchedData<$CurrentDataclass, $CurrentTable extends Table, $ReferencedDataclass> function

Future<List<MultiTypedResultEntry<$ReferencedDataclass>>> $_getPrefetchedData<$CurrentDataclass, $CurrentTable extends Table, $ReferencedDataclass>({
  1. required ProcessedTableManager<dynamic, dynamic, $ReferencedDataclass, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, $ReferencedDataclass, dynamic> managerFromTypedResult(
    1. TypedResult
    ),
  2. required MultiTypedResultKey<Table, dynamic> referencedTable,
  3. required List<TypedResult> typedResults,
  4. required TableInfo<$CurrentTable, $CurrentDataclass> currentTable,
  5. required Iterable<$ReferencedDataclass> referencedItemsForCurrentItem(
    1. $CurrentDataclass item,
    2. List<$ReferencedDataclass> referencedItems
    ),
})

This function is used to fetch referenced data for a List<TypedResults>.

Here is an example. Let's say we wanted to get all the groups, with their users. We would need to:

  1. Then run a 2nd query to get all the users who are in the groups. (Users who arent any groups will be ignored)
  2. Split the users into groups
  3. Return these users as a List<List<User>> (The first list is the groups, the 2nd list is the users in the group), along with the referenced table

Manually this would look like:

final groups = await groups.get();
final groupIds = groups.map((group)=> group.id);
final users = await users.filter((f)=> f.group.id.isIn(groupIds)).get()
final groupsWithUsers = groups.map((group)=>(group,users.where((user)=> user.group == group.id)));

This function does the same thing, but for any table and any referenced table.

Arguments:

  • typedResults is the raw result of the query, together with currentTable we can read it's results
  • managerFromTypedResult is the equivalent of:
    final groups = await groups.withReferences().get();
    for (final (group, refs) in groups){
        /// Manager with a filter to only get the users of this group.
        refs.users;
    }
    
    What we do, is collect all the filters from all of these refs.users and combine them with an OR operator to create a query which gets all the users managerFromTypedResult is the function which turns a single group into refs.users
  • referencedTable is a MultiTypedResultKey which is to write the results to the TypedResult object, This same class will be used in the BaseReferences class to read from the TypedResult.
  • referencedItemsForCurrentItem is the callback which does the mapping. It is the equivalent ofusers.where((user)=> user.group == group.id).

Results are returned as a list of MultiTypedResultEntry objects which contain the key and the list of references for each row.

This function is used by the generated code and should not be used directly.

Implementation

// ignore: non_constant_identifier_names
Future<List<MultiTypedResultEntry<$ReferencedDataclass>>> $_getPrefetchedData<
        $CurrentDataclass, $CurrentTable extends Table, $ReferencedDataclass>(
    {required ProcessedTableManager<
                dynamic,
                dynamic,
                $ReferencedDataclass,
                dynamic,
                dynamic,
                dynamic,
                dynamic,
                dynamic,
                dynamic,
                $ReferencedDataclass,
                dynamic>
            Function(TypedResult)
        managerFromTypedResult,
    required MultiTypedResultKey referencedTable,
    required List<TypedResult> typedResults,
    required TableInfo<$CurrentTable, $CurrentDataclass> currentTable,
    required Iterable<$ReferencedDataclass> Function(
            $CurrentDataclass item, List<$ReferencedDataclass> referencedItems)
        referencedItemsForCurrentItem}) async {
  if (typedResults.isEmpty) {
    return [];
  } else {
    final managers = typedResults.map(managerFromTypedResult);
    // Combine all the referenced managers into 1 large query which will return all the
    // referenced items in one go.
    final manager = managers.reduce((value, element) {
      if (element.$state.filter != null) {
        return value._filter(
            (_) => element.$state.filter!, _BooleanOperator.or);
      } else {
        return value;
      }
    });

    return manager.get(distinct: true).then(
      (value) {
        return typedResults.map((e) {
          final item = e.readTable(currentTable);
          final refs = referencedItemsForCurrentItem(item, value).toList();
          return MultiTypedResultEntry(key: referencedTable, value: refs);
        }).toList();
      },
    );
  }
}