Added client library

This commit is contained in:
EzFeDezy
2025-05-10 09:23:28 +02:00
parent 36d126c63f
commit 97afed4a5b
14 changed files with 322 additions and 72 deletions

6
.gitignore vendored
View File

@@ -5,4 +5,8 @@ src/embeddingsearch/obj
src/debug src/debug
src/server/appsettings.Development.json src/server/appsettings.Development.json
src/server/bin src/server/bin
src/server/obj src/server/obj
src/Client/bin
src/Client/obj
src/Models/bin
src/Models/obj

View File

@@ -13,6 +13,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cli", "cli", "{BC4F3063-B92
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cli", "src\cli\cli.csproj", "{D61A2C50-B46C-42BA-B75D-E84D8FA28C29}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cli", "src\cli\cli.csproj", "{D61A2C50-B46C-42BA-B75D-E84D8FA28C29}"
EndProject 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 Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU 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}.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.ActiveCfg = Release|Any CPU
{D61A2C50-B46C-42BA-B75D-E84D8FA28C29}.Release|Any CPU.Build.0 = 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 EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{67AA89C0-3630-4994-B4EE-FC86CFF407DB} = {6AA0A9E0-A361-4E86-BA02-D5F6779C6DEF} {67AA89C0-3630-4994-B4EE-FC86CFF407DB} = {6AA0A9E0-A361-4E86-BA02-D5F6779C6DEF}
{643CB1D1-02F6-4BCC-A1CC-6E403D78C442} = {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} {BC4F3063-B921-4C4A-A7CE-11FAF5B73D50} = {6AA0A9E0-A361-4E86-BA02-D5F6779C6DEF}
{D61A2C50-B46C-42BA-B75D-E84D8FA28C29} = {BC4F3063-B921-4C4A-A7CE-11FAF5B73D50} {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 EndGlobalSection
EndGlobal EndGlobal

142
src/Client/Client.cs Normal file
View File

@@ -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<Client> logger, IConfiguration configuration)
{
string? baseUri = configuration.GetSection("Embeddingsearch").GetValue<string>("BaseUri");
string? apiKey = configuration.GetSection("Embeddingsearch").GetValue<string>("ApiKey");
string? searchdomain = configuration.GetSection("Embeddingsearch").GetValue<string>("Searchdomain");
this.baseUri = baseUri ?? "";
this.apiKey = apiKey ?? "";
this.searchdomain = searchdomain ?? "";
}
public async Task<SearchdomainListResults> SearchdomainListAsync()
{
var url = $"{baseUri}/Searchdomain/List?apiKey={HttpUtility.UrlEncode(apiKey)}";
return await GetUrlAndProcessJson<SearchdomainListResults>(url);
}
public async Task<SearchdomainDeleteResults> SearchdomainDeleteAsync()
{
return await SearchdomainDeleteAsync(searchdomain);
}
public async Task<SearchdomainDeleteResults> SearchdomainDeleteAsync(string searchdomain)
{
var url = $"{baseUri}/Searchdomain/Delete?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}";
return await GetUrlAndProcessJson<SearchdomainDeleteResults>(url);
}
public async Task<SearchdomainCreateResults> SearchdomainCreateAsync()
{
return await SearchdomainCreateAsync(searchdomain);
}
public async Task<SearchdomainCreateResults> SearchdomainCreateAsync(string searchdomain)
{
var url = $"{baseUri}/Searchdomain/Create?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}";
return await GetUrlAndProcessJson<SearchdomainCreateResults>(url);
}
public async Task<SearchdomainUpdateResults> SearchdomainUpdateAsync(string newName, string settings = "{}")
{
SearchdomainUpdateResults updateResults = await SearchdomainUpdateAsync(searchdomain, newName, settings);
searchdomain = newName;
return updateResults;
}
public async Task<SearchdomainUpdateResults> 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<SearchdomainUpdateResults>(url);
}
public async Task<EntityQueryResults> EntityQueryAsync(string query)
{
return await EntityQueryAsync(searchdomain, query);
}
public async Task<EntityQueryResults> 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<EntityQueryResults>(url);
}
public async Task<EntityIndexResult> EntityIndexAsync(List<JSONEntity> jsonEntity)
{
return await EntityIndexAsync(searchdomain, jsonEntity);
}
public async Task<EntityIndexResult> EntityIndexAsync(string searchdomain, List<JSONEntity> jsonEntity)
{
return await EntityIndexAsync(searchdomain, JsonSerializer.Serialize(jsonEntity));
}
public async Task<EntityIndexResult> EntityIndexAsync(string jsonEntity)
{
return await EntityIndexAsync(searchdomain, jsonEntity);
}
public async Task<EntityIndexResult> 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<EntityIndexResult>(url);
}
public async Task<EntityListResults> EntityListAsync(bool returnEmbeddings = false)
{
return await EntityListAsync(searchdomain, returnEmbeddings);
}
public async Task<EntityListResults> 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<EntityListResults>(url);
}
public async Task<EntityDeleteResults> EntityDeleteAsync(string entityName)
{
return await EntityDeleteAsync(searchdomain, entityName);
}
public async Task<EntityDeleteResults> 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<EntityDeleteResults>(url);
}
private static async Task<T> GetUrlAndProcessJson<T>(string url)
{
using var client = new HttpClient();
var response = await client.GetAsync(url);
string content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<T>(content)
?? throw new Exception($"Failed to deserialize JSON to type {typeof(T).Name}");
return result;
}
}

