Skip to content

Commit

Permalink
✨ add Patch/PatchAll methods (surrealdb#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
Odonno authored Dec 1, 2023
1 parent 8501a92 commit ad17e5c
Show file tree
Hide file tree
Showing 17 changed files with 348 additions and 50 deletions.
38 changes: 22 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,12 @@ public class WeatherForecastController : ControllerBase
}

[HttpGet]
[Route("/")]
public Task<List<WeatherForecast>> GetAll(CancellationToken cancellationToken)
public Task<IEnumerable<WeatherForecast>> GetAll(CancellationToken cancellationToken)
{
return _surrealDbClient.Select<WeatherForecast>(Table, cancellationToken);
}

[HttpGet]
[Route("/{id}")]
[HttpGet("{id}")]
public async Task<IActionResult> Get(string id, CancellationToken cancellationToken)
{
var weatherForecast = await _surrealDbClient.Select<WeatherForecast>(Table, id, cancellationToken);
Expand All @@ -177,7 +175,6 @@ public class WeatherForecastController : ControllerBase
}

[HttpPost]
[Route("/")]
public Task<WeatherForecast> Create(CreateWeatherForecast data, CancellationToken cancellationToken)
{
var weatherForecast = new WeatherForecast
Expand All @@ -192,30 +189,39 @@ public class WeatherForecastController : ControllerBase
}

[HttpPut]
[Route("/")]
public Task<WeatherForecast> Update(WeatherForecast data, CancellationToken cancellationToken)
{
return _surrealDbClient.Upsert(data, cancellationToken);
}

[HttpPatch]
[Route("/{id}")]
public Task<WeatherForecast> Patch(string id, Dictionary<string, object> data, CancellationToken cancellationToken)
{
var thing = new Thing(Table, id);
[HttpPatch]
public Task<IEnumerable<WeatherForecast>> PatchAll(
JsonPatchDocument<WeatherForecast> patches,
CancellationToken cancellationToken
)
{
return _surrealDbClient.PatchAll(Table, patches, cancellationToken);
}

return _surrealDbClient.Patch<WeatherForecast>(thing, data, cancellationToken);
}
[HttpPatch("{id}")]
public Task<WeatherForecast> Patch(
string id,
JsonPatchDocument<WeatherForecast> patches,
CancellationToken cancellationToken
)
{
var thing = new Thing(Table, id);

return _surrealDbClient.Patch(thing, patches, cancellationToken);
}

[HttpDelete]
[Route("/")]
public Task DeleteAll(CancellationToken cancellationToken)
{
return _surrealDbClient.Delete(Table, cancellationToken);
}

