Skip to content

Commit

Permalink
partially implemented search functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
petefox committed Nov 25, 2023
1 parent 057bfa8 commit 528c078
Show file tree
Hide file tree
Showing 16 changed files with 207 additions and 12 deletions.
3 changes: 1 addition & 2 deletions src/Close/CloseClient.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Close.Helpers;
using Close.Models;
using Close.Models;

namespace Close;

Expand Down
28 changes: 23 additions & 5 deletions src/Close/CloseRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class CloseRequest<TEntity> where TEntity : ICloseEntity
private readonly JsonSerializerOptions _jsonSerializerOptions = new()
{
Converters = { new JsonStringEnumConverter() },
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};

public CloseRequest(CloseClient closeClient, string endpoint)
Expand All @@ -27,9 +27,11 @@ public CloseRequest(CloseClient closeClient, string endpoint)

internal async Task<T> GetEntityAsync<T>(string id, CancellationToken cancellationToken) where T : TEntity
{
var uri = _httpClient.InstanceUrl(_endpoint, id);

var request = new HttpRequestMessage()
{
RequestUri = _httpClient.InstanceUrl(_endpoint, id),
RequestUri = uri,
Method = HttpMethod.Get,
};

Expand Down Expand Up @@ -91,14 +93,30 @@ internal async Task DeleteEntityAsync(string id, CancellationToken cancellationT
};

var response = await _httpClient.SendAsync(request, cancellationToken);
await response.HandleErrorResponseAsync(request);
await response.HandleErrorResponseAsync(request, cancellationToken);
}

public async Task<SearchResults<T>> SearchAsync<T, TT>(TT query, CancellationToken cancellationToken) where T : TEntity where TT : SearchRequest
{
var content = JsonContent.Create(query, options: _jsonSerializerOptions);
await content.LoadIntoBufferAsync();

var request = new HttpRequestMessage()
{
RequestUri = _httpClient.ClassUrl("data/search"),
Method = HttpMethod.Post,
Content = content,
};

return await SendAsync<SearchResults<T>>(request, cancellationToken);
}

private async Task<T> SendAsync<T>(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await _httpClient.SendAsync(request, cancellationToken);
await response.HandleErrorResponseAsync(request);
return await response.Content.ReadFromJsonAsync<T>(_jsonSerializerOptions);
var stringResponse = await response.Content.ReadAsStringAsync(cancellationToken:cancellationToken);
await response.HandleErrorResponseAsync(request, cancellationToken);
var result = JsonSerializer.Deserialize<T>(stringResponse, _jsonSerializerOptions);
return result;
}
}
13 changes: 13 additions & 0 deletions src/Close/CloseService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,18 @@ public virtual async Task DeleteAsync(string id, CancellationToken cancellationT
}

#endregion

#region SEARCH

public virtual async Task<SearchResults<TEntity>> SearchAsync<T>(T query, CancellationToken cancellationToken = default) where T : SearchRequest
{
return await CloseRequest.SearchAsync<TEntity, T>(query, cancellationToken);
}

public virtual async Task<SearchResults<T>> SearchAsync<T, TT>(TT query, CancellationToken cancellationToken = default) where T : TEntity where TT : SearchRequest
{
return await CloseRequest.SearchAsync<T, TT>(query, cancellationToken);
}

#endregion
}
2 changes: 1 addition & 1 deletion src/Close/Extensions/UriExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ internal static Uri InstanceUrl(this HttpClient httpClient, string endpoint, str
throw new ArgumentException("The resource ID cannot be null or empty.", nameof(id));

var builder = new UriBuilder(httpClient.ClassUrl(endpoint));
builder.Path += id;
builder.Path += $"{id}/";

return builder.Uri;
}
Expand Down
6 changes: 3 additions & 3 deletions src/Close/Helpers/HttpErrorHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ namespace Close.Helpers;