13
src/Client/Client.csproj Normal file
View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\server\server.csproj" />
</ItemGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@@ -1,55 +1,75 @@
namespace server.Models; using System.Text.Json.Serialization;
namespace Models;
public class EntityQueryResults public class EntityQueryResults
{ {
[JsonPropertyName("Results")]
public required List<EntityQueryResult> Results { get; set; } public required List<EntityQueryResult> Results { get; set; }
} }
public class EntityQueryResult public class EntityQueryResult
{ {
[JsonPropertyName("Name")]
public required string Name { get; set; } public required string Name { get; set; }
[JsonPropertyName("Value")]
public float Value { get; set; } public float Value { get; set; }
} }
public class EntityIndexResult public class EntityIndexResult
{ {
[JsonPropertyName("Success")]
public required bool Success { get; set; } public required bool Success { get; set; }
} }
public class EntityListResults public class EntityListResults
{ {
[JsonPropertyName("Results")]
public required List<EntityListResult> Results { get; set; } public required List<EntityListResult> Results { get; set; }
[JsonPropertyName("Success")]
public required bool Success { get; set; }
} }
public class EntityListResult public class EntityListResult
{ {
[JsonPropertyName("Name")]
public required string Name { get; set; } public required string Name { get; set; }
[JsonPropertyName("Attributes")]
public required List<AttributeResult> Attributes { get; set; } public required List<AttributeResult> Attributes { get; set; }
[JsonPropertyName("Datapoints")]
public required List<DatapointResult> Datapoints { get; set; } public required List<DatapointResult> Datapoints { get; set; }
} }
public class AttributeResult public class AttributeResult
{ {
[JsonPropertyName("Name")]
public required string Name { get; set; } public required string Name { get; set; }
[JsonPropertyName("Value")]
public required string Value { get; set; } public required string Value { get; set; }
} }
public class DatapointResult public class DatapointResult
{ {
[JsonPropertyName("Name")]
public required string Name { get; set; } public required string Name { get; set; }
[JsonPropertyName("ProbMethod")]
public required string ProbMethod { get; set; } public required string ProbMethod { get; set; }
[JsonPropertyName("Embeddings")]
public required List<EmbeddingResult>? Embeddings { get; set; } public required List<EmbeddingResult>? Embeddings { get; set; }
} }
public class EmbeddingResult public class EmbeddingResult
{ {
[JsonPropertyName("Model")]
public required string Model { get; set; } public required string Model { get; set; }
[JsonPropertyName("Embeddings")]
public required float[] Embeddings { get; set; } public required float[] Embeddings { get; set; }
} }
public class EntityDeleteResults public class EntityDeleteResults
{ {
[JsonPropertyName("Success")]
public required bool Success { get; set; } public required bool Success { get; set; }
} }

