page method
Future<MssqlPage<TRow> >
page({
- required int rows,
- int offset = 0,
- required List<
MssqlOrder> orderBy, - MssqlCondition? where,
- bool includeTotal = false,
- List<
MssqlRelation< include = const [],TRow, Object?> >
One page, and whether another follows.
One row beyond the page is fetched and discarded, which answers
MssqlPage.hasMore without a COUNT(*). The count runs only when
includeTotal asks for it.
Implementation
Future<MssqlPage<TRow>> page({
required int rows,
int offset = 0,
required List<MssqlOrder> orderBy,
MssqlCondition? where,
bool includeTotal = false,
List<MssqlRelation<TRow, Object?>> include = const [],
}) async {
if (offset < 0) {
throw ArgumentError.value(offset, 'offset', 'Cannot be negative.');
}
if (rows <= 0) {
throw ArgumentError.value(rows, 'rows', 'Must be positive.');
}
if (orderBy.isEmpty) {
throw ArgumentError.value(
orderBy,
'orderBy',
'A page needs an ordering: SQL Server rejects OFFSET without ORDER BY, '
'and an unordered page is not repeatable between calls.',
);
}
var query = _base;
if (where != null) query = query.where(where);
query = query.orderBy(orderBy).paged(offset: offset, rows: rows + 1);
// Include after dropping the sentinel: loading relations for a parent
// that is not on the page is wasted work and would attach children to a
// row the caller never sees.
final loader = include.isEmpty ? null : _loader(await _dialect());
loader?.snapshotScopes(include);
final fetched = await _run(query);
final hasMore = fetched.length > rows;
final slice = hasMore ? fetched.sublist(0, rows) : fetched;
final parents = include.isEmpty
? slice
: await loader!.attach(
binding,
slice,
include,
onWarning: warnings.add,
);
return MssqlPage<TRow>(
rows: parents,
offset: offset,
requestedRows: rows,
hasMore: hasMore,
total: includeTotal ? await _count(where) : null,
);
}