chunk method
Future<void>
chunk(
- MssqlSession session,
- int size,
- Future<
bool> handle(- List<
MssqlRow> rows
- List<
- MssqlDialect dialect = MssqlDialect.sql2012,
Walks the whole result in keyset pages of size, without holding it
all in memory.
OFFSET is not used: deleting a processed row would otherwise skip the
next one. Requires orderBy on named columns so each page can bind
the last row's keys. A mutable order column is still not a snapshot.
The callback returning false stops the walk, so a search can give up
early without reading the rest.
Implementation
Future<void> chunk(
MssqlSession session,
int size,
Future<bool> Function(List<MssqlRow> rows) handle, {
MssqlDialect dialect = MssqlDialect.sql2012,
}) async {
if (size <= 0) {
throw ArgumentError.value(size, 'size', 'Must be positive.');
}
if (ordering.isEmpty) {
throw StateError(
'chunk() needs orderBy(): without one, two pages can return the same '
'row and never return another. Source: ${source.quoted}.',
);
}
MssqlKeyset.requireNamedColumns(ordering, 'chunk()');
List<Object?>? after;
while (true) {
var query = this;
if (after != null) {
query = query.where(MssqlKeyset.after(ordering, after));
}
final page = await query.top(size).get(session, dialect: dialect);
if (page.isEmpty) return;
if (!await handle(page)) return;
if (page.length < size) return;
after = MssqlKeyset.keysFromRow(page.last, ordering);
}
}