9
src/Models/Models.csproj Normal file
View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@@ -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<string> 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; }
}
}

View File

@@ -156,7 +156,7 @@ parser.ParseArguments<OptionsCommand>(args).WithParsed<OptionsCommand>(opts =>
int counter = 0; int counter = 0;
foreach (Entity entity in searchdomain.entityCache) foreach (Entity entity in searchdomain.entityCache)
{ {
searchdomain.DatabaseRemoveEntity(entity.name); searchdomain.RemoveEntity(entity.name);
counter += 1; counter += 1;
} }
Console.WriteLine($"Number of entities deleted as part of deleting the searchdomain: {counter}"); Console.WriteLine($"Number of entities deleted as part of deleting the searchdomain: {counter}");
@@ -260,7 +260,7 @@ parser.ParseArguments<OptionsCommand>(args).WithParsed<OptionsCommand>(opts =>
bool hasEntity = searchdomain.HasEntity(opts.Name); bool hasEntity = searchdomain.HasEntity(opts.Name);
if (hasEntity) if (hasEntity)
{ {
searchdomain.DatabaseRemoveEntity(opts.Name); searchdomain.RemoveEntity(opts.Name);
} else } else
{ {
Console.Error.WriteLine($"No entity with the name {opts.Name} has been found."); Console.Error.WriteLine($"No entity with the name {opts.Name} has been found.");

View File

@@ -270,7 +270,8 @@ public class Searchdomain
} }
if (HasEntity(jsonEntity.name)) if (HasEntity(jsonEntity.name))
{ {
DatabaseRemoveEntity(jsonEntity.name); RemoveEntity(jsonEntity.name);
} }
int id_entity = DatabaseInsertEntity(jsonEntity.name, jsonEntity.probmethod, id); int id_entity = DatabaseInsertEntity(jsonEntity.name, jsonEntity.probmethod, id);
foreach (KeyValuePair<string, string> attribute in jsonEntity.attributes) foreach (KeyValuePair<string, string> attribute in jsonEntity.attributes)
@@ -325,30 +326,17 @@ public class Searchdomain
} }
} }
} }
//Console.WriteLine(JsonSerializer.Serialize(toBeCached));
//return new List<Entity>();
Dictionary<string, Dictionary<string, float[]>> cache = []; // local cache Dictionary<string, Dictionary<string, float[]>> cache = []; // local cache
foreach (KeyValuePair<string, List<string>> cacheThis in toBeCached) foreach (KeyValuePair<string, List<string>> cacheThis in toBeCached)
{ {
string model = cacheThis.Key; string model = cacheThis.Key;
List<string> contents = cacheThis.Value; List<string> contents = cacheThis.Value;
Console.WriteLine("DEBUG@searchdomain-1");
Console.WriteLine(model);
Console.WriteLine(contents);
Console.WriteLine(contents.Count);
if (contents.Count == 0) if (contents.Count == 0)
{ {
Console.WriteLine("DEBUG@searchdomain-2-no");
cache[model] = []; cache[model] = [];
continue; 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); cache[model] = Datapoint.GenerateEmbeddings(contents, model, ollama, embeddingCache);
//Console.WriteLine(JsonSerializer.Serialize(cache[model]));
} }
var tempEmbeddingCache = embeddingCache; var tempEmbeddingCache = embeddingCache;
embeddingCache = cache; embeddingCache = cache;
@@ -361,7 +349,7 @@ public class Searchdomain
return retVal; return retVal;
} }
public void DatabaseRemoveEntity(string name) public void RemoveEntity(string name)
{ {
Dictionary<string, dynamic> parameters = new() Dictionary<string, dynamic> 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 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 attribute.* FROM attribute JOIN entity ON id_entity = entity.id WHERE entity.name = @name", parameters);
ExecuteSQLNonQuery("DELETE FROM entity WHERE name = @name", parameters); ExecuteSQLNonQuery("DELETE FROM entity WHERE name = @name", parameters);
entityCache.RemoveAll(entity => entity.name == name);
} }
public int DatabaseInsertSearchdomain(string name) public int DatabaseInsertSearchdomain(string name)

