From 97afed4a5b27cceeb2cdc15230cca48359bfee4a Mon Sep 17 00:00:00 2001 From: EzFeDezy Date: Sat, 10 May 2025 09:23:28 +0200 Subject: [PATCH] Added client library --- .gitignore | 6 +- embeddingsearch.sln | 14 ++ src/Client/Client.cs | 142 ++++++++++++++++++ src/Client/Client.csproj | 13 ++ src/{server => }/Models/EntityModels.cs | 22 ++- src/Models/Models.csproj | 9 ++ src/Models/SearchdomainModels.cs | 34 +++++ src/cli/Program.cs | 4 +- src/embeddingsearch/Searchdomain.cs | 19 +-- src/server/Controllers/EntityController.cs | 58 +++++-- .../Controllers/SearchdomainController.cs | 39 +++-- src/server/Models/SearchdomainModels.cs | 24 --- src/server/SearchdomainManager.cs | 9 +- src/server/server.csproj | 1 + 14 files changed, 322 insertions(+), 72 deletions(-) create mode 100644 src/Client/Client.cs create mode 100644 src/Client/Client.csproj rename src/{server => }/Models/EntityModels.cs (63%) create mode 100644 src/Models/Models.csproj create mode 100644 src/Models/SearchdomainModels.cs delete mode 100644 src/server/Models/SearchdomainModels.cs diff --git a/.gitignore b/.gitignore index ea3555b..e208d6e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,8 @@ src/embeddingsearch/obj src/debug src/server/appsettings.Development.json src/server/bin -src/server/obj \ No newline at end of file +src/server/obj +src/Client/bin +src/Client/obj +src/Models/bin +src/Models/obj \ No newline at end of file diff --git a/embeddingsearch.sln b/embeddingsearch.sln index 39b3441..03e1d81 100644 --- a/embeddingsearch.sln +++ b/embeddingsearch.sln @@ -13,6 +13,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cli", "cli", "{BC4F3063-B92 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cli", "src\cli\cli.csproj", "{D61A2C50-B46C-42BA-B75D-E84D8FA28C29}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "src\Client\Client.csproj", "{A8EBB748-5BBA-47EB-840D-E398365C52A2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Models", "src\Models\Models.csproj", "{4468F2B1-425E-441C-B288-C3403BB771CB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -34,11 +38,21 @@ Global {D61A2C50-B46C-42BA-B75D-E84D8FA28C29}.Debug|Any CPU.Build.0 = Debug|Any CPU {D61A2C50-B46C-42BA-B75D-E84D8FA28C29}.Release|Any CPU.ActiveCfg = Release|Any CPU {D61A2C50-B46C-42BA-B75D-E84D8FA28C29}.Release|Any CPU.Build.0 = Release|Any CPU + {A8EBB748-5BBA-47EB-840D-E398365C52A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A8EBB748-5BBA-47EB-840D-E398365C52A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A8EBB748-5BBA-47EB-840D-E398365C52A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A8EBB748-5BBA-47EB-840D-E398365C52A2}.Release|Any CPU.Build.0 = Release|Any CPU + {4468F2B1-425E-441C-B288-C3403BB771CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4468F2B1-425E-441C-B288-C3403BB771CB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4468F2B1-425E-441C-B288-C3403BB771CB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4468F2B1-425E-441C-B288-C3403BB771CB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {67AA89C0-3630-4994-B4EE-FC86CFF407DB} = {6AA0A9E0-A361-4E86-BA02-D5F6779C6DEF} {643CB1D1-02F6-4BCC-A1CC-6E403D78C442} = {6AA0A9E0-A361-4E86-BA02-D5F6779C6DEF} {BC4F3063-B921-4C4A-A7CE-11FAF5B73D50} = {6AA0A9E0-A361-4E86-BA02-D5F6779C6DEF} {D61A2C50-B46C-42BA-B75D-E84D8FA28C29} = {BC4F3063-B921-4C4A-A7CE-11FAF5B73D50} + {A8EBB748-5BBA-47EB-840D-E398365C52A2} = {6AA0A9E0-A361-4E86-BA02-D5F6779C6DEF} + {4468F2B1-425E-441C-B288-C3403BB771CB} = {6AA0A9E0-A361-4E86-BA02-D5F6779C6DEF} EndGlobalSection EndGlobal diff --git a/src/Client/Client.cs b/src/Client/Client.cs new file mode 100644 index 0000000..8ec0449 --- /dev/null +++ b/src/Client/Client.cs @@ -0,0 +1,142 @@ +using System; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.Web; +using System.Text.Json; +using Models; +using embeddingsearch; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Configuration; +using System.Reflection.Metadata.Ecma335; + +namespace Client; + +public class Client +{ + public string baseUri; + public string apiKey; + public string searchdomain; + + public Client(string baseUri, string apiKey = "", string searchdomain = "") + { + this.baseUri = baseUri; + this.apiKey = apiKey; + this.searchdomain = searchdomain; + } + + public Client(ILogger logger, IConfiguration configuration) + { + string? baseUri = configuration.GetSection("Embeddingsearch").GetValue("BaseUri"); + string? apiKey = configuration.GetSection("Embeddingsearch").GetValue("ApiKey"); + string? searchdomain = configuration.GetSection("Embeddingsearch").GetValue("Searchdomain"); + this.baseUri = baseUri ?? ""; + this.apiKey = apiKey ?? ""; + this.searchdomain = searchdomain ?? ""; + } + + public async Task SearchdomainListAsync() + { + var url = $"{baseUri}/Searchdomain/List?apiKey={HttpUtility.UrlEncode(apiKey)}"; + return await GetUrlAndProcessJson(url); + } + + public async Task SearchdomainDeleteAsync() + { + return await SearchdomainDeleteAsync(searchdomain); + } + + public async Task SearchdomainDeleteAsync(string searchdomain) + { + var url = $"{baseUri}/Searchdomain/Delete?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}"; + return await GetUrlAndProcessJson(url); + } + + public async Task SearchdomainCreateAsync() + { + return await SearchdomainCreateAsync(searchdomain); + } + + public async Task SearchdomainCreateAsync(string searchdomain) + { + var url = $"{baseUri}/Searchdomain/Create?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}"; + return await GetUrlAndProcessJson(url); + } + + public async Task SearchdomainUpdateAsync(string newName, string settings = "{}") + { + SearchdomainUpdateResults updateResults = await SearchdomainUpdateAsync(searchdomain, newName, settings); + searchdomain = newName; + return updateResults; + } + + public async Task SearchdomainUpdateAsync(string searchdomain, string newName, string settings = "{}") + { + var url = $"{baseUri}/Searchdomain/Update?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}&newName={HttpUtility.UrlEncode(newName)}&settings={HttpUtility.UrlEncode(settings)}"; + return await GetUrlAndProcessJson(url); + } + + public async Task EntityQueryAsync(string query) + { + return await EntityQueryAsync(searchdomain, query); + } + + public async Task EntityQueryAsync(string searchdomain, string query) + { + var url = $"{baseUri}/Entity/Query?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}&query={HttpUtility.UrlEncode(query)}"; + return await GetUrlAndProcessJson(url); + } + + public async Task EntityIndexAsync(List jsonEntity) + { + return await EntityIndexAsync(searchdomain, jsonEntity); + } + + public async Task EntityIndexAsync(string searchdomain, List jsonEntity) + { + return await EntityIndexAsync(searchdomain, JsonSerializer.Serialize(jsonEntity)); + } + + public async Task EntityIndexAsync(string jsonEntity) + { + return await EntityIndexAsync(searchdomain, jsonEntity); + } + + public async Task EntityIndexAsync(string searchdomain, string jsonEntity) + { + var url = $"{baseUri}/Entity/Index?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}&jsonEntity={HttpUtility.UrlEncode(jsonEntity)}"; + return await GetUrlAndProcessJson(url); + } + + public async Task EntityListAsync(bool returnEmbeddings = false) + { + return await EntityListAsync(searchdomain, returnEmbeddings); + } + + public async Task EntityListAsync(string searchdomain, bool returnEmbeddings = false) + { + var url = $"{baseUri}/Entity/List?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}&returnEmbeddings={HttpUtility.UrlEncode(returnEmbeddings.ToString())}"; + return await GetUrlAndProcessJson(url); + } + + public async Task EntityDeleteAsync(string entityName) + { + return await EntityDeleteAsync(searchdomain, entityName); + } + + public async Task EntityDeleteAsync(string searchdomain, string entityName) + { + var url = $"{baseUri}/Entity/Delete?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}&entity={HttpUtility.UrlEncode(entityName)}"; + return await GetUrlAndProcessJson(url); + } + + private static async Task GetUrlAndProcessJson(string url) + { + using var client = new HttpClient(); + var response = await client.GetAsync(url); + string content = await response.Content.ReadAsStringAsync(); + var result = JsonSerializer.Deserialize(content) + ?? throw new Exception($"Failed to deserialize JSON to type {typeof(T).Name}"); + return result; + } +} diff --git a/src/Client/Client.csproj b/src/Client/Client.csproj new file mode 100644 index 0000000..e8ed42c --- /dev/null +++ b/src/Client/Client.csproj @@ -0,0 +1,13 @@ + + + + + + + + net8.0 + enable + enable + + + diff --git a/src/server/Models/EntityModels.cs b/src/Models/EntityModels.cs similarity index 63% rename from src/server/Models/EntityModels.cs rename to src/Models/EntityModels.cs index ffc5b33..20a702d 100644 --- a/src/server/Models/EntityModels.cs +++ b/src/Models/EntityModels.cs @@ -1,55 +1,75 @@ -namespace server.Models; +using System.Text.Json.Serialization; + +namespace Models; public class EntityQueryResults { + [JsonPropertyName("Results")] public required List Results { get; set; } } public class EntityQueryResult { + [JsonPropertyName("Name")] public required string Name { get; set; } + [JsonPropertyName("Value")] public float Value { get; set; } } public class EntityIndexResult { + [JsonPropertyName("Success")] public required bool Success { get; set; } } public class EntityListResults { + [JsonPropertyName("Results")] public required List Results { get; set; } + [JsonPropertyName("Success")] + public required bool Success { get; set; } } public class EntityListResult { + [JsonPropertyName("Name")] public required string Name { get; set; } + [JsonPropertyName("Attributes")] public required List Attributes { get; set; } + [JsonPropertyName("Datapoints")] public required List Datapoints { get; set; } } public class AttributeResult { + [JsonPropertyName("Name")] public required string Name { get; set; } + [JsonPropertyName("Value")] public required string Value { get; set; } } public class DatapointResult { + [JsonPropertyName("Name")] public required string Name { get; set; } + [JsonPropertyName("ProbMethod")] public required string ProbMethod { get; set; } + [JsonPropertyName("Embeddings")] public required List? Embeddings { get; set; } } public class EmbeddingResult { + [JsonPropertyName("Model")] public required string Model { get; set; } + [JsonPropertyName("Embeddings")] public required float[] Embeddings { get; set; } } public class EntityDeleteResults { + [JsonPropertyName("Success")] public required bool Success { get; set; } } diff --git a/src/Models/Models.csproj b/src/Models/Models.csproj new file mode 100644 index 0000000..bb23fb7 --- /dev/null +++ b/src/Models/Models.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/src/Models/SearchdomainModels.cs b/src/Models/SearchdomainModels.cs new file mode 100644 index 0000000..9d1f6b3 --- /dev/null +++ b/src/Models/SearchdomainModels.cs @@ -0,0 +1,34 @@ +using System.Text.Json.Serialization; + +namespace Models +{ + public class SearchdomainListResults + { + [JsonPropertyName("Searchdomains")] // Otherwise the api returns {"searchdomains": [...]} and the client requires {"Searchdomains": [...]} + public required List Searchdomains { get; set; } + } + + public class SearchdomainCreateResults + { + [JsonPropertyName("Success")] + public required bool Success { get; set; } + + [JsonPropertyName("Id")] + public int? Id { get; set; } + } + + public class SearchdomainUpdateResults + { + [JsonPropertyName("Success")] + public required bool Success { get; set; } + } + + public class SearchdomainDeleteResults + { + [JsonPropertyName("Success")] + public required bool Success { get; set; } + [JsonPropertyName("DeletedEntities")] + public required int DeletedEntities { get; set; } + } + +} diff --git a/src/cli/Program.cs b/src/cli/Program.cs index 78981bd..4abf221 100644 --- a/src/cli/Program.cs +++ b/src/cli/Program.cs @@ -156,7 +156,7 @@ parser.ParseArguments(args).WithParsed(opts => int counter = 0; foreach (Entity entity in searchdomain.entityCache) { - searchdomain.DatabaseRemoveEntity(entity.name); + searchdomain.RemoveEntity(entity.name); counter += 1; } Console.WriteLine($"Number of entities deleted as part of deleting the searchdomain: {counter}"); @@ -260,7 +260,7 @@ parser.ParseArguments(args).WithParsed(opts => bool hasEntity = searchdomain.HasEntity(opts.Name); if (hasEntity) { - searchdomain.DatabaseRemoveEntity(opts.Name); + searchdomain.RemoveEntity(opts.Name); } else { Console.Error.WriteLine($"No entity with the name {opts.Name} has been found."); diff --git a/src/embeddingsearch/Searchdomain.cs b/src/embeddingsearch/Searchdomain.cs index 5093a91..29ccdf2 100644 --- a/src/embeddingsearch/Searchdomain.cs +++ b/src/embeddingsearch/Searchdomain.cs @@ -270,7 +270,8 @@ public class Searchdomain } if (HasEntity(jsonEntity.name)) { - DatabaseRemoveEntity(jsonEntity.name); + RemoveEntity(jsonEntity.name); + } int id_entity = DatabaseInsertEntity(jsonEntity.name, jsonEntity.probmethod, id); foreach (KeyValuePair attribute in jsonEntity.attributes) @@ -325,30 +326,17 @@ public class Searchdomain } } } - //Console.WriteLine(JsonSerializer.Serialize(toBeCached)); - //return new List(); Dictionary> cache = []; // local cache foreach (KeyValuePair> cacheThis in toBeCached) { string model = cacheThis.Key; List contents = cacheThis.Value; - Console.WriteLine("DEBUG@searchdomain-1"); - Console.WriteLine(model); - Console.WriteLine(contents); - Console.WriteLine(contents.Count); if (contents.Count == 0) { - Console.WriteLine("DEBUG@searchdomain-2-no"); cache[model] = []; continue; } - Console.WriteLine("DEBUG@searchdomain-2-yes"); - //Console.WriteLine("DEBUG@searchdomain[["); - //Console.WriteLine(model); - //Console.WriteLine(JsonSerializer.Serialize(contents)); - //Console.WriteLine("]]"); cache[model] = Datapoint.GenerateEmbeddings(contents, model, ollama, embeddingCache); - //Console.WriteLine(JsonSerializer.Serialize(cache[model])); } var tempEmbeddingCache = embeddingCache; embeddingCache = cache; @@ -361,7 +349,7 @@ public class Searchdomain return retVal; } - public void DatabaseRemoveEntity(string name) + public void RemoveEntity(string name) { Dictionary parameters = new() { @@ -371,6 +359,7 @@ public class Searchdomain ExecuteSQLNonQuery("DELETE datapoint.* FROM datapoint JOIN entity ON id_entity = entity.id WHERE entity.name = @name", parameters); ExecuteSQLNonQuery("DELETE attribute.* FROM attribute JOIN entity ON id_entity = entity.id WHERE entity.name = @name", parameters); ExecuteSQLNonQuery("DELETE FROM entity WHERE name = @name", parameters); + entityCache.RemoveAll(entity => entity.name == name); } public int DatabaseInsertSearchdomain(string name) diff --git a/src/server/Controllers/EntityController.cs b/src/server/Controllers/EntityController.cs index 21d29ee..9b29702 100644 --- a/src/server/Controllers/EntityController.cs +++ b/src/server/Controllers/EntityController.cs @@ -1,8 +1,7 @@ using Microsoft.AspNetCore.Mvc; using embeddingsearch; using System.Text.Json; -using server.Models; - +using Models; namespace server.Controllers; [ApiController] @@ -23,7 +22,14 @@ public class EntityController : ControllerBase [HttpGet("Query")] public ActionResult Query(string searchdomain, string query) { - Searchdomain searchdomain_ = _domainManager.GetSearchdomain(searchdomain); + Searchdomain searchdomain_; + try + { + searchdomain_ = _domainManager.GetSearchdomain(searchdomain); + } catch (Exception) + { + return Ok(new EntityQueryResults() {Results = []}); + } var results = searchdomain_.Search(query); List queryResults = [.. results.Select(r => new EntityQueryResult { @@ -36,7 +42,14 @@ public class EntityController : ControllerBase [HttpGet("Index")] public ActionResult Index(string searchdomain, string jsonEntity) { - Searchdomain searchdomain_ = _domainManager.GetSearchdomain(searchdomain); + Searchdomain searchdomain_; + try + { + searchdomain_ = _domainManager.GetSearchdomain(searchdomain); + } catch (Exception) + { + return Ok(new EntityIndexResult() {Success = false}); + } List? jsonEntities = JsonSerializer.Deserialize?>(jsonEntity); if (jsonEntities is not null) { @@ -44,21 +57,29 @@ public class EntityController : ControllerBase List? entities = searchdomain_.EntitiesFromJSON(jsonEntity); if (entities is not null) { - return new EntityIndexResult() {Success = true}; + return Ok(new EntityIndexResult() {Success = true}); } else { _logger.LogDebug("Unable to deserialize an entity"); } } - return new EntityIndexResult() {Success = false}; + + return Ok(new EntityIndexResult() {Success = false}); } [HttpGet("List")] public ActionResult List(string searchdomain, bool returnEmbeddings = false) { - EntityListResults entityListResults = new() {Results = []}; - Searchdomain searchdomain_ = _domainManager.GetSearchdomain(searchdomain); + Searchdomain searchdomain_; + try + { + searchdomain_ = _domainManager.GetSearchdomain(searchdomain); + } catch (Exception) + { + return Ok(new EntityListResults() {Results = [], Success = false}); + } + EntityListResults entityListResults = new() {Results = [], Success = true}; foreach (Entity entity in searchdomain_.entityCache) { List attributeResults = []; @@ -91,19 +112,26 @@ public class EntityController : ControllerBase }; entityListResults.Results.Add(entityListResult); } - return entityListResults; + return Ok(entityListResults); } [HttpGet("Delete")] - public ActionResult Delete(string searchdomain, string entity) // TODO test this + public ActionResult Delete(string searchdomain, string entityName) // TODO test this { - Searchdomain searchdomain_ = _domainManager.GetSearchdomain(searchdomain); - Entity? entity_ = searchdomain_.GetEntity(entity); + Searchdomain searchdomain_; + try + { + searchdomain_ = _domainManager.GetSearchdomain(searchdomain); + } catch (Exception) + { + return Ok(new EntityDeleteResults() {Success = false}); + } + Entity? entity_ = searchdomain_.GetEntity(entityName); if (entity_ is null) { - return new EntityDeleteResults() {Success = false}; + return Ok(new EntityDeleteResults() {Success = false}); } - searchdomain_.DatabaseRemoveEntity(entity); - return new EntityDeleteResults() {Success = true}; + searchdomain_.RemoveEntity(entityName); + return Ok(new EntityDeleteResults() {Success = true}); } } diff --git a/src/server/Controllers/SearchdomainController.cs b/src/server/Controllers/SearchdomainController.cs index 5f2d1d0..414b4ce 100644 --- a/src/server/Controllers/SearchdomainController.cs +++ b/src/server/Controllers/SearchdomainController.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Mvc; using embeddingsearch; -using server.Models; +using Models; namespace server.Controllers; @@ -22,13 +22,23 @@ public class SearchdomainController : ControllerBase [HttpGet("List")] public ActionResult List() { - return Ok(_domainManager.ListSearchdomains()); + var results = _domainManager.ListSearchdomains() + ?? throw new Exception("Unable to list searchdomains"); + SearchdomainListResults searchdomainListResults = new() {Searchdomains = results}; + return Ok(searchdomainListResults); } [HttpGet("Create")] public ActionResult Create(string searchdomain, string settings = "{}") { - return Ok(new SearchdomainCreateResults(){Id = _domainManager.CreateSearchdomain(searchdomain, settings)}); + try + { + int id = _domainManager.CreateSearchdomain(searchdomain, settings); + return Ok(new SearchdomainCreateResults(){Id = id, Success = true}); + } catch (Exception) + { + return Ok(new SearchdomainCreateResults(){Id = null, Success = false}); + } } [HttpGet("Delete")] @@ -40,8 +50,9 @@ public class SearchdomainController : ControllerBase { success = true; deletedEntries = _domainManager.DeleteSearchdomain(searchdomain); - } catch (Exception) + } catch (Exception ex) { + Console.WriteLine(ex); success = false; deletedEntries = 0; } @@ -51,14 +62,20 @@ public class SearchdomainController : ControllerBase [HttpGet("Update")] public ActionResult Update(string searchdomain, string newName, string settings = "{}") { - Searchdomain searchdomain_ = _domainManager.GetSearchdomain(searchdomain); - Dictionary parameters = new() + try { - {"name", newName}, - {"settings", settings}, - {"id", searchdomain_.id} - }; - searchdomain_.ExecuteSQLNonQuery("UPDATE searchdomain set name = @name, settings = @settings WHERE id = @id", parameters); + Searchdomain searchdomain_ = _domainManager.GetSearchdomain(searchdomain); + Dictionary parameters = new() + { + {"name", newName}, + {"settings", settings}, + {"id", searchdomain_.id} + }; + searchdomain_.ExecuteSQLNonQuery("UPDATE searchdomain set name = @name, settings = @settings WHERE id = @id", parameters); + } catch (Exception) + { + return Ok(new SearchdomainUpdateResults(){Success = false}); + } return Ok(new SearchdomainUpdateResults(){Success = true}); } } diff --git a/src/server/Models/SearchdomainModels.cs b/src/server/Models/SearchdomainModels.cs deleted file mode 100644 index fe88c4f..0000000 --- a/src/server/Models/SearchdomainModels.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace server.Models -{ - public class SearchdomainListResults - { - public required List Searchdomains { get; set; } - } - - public class SearchdomainCreateResults - { - public required int Id { get; set; } - } - - public class SearchdomainUpdateResults - { - public required bool Success { get; set; } - } - - public class SearchdomainDeleteResults - { - public required bool Success { get; set; } - public required int DeletedEntities { get; set; } - } - -} diff --git a/src/server/SearchdomainManager.cs b/src/server/SearchdomainManager.cs index c14666c..b79fc28 100644 --- a/src/server/SearchdomainManager.cs +++ b/src/server/SearchdomainManager.cs @@ -56,6 +56,10 @@ public class SearchomainManager public int CreateSearchdomain(string searchdomain, string settings = "{}") { + if (searchdomains.TryGetValue(searchdomain, out Searchdomain? value)) + { + throw new Exception("Searchdomain already exists"); // TODO create proper SearchdomainAlreadyExists exception + } Dictionary parameters = new() { { "name", searchdomain }, @@ -68,13 +72,12 @@ public class SearchomainManager { Searchdomain searchdomain_ = GetSearchdomain(searchdomain); int counter = 0; - foreach (Entity entity in searchdomain_.entityCache) + while (searchdomain_.entityCache.Count > 0) { - searchdomain_.DatabaseRemoveEntity(entity.name); + searchdomain_.RemoveEntity(searchdomain_.entityCache.First().name); counter += 1; } _logger.LogDebug($"Number of entities deleted as part of deleting the searchdomain \"{searchdomain}\": {counter}"); - searchdomain_.ExecuteSQLNonQuery("DELETE FROM entity WHERE id_searchdomain = @id", new() {{"id", searchdomain_.id}}); // Cleanup // TODO add rows affected searchdomain_.ExecuteSQLNonQuery("DELETE FROM searchdomain WHERE name = @name", new() {{"name", searchdomain}}); searchdomains.Remove(searchdomain); _logger.LogDebug($"Searchdomain has been successfully removed"); diff --git a/src/server/server.csproj b/src/server/server.csproj index 4b546bb..948f4cb 100644 --- a/src/server/server.csproj +++ b/src/server/server.csproj @@ -12,6 +12,7 @@ +