Clarify docs to support latest syntax from 0.8.0

This commit is contained in:
Joseph Schultz committed 2023-01-31 23:04:23 -06:00
1 parent 392a95cc37
commit acd3d0e110
2 files changed
+139 -316

No files matched your search

@@ -3,6 +3,39 @@ id: release-notes
title: Release Notes
---
## 0.8.0 - 2023-01-31
- Update dependency: realtime-csharp@5.0.0
- Re: [#21](https://github.com/supabase-community/realtime-csharp/pull/21) Provide API for `presence`, `broadcast` and `postgres_changes`
- [Major, New] `Channel.PostgresChanges` event will receive the wildcard `*` changes event, not `Channel.OnMessage`.
- [Major] `Channel.OnInsert`, `Channel.OnUpdate`, and `Channel.OnDelete` now conform to the server's payload of `Response.Payload.**Data**`
- [Major] `Channel.OnInsert`, `Channel.OnUpdate`, and `Channel.OnDelete` now return `PostgresChangesEventArgs`
- [Minor] Rename `Channel` to `RealtimeChannel`
- Supports better handling of disconnects in `RealtimeSocket` and adds a `Client.OnReconnect` event.
- [Minor] Moves `ChannelOptions` to `Channel.ChannelOptions`
- [Minor] Moves `ChannelStateChangedEventArgs` to `Channel.ChannelStateChangedEventArgs`
- [Minor] Moves `Push` to `Channel.Push`
- [Minor] Moves `Channel.ChannelState` to `Constants.ChannelState`
- [Minor] Moves `SocketResponse`, `SocketRequest`, `SocketResponsePayload`, `SocketResponseEventArgs`, and `SocketStateChangedEventArgs` to `Socket` namespace.
- [New] Adds `RealtimeBroadcast`
- [New] Adds `RealtimePresence`
- [Improvement] Better handling of disconnection/reconnection
- Update dependency: postgrest-csharp@3.1.3
- Another fix for [#61](https://github.com/supabase-community/postgrest-csharp/issues/61) which futher typechecks nullable values.
## 0.7.2 - 2023-01-27
- Update dependency: gotrue-csharp@3.0.4
- Makes `Session.CreatedAt` a publicly settable property, which should fix incorrect dates on retrieved `Session`s.
- Update dependency: postgrest-csharp@3.1.2
- Fix [#61](https://github.com/supabase-community/postgrest-csharp/issues/61) which did not correctly parse Linq `Where` when encountering a nullable type.
- Add missing support for transforming for `== null` and `!= null`
## 0.7.1 - 2023-01-17
- Update dependency: postgrest-csharp@3.1.1
- Fix issue from supabase-community/supabase-csharp#48 where boolean model properties would not be evaluated in predicate expressions
## 0.7.0 - 2023-01-16
- Update dependency: postgrest-csharp@3.1.0
+106 -316
View File
@@ -13,7 +13,7 @@ info:
libraries:
- name: 'C#'
id: 'csharp'
version: '0.0.1'
version: '0.8.0'
functions:
- id: sign-up
@@ -283,7 +283,8 @@ functions:
Performs vertical filtering with SELECT.
title: 'Fetch data: Select()'
notes: |
- **Column Names must match names in database, not names specified on model properties.**
- **LINQ expressions do not currently support parsing embedded resource columns. For these cases, `string` will need to be used.**
- **When using string Column Names to select, they must match names in database, not names specified on model properties.**
- 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.
- `From()` can be combined with [Modifiers](/docs/reference/csharp/using-modifiers)
- `From()` can be combined with [Filters](/docs/reference/csharp/using-filters)
@@ -313,7 +314,7 @@ functions:
code: |
```c#
var data = await supabase
.From<Products>()
.From<Transactions>()
.Select("id, supplier:supplier_id(name), purchaser:purchaser_id(name)")
.Get();
```
@@ -432,14 +433,14 @@ functions:
- `Update()` is typically called using a model as an argument or from a hydrated model.
examples:
- id: updating-your-data-with-filter
name: Update your data
name: Update your data using Filter
isSpotlight: true
code: |
```c#
var update = await supabase
.From<City>()
.Where(x => x.Name == "Auckland")
.Set(x => new KeyValuePair<object, object>(x.Name, "Middle Earth"))
.Set(x => x.Name, "Middle Earth")
.Update();
```
- id: updating-your-data
@@ -556,13 +557,68 @@ functions:
```
- id: subscribe
title: 'Realtime.Channel'
description: |
Subscribe to realtime changes in your database.
title: 'From<Model>().On()'
notes: |
- Realtime is disabled by default for new Projects for better database performance and security. You can turn it on by [managing replication](/docs/guides/api#managing-realtime).
- If you want to receive the "previous" data for updates and deletes, you will need to set `REPLICA IDENTITY` to `FULL`, like this: `ALTER TABLE your_table REPLICA IDENTITY FULL;`
examples:
- id: listen-to-broadcast
name: Listen to broadcast messages
isSpotlight: true
code: |
```c#
class CursorBroadcast : BaseBroadcast
{
[JsonProperty("cursorX")]
public int CursorX {get; set;}
[JsonProperty("cursorY")]
public int CursorY {get; set;}
}
var channel = supabase.Realtime.Channel("any");
var broadcast = channel.Register<CursorBroadcast>();
broadcast.OnBroadcast += (sender, _) =>
{
var data = broadcast.Current();
};
await channel.Subscribe();
// Send a broadcast
await broadcast.Send("cursor", new CursorBroadcast { CursorX = 123, CursorY = 456 });
```
- id: listen-to-presence-sync
name: Listen to presence sync
isSpotlight: true
code: |
```c#
class UserPresence : BasePresence
{
[JsonProperty("cursorX")]
public bool IsTyping {get; set;}
[JsonProperty("onlineAt")]
public DateTime OnlineAt {get; set;}
}
var channel = supabase.Realtime.Channel("any");
var presenceKey = Guid.NewGuid().ToString();
var presence = channel.Register<UserPresence>(presenceKey);
presence.OnSync += (sender, _) =>
{
var state = presence.CurrentState;
};
await channel.Subscribe();
// Send a presence update
await presence.Track(new UserPresence { IsTyping = false, OnlineAt = DateTime.Now });
```
- id: listening-to-a-specific-table
name: Listening to a specific table
isSpotlight: true
@@ -570,7 +626,7 @@ functions:
```c#
await supabase.From<City>().On(ChannelEventType.All, (sender, args) =>
{
Debug.WriteLine(args.Response.Payload);
Debug.WriteLine(args.Response.Payload.Data);
});
```
- id: listen-to-all-database-changes
@@ -579,9 +635,9 @@ functions:
```c#
var channel = supabase.Realtime.Channel("realtime", "public", "*");
channel.OnMessage += (sender, args) =>
channel.OnPostgresChanges += (sender, args) =>
{
Debug.WriteLine(args.Response.Payload);
Debug.WriteLine(args.Response.Payload.Data);
};
await channel.Subscribe();
@@ -592,7 +648,7 @@ functions:
```c#
await supabase.From<City>().On(ChannelEventType.Insert, (sender, args) =>
{
Debug.WriteLine(args.Response.Payload);
Debug.WriteLine(args.Response.Payload.Data);
});
```
- id: listening-to-updates
@@ -608,7 +664,7 @@ functions:
```c#
await supabase.From<City>().On(ChannelEventType.Update, (sender, args) =>
{
Debug.WriteLine(args.Response.Payload);
Debug.WriteLine(args.Response.Payload.Data);
});
```
- id: listening-to-deletes
@@ -624,7 +680,7 @@ functions:
```c#
await supabase.From<City>().On(ChannelEventType.Delete, (sender, args) =>
{
Debug.WriteLine(args.Response.Payload);
Debug.WriteLine(args.Response.Payload.Data);
});
```
- id: listening-to-row-level-changes
@@ -676,93 +732,6 @@ functions:
var channels = supabase.Realtime.Subscriptions;
```
# - id: stream
# description: |
# Notifies of data at the queried table.
# title: 'stream()'
# notes: |
# - `stream()` will emit the initial data as well as any further change on the database as `Stream` of `List<Map<String, dynamic>>` by combining Postgrest and Realtime.
# - Takes a list of primary key columns as its argument.
# examples:
# - id: listening-to-a-specific-table
# name: Listening to a specific table
# isSpotlight: true
# code: |
# ```dart
# supabase.from('countries')
# .stream(primaryKey: ['id'])
# .listen((List<Map<String, dynamic>> data) {
# // Do something awesome with the data
# });
# ```
# - id: listening-to-a-specific-rows-within-a-table
# name: Listening to a specific rows within a table
# description: |
# You can listen to individual rows using the format `{table}:{col}=eq.{val}` - where `{col}` is the column name, and `{val}` is the value which you want to match.
# This syntax is the as how you can filter data in Realtime
# code: |
# ```dart
# supabase.from('countries')
# .stream(primaryKey: ['id'])
# .eq('id', '120')
# .listen((List<Map<String, dynamic>> data) {
# // Do something awesome with the data
# });
# ```
# - id: with-order
# name: With `order()`
# code: |
# ```dart
# supabase.from('countries')
# .stream(primaryKey: ['id'])
# .order('name', ascending: true)
# .listen((List<Map<String, dynamic>> data) {
# // Do something awesome with the data
# });
# ```
# - id: with-limit
# name: With `limit()`
# code: |
# ```dart
# supabase.from('countries')
# .stream(primaryKey: ['id'])
# .order('name', ascending: true)
# .limit(10)
# .listen((List<Map<String, dynamic>> data) {
# // Do something awesome with the data
# });
# ```
# - id: using-stream-with-stream-builder
# name: Using `stream()` with `StreamBuilder`
# description: |
# When using `stream()` with a `StreamBuilder` within your Flutter application, make sure to store your stream in a variable to prevent refetching upon rebuilding.
# code: |
# ```dart
# final supabase = Supabase.instance.client;
# class MyWidget extends StatefulWidget {
# const MyWidget({Key? key}) : super(key: key);
# @override
# State<MyWidget> createState() => _MyWidgetState();
# }
# class _MyWidgetState extends State<MyWidget> {
# // Persist the stream in a local variable to prevent refetching upon rebuilds
# final _stream = supabase.from('countries').stream(primaryKey: ['id']);
# @override
# Widget build(BuildContext context) {
# return StreamBuilder(
# stream: _stream,
# builder: (context, snapshot) {
# // Return your widget with the data from the snapshot
# },
# );
# }
# }
# ```
- id: list-buckets
description: |
Retrieves the details of all Storage buckets within an existing product.
@@ -1043,7 +1012,7 @@ functions:
code: |
```c#
var result = await supabase.From<City>()
.Select("name, country_id")
.Select(x => new object[] { x.Name, x.CountryId })
.Limit(10)
.Get();
```
@@ -1069,8 +1038,8 @@ functions:
code: |
```c#
var result = await supabase.From<City>()
.Select("name, country_id")
.Order("id", Ordering.Descending)
.Select(x => new object[] { x.Name, x.CountryId })
.Order(x => x.Id, Ordering.Descending)
.Get();
```
- id: with-embedded-resources
@@ -1079,7 +1048,7 @@ functions:
```c#
var result = await supabase.From<Country>()
.Select("name, cities(name)")
.Filter("name", Operator.Equals, "United States")
.Filter(x => x.Name == "United States")
.Order("cities", "name", Ordering.Descending)
.Get();
```
@@ -1111,7 +1080,7 @@ functions:
code: |
```c#
var result = await supabase.From<City>()
.Select("name, country_id")
.Select(x => new object[] { x.Name, x.CountryId })
.Offset(25)
.Get();
```
@@ -1127,7 +1096,7 @@ functions:
code: |
```c#
var result = await supabase.From<City>()
.Select("name, country_id")
.Select(x => new object[] { x.Name, x.CountryId })
.Single();
```
@@ -1138,19 +1107,15 @@ functions:
Filters can be used on `Select()`, `Update()`, and `Delete()` queries.
If a Database function returns a table response, you can also apply filters.
**Note: LINQ expressions do not currently support parsing embedded resource columns. For these cases, `string` will need to be used.**
examples:
- id: applying-filters
name: Applying Filters
description: |
Filters must be applied after any of `Select()`, `Update()`, `Upsert()`,
`Delete()`, and `rpc()` and before
[modifiers](/docs/reference/csharp/using-modifiers).
code: |
```c#
var result = await supabase.From<City>()
.Select("name, country_id")
.Filter("name", Operator.Equals, "The Shire")
.Select(x => new object[] { x.Name, x.CountryId })
.Where(x => x.Name == "The Shire")
.Single();
```
- id: filter-by-value-within-json-column
@@ -1171,26 +1136,9 @@ functions:
(1, 'Michael', '{ "postcode": 90210 }'),
(2, 'Jane', null);
```
response: |
```json
{
"data": [
{
"id": 1,
"name": "Michael",
"address": {
"postcode": 90210
}
}
],
"status": 200,
"statusText": "OK"
}
```
code: |
```c#
var result = await supabase.From<City>()
.Select("name, country_id")
.Filter("address->postcode", Operator.Equals, 90210)
.Get();
```
@@ -1203,46 +1151,7 @@ functions:
.Filter("cities.name", Operator.Equals, "Bali")
.Get();
```
data:
sql: |
```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');
```
response: |
```json
{
"data": [
{
"name": "Indonesia",
"cities": [
{
"name": "Bali"
}
]
}
],
"status": 200,
"statusText": "OK"
}
```
- id: or
title: Or()
description: |
@@ -1253,33 +1162,17 @@ functions:
isSpotlight: true
code: |
```c#
var filters = new List<QueryFilter>
{
new QueryFilter("id", Operator.Equals, 20),
new QueryFilter("id", Operator.Equals, 30)
};
var result = await supabase.From<Country>()
.Or(filters)
.Where(x => x.Id == 20 || x.Id == 30)
.Get();
```
- id: use-or-with-and
name: Use `or` with `and`
code: |
```c#
var filters = new List<QueryFilter>
{
new QueryFilter("id", Operator.Equals, 20),
new QueryFilter("id", Operator.Equals, 30),
new QueryFilter(Operator.And, new List<QueryFilter>
{
new QueryFilter("name", Operator.Equals, "New Zealand"),
new QueryFilter("name", Operator.Equals, "France")
})
};
var result = await supabase.From<Country>()
.Or(filters)
.Where(x => x.Population > 300000 || x.BirthRate < 0.6)
.Where(x => x.Name != "Mordor")
.Get();
```
@@ -1294,8 +1187,8 @@ functions:
code: |
```c#
var result = await supabase.From<Country>()
.Select("id, name")
.Not("name", Operator.Equals, "Paris")
.Select(x => new object[] { x.Name, x.CountryId })
.Where(x => x.Name != "Paris")
.Get();
```
@@ -1342,17 +1235,9 @@ functions:
code: |
```c#
var result = await supabase.From<City>()
.Filter("name", Operator.Equals, "Bali")
.Where(x => x.Name == "Bali")
.Get();
```
- id: with-delete
name: With `Delete()`
code: |
```dart
await supabase.From<City>()
.Filter("name", Operator.Equals, "Bali")
.Delete();
```
- id: neq
title: Operator.NotEqual
@@ -1365,18 +1250,10 @@ functions:
code: |
```c#
var result = await supabase.From<City>()
.Select("name, country_id")
.Filter("name", Operator.NotEqual, "Bali")
.Select(x => new object[] { x.Name, x.CountryId })
.Where(x => x.Name != "Bali")
.Get();
```
- id: with-delete
name: With `Delete()`
code: |
```c#
await supabase.From<City>()
.Filter("name", Operator.NotEqual, "Bali")
.Delete();
```
- id: gt
title: Operator.GreaterThan
@@ -1389,18 +1266,10 @@ functions:
code: |
```c#
var result = await supabase.From<City>()
.Select("name, country_id")
.Filter("country_id", Operator.GreaterThan, 250)
.Select(x => new object[] { x.Name, x.CountryId })
.Where(x => x.CountryId > 250)
.Get();
```
- id: with-delete
name: With `Delete()`
code: |
```c#
await supabase.From<City>()
.Filter("country_id", Operator.GreaterThan, 250)
.Delete();
```
- id: gte
title: Operator.GreaterThanOrEqual
@@ -1413,18 +1282,10 @@ functions:
code: |
```c#
var result = await supabase.From<City>()
.Select("name, country_id")
.Filter("country_id", Operator.GreaterThanOrEqual, 250)
.Select(x => new object[] { x.Name, x.CountryId })
.Where(x => x.CountryId >= 250)
.Get();
```
- id: with-delete
name: With `Delete()`
code: |
```c#
await supabase.From<City>()
.Filter("country_id", Operator.GreaterThanOrEqual, 250)
.Delete();
```
- id: lt
title: Operator.LessThan
@@ -1438,23 +1299,14 @@ functions:
```c#
var result = await supabase.From<City>()
.Select("name, country_id")
.Filter("country_id", Operator.LessThan, 250)
.Where(x => x.CountryId < 250)
.Get();
```
- id: with-delete
name: With `Delete()`
code: |
```c#
await supabase.From<City>()
.Filter("country_id", Operator.LessThan, 250)
.Delete();
```
- id: lte
title: Operator.LessThanOrEqual
description: |
Finds all rows whose value on the stated `column` is less than or equal to the specified `value`.
$ref: '@supabase/postgrest-js.PostgrestFilterBuilder.lte'
examples:
- id: with-select
name: With `Select()`
@@ -1462,18 +1314,9 @@ functions:
code: |
```c#
var result = await supabase.From<City>()
.Select("name, country_id")
.Filter("country_id", Operator.LessThanOrEqual, 250)
.Where(x => x.CountryId <= 250)
.Get();
```
- id: with-delete
name: With `Delete()`
code: |
```c#
await supabase.From<City>()
.Filter("country_id", Operator.LessThanOrEqual, 250)
.Delete();
```
- id: like
title: Operator.Like
@@ -1486,18 +1329,9 @@ functions:
code: |
```c#
var result = await supabase.From<City>()
.Select("name, country_id")
.Filter("name", Operator.Like, "%la%")
.Filter(x => x.Name, Operator.Like, "%la%")
.Get();
```
- id: with-delete
name: With `Delete()`
code: |
```c#
await supabase.From<City>()
.Filter("name", Operator.Like, "%la%")
.Delete();
```
- id: ilike
title: Operator.ILike
@@ -1510,16 +1344,8 @@ functions:
code: |
```c#
await supabase.From<City>()
.Filter("name", Operator.ILike, "%la%")
.Delete();
```
- id: with-delete
name: With `Delete()`
code: |
```c#
await supabase.From<City>()
.Filter("name", Operator.ILike, "%la%")
.Delete();
.Filter(x => x.Name, Operator.ILike, "%la%")
.Get();
```
- id: is
@@ -1533,18 +1359,9 @@ functions:
code: |
```c#
var result = await supabase.From<City>()
.Select("name, country_id")
.Filter("name", Operator.Is, null)
.Where(x => x.Name == null
.Get();
```
- id: with-delete
name: With `Delete()`
code: |
```c#
await supabase.From<City>()
.Filter("name", Operator.Is, null)
.Delete();
```
- id: in
title: Operator.In
@@ -1557,18 +1374,9 @@ functions:
code: |
```c#
var result = await supabase.From<City>()
.Select("name, country_id")
.Filter("name", Operator.In, new List<object> { "Rio de Janiero", "San Francisco" })
.Filter(x => x.Name, Operator.In, new List<object> { "Rio de Janiero", "San Francisco" })
.Get();
```
- id: with-delete
name: With `Delete()`
code: |
```c#
await supabase.From<City>()
.Filter("name", Operator.In, new List<object> { "Rio de Janiero", "San Francisco" })
.Delete();
```
- id: contains
title: Operator.Contains
@@ -1579,18 +1387,9 @@ functions:
code: |
```c#
var result = await supabase.From<City>()
.Select("name, country_id, main_exports")
.Filter("main_exports", Operator.Contains, new List<object> { "oil", "fish" })
.Filter(x => x.MainExports, Operator.Contains, new List<object> { "oil", "fish" })
.Get();
```
- id: with-delete
name: With `Delete()`
code: |
```c#
await supabase.From<City>()
.Filter("main_exports", Operator.Contains, new List<object> { "oil", "fish" })
.Delete();
```
- id: contained-by
title: Operator.ContainedIn
@@ -1601,18 +1400,9 @@ functions:
code: |
```c#
var result = await supabase.From<City>()
.Select("name, country_id, main_exports")
.Filter("main_exports", Operator.ContainedIn, new List<object> { "oil", "fish" })
.Filter(x => x.MainExports, Operator.ContainedIn, new List<object> { "oil", "fish" })
.Get();
```
- id: with-delete
name: With `Delete()`
code: |
```c#
await supabase.From<City>()
.Filter("main_exports", Operator.ContainedIn, new List<object> { "oil", "fish" })
.Delete();
```
- id: text-search
title: Operator.[FTS,PLFTS,PHFTS,WFTS] (Full Text Search)
@@ -1624,8 +1414,8 @@ functions:
code: |
```c#
var result = await supabase.From<Quote>()
.Select("catchphrase")
.Filter("catchphrase", Operator.FTS, new FullTextSearchConfig("'fat' & 'cat", "english"))
.Select(x => x.Catchphrase)
.Filter(x => x.Catchphrase, Operator.FTS, new FullTextSearchConfig("'fat' & 'cat", "english"))
.Get();
```
- id: basic-normalization
@@ -1634,8 +1424,8 @@ functions:
code: |
```c#
var result = await supabase.From<Quote>()
.Select("catchphrase")
.Filter("catchphrase", Operator.PLFTS, new FullTextSearchConfig("'fat' & 'cat", "english"))
.Select(x => x.Catchphrase)
.Filter(x => x.Catchphrase, Operator.PLFTS, new FullTextSearchConfig("'fat' & 'cat", "english"))
.Get();
```
- id: full-normalization
@@ -1644,8 +1434,8 @@ functions:
code: |
```c#
var result = await supabase.From<Quote>()
.Select("catchphrase")
.Filter("catchphrase", Operator.PHFTS, new FullTextSearchConfig("'fat' & 'cat", "english"))
.Select(x => x.Catchphrase)
.Filter(x => x.Catchphrase, Operator.PHFTS, new FullTextSearchConfig("'fat' & 'cat", "english"))
.Get();
```
- id: web-search
@@ -1663,7 +1453,7 @@ functions:
code: |
```c#
var result = await supabase.From<Quote>()
.Select("catchphrase")
.Filter("catchphrase", Operator.WFTS, new FullTextSearchConfig("'fat' & 'cat", "english"))
.Select(x => x.Catchphrase)
.Filter(x => x.Catchphrase, Operator.WFTS, new FullTextSearchConfig("'fat' & 'cat", "english"))
.Get();
```