View File

@@ -1,8 +1,7 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using embeddingsearch; using embeddingsearch;
using System.Text.Json; using System.Text.Json;
using server.Models; using Models;
namespace server.Controllers; namespace server.Controllers;
[ApiController] [ApiController]
@@ -23,7 +22,14 @@ public class EntityController : ControllerBase
[HttpGet("Query")] [HttpGet("Query")]
public ActionResult<EntityQueryResults> Query(string searchdomain, string query) public ActionResult<EntityQueryResults> 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); var results = searchdomain_.Search(query);
List<EntityQueryResult> queryResults = [.. results.Select(r => new EntityQueryResult List<EntityQueryResult> queryResults = [.. results.Select(r => new EntityQueryResult
{ {
@@ -36,7 +42,14 @@ public class EntityController : ControllerBase
[HttpGet("Index")] [HttpGet("Index")]
public ActionResult<EntityIndexResult> Index(string searchdomain, string jsonEntity) public ActionResult<EntityIndexResult> 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<JSONEntity>? jsonEntities = JsonSerializer.Deserialize<List<JSONEntity>?>(jsonEntity); List<JSONEntity>? jsonEntities = JsonSerializer.Deserialize<List<JSONEntity>?>(jsonEntity);
if (jsonEntities is not null) if (jsonEntities is not null)
{ {
@@ -44,21 +57,29 @@ public class EntityController : ControllerBase
List<Entity>? entities = searchdomain_.EntitiesFromJSON(jsonEntity); List<Entity>? entities = searchdomain_.EntitiesFromJSON(jsonEntity);
if (entities is not null) if (entities is not null)
{ {
return new EntityIndexResult() {Success = true}; return Ok(new EntityIndexResult() {Success = true});
} }
else else
{ {
_logger.LogDebug("Unable to deserialize an entity"); _logger.LogDebug("Unable to deserialize an entity");
} }
} }
return new EntityIndexResult() {Success = false};
return Ok(new EntityIndexResult() {Success = false});
} }
[HttpGet("List")] [HttpGet("List")]
public ActionResult<EntityListResults> List(string searchdomain, bool returnEmbeddings = false) public ActionResult<EntityListResults> List(string searchdomain, bool returnEmbeddings = false)
{ {
EntityListResults entityListResults = new() {Results = []}; Searchdomain searchdomain_;
Searchdomain searchdomain_ = _domainManager.GetSearchdomain(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) foreach (Entity entity in searchdomain_.entityCache)
{ {
List<AttributeResult> attributeResults = []; List<AttributeResult> attributeResults = [];
@@ -91,19 +112,26 @@ public class EntityController : ControllerBase
}; };
entityListResults.Results.Add(entityListResult); entityListResults.Results.Add(entityListResult);
} }
return entityListResults; return Ok(entityListResults);
} }
[HttpGet("Delete")] [HttpGet("Delete")]
public ActionResult<EntityDeleteResults> Delete(string searchdomain, string entity) // TODO test this public ActionResult<EntityDeleteResults> Delete(string searchdomain, string entityName) // TODO test this
{ {
Searchdomain searchdomain_ = _domainManager.GetSearchdomain(searchdomain); Searchdomain searchdomain_;
Entity? entity_ = searchdomain_.GetEntity(entity); try
{
searchdomain_ = _domainManager.GetSearchdomain(searchdomain);
} catch (Exception)
{
return Ok(new EntityDeleteResults() {Success = false});
}
Entity? entity_ = searchdomain_.GetEntity(entityName);
if (entity_ is null) if (entity_ is null)
{ {
return new EntityDeleteResults() {Success = false}; return Ok(new EntityDeleteResults() {Success = false});
} }
searchdomain_.DatabaseRemoveEntity(entity); searchdomain_.RemoveEntity(entityName);
return new EntityDeleteResults() {Success = true}; return Ok(new EntityDeleteResults() {Success = true});
} }
} }