[HttpDelete]
[Route("/{id}")]
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(string id, CancellationToken cancellationToken)
{
bool success = await _surrealDbClient.Delete(Table, id, cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using SurrealDb.Examples.WeatherApi.Models;
using SurrealDb.Net;
using SurrealDb.Net.Models;
using SystemTextJsonPatch;

namespace SurrealDb.Examples.WeatherApi.Controllers;

Expand All @@ -12,7 +13,7 @@ namespace SurrealDb.Examples.WeatherApi.Controllers;
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private const string Table = "weatherForecast";
internal const string Table = "weatherForecast";

private readonly ISurrealDbClient _surrealDbClient;

Expand All @@ -28,7 +29,6 @@ public WeatherForecastController(ISurrealDbClient surrealDbClient)
/// Get all weather forecasts.
/// </summary>
[HttpGet]
[Route("/")]
public Task<IEnumerable<WeatherForecast>> GetAll(CancellationToken cancellationToken)
{
return _surrealDbClient.Select<WeatherForecast>(Table, cancellationToken);
Expand All @@ -37,8 +37,7 @@ public Task<IEnumerable<WeatherForecast>> GetAll(CancellationToken cancellationT
/// <summary>
/// Get a weather forecast by id.
/// </summary>
[HttpGet]
[Route("/{id}")]
[HttpGet("{id}")]
public async Task<IActionResult> Get(string id, CancellationToken cancellationToken)
{
var weatherForecast = await _surrealDbClient.Select<WeatherForecast>(
Expand All @@ -57,7 +56,6 @@ public async Task<IActionResult> Get(string id, CancellationToken cancellationTo
/// Creates a new weather forecast.
/// </summary>
[HttpPost]
[Route("/")]
public Task<WeatherForecast> Create(
CreateWeatherForecast data,
CancellationToken cancellationToken
Expand All @@ -78,33 +76,41 @@ CancellationToken cancellationToken
/// Updates an existing weather forecast.
/// </summary>
[HttpPut]
[Route("/")]
public Task<WeatherForecast> Update(WeatherForecast data, CancellationToken cancellationToken)
{
return _surrealDbClient.Upsert(data, cancellationToken);
}

/// <summary>
/// Patches an existing weather forecast.
/// Patches all weather forecasts.
/// </summary>
[HttpPatch]
[Route("/{id}")]
public Task<IEnumerable<WeatherForecast>> PatchAll(
JsonPatchDocument<WeatherForecast> patches,
CancellationToken cancellationToken
)
{
return _surrealDbClient.PatchAll(Table, patches, cancellationToken);
}

/// <summary>
/// Patches an existing weather forecast.
/// </summary>
[HttpPatch("{id}")]
public Task<WeatherForecast> Patch(
string id,
Dictionary<string, object> data,
JsonPatchDocument<WeatherForecast> patches,
CancellationToken cancellationToken
)
{
var thing = new Thing(Table, id);

return _surrealDbClient.Merge<WeatherForecast>(thing, data, cancellationToken);
return _surrealDbClient.Patch(thing, patches, cancellationToken);
}

/// <summary>
/// Deletes all weather forecasts.
/// </summary>
[HttpDelete]
[Route("/")]
public Task DeleteAll(CancellationToken cancellationToken)
{
return _surrealDbClient.Delete(Table, cancellationToken);
Expand All @@ -113,8 +119,7 @@ public Task DeleteAll(CancellationToken cancellationToken)
/// <summary>
/// Deletes a weather forecast by id.
/// </summary>
[HttpDelete]
[Route("/{id}")]
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(string id, CancellationToken cancellationToken)
{
bool success = await _surrealDbClient.Delete(Table, id, cancellationToken);
Expand Down
22 changes: 14 additions & 8 deletions SurrealDb.Examples.WeatherApi/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Models;
using SurrealDb.Net;
using SurrealDb.Examples.WeatherApi.Controllers;
using SurrealDb.Examples.WeatherApi.Models;
using System.Reflection;

Expand Down Expand Up @@ -33,16 +34,21 @@

app.MapControllers();

using (var scope = app.Services.CreateScope())
app.Run();

await InitializeDbAsync(app.Services);

async Task InitializeDbAsync(IServiceProvider serviceProvider)
{
using var scope = serviceProvider.CreateScope();

int initialCount = 5;
var weatherForecasts = new WeatherForecastFaker().Generate(initialCount);
var surrealDbClient = scope.ServiceProvider.GetRequiredService<ISurrealDbClient>();

foreach (var weatherForecast in weatherForecasts)
{
await surrealDbClient.Create("weatherForecast", weatherForecast);
}
}
var tasks = weatherForecasts.Select(
weatherForecast => surrealDbClient.Create(WeatherForecastController.Table, weatherForecast)
);

app.Run();
await Task.WhenAll(tasks);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<ItemGroup>
<PackageReference Include="Bogus" Version="34.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="SystemTextJsonPatch" Version="3.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion SurrealDb.Examples.WeatherApi/appsettings.Development.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
}
},
"ConnectionStrings": {
"SurrealDB": "Server=http://127.0.0.1:8000;Namespace=test;Database=test;Username=root;Password=root"
"SurrealDB": "Server=ws://127.0.0.1:8000/rpc;Namespace=test;Database=test;Username=root;Password=root"
}
}
12 changes: 8 additions & 4 deletions SurrealDb.Net.LiveQuery.Tests/LiveTableTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using SurrealDb.Net.LiveQuery.Tests.Abstract;
using SurrealDb.Net.LiveQuery.Tests.Models;
using SurrealDb.Net.Models.LiveQuery;
using JsonPatchOperations = System.Collections.Immutable.IImmutableList<Microsoft.AspNetCore.JsonPatch.Operations.Operation>;
using SystemTextJsonPatch;

namespace SurrealDb.Net.LiveQuery.Tests;

Expand Down Expand Up @@ -119,7 +119,7 @@ public async Task ShouldReceiveDataInJsonPatchFormat()
await client.SignIn(new RootAuth { Username = "root", Password = "root" });
await client.Use(dbInfo.Namespace, dbInfo.Database);

var liveQuery = await client.LiveTable<JsonPatchOperations>("test", true);
var liveQuery = await client.LiveTable<JsonPatchDocument<TestRecord>>("test", true);

var cts = new CancellationTokenSource();

Expand Down Expand Up @@ -167,10 +167,14 @@ public async Task ShouldReceiveDataInJsonPatchFormat()
firstResult.Should().BeOfType<SurrealDbLiveQueryOpenResponse>();

var secondResult = allResults[1];
secondResult.Should().BeOfType<SurrealDbLiveQueryCreateResponse<JsonPatchOperations>>();
secondResult
.Should()
.BeOfType<SurrealDbLiveQueryCreateResponse<JsonPatchDocument<TestRecord>>>();

var thirdResult = allResults[2];
thirdResult.Should().BeOfType<SurrealDbLiveQueryUpdateResponse<JsonPatchOperations>>();
thirdResult
.Should()
.BeOfType<SurrealDbLiveQueryUpdateResponse<JsonPatchDocument<TestRecord>>>();

var fourthResult = allResults[3];
fourthResult.Should().BeOfType<SurrealDbLiveQueryDeleteResponse>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Microsoft.Reactive.Testing" Version="6.0.0" />
<PackageReference Include="System.Interactive.Async" Version="6.0.1" />
<PackageReference Include="SystemTextJsonPatch" Version="3.0.1" />
<PackageReference Include="xunit" Version="2.6.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
8 changes: 4 additions & 4 deletions SurrealDb.Net.Tests/MergeAllTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ namespace SurrealDb.Net.Tests;
public class MergeAllTests
{
[Theory]
[InlineData("http://localhost:8000")]
[InlineData("ws://localhost:8000/rpc")]
[InlineData("http://127.0.0.1:8000")]
[InlineData("ws://127.0.0.1:8000/rpc")]
public async Task ShouldMergeAllRecords(string url)
{
IEnumerable<Post>? list = null;
Expand Down Expand Up @@ -57,8 +57,8 @@ public async Task ShouldMergeAllRecords(string url)
}

[Theory]
[InlineData("http://localhost:8000")]
[InlineData("ws://localhost:8000/rpc")]
[InlineData("http://127.0.0.1:8000")]
[InlineData("ws://127.0.0.1:8000/rpc")]
public async Task ShouldMergeAllRecordsUsingDictionary(string url)
{
IEnumerable<Post>? list = null;
Expand Down
64 changes: 64 additions & 0 deletions SurrealDb.Net.Tests/PatchAllTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System.Text;
using SurrealDb.Net.Internals.Json;
using SystemTextJsonPatch;

namespace SurrealDb.Net.Tests;

public class PatchAllTests
{
[Theory]
[InlineData("http://127.0.0.1:8000")]
[InlineData("ws://127.0.0.1:8000/rpc")]
public async Task ShouldPatchAllRecords(string url)
{
IEnumerable<Post>? list = null;
IEnumerable<Post>? results = null;

Func<Task> func = async () =>
{
await using var surrealDbClientGenerator = new SurrealDbClientGenerator();
var dbInfo = surrealDbClientGenerator.GenerateDatabaseInfo();

string filePath = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"Schemas/post.surql"
);
string fileContent = File.ReadAllText(filePath, Encoding.UTF8);

string query = fileContent;

using var client = surrealDbClientGenerator.Create(url);
await client.SignIn(new RootAuth { Username = "root", Password = "root" });
await client.Use(dbInfo.Namespace, dbInfo.Database);
await client.Query(query);

var jsonPatchDocument = new JsonPatchDocument<Post>
{
Options = SurrealDbSerializerOptions.Default
};
jsonPatchDocument.Replace(x => x.Content, "[Edit] Oops");

list = await client.Select<Post>("post");

results = await client.PatchAll("post", jsonPatchDocument);
};

await func.Should().NotThrowAsync();

list.Should().NotBeNull().And.HaveCount(2);

var expected = list!.Select(
item =>
new Post
{
Id = item.Id,
Title = item.Title,
Content = "[Edit] Oops",
CreatedAt = item.CreatedAt,
Status = item.Status,
}
);

results.Should().BeEquivalentTo(expected);
}
}
Loading

0 comments on commit ad17e5c

Please sign in to comment.