fetchSince method
Implementation
@override
Future<Delta<T, Id>> fetchSince(SyncScope scope, DateTime? since) async {
var upsertQuery = _table()
.select()
.eq(config.scopeNameColumn, scope.name)
.contains(config.scopeKeysColumn, scope.keys);
if (since != null) {
upsertQuery = upsertQuery.gt(
config.updatedAtColumn,
since.toUtc().toIso8601String(),
);
}
if (config.deletedAtColumn != null) {
// `is` operator to check for NULL
upsertQuery = upsertQuery.filter(config.deletedAtColumn!, 'is', null);
}
final upsertsRaw = await upsertQuery;
final upserts = (upsertsRaw as List)
.map((e) => config.fromJson(Map<String, dynamic>.from(e)))
.toList(growable: false);
// Deletes: updated_at > since and soft-deleted (if supported). For hard delete, server must provide tombstones.
List<Id> deletes = const [];
if (config.deletedAtColumn != null) {
var delQ = _table()
.select(config.idColumn)
.eq(config.scopeNameColumn, scope.name)
.contains(config.scopeKeysColumn, scope.keys);
if (since != null) {
delQ = delQ.gt(config.updatedAtColumn, since.toUtc().toIso8601String());
}
delQ = delQ.not(config.deletedAtColumn!, 'is', null);
final delsRaw = await delQ;
deletes = (delsRaw as List)
.map((e) => config.idFromString('${(e as Map)[config.idColumn]}'))
.toList(growable: false);
}
final serverTs = await getServerTime();
return Delta<T, Id>(
upserts: upserts,
deletes: deletes,
serverTimestamp: serverTs,
);
}