QueryPredicate.and constructor

QueryPredicate.and(
  1. Iterable<QueryPredicate?>? predicates
)

Combines predicates with 'AND' keyword.

The format of the return value is produced by joining together each predicates format string with 'AND'. Each parameters from individual predicates is combined into the returned parameters.

If there are duplicate parameter names in predicates, they will be disambiguated by suffixing the parameter name in both format and parameters with a unique integer.

If predicates is null or empty, an empty predicate is returned. If predicates contains only one predicate, that predicate is returned.

Implementation

factory QueryPredicate.and(Iterable<QueryPredicate?>? predicates) {
  List<QueryPredicate?>? predicateList = predicates!
      .where((p) => p!.format != null && p.format!.isNotEmpty)
      .toList();
  dynamic? predicateListCheck = predicateList;
  if (predicateListCheck == null) {
    return QueryPredicate.empty();
  }

  if (predicateList.isEmpty) {
    return QueryPredicate.empty();
  }

  if (predicateList.length == 1) {
    return predicateList.first!;
  }

  // If we have duplicate keys anywhere, we need to disambiguate them.
  int dupeCounter = 0;
  final allFormatStrings = [];
  final valueMap = <String, dynamic>{};
  for (var predicate in predicateList) {
    final duplicateKeys = predicate!.parameters?.keys
            .where((k) => valueMap.keys.contains(k))
            .toList() ??
        [];

    if (duplicateKeys.isNotEmpty) {
      var fmt = predicate.format;
      Map<String, String> dupeMap = {};
      duplicateKeys.forEach((key) {
        final replacementKey = "$key$dupeCounter";
        fmt = fmt!.replaceAll("@$key", "@$replacementKey");
        dupeMap[key] = replacementKey;
        dupeCounter++;
      });

      allFormatStrings.add(fmt);
      predicate.parameters?.forEach((key, value) {
        valueMap[dupeMap[key] ?? key] = value;
      });
    } else {
      allFormatStrings.add(predicate.format);
      valueMap.addAll(predicate.parameters ?? {});
    }
  }

  final predicateFormat = "(${allFormatStrings.join(" AND ")})";
  return QueryPredicate(predicateFormat, valueMap);
}