queryWith method

  1. @override
Future<List<T>> queryWith(
  1. SyncScope scope,
  2. QuerySpec spec
)
override

Query with general DB-like filters, ordering and pagination within a scope. This does not escape the scope and respects soft-delete semantics.

Implementation

@override
Future<List<T>> queryWith(SyncScope scope, store.QuerySpec spec) async {
  // First, constrain by scope and soft-delete at SQL level for efficiency.
  final sk = _scopeKey(scope);
  final baseQ = db.select(db.items)
    ..where(
      (t) => supportsSoftDelete
          ? (t.scopeName.equals(scope.name) &
                t.scopeKeys.equals(sk) &
                t.deletedAt.isNull())
          : (t.scopeName.equals(scope.name) & t.scopeKeys.equals(sk)),
    );
  final rows = await baseQ.get();

  // Apply filters on JSON payload (and special fields) in Dart.
  final filtered = <_RowHolder>[];
  for (final r in rows) {
    final payloadMap = jsonDecode(r.payload) as Map<String, dynamic>;
    if (_matchesSpec(payloadMap, r.id, r.updatedAt, spec)) {
      filtered.add(
        _RowHolder(id: r.id, updatedAtIso: r.updatedAt, payload: payloadMap),
      );
    }
  }

  // Sort
  if (spec.orderBy.isNotEmpty) {
    filtered.sort((a, b) {
      for (final o in spec.orderBy) {
        final c = _compareField(a, b, o.field, o.descending);
        if (c != 0) return c;
      }
      return 0;
    });
  }

  // Pagination
  final start = (spec.offset ?? 0).clamp(0, filtered.length);
  final end = spec.limit == null
      ? filtered.length
      : (start + spec.limit!).clamp(0, filtered.length);
  final window = filtered.sublist(start, end);

  // Map to T
  return window.map((h) => fromJson(h.payload)).toList(growable: false);
}