applySelectOrderAndPagination<T> function

Iterable<T> applySelectOrderAndPagination<T>(
  1. Iterable<T> itr,
  2. Object? idGetter(
    1. T o
    ), {
  3. int? limit,
  4. int? offset,
  5. bool? orderByID,
  6. OrderDirection? orderDirection,
  7. bool zeroLimitIsUnlimited = false,
})

Applies the ordering and the pagination of a select* operation to itr.

Orders the elements by ID (resolved through idGetter) when OrderDirection.resolveOrderByID resolves to true, then skips offset elements and takes limit of them — in that order, matching SQL semantics (ORDER BYOFFSETLIMIT).

Used by the DBAdapters that can't delegate the ordering and the pagination to a DB engine, and by IterableEntityRepository.

zeroLimitIsUnlimited selects how a limit of 0 is interpreted, since the pre-existing call sites disagree: the generated SQL treats it as "no LIMIT clause" (true), while the in-memory selects treat it as an empty result (false, the default). Only relevant for a limit of exactly 0.

Implementation

Iterable<T> applySelectOrderAndPagination<T>(
  Iterable<T> itr,
  Object? Function(T o) idGetter, {
  int? limit,
  int? offset,
  bool? orderByID,
  OrderDirection? orderDirection,
  bool zeroLimitIsUnlimited = false,
}) {
  if (OrderDirection.resolveOrderByID(orderByID, offset)) {
    var descending = OrderDirection.resolve(orderDirection).isDescending;

    var sorted = itr.toList();
    sorted.sort(
      descending
          ? (a, b) => compareEntityIDs(idGetter(b), idGetter(a))
          : (a, b) => compareEntityIDs(idGetter(a), idGetter(b)),
    );
    itr = sorted;
  }

  if (offset != null && offset > 0) {
    itr = itr.skip(offset);
  }

  if (limit != null && (zeroLimitIsUnlimited ? limit > 0 : limit >= 0)) {
    itr = itr.take(limit);
  }

  return itr;
}