Skip to content

Commit af3da75

Browse files
committed
Update Watch to also support dynamic results
1 parent 144ce7d commit af3da75

4 files changed

Lines changed: 76 additions & 2 deletions

File tree

PowerSync/PowerSync.Common/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# PowerSync.Common Changelog
22

3+
## 0.0.8-alpha.1
4+
- Replaced the old JSON-based method of extracting type information from queries with using Dapper internally for queries, improving memory usage and execution time for querying.
5+
- Added non-generic overloads for `GetAll()`, `GetOptional()`, `Get()`, `Watch()` which return `dynamic`:
6+
7+
```csharp
8+
dynamic asset = db.Get("SELECT id, description, make FROM assets");
9+
Console.WriteLine($"Asset ID: {asset.id}");
10+
```
11+
312
## 0.0.7-alpha.1
413
- Added fallback to check the application's root directory for the PowerSync extension - fixing compatibility with WPF/WAP, .NET Framework <= 4.8, and other platforms that flatten DLLs into the base folder.
514
- Added `ExecuteBatch()` implementation.

PowerSync/PowerSync.Common/Client/PowerSyncDatabase.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,24 @@ public async Task<T> WriteTransaction<T>(Func<ITransaction, Task<T>> fn, DBLockO
672672
/// Source tables are automatically detected using <c>EXPLAIN QUERY PLAN</c>.
673673
/// </summary>
674674
public Task Watch<T>(string query, object?[]? parameters, WatchHandler<T> handler, SQLWatchOptions? options = null)
675+
=> WatchInternal(query, parameters, handler, options, GetAll<T>);
676+
677+
/// <summary>
678+
/// Executes a read query every time the source tables are modified.
679+
/// <para />
680+
/// Use <see cref="SQLWatchOptions.ThrottleMs"/> to specify the minimum interval between queries.
681+
/// Source tables are automatically detected using <c>EXPLAIN QUERY PLAN</c>.
682+
/// </summary>
683+
public Task Watch(string query, object?[]? parameters, WatchHandler<dynamic> handler, SQLWatchOptions? options = null)
684+
=> WatchInternal(query, parameters, handler, options, GetAll);
685+
686+
private Task WatchInternal<T>(
687+
string query,
688+
object?[]? parameters,
689+
WatchHandler<T> handler,
690+
SQLWatchOptions? options,
691+
Func<string, object?[]?, Task<T[]>> getter
692+
)
675693
{
676694
var tcs = new TaskCompletionSource<bool>();
677695
Task.Run(async () =>
@@ -688,7 +706,7 @@ public Task Watch<T>(string query, object?[]? parameters, WatchHandler<T> handle
688706
{
689707
try
690708
{
691-
var result = await GetAll<T>(query, parameters);
709+
var result = await getter(query, parameters);
692710
handler.OnResult(result);
693711
}
694712
catch (Exception ex)

PowerSync/PowerSync.Maui/CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# PowerSync.Maui Changelog
22

3+
## 0.0.6-alpha.1
4+
- Upstream PowerSync.Common version bump (See Powersync.Common changelog 0.0.8-alpha.1 for more information)
5+
36
## 0.0.5-alpha.1
47
- Upstream PowerSync.Common version bump (See Powersync.Common changelog 0.0.7-alpha.1 for more information)
58

@@ -20,4 +23,4 @@
2023

2124
### Platform Runtime Support Added
2225
* MAUI iOS
23-
* MAUI Android
26+
* MAUI Android

Tests/PowerSync/PowerSync.Common.Tests/Client/PowerSyncDatabaseTests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,4 +524,48 @@ await db.Execute(
524524
Assert.Equal(description, dynamicAsset.description);
525525
Assert.Equal(make, dynamicAsset.make);
526526
}
527+
528+
[Fact(Timeout = 2000)]
529+
public async Task DynamicWatchTest()
530+
{
531+
string id = Guid.NewGuid().ToString();
532+
string description = "new description";
533+
string make = "some make";
534+
535+
var watched = new TaskCompletionSource<bool>();
536+
var cts = new CancellationTokenSource();
537+
538+
await db.Watch("select id, description, make from assets", null, new WatchHandler<dynamic>
539+
{
540+
OnResult = (assets) =>
541+
{
542+
// Only care about results after Execute is called
543+
if (assets.Length == 0) return;
544+
545+
Assert.Single(assets);
546+
dynamic dynamicAsset = assets[0];
547+
Assert.Equal(id, dynamicAsset.id);
548+
Assert.Equal(description, dynamicAsset.description);
549+
Assert.Equal(make, dynamicAsset.make);
550+
551+
watched.SetResult(true);
552+
cts.Cancel();
553+
},
554+
OnError = (ex) => throw ex,
555+
},
556+
new SQLWatchOptions
557+
{
558+
Signal = cts.Token
559+
});
560+
561+
await db.WriteTransaction(async tx =>
562+
{
563+
await tx.Execute(
564+
"insert into assets (id, description, make) values (?, ?, ?)",
565+
[id, description, make]
566+
);
567+
});
568+
569+
await watched.Task;
570+
}
527571
}

0 commit comments

Comments
 (0)