Removed CLI project, added database migrations, added SQLHelper

This commit is contained in:
2025-06-06 00:29:38 +02:00
parent 89545b0d71
commit ad599433bf
10 changed files with 152 additions and 555 deletions

View File

@@ -0,0 +1,14 @@
namespace Server.Exceptions;
public class DatabaseVersionException : Exception
{
public DatabaseVersionException()
: base("DatabaseVersion could not be parsed as integer. Please ensure the DatabaseVersion can be parsed as an integer.")
{
}
public DatabaseVersionException(string message)
: base(message)
{
}
}

View File

@@ -0,0 +1,69 @@
using System.Data.Common;
using Server.Exceptions;
namespace Server.Migrations;
public static class DatabaseMigrations
{
public static void Migrate(SQLHelper helper)
{
int databaseVersion = DatabaseGetVersion(helper);
switch (databaseVersion)
{
case 0:
databaseVersion = Create(helper);
goto case 1; // Here lies a dead braincell.
case 1:
databaseVersion = UpdateFrom1(helper); // TODO: Implement reflection based dynamic invocation.
goto case 2;
case 2:
default:
break;
}
}
public static int DatabaseGetVersion(SQLHelper helper)
{
DbDataReader reader = helper.ExecuteSQLCommand("show tables", []);
bool hasTables = reader.Read();
reader.Close();
if (!hasTables)
{
return 0;
}
reader = helper.ExecuteSQLCommand("show tables like '%settings%'", []);
bool hasSystemTable = reader.Read();
reader.Close();
if (!hasSystemTable)
{
return 1;
}
reader = helper.ExecuteSQLCommand("SELECT value FROM settings WHERE name=\"DatabaseVersion\"", []);
reader.Read();
string rawVersion = reader.GetString(0);
reader.Close();
bool success = int.TryParse(rawVersion, out int version);
if (!success)
{
throw new DatabaseVersionException();
}
return version;
}
public static int Create(SQLHelper helper)
{
helper.ExecuteSQLNonQuery("CREATE TABLE searchdomain (id int PRIMARY KEY auto_increment, name varchar(512), settings JSON);", []);
helper.ExecuteSQLNonQuery("CREATE TABLE entity (id int PRIMARY KEY auto_increment, name varchar(512), probmethod varchar(128), id_searchdomain int, FOREIGN KEY (id_searchdomain) REFERENCES searchdomain(id));", []);
helper.ExecuteSQLNonQuery("CREATE TABLE attribute (id int PRIMARY KEY auto_increment, id_entity int, attribute varchar(512), value longtext, FOREIGN KEY (id_entity) REFERENCES entity(id));", []);
helper.ExecuteSQLNonQuery("CREATE TABLE datapoint (id int PRIMARY KEY auto_increment, name varchar(512), probmethod_embedding varchar(512), id_entity int, FOREIGN KEY (id_entity) REFERENCES entity(id));", []);
helper.ExecuteSQLNonQuery("CREATE TABLE embedding (id int PRIMARY KEY auto_increment, id_datapoint int, model varchar(512), embedding blob, FOREIGN KEY (id_datapoint) REFERENCES datapoint(id));", []);
return 1;
}
public static int UpdateFrom1(SQLHelper helper)
{
helper.ExecuteSQLNonQuery("CREATE TABLE settings (name varchar(512), value varchar(8192));", []);
helper.ExecuteSQLNonQuery("INSERT INTO settings (name, value) VALUES (\"DatabaseVersion\", \"2\");", []);
return 2;
}
}

49
src/Server/SQLHelper.cs Normal file
View File

@@ -0,0 +1,49 @@
using System.Data.Common;
using MySql.Data.MySqlClient;
namespace Server;
public class SQLHelper
{
public MySqlConnection connection;
public SQLHelper(MySqlConnection connection)
{
this.connection = connection;
}
public DbDataReader ExecuteSQLCommand(string query, Dictionary<string, dynamic> parameters)
{
using MySqlCommand command = connection.CreateCommand();
command.CommandText = query;
foreach (KeyValuePair<string, dynamic> parameter in parameters)
{
command.Parameters.AddWithValue($"@{parameter.Key}", parameter.Value);
}
return command.ExecuteReader();
}
public void ExecuteSQLNonQuery(string query, Dictionary<string, dynamic> parameters)
{
using MySqlCommand command = connection.CreateCommand();
command.CommandText = query;
foreach (KeyValuePair<string, dynamic> parameter in parameters)
{
command.Parameters.AddWithValue($"@{parameter.Key}", parameter.Value);
}
command.ExecuteNonQuery();
}
public int ExecuteSQLCommandGetInsertedID(string query, Dictionary<string, dynamic> parameters)
{
using MySqlCommand command = connection.CreateCommand();
command.CommandText = query;
foreach (KeyValuePair<string, dynamic> parameter in parameters)
{
command.Parameters.AddWithValue($"@{parameter.Key}", parameter.Value);
}
command.ExecuteNonQuery();
command.CommandText = "SELECT LAST_INSERT_ID();";
return Convert.ToInt32(command.ExecuteScalar());
}
}

View File

@@ -3,6 +3,7 @@ using System.Data.Common;
using OllamaSharp;
using Microsoft.IdentityModel.Tokens;
using Server.Exceptions;
using Server.Migrations;
namespace Server;
@@ -29,8 +30,11 @@ public class SearchdomainManager
client = new(new Uri(ollamaURL));
connection = new MySqlConnection(connectionString);
connection.Open();
DatabaseMigrations.Migrate(new SQLHelper(connection));
}
public Searchdomain GetSearchdomain(string searchdomain)
{
if (searchdomains.TryGetValue(searchdomain, out Searchdomain? value))
@@ -40,7 +44,8 @@ public class SearchdomainManager
try
{
return SetSearchdomain(searchdomain, new Searchdomain(searchdomain, connectionString, client));
} catch (MySqlException)
}
catch (MySqlException)
{
_logger.LogError("Unable to find the searchdomain {searchdomain}", searchdomain);
throw new Exception($"Unable to find the searchdomain {searchdomain}");
@@ -105,6 +110,18 @@ public class SearchdomainManager
return command.ExecuteReader();
}
public void ExecuteSQLNonQuery(string query, Dictionary<string, dynamic> parameters)
{
using MySqlCommand command = connection.CreateCommand();
command.CommandText = query;
foreach (KeyValuePair<string, dynamic> parameter in parameters)
{
command.Parameters.AddWithValue($"@{parameter.Key}", parameter.Value);
}
command.ExecuteNonQuery();
}
public int ExecuteSQLCommandGetInsertedID(string query, Dictionary<string, dynamic> parameters)
{
using MySqlCommand command = connection.CreateCommand();

View File

@@ -18,9 +18,4 @@
<PackageReference Include="System.Data.Sqlite" Version="1.0.119" />
<PackageReference Include="System.Numerics.Tensors" Version="9.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Models\Models.csproj" />
</ItemGroup>
</Project>