public static class HttpErrorHandler
{
public static async Task HandleErrorResponseAsync(this HttpResponseMessage httpResponseMessage, HttpRequestMessage httpRequestMessage)
public static async Task HandleErrorResponseAsync(this HttpResponseMessage httpResponseMessage, HttpRequestMessage httpRequestMessage, CancellationToken ct)
{
if (!httpResponseMessage.IsSuccessStatusCode)
{
string payload = null;
if (httpRequestMessage.Content?.Headers.ContentType?.MediaType == "application/json")
{
payload = await httpRequestMessage.Content.ReadAsStringAsync();
payload = await httpRequestMessage.Content.ReadAsStringAsync(ct);
}

var responseString = await httpResponseMessage.Content.ReadAsStringAsync();
var responseString = await httpResponseMessage.Content.ReadAsStringAsync(ct);

if (httpResponseMessage.Content.Headers.ContentType?.MediaType == "application/json" && !string.IsNullOrEmpty(responseString))
{
Expand Down
12 changes: 12 additions & 0 deletions src/Close/Models/Condition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Text.Json.Serialization;

namespace Close.Models;

public class Condition
{
[JsonPropertyName("type")]
public string Type { get; set; }

[JsonPropertyName("values")]
public List<string> Values { get; set; }
}
4 changes: 4 additions & 0 deletions src/Close/Models/Enums/EmailType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@ public enum EmailType
office,
home,
direct,
work,
fax,
url,
mobile,
other
}
6 changes: 6 additions & 0 deletions src/Close/Models/Enums/FieldType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Close.Models.Enums;

public enum FieldType
{
regular_field
}
6 changes: 6 additions & 0 deletions src/Close/Models/Enums/Mode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Close.Models.Enums;

public enum Mode
{
beginning_of_words
}
3 changes: 2 additions & 1 deletion src/Close/Models/Enums/ObjectType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ public enum ObjectType
call,
opportunity,
sms,
taskcompleted
taskcompleted,
custom_object,
}
12 changes: 12 additions & 0 deletions src/Close/Models/Enums/QueryType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Close.Models.Enums;

public enum QueryType
{
and,
or,
object_type,
field_condition,
has_related,
text,
match_all
}
16 changes: 16 additions & 0 deletions src/Close/Models/Field.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Text.Json.Serialization;
using Close.Models.Enums;

namespace Close.Models;

public class Field
{
[JsonPropertyName("field_name")]
public string FieldName { get; set; }

[JsonPropertyName("object_type")]
public ObjectType ObjectType { get; set; }

[JsonPropertyName("type")]
public FieldType Type { get; set; }
}
44 changes: 44 additions & 0 deletions src/Close/Models/Query.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System.Text.Json.Serialization;
using Close.Models.Enums;

namespace Close.Models;

public abstract class Query
{
[JsonPropertyName("negate")]
public bool Negate { get; set; } = false;

[JsonPropertyName("object_type")]
public ObjectType? ObjectType { get; set; } = null;

[JsonPropertyName("type")]
public QueryType Type { get; set; } = QueryType.and;

[JsonPropertyName("queries")]
public List<Query> Queries { get; set; } = null;

[JsonPropertyName("related_object_type")]
public ObjectType? RelatedObjectType { get; set; } = null;

[JsonPropertyName("related_query")]
public Query RelatedQuery { get; set; } = null;

[JsonPropertyName("this_object_type")]
public ObjectType? ThisObjectType { get; set; } = null;

[JsonPropertyName("condition")]
public Condition Condition { get; set; } = null;

[JsonPropertyName("field")]
public Field Field { get; set; } = null;

[JsonPropertyName("mode")]
public Mode? Mode { get; set; } = null;

[JsonPropertyName("value")]
public string Value { get; set; } = null;
}

public class SearchQuery : Query
{
}
27 changes: 27 additions & 0 deletions src/Close/Models/SearchRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Text.Json.Serialization;

namespace Close.Models;

public class SearchRequest
{
[JsonPropertyName("query")]
public Query Query { get; set; }

[JsonPropertyName("results_limit")]
public int? ResultsLimit { get; set; } = null;

[JsonPropertyName("limit")]
public int? Limit { get; set; } = null;

[JsonPropertyName("sort")]
public List<Sorting> Sort { get; set; }

[JsonPropertyName("include_counts")]
public bool IncludeCounts { get; set; } = true;

[JsonPropertyName("cursor")]
public string Cursor { get; set; } = null;

[JsonPropertyName("_fields")]
public Dictionary<string, string[]> Fields { get; set; }
}
25 changes: 25 additions & 0 deletions src/Close/Models/SearchResults.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Text.Json.Serialization;
using Close.Models.Interfaces;

namespace Close.Models;

public class SearchResults<T> : ICloseEntity where T : ICloseEntity
{
[JsonPropertyName("data")]
public List<T> Data { get; set; }

[JsonPropertyName("count")]
public Count Count { get; set; }

[JsonPropertyName("cursor")]
public string Cursor { get; set; }
}

public class Count
{
[JsonPropertyName("limited")]
public int Limited { get; set; }

[JsonPropertyName("total")]
public int Total { get; set; }
}
12 changes: 12 additions & 0 deletions src/Close/Models/Sorting.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Text.Json.Serialization;

namespace Close.Models;

public class Sorting
{
[JsonPropertyName("direction")]
public string Direction { get; set; }

[JsonPropertyName("field")]
public Field Field { get; set; }
}

0 comments on commit 528c078

Please sign in to comment.