Skip to content

Commit

Permalink
fix(offline_first): apply get policy to getAssociation requests #371 (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
tshedor authored May 7, 2024
1 parent ecfa725 commit 3aaedc3
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 23 deletions.
6 changes: 3 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"dart.lineLength": 100,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.organizeImports": true,
"source.fixAll": "explicit",
"source.organizeImports": "explicit"
},
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.expand": false,
"files.insertFinalNewline": true,
"files.insertFinalNewline": true
}
2 changes: 2 additions & 0 deletions packages/brick_offline_first/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Unreleased

* Apply desired policy to all association fetches during `OfflineFirstRepository#get` requests. Fixes #371.

## 3.1.0

* Apply standardized lints
Expand Down
56 changes: 36 additions & 20 deletions packages/brick_offline_first/lib/src/offline_first_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ abstract class OfflineFirstRepository<RepositoryModel extends OfflineFirstModel>
/// Defaults to [false].
final bool autoHydrate;

/// Required to maintain the same policy for [getAssociation] requests.
/// This is a stateful variable that should be cleared immediately after
/// it is no longer necessary.
///
/// See discussion: https://github.com/GetDutchie/brick/issues/371
OfflineFirstGetPolicy? _latestGetPolicy;

/// The first data source to speed up otherwise taxing queries. Only caches specified models.
final MemoryCacheProvider memoryCacheProvider;

Expand Down Expand Up @@ -179,38 +186,47 @@ abstract class OfflineFirstRepository<RepositoryModel extends OfflineFirstModel>
final hydrateUnexisting = policy == OfflineFirstGetPolicy.awaitRemoteWhenNoneExist;
final alwaysHydrate = policy == OfflineFirstGetPolicy.alwaysHydrate;

if (memoryCacheProvider.canFind<TModel>(query) && !requireRemote) {
final memoryCacheResults = memoryCacheProvider.get<TModel>(query: query, repository: this);
try {
_latestGetPolicy = policy;

if (memoryCacheProvider.canFind<TModel>(query) && !requireRemote) {
final memoryCacheResults = memoryCacheProvider.get<TModel>(query: query, repository: this);

if (alwaysHydrate) {
// start round trip for fresh data
// ignore: unawaited_futures
hydrate<TModel>(query: query, deserializeSqlite: !seedOnly);
}

if (memoryCacheResults?.isNotEmpty ?? false) return memoryCacheResults!;
}

final modelExists = await exists<TModel>(query: query);

if (alwaysHydrate) {
if (requireRemote || (hydrateUnexisting && !modelExists)) {
return await hydrate<TModel>(query: query, deserializeSqlite: !seedOnly);
} else if (alwaysHydrate) {
// start round trip for fresh data
// ignore: unawaited_futures
hydrate<TModel>(query: query, deserializeSqlite: !seedOnly);
}

if (memoryCacheResults?.isNotEmpty ?? false) return memoryCacheResults!;
}

final modelExists = await exists<TModel>(query: query);

if (requireRemote || (hydrateUnexisting && !modelExists)) {
return await hydrate<TModel>(query: query, deserializeSqlite: !seedOnly);
} else if (alwaysHydrate) {
// start round trip for fresh data
// ignore: unawaited_futures
hydrate<TModel>(query: query, deserializeSqlite: !seedOnly);
return await sqliteProvider
.get<TModel>(query: query, repository: this)
// cache this query
.then((m) => memoryCacheProvider.hydrate<TModel>(m));
} finally {
_latestGetPolicy = null;
}

return await sqliteProvider
.get<TModel>(query: query, repository: this)
// cache this query
.then((m) => memoryCacheProvider.hydrate<TModel>(m));
}

/// Used exclusively by the [OfflineFirstAdapter]. If there are no results, returns `null`.
Future<List<TModel>?> getAssociation<TModel extends RepositoryModel>(Query query) async {
logger.finest('#getAssociation: $TModel $query');
final results = await get<TModel>(query: query);
final results = await get<TModel>(
query: query,
policy: _latestGetPolicy ?? OfflineFirstGetPolicy.awaitRemoteWhenNoneExist,
);
if (results.isEmpty) return null;
return results;
}
Expand Down

0 comments on commit 3aaedc3

Please sign in to comment.