query method
Future<List<T> >
query(
- DatumQuery query, {
- DataSource source = DataSource.local,
- String? userId,
- bool includeDeleted = false,
Implementation
Future<List<T>> query(
DatumQuery query, {
DataSource source = DataSource.local,
String? userId,
bool includeDeleted = false,
}) async {
_ensureInitialized();
// Tombstones are filtered via query pushdown so limit/offset count only
// live rows. Remote queries are passed through untouched — translation
// capabilities vary by remote adapter.
if (!includeDeleted && source == DataSource.local) {
query = _excludeTombstones(query);
}
// Create a cache key for this query
final cacheKey = _cacheCoordinator.createQueryCacheKey(query, source, userId);
// Local query caching is opt-in (config.enableQueryCache, default false):
// the local DB is already fast, and caching returned shared, mutable
// instances that could go stale (external sync/realtime writes) and break
// reactive updates. Only for local queries without related entities.
final useQueryCache = config.enableQueryCache && source == DataSource.local && query.withRelated.isEmpty;
if (useQueryCache) {
final cached = _cacheCoordinator.getCachedQuery(cacheKey);
if (cached != null) {
_logger.debug('Using cached query results for key: $cacheKey');
return Future.wait(cached.map(_applyPostFetchTransforms));
}
}
final adapter = (source == DataSource.local ? localAdapter : remoteAdapter) as dynamic;
final entities = await adapter.query(query, userId: userId) as List<T>;
if (query.withRelated.isNotEmpty && entities.isNotEmpty) {
await _fetchAndStitchRelations(entities, query.withRelated, source, userId);
}
// Cache the results (only when query caching is enabled).
if (useQueryCache) {
_cacheCoordinator.cacheQuery(cacheKey, entities);
}
// Apply post-fetch transforms with error handling
final transformedEntities = <T>[];
for (final entity in entities) {
try {
final transformed = await _applyPostFetchTransforms(entity);
transformedEntities.add(transformed);
} catch (e, stack) {
_logger.error('Failed to apply post-fetch transforms to entity ${entity.id}: $e', stack);
// Continue with other entities instead of failing the entire operation
transformedEntities.add(entity); // Use original entity if transform fails
}
}
return transformedEntities;
}