Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ not wrap untyped builders. Each method returns a copy holding an immutable `Post
that describes the query as structured values (operation, columns, filter, orderings, payload, and
`PostgrestRequestOptions` for headers, retry, timeout and abort signal). Awaiting the builder hands
the request to a `PostgrestTableExecutor` and converts the `PostgrestTableResult` into the table's
`Row` type. The default `PostgrestHttpTableExecutor` renders the request through the untyped
builders at execution time, so both APIs send the same wire request; another executor (a
`SupabaseClientPlugin` can wrap it) may cache, queue or answer from a local store instead.
`Row` type. `PostgrestHttpTableExecutor` renders the request through the untyped builders at
execution time, so both APIs send the same wire request. These types are internal to the postgrest
package and not exported.

### Realtime Architecture

Expand Down
4 changes: 0 additions & 4 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -2240,10 +2240,6 @@ are checked against the column types at compile time, and writes only accept the
and update types. `from()` keeps working, and both can be used on one client, so a codebase can move
over one table at a time.

Requests made through `table()` run through the executor that `SupabaseClientPlugin`s wrap, so
features built as plugins, such as offline support, only apply to them. Requests made through
`from()` bypass every plugin.

The typed API is marked `@experimental` while it settles. Referencing an experimental type such as
`PostgrestFilter` directly reports `experimental_member_use`, which an
`// ignore_for_file: experimental_member_use` silences; the generated file already carries it.
Expand Down
13 changes: 12 additions & 1 deletion packages/postgrest/lib/postgrest.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@ export 'package:yet_another_json_isolate/yet_another_json_isolate.dart'