View File

@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using embeddingsearch; using embeddingsearch;
using server.Models; using Models;
namespace server.Controllers; namespace server.Controllers;
@@ -22,13 +22,23 @@ public class SearchdomainController : ControllerBase
[HttpGet("List")] [HttpGet("List")]
public ActionResult<SearchdomainListResults> List() public ActionResult<SearchdomainListResults> 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")] [HttpGet("Create")]
public ActionResult<SearchdomainCreateResults> Create(string searchdomain, string settings = "{}") public ActionResult<SearchdomainCreateResults> 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")] [HttpGet("Delete")]
@@ -40,8 +50,9 @@ public class SearchdomainController : ControllerBase
{ {
success = true; success = true;
deletedEntries = _domainManager.DeleteSearchdomain(searchdomain); deletedEntries = _domainManager.DeleteSearchdomain(searchdomain);
} catch (Exception) } catch (Exception ex)
{ {
Console.WriteLine(ex);
success = false; success = false;
deletedEntries = 0; deletedEntries = 0;
} }
@@ -51,14 +62,20 @@ public class SearchdomainController : ControllerBase
[HttpGet("Update")] [HttpGet("Update")]
public ActionResult<SearchdomainUpdateResults> Update(string searchdomain, string newName, string settings = "{}") public ActionResult<SearchdomainUpdateResults> Update(string searchdomain, string newName, string settings = "{}")
{ {
Searchdomain searchdomain_ = _domainManager.GetSearchdomain(searchdomain); try
Dictionary<string, dynamic> parameters = new()
{ {
{"name", newName}, Searchdomain searchdomain_ = _domainManager.GetSearchdomain(searchdomain);
{"settings", settings}, Dictionary<string, dynamic> parameters = new()
{"id", searchdomain_.id} {
}; {"name", newName},
searchdomain_.ExecuteSQLNonQuery("UPDATE searchdomain set name = @name, settings = @settings WHERE id = @id", parameters); {"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}); return Ok(new SearchdomainUpdateResults(){Success = true});
} }
} }

View File

@@ -1,24 +0,0 @@
namespace server.Models
{
public class SearchdomainListResults
{
public required List<string> 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; }
}
}

View File

@@ -56,6 +56,10 @@ public class SearchomainManager
public int CreateSearchdomain(string searchdomain, string settings = "{}") 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<string, dynamic> parameters = new() Dictionary<string, dynamic> parameters = new()
{ {
{ "name", searchdomain }, { "name", searchdomain },
@@ -68,13 +72,12 @@ public class SearchomainManager
{ {
Searchdomain searchdomain_ = GetSearchdomain(searchdomain); Searchdomain searchdomain_ = GetSearchdomain(searchdomain);
int counter = 0; 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; counter += 1;
} }
_logger.LogDebug($"Number of entities deleted as part of deleting the searchdomain \"{searchdomain}\": {counter}"); _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}}); searchdomain_.ExecuteSQLNonQuery("DELETE FROM searchdomain WHERE name = @name", new() {{"name", searchdomain}});
searchdomains.Remove(searchdomain); searchdomains.Remove(searchdomain);
_logger.LogDebug($"Searchdomain has been successfully removed"); _logger.LogDebug($"Searchdomain has been successfully removed");

View File

@@ -12,6 +12,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\embeddingsearch\embeddingsearch.csproj" /> <ProjectReference Include="..\embeddingsearch\embeddingsearch.csproj" />
<ProjectReference Include="..\Models\Models.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>