From 81f56cb2ba94df98bd5213788d59cb6f245dc7a1 Mon Sep 17 00:00:00 2001 From: Daniel Williams Date: Sat, 25 Jan 2025 20:16:04 +0000 Subject: [PATCH 1/5] Added GetWithCount method --- Postgrest/Interfaces/IPostgrestTable.cs | 9 +++++++++ Postgrest/Table.cs | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/Postgrest/Interfaces/IPostgrestTable.cs b/Postgrest/Interfaces/IPostgrestTable.cs index ca06d5d..8272b24 100644 --- a/Postgrest/Interfaces/IPostgrestTable.cs +++ b/Postgrest/Interfaces/IPostgrestTable.cs @@ -119,6 +119,15 @@ IPostgrestTable Filter(Expression> pred /// Task> Get(CancellationToken cancellationToken = default); + /// + /// Executes the query using the defined filters on the current instance, along with count from the specified query. + /// + /// The kind of count. + /// + /// + Task, int>> GetWithCount(Constants.CountType type, + CancellationToken cancellationToken = default); + /// /// Executes a BULK INSERT query using the defined query params on the current instance. /// diff --git a/Postgrest/Table.cs b/Postgrest/Table.cs index 58b3f8c..cce8ad5 100644 --- a/Postgrest/Table.cs +++ b/Postgrest/Table.cs @@ -634,6 +634,26 @@ public Task> Get(CancellationToken cancellationToken = d Clear(); return request; } + + /// + public async Task, int>> GetWithCount(CountType type, CancellationToken cancellationToken = default) + { + var attr = type.GetAttribute(); + + var headers = new Dictionary + { + { "Prefer", $"count={attr?.Mapping}" } + }; + + var request = Send(_method, null, headers, cancellationToken); + Clear(); + + var response = await request; + var countStr = response.ResponseMessage?.Content.Headers.GetValues("Content-Range").FirstOrDefault(); + var count = int.Parse(countStr?.Split('/')[1] ?? throw new InvalidOperationException()); + + return new Tuple, int>(response.Models, count); + } /// /// Generates the encoded URL with defined query parameters that will be sent to the Postgrest API. From 09c2ad5e1d720adfe78a6fe7159bcd4202ab3972 Mon Sep 17 00:00:00 2001 From: Daniel Williams Date: Sat, 25 Jan 2025 20:40:44 +0000 Subject: [PATCH 2/5] Made improvements --- Postgrest/Interfaces/IPostgrestTable.cs | 2 +- Postgrest/Table.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Postgrest/Interfaces/IPostgrestTable.cs b/Postgrest/Interfaces/IPostgrestTable.cs index 8272b24..cbbfe56 100644 --- a/Postgrest/Interfaces/IPostgrestTable.cs +++ b/Postgrest/Interfaces/IPostgrestTable.cs @@ -125,7 +125,7 @@ IPostgrestTable Filter(Expression> pred /// The kind of count. /// /// - Task, int>> GetWithCount(Constants.CountType type, + Task<(ModeledResponse Result, int Count)> GetWithCount(Constants.CountType type, CancellationToken cancellationToken = default); /// diff --git a/Postgrest/Table.cs b/Postgrest/Table.cs index cce8ad5..4639608 100644 --- a/Postgrest/Table.cs +++ b/Postgrest/Table.cs @@ -636,7 +636,7 @@ public Task> Get(CancellationToken cancellationToken = d } /// - public async Task, int>> GetWithCount(CountType type, CancellationToken cancellationToken = default) + public async Task<(ModeledResponse Result, int Count)>GetWithCount(CountType type, CancellationToken cancellationToken = default) { var attr = type.GetAttribute(); @@ -652,7 +652,7 @@ public async Task, int>> GetWithCount(CountType type, Cancell var countStr = response.ResponseMessage?.Content.Headers.GetValues("Content-Range").FirstOrDefault(); var count = int.Parse(countStr?.Split('/')[1] ?? throw new InvalidOperationException()); - return new Tuple, int>(response.Models, count); + return (response, count); } /// From 79c92b67f4cc8e9bb847129ea7b588944e5a4474 Mon Sep 17 00:00:00 2001 From: Daniel Williams Date: Sat, 1 Feb 2025 17:29:18 +0000 Subject: [PATCH 3/5] Changed existing get method to retrieve count, added count to modeledresponse --- Postgrest/Interfaces/IPostgrestTable.cs | 12 ++---------- Postgrest/Responses/ModeledResponse.cs | 8 ++++++++ Postgrest/Table.cs | 16 ++-------------- 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/Postgrest/Interfaces/IPostgrestTable.cs b/Postgrest/Interfaces/IPostgrestTable.cs index cbbfe56..eb480ef 100644 --- a/Postgrest/Interfaces/IPostgrestTable.cs +++ b/Postgrest/Interfaces/IPostgrestTable.cs @@ -116,17 +116,9 @@ IPostgrestTable Filter(Expression> pred /// Executes the query using the defined filters on the current instance. /// /// + /// /// - Task> Get(CancellationToken cancellationToken = default); - - /// - /// Executes the query using the defined filters on the current instance, along with count from the specified query. - /// - /// The kind of count. - /// - /// - Task<(ModeledResponse Result, int Count)> GetWithCount(Constants.CountType type, - CancellationToken cancellationToken = default); + Task> Get(CancellationToken cancellationToken = default, Constants.CountType countType = Constants.CountType.Estimated); /// /// Executes a BULK INSERT query using the defined query params on the current instance. diff --git a/Postgrest/Responses/ModeledResponse.cs b/Postgrest/Responses/ModeledResponse.cs index 7a79742..2fa9098 100644 --- a/Postgrest/Responses/ModeledResponse.cs +++ b/Postgrest/Responses/ModeledResponse.cs @@ -24,6 +24,11 @@ namespace Supabase.Postgrest.Responses /// A list of models in the response. /// public List Models { get; } = new(); + + /// + /// The number of results matching the specified filters + /// + public int Count = 0; /// public ModeledResponse(BaseResponse baseResponse, JsonSerializerSettings serializerSettings, Func>? getHeaders = null, bool shouldParse = true) : base(baseResponse.ClientOptions, baseResponse.ResponseMessage, baseResponse.Content) @@ -71,6 +76,9 @@ public ModeledResponse(BaseResponse baseResponse, JsonSerializerSettings seriali break; } } + + var countStr = baseResponse.ResponseMessage?.Content.Headers.GetValues("Content-Range").FirstOrDefault(); + Count = int.Parse(countStr?.Split('/')[1] ?? throw new InvalidOperationException()); Debugger.Instance.Log(this, $"Response: [{baseResponse.ResponseMessage?.StatusCode}]\n" + $"Parsed Models <{typeof(T).Name}>:\n\t{JsonConvert.SerializeObject(Models)}\n"); } diff --git a/Postgrest/Table.cs b/Postgrest/Table.cs index 4639608..47c2732 100644 --- a/Postgrest/Table.cs +++ b/Postgrest/Table.cs @@ -628,15 +628,7 @@ public async Task Count(CountType type, CancellationToken cancellationToken } /// - public Task> Get(CancellationToken cancellationToken = default) - { - var request = Send(_method, null, null, cancellationToken); - Clear(); - return request; - } - - /// - public async Task<(ModeledResponse Result, int Count)>GetWithCount(CountType type, CancellationToken cancellationToken = default) + public Task> Get(CancellationToken cancellationToken = default, CountType type = CountType.Estimated) { var attr = type.GetAttribute(); @@ -648,11 +640,7 @@ public Task> Get(CancellationToken cancellationToken = d var request = Send(_method, null, headers, cancellationToken); Clear(); - var response = await request; - var countStr = response.ResponseMessage?.Content.Headers.GetValues("Content-Range").FirstOrDefault(); - var count = int.Parse(countStr?.Split('/')[1] ?? throw new InvalidOperationException()); - - return (response, count); + return request; } /// From c3c8b60d52ad49f7fb72254800ab55b6d9cfc318 Mon Sep 17 00:00:00 2001 From: Daniel Williams Date: Sat, 1 Feb 2025 17:48:20 +0000 Subject: [PATCH 4/5] Fixed issue when making non get requests --- Postgrest/Responses/ModeledResponse.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Postgrest/Responses/ModeledResponse.cs b/Postgrest/Responses/ModeledResponse.cs index 2fa9098..02644f6 100644 --- a/Postgrest/Responses/ModeledResponse.cs +++ b/Postgrest/Responses/ModeledResponse.cs @@ -76,9 +76,18 @@ public ModeledResponse(BaseResponse baseResponse, JsonSerializerSettings seriali break; } } - - var countStr = baseResponse.ResponseMessage?.Content.Headers.GetValues("Content-Range").FirstOrDefault(); - Count = int.Parse(countStr?.Split('/')[1] ?? throw new InvalidOperationException()); + + try + { + var countStr = baseResponse.ResponseMessage?.Content.Headers.GetValues("Content-Range") + .FirstOrDefault(); + Count = int.Parse(countStr?.Split('/')[1] ?? throw new InvalidOperationException()); + } + catch (Exception e) + { + Debugger.Instance.Log(this, e.Message); + Count = -1; + } Debugger.Instance.Log(this, $"Response: [{baseResponse.ResponseMessage?.StatusCode}]\n" + $"Parsed Models <{typeof(T).Name}>:\n\t{JsonConvert.SerializeObject(Models)}\n"); } From f56a2bcba248650fc58291769427a2f4a5e43124 Mon Sep 17 00:00:00 2001 From: Daniel Williams Date: Sat, 1 Feb 2025 17:56:05 +0000 Subject: [PATCH 5/5] Added tests --- PostgrestTests/ClientTests.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/PostgrestTests/ClientTests.cs b/PostgrestTests/ClientTests.cs index 47bd4c6..b3541b3 100644 --- a/PostgrestTests/ClientTests.cs +++ b/PostgrestTests/ClientTests.cs @@ -1041,6 +1041,24 @@ public async Task TestCountWithFilter() Assert.IsNotNull(resp); } + [TestMethod("response count")] + public async Task TestCountInResponse() + { + var client = new Client(BaseUrl); + + var resp = await client.Table().Get(default, CountType.Exact); + Assert.IsTrue(resp.Count > -1); + } + + [TestMethod("response count: with filter")] + public async Task TestCountInResponseWithFilter() + { + var client = new Client(BaseUrl); + + var resp = await client.Table().Filter("status", Operator.Equals, "ONLINE").Get(default, CountType.Exact); + Assert.IsTrue(resp.Count > -1); + } + [TestMethod("support: int arrays")] public async Task TestSupportIntArraysAsLists() {