export 'src/postgrest.dart';
export 'src/postgrest_builder.dart';
export 'src/postgrest_typed_builder.dart' hide renderPostgrestQueryValue;
export 'src/postgrest_typed_builder.dart'
hide
PostgrestEmbeddedPage,
PostgrestExplainOptions,
PostgrestHttpTableExecutor,
PostgrestRequestOptions,
PostgrestResultShape,
PostgrestTableExecutor,
Comment thread
spydon marked this conversation as resolved.
PostgrestTableOperation,
PostgrestTableRequest,
PostgrestTableResult,
renderPostgrestQueryValue;
export 'src/types.dart';
export 'package:http/http.dart' show RequestAbortedException;
15 changes: 3 additions & 12 deletions packages/postgrest/lib/src/postgrest.dart
Original file line number Diff line number Diff line change
Expand Up @@ -165,21 +165,12 @@ class PostgrestClient {
/// .select()
/// .where(Books.id.gt(10));
/// ```
///
/// The builder collects a [PostgrestTableRequest] and hands it to
/// [executor] when awaited; without one the request is sent to PostgREST
/// through this client by a [PostgrestHttpTableExecutor].
@experimental
PostgrestTypedQueryBuilder<Row, Insert, Update> table<Row, Insert, Update>(
PostgrestTable<Row, Insert, Update> table, {
PostgrestTableExecutor? executor,
}) {
PostgrestTable<Row, Insert, Update> table,
) {
final schema = _schemaIsExplicit ? _schema : (table.schema ?? _schema);
return PostgrestTypedQueryBuilder(
table,
executor: executor ?? PostgrestHttpTableExecutor(this),
schema: schema,
);
return PostgrestTypedQueryBuilder(table, client: this, schema: schema);
}

/// Select a schema to query or perform an function (rpc) call.
Expand Down
24 changes: 11 additions & 13 deletions packages/postgrest/lib/src/postgrest_typed_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -229,24 +229,22 @@ extension PostgrestTypedRowsBuilder<Row, Element>

/// A typed PostgREST request that can be awaited.
///
/// Holds the [request] the builder methods have collected so far and the
/// [PostgrestTableExecutor] that runs it. Awaiting the builder executes the
/// request and converts the result into [T], so awaiting it never exposes raw
/// `Map<String, dynamic>` data.
/// Holds the request the builder methods have collected so far. Awaiting the
/// builder executes the request and converts the result into [T], so
/// awaiting it never exposes raw `Map<String, dynamic>` data.
@experimental
class PostgrestTypedBuilder<T> implements Future<T> {
const PostgrestTypedBuilder._(this.request, this._executor, this._convert);
const PostgrestTypedBuilder._(this._request, this._executor, this._convert);

/// The request awaiting this builder executes.
final PostgrestTableRequest request;
final PostgrestTableRequest _request;

final PostgrestTableExecutor _executor;
final _ResultConverter<T> _convert;

/// Runs [request] on the executor, routing a synchronous throw into the
/// Runs [_request] on the executor, routing a synchronous throw into the
/// returned future so the [Future] contract holds for every executor.
Future<T> _execute() =>
Future.sync(() => _executor.execute(request)).then(_convert);
Future.sync(() => _executor.execute(_request)).then(_convert);

PostgrestTypedBuilder<T> _with(PostgrestTableRequest changed) =>
PostgrestTypedBuilder._(changed, _executor, _convert);
Expand All @@ -255,15 +253,15 @@ class PostgrestTypedBuilder<T> implements Future<T> {
///
/// See [PostgrestBuilder.retry] for [enabled] and [count].
PostgrestTypedBuilder<T> retry({bool enabled = true, int? count}) =>
_with(request._retry(enabled, count));
_with(_request._retry(enabled, count));

/// Bounds how long a single attempt of this request may take, overriding
/// the timeout configured on [PostgrestClient].
///
/// Unlike [timeout], which only stops waiting for the result, this cancels
/// the attempt. See [PostgrestBuilder.requestTimeout].
PostgrestTypedBuilder<T> requestTimeout(Duration timeout) =>
_with(request._requestTimeout(timeout));
_with(_request._requestTimeout(timeout));

/// Cancels the request when [abortSignal] completes, throwing a
/// [RequestAbortedException] and stopping any retries.
Expand All @@ -278,11 +276,11 @@ class PostgrestTypedBuilder<T> implements Future<T> {
///
/// See [PostgrestBuilder.abortSignal].
PostgrestTypedBuilder<T> abortSignal(Future<void> abortSignal) =>
_with(request._abortSignal(abortSignal));
_with(_request._abortSignal(abortSignal));

/// Sets [key] to [value] in the headers of this request.
PostgrestTypedBuilder<T> setHeader(String key, String value) =>
_with(request._header(key, value));
_with(_request._header(key, value));

/// A broadcast stream of the one result. The request runs when the first
/// listener subscribes, so a listener added later still receives it.
Expand Down
18 changes: 9 additions & 9 deletions packages/postgrest/lib/src/postgrest_typed_filter_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ part of 'postgrest_typed_builder.dart';
class PostgrestTypedFilterBuilder<Row, T>
extends PostgrestTypedTransformBuilder<Row, T> {
const PostgrestTypedFilterBuilder._(
super.request,
super._request,
super.executor,
super.convert,
super.rowFromJson,
) : super._();

PostgrestTypedFilterBuilder<Row, T> _filtered(
PostgrestTableRequest request,
PostgrestTableRequest changed,
) => PostgrestTypedFilterBuilder._(
request,
changed,
_executor,
_convert,
_rowFromJson,
Expand All @@ -27,19 +27,19 @@ class PostgrestTypedFilterBuilder<Row, T>
PostgrestTypedFilterBuilder<Row, T> retry({
bool enabled = true,
int? count,
}) => _filtered(request._retry(enabled, count));
}) => _filtered(_request._retry(enabled, count));

@override
PostgrestTypedFilterBuilder<Row, T> requestTimeout(Duration timeout) =>
_filtered(request._requestTimeout(timeout));
_filtered(_request._requestTimeout(timeout));

@override
PostgrestTypedFilterBuilder<Row, T> abortSignal(Future<void> abortSignal) =>
_filtered(request._abortSignal(abortSignal));
_filtered(_request._abortSignal(abortSignal));

@override
PostgrestTypedFilterBuilder<Row, T> setHeader(String key, String value) =>
_filtered(request._header(key, value));
_filtered(_request._header(key, value));

/// Only rows satisfying [filter].
///
Expand All @@ -65,9 +65,9 @@ class PostgrestTypedFilterBuilder<Row, T>
///
/// Repeated [where] calls combine with logical AND.
PostgrestTypedFilterBuilder<Row, T> where(PostgrestFilter<Row> filter) {
final current = request.filter;
final current = _request.filter;
return _filtered(
request.copyWith(filter: current == null ? filter : current & filter),
_request.copyWith(filter: current == null ? filter : current & filter),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ part of 'postgrest_typed_builder.dart';
@experimental
class PostgrestTypedQueryBuilder<Row, Insert, Update> {
/// {@macro postgrest_typed_query_builder}
const PostgrestTypedQueryBuilder(
PostgrestTypedQueryBuilder(
this.table, {
required PostgrestTableExecutor executor,
required PostgrestClient client,
String? schema,
}) : _executor = executor,
}) : _executor = PostgrestHttpTableExecutor(client),
_schema = schema,
_options = null;

Expand Down
44 changes: 22 additions & 22 deletions packages/postgrest/lib/src/postgrest_typed_transform_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ part of 'postgrest_typed_builder.dart';
@experimental
class PostgrestTypedTransformBuilder<Row, T> extends PostgrestTypedBuilder<T> {
const PostgrestTypedTransformBuilder._(
super.request,
super._request,
super.executor,
super.convert,
this._rowFromJson,
Expand All @@ -28,7 +28,7 @@ class PostgrestTypedTransformBuilder<Row, T> extends PostgrestTypedBuilder<T> {
PostgrestResultShape shape,
_ResultConverter<U> convert,
) => PostgrestTypedTransformBuilder._(
request.copyWith(shape: shape),
_request.copyWith(shape: shape),
_executor,
convert,
_rowFromJson,
Expand All @@ -38,20 +38,20 @@ class PostgrestTypedTransformBuilder<Row, T> extends PostgrestTypedBuilder<T> {
PostgrestTypedTransformBuilder<Row, T> retry({
bool enabled = true,
int? count,
}) => _with(request._retry(enabled, count));
}) => _with(_request._retry(enabled, count));

@override
PostgrestTypedTransformBuilder<Row, T> requestTimeout(Duration timeout) =>
_with(request._requestTimeout(timeout));
_with(_request._requestTimeout(timeout));

@override
PostgrestTypedTransformBuilder<Row, T> abortSignal(
Future<void> abortSignal,
) => _with(request._abortSignal(abortSignal));
) => _with(_request._abortSignal(abortSignal));

@override
PostgrestTypedTransformBuilder<Row, T> setHeader(String key, String value) =>
_with(request._header(key, value));
_with(_request._header(key, value));

/// Performs horizontal filtering with SELECT, returning the affected rows
/// typed as [Row].
Expand All @@ -67,7 +67,7 @@ class PostgrestTypedTransformBuilder<Row, T> extends PostgrestTypedBuilder<T> {
/// See [selectOnly] to return some columns only.
PostgrestTypedTransformBuilder<Row, List<Row>> select() =>
PostgrestTypedTransformBuilder._(
request.copyWith(
_request.copyWith(
columns: const [],
shape: PostgrestResultShape.rows,
returning: true,
Expand All @@ -92,7 +92,7 @@ class PostgrestTypedTransformBuilder<Row, T> extends PostgrestTypedBuilder<T> {
PostgrestTypedTransformBuilder<Row, List<PostgrestPartialRow<Row>>>
selectOnly(List<PostgrestSelectable<Row>> columns) =>
PostgrestTypedTransformBuilder._(
request.copyWith(
_request.copyWith(
columns: _checkedSelections(columns, 'columns'),
shape: PostgrestResultShape.rows,
returning: true,
Expand All @@ -116,18 +116,18 @@ class PostgrestTypedTransformBuilder<Row, T> extends PostgrestTypedBuilder<T> {
/// Repeated calls append, so the second key breaks ties in the first.
PostgrestTypedTransformBuilder<Row, T> order(
PostgrestOrdering<Row> ordering,
) => _with(request.copyWith(orderings: [...request.orderings, ordering]));
) => _with(_request.copyWith(orderings: [..._request.orderings, ordering]));

/// Limits the result with the specified [count].
PostgrestTypedTransformBuilder<Row, T> limit(
int count, {
String? referencedTable,
}) => _with(
referencedTable == null
? request.copyWith(limit: count)
: request.copyWith(
? _request.copyWith(limit: count)
: _request.copyWith(
embeddedPages: [
...request.embeddedPages,
..._request.embeddedPages,
PostgrestEmbeddedPage(referencedTable, limit: count),
],
),
Expand All @@ -140,10 +140,10 @@ class PostgrestTypedTransformBuilder<Row, T> extends PostgrestTypedBuilder<T> {
String? referencedTable,
}) => _with(
referencedTable == null
? request.copyWith(offset: from, limit: to - from + 1)
: request.copyWith(
? _request.copyWith(offset: from, limit: to - from + 1)
: _request.copyWith(
embeddedPages: [
...request.embeddedPages,
..._request.embeddedPages,
PostgrestEmbeddedPage(
referencedTable,
limit: to - from + 1,
Expand All @@ -159,7 +159,7 @@ class PostgrestTypedTransformBuilder<Row, T> extends PostgrestTypedBuilder<T> {
/// requires PostgREST 11.2 or higher. It applies to row and [single]
/// responses, in either call order.
PostgrestTypedTransformBuilder<Row, T> stripNulls() =>
_with(request.copyWith(stripNulls: true));
_with(_request.copyWith(stripNulls: true));

/// Runs the query but rolls back the transaction, so no changes are
/// persisted.
Expand All @@ -171,7 +171,7 @@ class PostgrestTypedTransformBuilder<Row, T> extends PostgrestTypedBuilder<T> {
/// await client.table(Books.table).insert(BookInsert(title: 'foo')).dryRun();
/// ```
PostgrestTypedTransformBuilder<Row, T> dryRun() =>
_with(request.copyWith(dryRun: true));
_with(_request.copyWith(dryRun: true));

/// Sets the maximum number of rows that can be affected by the query.
///
Expand All @@ -186,7 +186,7 @@ class PostgrestTypedTransformBuilder<Row, T> extends PostgrestTypedBuilder<T> {
/// .maxAffected(10);
/// ```
PostgrestTypedTransformBuilder<Row, T> maxAffected(int value) =>
_with(request.copyWith(maxAffected: value));
_with(_request.copyWith(maxAffected: value));

/// Retrieves the response as CSV.
///
Expand All @@ -206,7 +206,7 @@ class PostgrestTypedTransformBuilder<Row, T> extends PostgrestTypedBuilder<T> {
/// await client.table(Books.table).select().head();
/// ```
PostgrestTypedBuilder<void> head() => PostgrestTypedBuilder._(
request.copyWith(shape: PostgrestResultShape.head),
_request.copyWith(shape: PostgrestResultShape.head),
_executor,
_noResult,
);
Expand All @@ -219,7 +219,7 @@ class PostgrestTypedTransformBuilder<Row, T> extends PostgrestTypedBuilder<T> {
/// https://supabase.com/docs/guides/database/extensions/postgis
PostgrestTypedBuilder<Map<String, dynamic>> geojson() =>
PostgrestTypedBuilder._(
request.copyWith(shape: PostgrestResultShape.geojson),
_request.copyWith(shape: PostgrestResultShape.geojson),
_executor,
(result) => result.data! as Map<String, dynamic>,
);
Expand All @@ -241,7 +241,7 @@ class PostgrestTypedTransformBuilder<Row, T> extends PostgrestTypedBuilder<T> {
bool wal = false,
ExplainFormat format = ExplainFormat.text,
}) => PostgrestTypedBuilder._(
request.copyWith(
_request.copyWith(
shape: PostgrestResultShape.explain,
explainOptions: PostgrestExplainOptions(
analyze: analyze,
Expand Down Expand Up @@ -270,7 +270,7 @@ class PostgrestTypedTransformBuilder<Row, T> extends PostgrestTypedBuilder<T> {
PostgrestTypedBuilder<PostgrestResponse<T>> count([
CountOption option = CountOption.exact,
]) => PostgrestTypedBuilder._(
request.copyWith(countOption: option),
_request.copyWith(countOption: option),
_executor,
(result) => PostgrestResponse(
data: _convert(result),
Expand Down
Loading
Loading