Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: fix broken doc links; add policies page #452

Merged
merged 7 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
- [Fetching data](data/query.md)
- [Providers](data/providers.md)
- [Repositories](data/repositories.md)
- [Supabase](supabase/repository.md)
- [Supabase](supabase/fields.md)
- [Model Config](supabase/models.md)
- [Field Config](supabase/fields.md)
- [Querying](supabase/query.md)
Expand All @@ -29,6 +29,7 @@
- [Offline First](offline_first/fields.md)
- [Model Config](offline_first/models.md)
- [Field Config](offline_first/fields.md)
- [Policies](offline_first/policies.md)
- [Testing](offline_first/testing.md)
- [With Supabase](offline_first/offline_first_with_supabase_repository.md)
- [With GraphQL](offline_first/offline_first_with_graphql_repository.md)
Expand Down
46 changes: 23 additions & 23 deletions docs/data/query.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ Query.where('lastName', 'Mustermann') // note this is lastName and not name or l

Querying can be done with `Where` or `WherePhrase`:

1) `WherePhrase` is a collection of `Where` statements.
2) `WherePhrase` can't contain mixed `required:` because this will output invalid SQL. For example, when it's mixed: `WHERE id = 2 AND name = 'Thomas' OR name = 'Guy'`. The OR needs to be its own phrase: `WHERE (id = 2 AND name = 'Thomas') OR (name = 'Guy')`.
3) `WherePhrase` can be intermixed with `Where`.
```dart
[
Where('id').isExactly(2),
WherePhrase([
Or('name').isExactly('Guy'),
Or('name').isExactly('Thomas')
], required: false)
]
// => (id == 2) || (name == 'Thomas' || name == 'Guy')
```
1. `WherePhrase` is a collection of `Where` statements.
2. `WherePhrase` can't contain mixed `required:` because this will output invalid SQL. For example, when it's mixed: `WHERE id = 2 AND name = 'Thomas' OR name = 'Guy'`. The OR needs to be its own phrase: `WHERE (id = 2 AND name = 'Thomas') OR (name = 'Guy')`.
3. `WherePhrase` can be intermixed with `Where`.
```dart
[
Where('id').isExactly(2),
WherePhrase([
Or('name').isExactly('Guy'),
Or('name').isExactly('Thomas')
], required: false)
]
// => (id == 2) || (name == 'Thomas' || name == 'Guy')
```

!> Queried enum values should map to a primitive. Plainly, **always include `.index`**: `Where('type').isExactly(MyEnumType.value.index)`.

Expand All @@ -57,15 +57,15 @@ Fields can be compared to their values beyond an exact match (the default).
Where('name', value: 'Thomas', compare: Compare.contains);
```

* `between`
* `contains`
* `doesNotContain`
* `exact`
* `greaterThan`
* `greaterThanOrEqualTo`
* `lessThan`
* `lessThanOrEqualTo`
* `notEqual`
- `between`
- `contains`
- `doesNotContain`
- `exact`
- `greaterThan`
- `greaterThanOrEqualTo`
- `lessThan`
- `lessThanOrEqualTo`
- `notEqual`

Please note that the provider is ultimately responsible for supporting `Where` queries.

Expand Down Expand Up @@ -97,7 +97,7 @@ Query(where: [
// => (name == 'Thomas' || age != 42) && (height > 182 && height < 186 && country == 'France')
```

?> If expanded `WherePhrase`s become unlegible, helpers `And` and `Or` can be used:
?> If expanded `WherePhrase`s become illegible, helpers `And` and `Or` can be used:

```dart
Query(where: [
Expand Down
8 changes: 3 additions & 5 deletions docs/graphql/fields.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
?> The GraphQL domain is currently in Alpha. APIs are subject to change.

# Field Configuration

## Annotations
Expand All @@ -11,7 +9,7 @@ Brick by default assumes enums from a GraphQL API will be delivered as integers
Given the API:

```json
{ "user": { "hats": [ "bowler", "birthday" ] } }
{ "user": { "hats": ["bowler", "birthday"] } }
```

Simply convert `hats` into a Dart enum:
Expand Down Expand Up @@ -80,5 +78,5 @@ query {

The following are not serialized to GraphQL. However, unsupported types can still be accessed in the model as non-final fields.

* Nested `List<>` e.g. `<List<List<int>>>`
* Many-to-many associations
- Nested `List<>` e.g. `<List<List<int>>>`
- Many-to-many associations
13 changes: 6 additions & 7 deletions docs/graphql/query.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
?> The GraphQL domain is currently in Alpha. APIs are subject to change.

# `Query` Configuration

## `providerArgs:`

| Name | Type | Description |
|---|---|---|
| `'operation'` | `GraphqlOperation` | apply this operation instead of one of the defaults from `graphqlOperationTransformer`. The document subfields **will not** be populated by the model. |
| `'context'` | `Map<String, ContextEntry>` | apply this as the context to the request instead of an empty object. Useful for subsequent consumers/`Link`s of the request. The key should be the runtime type of the `ContextEntry`. |
| Name | Type | Description |
| ------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `'operation'` | `GraphqlOperation` | apply this operation instead of one of the defaults from `graphqlOperationTransformer`. The document subfields **will not** be populated by the model. |
| `'context'` | `Map<String, ContextEntry>` | apply this as the context to the request instead of an empty object. Useful for subsequent consumers/`Link`s of the request. The key should be the runtime type of the `ContextEntry`. |

#### `variablesNamespace`

Expand Down Expand Up @@ -47,4 +45,5 @@ final variables = {
!> Association values within `Where` **are not** converted to variables

!> Multiple `where` keys (`OfflineFirst(where: {'id': 'data["id"]', 'otherVar': 'data["otherVar"]'})`) or nested properties (`OfflineFirst(where: {'id': 'data["subfield"]["id"]})`) will not generate.
* `@OfflineFirst(where:` only supports extremely simple renames. Multiple `where` keys (`OfflineFirst(where: {'id': 'data["id"]', 'otherVar': 'data["otherVar"]'})`) or nested properties (`OfflineFirst(where: {'id': 'data["subfield"]["id"]})`) will be ignored. Be sure to use `@Graphql(name:)` to rename the generated document field.

- `@OfflineFirst(where:` only supports extremely simple renames. Multiple `where` keys (`OfflineFirst(where: {'id': 'data["id"]', 'otherVar': 'data["otherVar"]'})`) or nested properties (`OfflineFirst(where: {'id': 'data["subfield"]["id"]})`) will be ignored. Be sure to use `@Graphql(name:)` to rename the generated document field.
3 changes: 2 additions & 1 deletion docs/home.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,11 @@

## Learn

- Video: [Brick Architecture](https://www.youtube.com/watch?v=2noLcro9iIw). An explanation of Brick parlance with a supplemental analogy.
- Video: [Brick Architecture](https://www.youtube.com/watch?v=2noLcro9iIw). An explanation of Brick parlance with a [supplemental analogy](https://medium.com/flutter-community/brick-your-app-five-compelling-reasons-and-a-pizza-analogy-to-make-your-data-accessible-8d802e1e526e).
- Video: [Brick Basics](https://www.youtube.com/watch?v=jm5i7e_BQq0). An overview of essential Brick mechanics.
- Example: [Simple Associations using the OfflineFirstWithGraphql domain](https://github.com/GetDutchie/brick/blob/main/example_graphql)
- Example: [Simple Associations using the OfflineFirstWithRest domain](https://github.com/GetDutchie/brick/blob/main/example)
- Example: [Simple Associations using the OfflineFirstWithSupabase domain](https://github.com/GetDutchie/brick/blob/main/example_supabase)
- Tutorial: [Setting up a simple app with Brick](http://www.flutterbyexample.com/#/posts/2_adding_a_repository)

## Glossary
Expand Down
2 changes: 0 additions & 2 deletions docs/offline_first/offline_first_with_graphql_repository.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
?> The GraphQL domain is currently in Alpha. APIs are subject to change.

# Offline First With GraphQL Repository

`OfflineFirstWithGraphqlRepository` streamlines the GraphQL integration with an `OfflineFirstRepository`. A serial queue is included to track GraphQL mutations in a separate SQLite database, only removing requests when a response is returned from the host (i.e. the device has lost internet connectivity).
Expand Down
41 changes: 41 additions & 0 deletions docs/offline_first/policies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Offline First Policies

Repository methods can be invoked with policies to prioritize data sources. For example, a request may need to skip the offline queue or the response must come from a remote source. It is strongly encouraged to use a policy (e.g. `Repository().get<User>(policy: .requireRemote))`) instead of directly accessing a provider (e.g. `Repository().restPovider.get<User>()`)

## OfflineFirstDeletePolicy

### `optimisticLocal`

Delete local results before waiting for the remote provider to respond

### `requireRemote`

Delete local results after remote responds; local results are not deleted if remote responds with any exception

## OfflineFirstGetPolicy

### `alwaysHydrate`

Ensures data is fetched from the remote provider(s) at each invocation. This hydration is unawaited and is not guaranteed to complete before results are returned. This can be expensive to perform for some queries; see [`awaitRemoteWhenNoneExist`](#awaitremotewhennoneexist) for a more performant option or [`awaitRemote`](#awaitremote) to await the hydration before returning results.

### `awaitRemote`

Ensures results must be updated from the remote proivder(s) before returning if the app is online. An empty array will be returned if the app is offline.

### `awaitRemoteWhenNoneExist`

Retrieves from the remote provider(s) if the query returns no results from the local provider(s).

### `localOnly`

Do not request from the remote provider(s)

## OfflineFirstUpsertPolicy

### `optimisticLocal`

Save results to local before waiting for the remote provider to respond

### `requireRemote`

Save results to local after remote responds; local results are not saved if remote responds with any exception
5 changes: 1 addition & 4 deletions example_supabase/lib/brick/models/customer.model.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import 'package:brick_offline_first_with_supabase/brick_offline_first_with_supabase.dart';
import 'package:brick_sqlite/brick_sqlite.dart';
import 'package:brick_supabase/brick_supabase.dart';

@ConnectOfflineFirstWithSupabase(
supabaseConfig: SupabaseSerializable(),
)
@ConnectOfflineFirstWithSupabase()
class Customer extends OfflineFirstWithSupabaseModel {
@Sqlite(unique: true)
final String id;
Expand Down