From 0bb3555e8a8088091bcd3d8c609a9f75d38cc93f Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Fri, 23 Sep 2022 18:03:37 +0800 Subject: [PATCH] docs(reference/js/v2): update Database section This is everything except Filters and Modifiers --- spec/supabase_js_v2_legacy.yml | 1400 +++++++++++++++++++++++++++----- 1 file changed, 1208 insertions(+), 192 deletions(-) diff --git a/spec/supabase_js_v2_legacy.yml b/spec/supabase_js_v2_legacy.yml index bb2011bd883..692f6e22b16 100644 --- a/spec/supabase_js_v2_legacy.yml +++ b/spec/supabase_js_v2_legacy.yml @@ -640,31 +640,146 @@ pages: title: 'Fetch data: select()' $ref: '@supabase/postgrest-js.PostgrestQueryBuilder.select' notes: | - - By default, Supabase projects will return a maximum of 1,000 rows. This setting can be changed in Project API Settings. It's recommended that you keep it low to limit the payload size of accidental or malicious requests. You can use `range()` queries to paginate through your data. - - `select()` can be combined with [Modifiers](/docs/reference/javascript/using-modifiers) - - `select()` can be combined with [Filters](/docs/reference/javascript/using-filters) - - If using the Supabase hosted platform `apikey` is technically a reserved keyword, since the API gateway will pluck it out for authentication. [It should be avoided as a column name](https://github.com/supabase/supabase/issues/5465). + - By default, Supabase projects will return a maximum of 1,000 rows. This setting can be changed in project [API settings](https://app.supabase.com/project/_/settings/api). It's recommended that you keep it low to limit the payload size of accidental or malicious requests. You can use `range()` queries to paginate through your data. + - `select()` can be combined with [Filters](/docs/reference/javascript/next/using-filters) + - `select()` can be combined with [Modifiers](/docs/reference/javascript/next/using-modifiers) + - If using the Supabase hosted platform, `apikey` is technically a reserved keyword, since the API gateway will pluck it out for authentication. [It should be avoided as a column name](https://github.com/supabase/supabase/issues/5465). examples: - name: Getting your data + description: | +
+ Schema + + ```sql + create table + countries (id int8 primary key, name text); + + insert into + countries (id, name) + values + (1, 'Afghanistan'), + (2, 'Albania'), + (3, 'Algeria'); + ``` +
+ + ```ts + const { data, error } = await supabase + .from('countries') + .select() + ``` + +
+ Result + + ```json + { + "data": [ + { + "id": 1, + "name": "Afghanistan" + }, + { + "id": 2, + "name": "Albania" + }, + { + "id": 3, + "name": "Algeria" + } + ], + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true isSpotlight: true js: | - ```js + ```ts const { data, error } = await supabase - .from('cities') + .from('countries') .select() ``` - name: Selecting specific columns - description: You can select specific fields from your tables. - js: | - ```js + description: | + You can select specific fields from your tables. + +
+ Schema + + ```sql + create table + countries (id int8 primary key, name text); + + insert into + countries (id, name) + values + (1, 'Afghanistan'), + (2, 'Albania'), + (3, 'Algeria'); + ``` +
+ + ```ts const { data, error } = await supabase - .from('cities') + .from('countries') .select('name') ``` + +
+ Result + + ```json + { + "data": [ + { + "name": "Afghanistan" + }, + { + "name": "Albania" + }, + { + "name": "Algeria" + } + ], + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true - name: Query foreign tables - description: If your database has foreign key relationships, you can query related tables too. - js: | - ```js + description: | + If your database has foreign key relationships, you can query related tables too. + +
+ Schema + + ```sql + create table + countries (id int8 primary key, name text); + create table + cities ( + id int8 primary key, + country_id int8 not null references countries, + name text + ); + + insert into + countries (id, name) + values + (1, 'Germany'), + (2, 'Indonesia'); + insert into + cities (id, country_id, name) + values + (1, 2, 'Bali'), + (2, 1, 'Munich'); + ``` +
+ + ```ts const { data, error } = await supabase .from('countries') .select(` @@ -674,233 +789,888 @@ pages: ) `) ``` - note: | - What about join tables - If you're in a situation where your tables are **NOT** directly related, but instead are joined by a _join table_, - you can still use the `select()` method to query the related data. The PostgREST engine detects the relationship automatically. - For more details, [follow the link](https://postgrest.org/en/latest/api.html#embedding-through-join-tables). + +
+ Result + + ```json + { + "data": [ + { + "name": "Germany", + "cities": [ + { + "name": "Munich" + } + ] + }, + { + "name": "Indonesia", + "cities": [ + { + "name": "Bali" + } + ] + } + ], + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true + - name: Query foreign tables through a join table + description: | + If you're in a situation where your tables are **NOT** directly + related, but instead are joined by a _join table_, you can still use + the `select()` method to query the related data. The join table needs + to have the foreign keys as part of its composite primary key. + +
+ Schema + + ```sql + create table + users ( + id int8 primary key, + name text + ); + create table + teams ( + id int8 primary key, + name text + ); + -- join table + create table + users_teams ( + user_id int8 not null references users, + team_id int8 not null references teams, + -- both foreign keys must be part of a composite primary key + primary key (user_id, team_id) + ); + + insert into + users (id, name) + values + (1, 'Kiran'), + (2, 'Evan'); + insert into + teams (id, name) + values + (1, 'Green'), + (2, 'Blue'); + insert into + users_teams (user_id, team_id) + values + (1, 1), + (1, 2), + (2, 2); + ``` +
+ + ```ts + const { data, error } = await supabase + .from('users') + .select(` + name, + teams ( + name + ) + `) + ``` + +
+ Result + + ```json + { + "data": [ + { + "name": "Kiran", + "teams": [ + { + "name": "Green" + }, + { + "name": "Blue" + } + ] + }, + { + "name": "Evan", + "teams": [ + { + "name": "Blue" + } + ] + } + ], + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true - name: Query the same foreign table multiple times description: | Sometimes you will need to query the same foreign table twice. In this case, you can use the name of the joined column to identify which join you intend to use. For convenience, you can also give an - alias for each column. For example, if we had a shop of products, - and we wanted to get the supplier and the purchaser at the same time - (both in the users) table: - js: | - ```js - const { data, error } = await supabase - .from('products') - .select(` - id, - supplier:supplier_id ( name ), - purchaser:purchaser_id ( name ) - `) - ``` - - name: Filtering with inner joins - description: | - If you want to filter a table based on a child table's values you can use the `!inner()` function. For example, if you wanted - to select all rows in a `message` table which belong to a user with the `username` "Jane": - js: | - ```js + alias for each column. + +
+ Schema + + ```sql + create table + users (id int8 primary key, name text); + + create table + messages ( + sender_id int8 not null references users, + receiver_id int8 not null references users, + content text + ); + + insert into + users (id, name) + values + (1, 'Kiran'), + (2, 'Evan'); + + insert into + messages (sender_id, receiver_id, content) + values + (1, 2, '👋'); + ``` +
+ + ```ts const { data, error } = await supabase .from('messages') - .select('*, users!inner(*)') - .eq('users.username', 'Jane') + .select(` + content, + from:sender_id(name), + to:receiver_id(name) + `) ``` + +
+ Result + + ```json + { + "data": [ + { + "content": "👋", + "from": { + "name": "Kiran" + }, + "to": { + "name": "Evan" + } + } + ], + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true + - name: Filtering through foreign tables + description: | + Normally when you perform a filter on a foreign table's column, if the + filter is not satisfied, you would get either `[]` or `null` for the + foreign table, but the parent table is not filtered out. + +
+ Schema + + ```sql + create table + countries (id int8 primary key, name text); + create table + cities ( + id int8 primary key, + country_id int8 not null references countries, + name text + ); + + insert into + countries (id, name) + values + (1, 'Germany'), + (2, 'Indonesia'); + insert into + cities (id, country_id, name) + values + (1, 2, 'Bali'), + (2, 1, 'Munich'); + ``` +
+ + ```ts + const { data, error } = await supabase + .from('cities') + .select('name, countries(*)') + .eq('countries.name', 'Estonia') + ``` + +
+ Result + + ```json + { + "data": [ + { + "name": "Bali", + "countries": null + }, + { + "name": "Munich", + "countries": null + } + ], + "status": 200, + "statusText": "OK" + } + ``` +
+ + If you want to filter out the parent table rows, you can use the `!inner` hint: + + ```ts + const { data, error } = await supabase + .from('cities') + .select('name, countries!inner(*)') + .eq('countries.name', 'Estonia') + ``` + +
+ Result + + ```json + { + "data": [], + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true - name: Querying with count option description: | - You can get the number of rows by using the count option. - Allowed values for count option are `null`, [exact](https://postgrest.org/en/stable/api.html#exact-count), [planned](https://postgrest.org/en/stable/api.html#planned-count) and [estimated](https://postgrest.org/en/stable/api.html#estimated-count). - js: | - ```js - const { data, error, count } = await supabase - .from('cities') - .select('name', { count: 'exact' }) // if you don't want to return any rows, you can use { count: 'exact', head: true } + You can get the number of rows by using the + [count](/docs/reference/javascript/next/select#parameters) option. For + example, to get the table count without returning all rows: + +
+ Schema + + ```sql + create table + countries (id int8 primary key, name text); + + insert into + countries (id, name) + values + (1, 'Afghanistan'), + (2, 'Albania'), + (3, 'Algeria'); + ``` +
+ + ```ts + const { count, error } = await supabase + .from('countries') + .select('*', { count: 'exact', head: true }) ``` + +
+ Result + + ```json + { + "count": 3, + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true - name: Querying JSON data description: | - If you have data inside of a JSONB column, you can apply select - and query filters to the data values. Postgres offers a - [number of operators](https://www.postgresql.org/docs/current/functions-json.html) - for querying JSON data. Also see - [PostgREST docs](http://postgrest.org/en/v7.0.0/api.html#json-columns) for more details. - js: | - ```js + You can select and filter data inside of + [JSON](/docs/guides/database/json) columns. Postgres offers some + [operators](/docs/guides/database/json#query-the-jsonb-data) for + querying JSON data. + +
+ Schema + + ```sql + create table + users ( + id int8 primary key, + name text, + address jsonb + ); + + insert into + users (id, name, address) + values + (1, 'Avdotya', '{"city":"Saint Petersburg"}'); + ``` +
+ + ```ts const { data, error } = await supabase .from('users') .select(` id, name, - address->street + address->city `) - .eq('address->postcode', 90210) - ``` - - name: Return data as CSV - description: | - By default the data is returned in JSON format, however you can also request for it to be returned as Comma Separated Values. - js: | - ```js - const { data, error } = await supabase - .from('users') - .select() - .csv() - ``` - - name: Aborting requests in-flight - description: | - You can use an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) to abort requests. Note that `status` and `statusText` doesn't mean anything for aborted requests, since the request wasn't actually fulfilled. - js: | - ```js - const ac = new AbortController() - supabase - .from('very_big_table') - .select() - .abortSignal(ac.signal) - .then(console.log) - ac.abort() - // { - // error: { - // message: 'FetchError: The user aborted a request.', - // details: '', - // hint: '', - // code: '' - // }, - // data: null, - // body: null, - // count: null, - // status: 400, - // statusText: 'Bad Request' - // } ``` +
+ Result + + ```json + { + "data": [ + { + "id": 1, + "name": "Avdotya", + "city": "Saint Petersburg" + } + ], + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true + insert(): title: 'Create data: insert()' $ref: '@supabase/postgrest-js.PostgrestQueryBuilder.insert' examples: - name: Create a record - isSpotlight: true - js: | - ```js - const { data, error } = await supabase - .from('cities') - .insert([ - { name: 'The Shire', country_id: 554 } - ]) + description: | +
+ Schema + + ```sql + create table + countries (id int8 primary key, name text); + ``` +
+ + ```ts + const { error } = await supabase + .from('countries') + .insert({ id: 1, name: 'Denmark' }) ``` - - name: Create a record and return it - js: | - ```js + +
+ Result + + ```json + { + "status": 201, + "statusText": "Created" + } + ``` +
+ + ```ts const { data, error } = await supabase - .from('cities') - .insert([ - { name: 'The Shire', country_id: 554 } - ]) + .from('countries') .select() ``` + +
+ Result + + ```json + { + "data": [ + { + "id": 1, + "name": "Denmark" + } + ], + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true + isSpotlight: true + js: | + ```ts + const { error } = await supabase + .from('countries') + .insert({ id: 1, name: 'Denmark' }) + ``` + - name: Create a record and return it + description: | +
+ Schema + + ```sql + create table + countries (id int8 primary key, name text); + ``` +
+ + ```ts + const { data, error } = await supabase + .from('countries') + .insert({ id: 1, name: 'Denmark' }) + .select() + ``` + +
+ Result + + ```json + { + "data": [ + { + "id": 1, + "name": "Denmark" + } + ], + "status": 201, + "statusText": "Created" + } + ``` +
+ hideCodeBlock: true - name: Bulk create description: | - When running a bulk create, the operation is handled in a single transaction. If any of the inserts fail, all other operations are - rolled back. - js: | - ```js - const { data, error } = await supabase - .from('cities') + When running a bulk create, the operation is handled in a single + transaction. If any of the inserts fail, none of the rows are + inserted. + +
+ Schema + + ```sql + create table + countries (id int8 primary key, name text); + ``` +
+ + ```ts + const { error } = await supabase + .from('countries') .insert([ - { name: 'The Shire', country_id: 554 }, - { name: 'Rohan', country_id: 555 }, + { id: 1, name: 'Nepal' }, + { id: 1, name: 'Vietnam' }, ]) ``` +
+ Result + + ```json + { + "error": { + "code": "23505", + "details": "Key (id)=(1) already exists.", + "hint": null, + "message": "duplicate key value violates unique constraint \"countries_pkey\"" + }, + "status": 409, + "statusText": "Conflict" + } + ``` +
+ + ```ts + const { data, error } = await supabase + .from('countries') + .select() + ``` + +
+ Result + + ```json + { + "data": [], + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true + update(): title: 'Modify data: update()' $ref: '@supabase/postgrest-js.PostgrestQueryBuilder.update' notes: | - - `update()` should always be combined with [Filters](/docs/reference/javascript/using-filters) to target the item(s) you wish to update. + - `update()` should always be combined with [Filters](/docs/reference/javascript/next/using-filters) to target the item(s) you wish to update. examples: - name: Updating your data + description: | +
+ Schema + + ```sql + create table + countries (id int8 primary key, name text); + + insert into + countries (id, name) + values + (1, 'Taiwan'); + ``` +
+ + ```ts + const { error } = await supabase + .from('countries') + .update({ name: 'Australia' }) + .eq('id', 1) + ``` + +
+ Result + + ```json + { + "status": 204, + "statusText": "No Content" + } + ``` +
+ + ```ts + const { data, error } = await supabase + .from('countries') + .select() + ``` + +
+ Result + + ```json + { + "data": [ + { + "id": 1, + "name": "Australia" + } + ], + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true isSpotlight: true js: | - ```js - const { data, error } = await supabase - .from('cities') - .update({ name: 'Middle Earth' }) - .match({ name: 'Auckland' }) + ```ts + const { error } = await supabase + .from('countries') + .update({ name: 'Australia' }) + .eq('id', 1) ``` + - name: Update a record and return it + description: | +
+ Schema + + ```sql + create table + countries (id int8 primary key, name text); + + insert into + countries (id, name) + values + (1, 'Taiwan'); + ``` +
+ + ```ts + const { data, error } = await supabase + .from('countries') + .update({ name: 'Australia' }) + .eq('id', 1) + .select() + ``` + +
+ Result + + ```json + { + "data": [ + { + "id": 1, + "name": "Australia" + } + ], + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true - name: Updating JSON data description: | - Postgres offers a - [number of operators](https://www.postgresql.org/docs/current/functions-json.html) - for working with JSON data. Right now it is only possible to update an entire JSON document, - but we are [working on ideas](https://github.com/PostgREST/postgrest/issues/465) for updating individual keys. For example: - js: | - ```js + Postgres offers some + [operators](/docs/guides/database/json#query-the-jsonb-data) for + working with JSON data. For example: + +
+ Schema + + ```sql + create table + users ( + id int8 primary key, + name text, + address jsonb + ); + + insert into + users (id, name, address) + values + (1, 'Thekla', '{ "postcode": 90210 }'); + ``` +
+ + ```ts const { data, error } = await supabase .from('users') - .update(` + .update({ address: { street: 'Melrose Place', postcode: 90210 } - `) + }) .eq('address->postcode', 90210) + .select() ``` +
+ Result + + ```json + { + "data": [ + { + "id": 1, + "name": "Thekla", + "address": { + "street": "Melrose Place", + "postcode": 90210 + } + } + ], + "status": 200, + "statusText": "OK" + } + ``` +
+ + Right now it is only possible to update the entire JSON document. + hideCodeBlock: true + upsert(): title: 'Upsert data: upsert()' $ref: '@supabase/postgrest-js.PostgrestQueryBuilder.upsert' notes: | - - Primary keys should be included in the data payload in order for an update to work correctly. - - Primary keys must be natural, not surrogate. There are however, [workarounds](https://github.com/PostgREST/postgrest/issues/1118) for surrogate primary keys. + - Primary keys should be included in `values` in order for an upsert to work correctly. examples: - name: Upsert your data + description: | +
+ Schema + + ```sql + create table + countries (id int8 primary key, name text); + + insert into + countries (id, name) + values + (1, 'Afghanistan'); + ``` +
+ + ```ts + const { data, error } = await supabase + .from('countries') + .upsert({ id: 1, name: 'Albania' }) + .select() + ``` + +
+ Result + + ```json + { + "data": [ + { + "id": 1, + "name": "Albania" + } + ], + "status": 201, + "statusText": "Created" + } + ``` +
+ hideCodeBlock: true isSpotlight: true js: | - ```js + ```ts const { data, error } = await supabase - .from('messages') - .upsert({ id: 3, message: 'foo', username: 'supabot' }) + .from('countries') + .upsert({ id: 1, name: 'Albania' }) + .select() ``` - name: Bulk Upsert your data - isSpotlight: false - js: | - ```js + description: | +
+ Schema + + ```sql + create table + countries (id int8 primary key, name text); + + insert into + countries (id, name) + values + (1, 'Afghanistan'); + ``` +
+ + ```ts const { data, error } = await supabase - .from('messages') + .from('countries') .upsert([ - { id: 3, message: 'foo', username: 'supabot' }, - { id: 4, message: 'bar', username: 'supabot' } + { id: 1, name: 'Albania' }, + { id: 2, name: 'Algeria' }, ]) + .select() ``` + +
+ Result + + ```json + { + "data": [ + { + "id": 1, + "name": "Albania" + }, + { + "id": 2, + "name": "Algeria" + } + ], + "status": 201, + "statusText": "Created" + } + ``` +
+ hideCodeBlock: true - name: Upserting into tables with constraints description: | - Running the following will cause supabase to upsert data into the `users` table. - If the username 'supabot' already exists, the `onConflict` argument tells supabase to overwrite that row - based on the column passed into `onConflict`. - isSpotlight: true - js: | - ```js + In the following query, `upsert()` will implicitly use the `id` + (primary key) column to determine conflicts. If there is no existing + row with the same `id`, `upsert()` will try to insert a new row, which + will fail in this case because there is already a row with `handle` + `"saoirse"`: + +
+ Schema + + ```sql + create table + users ( + id int8 generated by default as identity primary key, + handle text not null unique, + display_name text + ); + + insert into + users (id, handle, display_name) + values + (1, 'saoirse', null); + ``` +
+ + ```ts const { data, error } = await supabase .from('users') - .upsert({ username: 'supabot' }, { onConflict: 'username' }) + .upsert({ id: 42, handle: 'saoirse', display_name: 'Saoirse' }) + .select() ``` - - name: Return the exact number of rows - isSpotlight: true - js: | - ```js - const { data, error, count } = await supabase + +
+ Result + + ```json + { + "error": { + "code": "23505", + "details": "Key (handle)=(saoirse) already exists.", + "hint": null, + "message": "duplicate key value violates unique constraint \"users_handle_key\"" + }, + "status": 409, + "statusText": "Conflict" + } + ``` +
+ + Using the `onConflict` option, you can instruct `upsert()` to use + another column with a unique constraint to determine conflicts: + + ```ts + await supabase .from('users') - .upsert({ - id: 3, message: 'foo', - username: 'supabot' - }, { - count: 'exact' - }) + .upsert( + { id: 42, handle: 'saoirse', display_name: 'Saoirse' }, + { onConflict: 'handle' }, + ) + const { data, error } = await supabase + .from('users') + .select() ``` +
+ Result + + ```json + { + "data": [ + { + "id": 42, + "handle": "saoirse", + "display_name": "Saoirse" + } + ], + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true + delete(): title: 'Delete data: delete()' $ref: '@supabase/postgrest-js.PostgrestQueryBuilder.delete' notes: | - - `delete()` should always be combined with [filters](/docs/reference/javascript/using-filters) to target the item(s) you wish to delete. + - `delete()` should always be combined with [filters](/docs/reference/javascript/next/using-filters) to target the item(s) you wish to delete. - If you use `delete()` with filters and you have [RLS](/docs/learn/auth-deep-dive/auth-row-level-security) enabled, only rows visible through `SELECT` policies are deleted. Note that by default @@ -908,13 +1678,64 @@ pages: makes the rows visible. examples: - name: Delete records + description: | +
+ Schema + + ```sql + create table + countries (id int8 primary key, name text); + + insert into + countries (id, name) + values + (1, 'Spain'); + ``` +
+ + ```ts + const { error } = await supabase + .from('countries') + .delete() + .eq('id', 1) + ``` + +
+ Result + + ```json + { + "status": 204, + "statusText": "No Content" + } + ``` +
+ + ```ts + const { data, error } = await supabase + .from('countries') + .select() + ``` + +
+ Result + + ```json + { + "data": [], + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true isSpotlight: true js: | - ```js - const { data, error } = await supabase - .from('cities') + ```ts + const { error } = await supabase + .from('countries') .delete() - .match({ id: 666 }) + .eq('id', 1) ``` rpc(): @@ -933,48 +1754,153 @@ pages: $ref: '@supabase/postgrest-js.PostgrestClient.rpc' examples: - name: Call a Postgres function + description: | + This is an example of invoking a Postgres function with no parameters. + +
+ Schema + + ```sql + create function hello_world() returns text as $$ + select 'Hello world'; + $$ language sql; + ``` +
+ + ```ts + const { data, error } = await supabase.rpc('hello_world') + ``` + +
+ Result + + ```json + { + "data": "Hello world", + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true isSpotlight: true - description: This is an example of invoking a Postgres function with no parameters. js: | - ```js - const { data, error } = await supabase - .rpc('hello_world') + ```ts + const { data, error } = await supabase.rpc('hello_world') ``` - - name: With Parameters - js: | - ```js - const { data, error } = await supabase - .rpc('echo_city', { name: 'The Shire' }) + - name: With arguments + description: | +
+ Schema + + ```sql + create function echo(say text) returns text as $$ + select say; + $$ language sql; + ``` +
+ + ```ts + const { data, error } = await supabase.rpc('echo', { say: '👋' }) ``` + +
+ Result + + ```json + { + "data": "👋", + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true - name: Bulk processing - description: You can process large payloads at once using [array parameters](https://postgrest.org/en/stable/api.html#calling-functions-with-array-parameters). - js: | - ```js - const { data, error } = await postgrest - .rpc('echo_cities', { names: ['The Shire', 'Mordor'] }) + description: | + You can process large payloads at once using array parameters: + +
+ Schema + + ```sql + create function add_one_each(arr int[]) returns int[] as $$ + select array_agg(n + 1) from unnest(arr) as n; + $$ language sql; + ``` +
+ + ```ts + const { data, error } = await supabase.rpc('add_one_each', { arr: [1, 2, 3] }) ``` + +
+ Result + + ```json + { + "data": [ + 2, + 3, + 4 + ], + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true - name: With filters description: | Postgres functions that return tables can also be combined with - [Modifiers](/docs/reference/javascript/using-modifiers) and - [Filters](/docs/reference/javascript/using-filters). - js: | - ```js + [Filters](/docs/reference/javascript/next/using-filters) and + [Modifiers](/docs/reference/javascript/next/using-modifiers). + +
+ Schema + + ```sql + create table + countries (id int8 primary key, name text); + + insert into + countries (id, name) + values + (1, 'France'), + (2, 'United Kingdom'); + + create function list_stored_countries() returns setof countries as $$ + select * from countries; + $$ language sql; + ``` +
+ + ```ts const { data, error } = await supabase - .rpc('echo_all_cities') - .select('name, population') - .eq('name', 'The Shire') - ``` - - name: With count option - description: | - You can specify a count option to get the row count along with your data. - Allowed values for count option are `null`, `exact`, `planned` and `estimated`. - js: | - ```js - const { data, error, count } = await supabase - .rpc('hello_world', {}, { count: 'exact' }) + .rpc('list_stored_countries') + .eq('id', 1) + .single() ``` +
+ Result + + ```json + { + "data": { + "id": 1, + "name": "France" + }, + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true + + # TODO: filter inside json column + # TODO: filter embedded resources + # TODO: explain what filters do Using Filters: description: | Filters can be used on `select()`, `update()`, and `delete()` queries. @@ -1958,6 +2884,7 @@ pages: .filter('countries.name', 'in', '("France","Japan")') ``` + # TODO: explain what modifiers do, and how they differ from filters Using Modifiers: description: | Modifiers can be used on `select()` queries. @@ -2028,6 +2955,47 @@ pages: db.abortSignal(): $ref: '@supabase/postgrest-js.PostgrestTransformBuilder.abortSignal' title: abortSignal() + examples: + - name: Aborting requests in-flight + description: | + You can use an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) to abort requests. Note that `status` and `statusText` doesn't mean anything for aborted requests, since the request wasn't actually fulfilled. + + ```ts + const ac = new AbortController() + ac.abort() + const { data, error } = await supabase + .from('very_big_table') + .select() + .abortSignal(ac.signal) + ``` + +
+ Result + + ```json + { + "error": { + "message": "FetchError: The user aborted a request.", + "details": "", + "hint": "", + "code": "" + }, + "status": 400, + "statusText": "Bad Request" + } + ``` +
+ hideCodeBlock: true + isSpotlight: true + js: | + ```ts + const ac = new AbortController() + ac.abort() + const { data, error } = await supabase + .from('very_big_table') + .select() + .abortSignal(ac.signal) + ``` single(): $ref: '@supabase/postgrest-js.PostgrestTransformBuilder.single' @@ -2060,6 +3028,54 @@ pages: db.csv(): $ref: '@supabase/postgrest-js.PostgrestTransformBuilder.csv' title: csv() + examples: + - name: Return data as CSV + description: | + By default the data is returned in JSON format, however you can also request for it to be returned as Comma Separated Values. + +
+ Schema + + ```sql + create table + countries (id int8 primary key, name text); + + insert into + countries (id, name) + values + (1, 'Afghanistan'), + (2, 'Albania'), + (3, 'Algeria'); + ``` +
+ + ```ts + const { data, error } = await supabase + .from('countries') + .select() + .csv() + ``` + +
+ Result + + ```json + { + "data": "id,name\n1,Afghanistan\n2,Albania\n3,Algeria", + "status": 200, + "statusText": "OK" + } + ``` +
+ hideCodeBlock: true + isSpotlight: true + js: | + ```ts + const { data, error } = await supabase + .from('countries') + .select() + .csv() + ``` db.geojson(): $ref: '@supabase/postgrest-js.PostgrestTransformBuilder.geojson'