From f9ddcbdc25876b04411b1f21326ec7a88d074745 Mon Sep 17 00:00:00 2001 From: Arthur Date: Wed, 6 Nov 2024 00:47:46 +0200 Subject: [PATCH] Add read level support for queries and unit tests --- RqliteDotnet.Test/UrlBuilderTests.cs | 28 ++++++++++++++++++++++++++++ RqliteDotnet/IRqliteClient.cs | 3 ++- RqliteDotnet/ReadLevel.cs | 11 +++++++++++ RqliteDotnet/RqliteClient.cs | 7 +++---- RqliteDotnet/UrlBuilder.cs | 26 ++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 RqliteDotnet.Test/UrlBuilderTests.cs create mode 100644 RqliteDotnet/ReadLevel.cs create mode 100644 RqliteDotnet/UrlBuilder.cs diff --git a/RqliteDotnet.Test/UrlBuilderTests.cs b/RqliteDotnet.Test/UrlBuilderTests.cs new file mode 100644 index 0000000..bb54265 --- /dev/null +++ b/RqliteDotnet.Test/UrlBuilderTests.cs @@ -0,0 +1,28 @@ +using NUnit.Framework; + +namespace RqliteDotnet.Test; + +public class UrlBuilderTests +{ + [Test] + public void UrlBuilder_BuildsCorrectUrl() + { + var query = "select * from foo"; + var baseUrl = "/db/query?timings"; + var url = UrlBuilder.Build(baseUrl, query, ReadLevel.Default); + + Assert.That(url.StartsWith(baseUrl)); + Assert.That(url, Is.EqualTo("/db/query?timings&q=select%20%2A%20from%20foo")); + } + + [Test] + public void UrlBuilder_BuildsCorrectUrlWithReadLevel() + { + var query = "select * from foo"; + var baseUrl = "/db/query?timings"; + var url = UrlBuilder.Build(baseUrl, query, ReadLevel.Strong); + + Assert.That(url.StartsWith(baseUrl)); + Assert.That(url, Is.EqualTo("/db/query?timings&q=select%20%2A%20from%20foo&level=strong")); + } +} \ No newline at end of file diff --git a/RqliteDotnet/IRqliteClient.cs b/RqliteDotnet/IRqliteClient.cs index da946b2..a885055 100644 --- a/RqliteDotnet/IRqliteClient.cs +++ b/RqliteDotnet/IRqliteClient.cs @@ -14,9 +14,10 @@ public interface IRqliteClient /// Query DB and return result /// /// Query to run + /// /// /// - Task Query(string query, CancellationToken cancellationToken); + Task Query(string query, ReadLevel level, CancellationToken cancellationToken); /// /// Execute command and return result diff --git a/RqliteDotnet/ReadLevel.cs b/RqliteDotnet/ReadLevel.cs new file mode 100644 index 0000000..e4f3929 --- /dev/null +++ b/RqliteDotnet/ReadLevel.cs @@ -0,0 +1,11 @@ +namespace RqliteDotnet; + +public enum ReadLevel +{ + Default = 1, + Weak, + Linearizable, + Strong, + None, + Auto +} \ No newline at end of file diff --git a/RqliteDotnet/RqliteClient.cs b/RqliteDotnet/RqliteClient.cs index d96d829..218cac1 100644 --- a/RqliteDotnet/RqliteClient.cs +++ b/RqliteDotnet/RqliteClient.cs @@ -33,12 +33,11 @@ public async Task Ping(CancellationToken cancellationToken = default) } /// - public async Task Query(string query, CancellationToken cancellationToken = default) + public async Task Query(string query, ReadLevel level = ReadLevel.Default, CancellationToken cancellationToken = default) { - var data = "&q=" + Uri.EscapeDataString(query); - var baseUrl = "/db/query?timings"; + var url = UrlBuilder.Build("/db/query?timings", query, level); - var r = await _httpClient.GetAsync($"{baseUrl}&{data}", cancellationToken); + var r = await _httpClient.GetAsync(url, cancellationToken); var str = await r.Content.ReadAsStringAsync(cancellationToken); var result = JsonSerializer.Deserialize(str, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true }); diff --git a/RqliteDotnet/UrlBuilder.cs b/RqliteDotnet/UrlBuilder.cs new file mode 100644 index 0000000..8b0516f --- /dev/null +++ b/RqliteDotnet/UrlBuilder.cs @@ -0,0 +1,26 @@ +namespace RqliteDotnet; + +public static class UrlBuilder +{ + public static string Build(string baseUrl, string query, ReadLevel level) + { + var data = "&q=" + Uri.EscapeDataString(query); + var readLevelParam = GetReadLevel(level); + + return $"{baseUrl}{data}{readLevelParam}"; + } + + private static string GetReadLevel(ReadLevel level) + { + var result = level switch + { + ReadLevel.Default => "", + ReadLevel.Weak => "&level=weak", + ReadLevel.Linearizable => "&level=linearizable", + ReadLevel.Strong => "&level=strong", + ReadLevel.None => "&level=none", + ReadLevel.Auto => "&level=auto" + }; + return result; + } +} \ No newline at end of file