page method
Future<MssqlPage<TRow> >
page({
- int size = 25,
- int offset = 0,
- bool total = false,
- MssqlReadConsistency consistency = MssqlReadConsistency.committed,
One OFFSET page, and whether another follows.
Fetches size+1 and drops the extra row before include, so relations
are not loaded for a parent that is not on the page. total runs a
second count over the same filter/scope; consistency snapshot puts
both (and includes) in one SNAPSHOT transaction.
Implementation
Future<MssqlPage<TRow>> page({
int size = 25,
int offset = 0,
bool total = false,
MssqlReadConsistency consistency = MssqlReadConsistency.committed,
}) async {
if (offset < 0) {
throw ArgumentError.value(offset, 'offset', 'Cannot be negative.');
}
if (size <= 0) {
throw ArgumentError.value(size, 'size', 'Must be positive.');
}
final ordered = ensureStableOrder();
final dialect = await _resolvedDialect();
// One snapshot for the page, its includes and its total: a tenant scope
// resolved twice could count one tenant's rows against another's page.
final scopes = ordered.context.scopeCompiler(ordered.state.scope);
final loader = ordered._loaderFor(session, dialect);
return mssqlRunConsistent(
session: session,
consistency: consistency,
body: (s) async {
final fetched = await ordered
._select(scopes: scopes)
.paged(offset: offset, rows: size + 1)
.get(
s,
dialect: dialect,
timeout: state.options.timeout,
cancellationToken: state.options.cancellationToken,
options: state.options,
);
final mapped = fetched.map(binding.fromRow).toList();
final hasMore = mapped.length > size;
final slice = ordered.dropPageSentinel(mapped, size);
final parents = await ordered._attachOn(
s,
slice,
dialect: dialect,
loader: loader.withSession(s),
);
return MssqlPage<TRow>(
rows: parents,
offset: offset,
requestedRows: size,
hasMore: hasMore,
total: total
? await ordered._countOn(s, dialect: dialect, scopes: scopes)
: null,
);
},
);
}