constructQueryFromRef function

Query<Map<String, dynamic>> constructQueryFromRef(
  1. Query<Map<String, dynamic>> ref, {
  2. required List<WhereQueryFilter> whereFilters,
  3. required List<OrderByQueryFilter> orderByOperations,
  4. int? limit,
  5. required ScopedValues scopedValues,
  6. required NullSubstitutionMode nullSubstitutionMode,
})

Constructs a Query on top of given Query reference using given whereFilters and orderByOperations.

Implementation

Query<Map<String, dynamic>> constructQueryFromRef(
  Query<Map<String, dynamic>> ref, {
  required List<WhereQueryFilter> whereFilters,
  required List<OrderByQueryFilter> orderByOperations,
  int? limit,
  required ScopedValues scopedValues,
  required NullSubstitutionMode nullSubstitutionMode,
}) {
  Query<Map<String, dynamic>> query = ref;

  if (limit != null) query.limit(limit);

  if (whereFilters.isEmpty && orderByOperations.isEmpty) return query;

  for (final whereFilter in whereFilters) {
    Object? field;
    final matches = VariableMatch.parseAll(whereFilter.field);
    if (matches.length == 1) {
      final match = matches.first;
      if (match.hasRawValue && match.name == 'documentId') {
        field = FieldPath.documentId;
      }
    }
    field ??= PropertyValueDelegate.substituteVariables(
      whereFilter.field,
      scopedValues: scopedValues,
      nullSubstitutionMode: nullSubstitutionMode,
    );
    final Object value = PropertyValueDelegate.substituteVariables(
          whereFilter.value,
          scopedValues: scopedValues,
          nullSubstitutionMode: nullSubstitutionMode,
        ).parsedValue() ??
        '';

    query = switch (whereFilter.operator) {
      WhereQueryOperator.equal => query.where(
          field,
          isEqualTo: value,
        ),
      WhereQueryOperator.notEqual => query.where(
          field,
          isNotEqualTo: value,
        ),
      WhereQueryOperator.arrayContains => query.where(
          field,
          arrayContains: value,
        ),
      WhereQueryOperator.greaterThan => query.where(
          field,
          isGreaterThan: value,
        ),
      WhereQueryOperator.greaterThanOrEqual => query.where(
          field,
          isGreaterThanOrEqualTo: value,
        ),
      WhereQueryOperator.lessThan => query.where(
          field,
          isLessThan: value,
        ),
      WhereQueryOperator.lessThanOrEqual => query.where(
          field,
          isLessThanOrEqualTo: value,
        ),
      WhereQueryOperator.arrayContainsAny => query.where(
          field,
          arrayContainsAny: value.typedValue<List>(),
        ),
      WhereQueryOperator.inArray => query.where(
          field,
          whereIn: value.typedValue<List>(),
        ),
      WhereQueryOperator.notInArray => query.where(
          field,
          whereNotIn: value.typedValue<List>(),
        ),
    };
  }

  for (final orderByFilter in orderByOperations) {
    Object? field;
    final matches = VariableMatch.parseAll(orderByFilter.field);
    if (matches.length == 1) {
      final match = matches.first;
      if (match.hasRawValue && match.name == 'documentId') {
        field = FieldPath.documentId;
      }
    }

    field ??= PropertyValueDelegate.substituteVariables(
      orderByFilter.field,
      scopedValues: scopedValues,
      nullSubstitutionMode: nullSubstitutionMode,
    );

    query = query.orderBy(
      field,
      descending: orderByFilter.sortOrder == OrderByQuerySortOrder.descending,
    );
  }

  return query;
}