seekToken method

Query<R, F> seekToken(
  1. String token, {
  2. required List<OrderTerm> orderBy(
    1. F
    ),
})

Restores a cursorToken using the expected table and complete sort order.

Rejects malformed tokens or mismatched columns, codecs, directions, and nullability with QUERY.CURSOR. Existing filters still apply; the token is neither signed authorization nor a database snapshot.

Implementation

Query<R, F> seekToken(
  String token, {
  required List<OrderTerm> Function(F) orderBy,
}) {
  final order = orderBy(queryFields);
  _validateCursor(order);
  try {
    final payload = jsonDecode(
      utf8.decode(base64Url.decode(token)),
    ) as Map<String, Object?>;
    if (payload['version'] != 1 ||
        payload['table'] != queryState.source.schema.name ||
        jsonEncode(payload['order']) != jsonEncode(_cursorShape(order))) {
      throw const FormatException(
        'Cursor belongs to another schema or sort order.',
      );
    }
    final values = payload['values'] as List<Object?>;
    if (values.length != order.length) {
      throw const FormatException('Cursor arity differs.');
    }
    final terms = <CursorTerm>[];
    for (var i = 0; i < order.length; i++) {
      final codec = order[i].expression.codec;
      final decoded = codec.decode(_decodeCursorValue(values[i]));
      terms.add(CursorTerm.internal(order[i], codec.encode(decoded)));
    }
    return seekAfter((_) => terms);
  } catch (e) {
    throw OrmException(
      'QUERY.CURSOR',
      'Invalid cursor for this query.',
      cause: e,
    );
  }
}