From 7cb5c1aa7e83e36e20caac38884f5eb9e291feee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veikko=20Lintuj=C3=A4rvi?= Date: Tue, 17 Feb 2026 21:02:24 +0200 Subject: [PATCH] Added new db connection and health check endpoint --- api/Database/klapi.db | 0 api/Public/Program.cs | 37 ++++++++++++++++++++ api/Public/Public.csproj | 1 + api/Public/appsettings.Development.json | 3 ++ api/Public/appsettings.json | 3 ++ api/Tests/Http/Health-Db.http | 4 +++ api/Tests/Http/Version.http | 2 -- start.sh | 46 ++++++++++++++++++++----- 8 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 api/Database/klapi.db create mode 100644 api/Tests/Http/Health-Db.http diff --git a/api/Database/klapi.db b/api/Database/klapi.db new file mode 100644 index 0000000..e69de29 diff --git a/api/Public/Program.cs b/api/Public/Program.cs index 17c5b77..3dd1942 100644 --- a/api/Public/Program.cs +++ b/api/Public/Program.cs @@ -1,9 +1,31 @@ +using Microsoft.Data.Sqlite; + var builder = WebApplication.CreateBuilder(args); +var configuredConnectionString = builder.Configuration.GetConnectionString("DefaultConnection") + ?? throw new InvalidOperationException("Connection string 'DefaultConnection' was not found."); + +var sqliteConnectionStringBuilder = new SqliteConnectionStringBuilder(configuredConnectionString); +var databasePath = Path.GetFullPath(Path.Combine(builder.Environment.ContentRootPath, sqliteConnectionStringBuilder.DataSource)); +var databaseDirectory = Path.GetDirectoryName(databasePath) + ?? throw new InvalidOperationException("Could not determine database directory."); + +Directory.CreateDirectory(databaseDirectory); + +sqliteConnectionStringBuilder.DataSource = databasePath; +var resolvedConnectionString = sqliteConnectionStringBuilder.ToString(); + +builder.Services.AddScoped(_ => new SqliteConnection(resolvedConnectionString)); + builder.Services.AddOpenApi(); var app = builder.Build(); +using (var connection = new SqliteConnection(resolvedConnectionString)) +{ + connection.Open(); +} + if (app.Environment.IsDevelopment()) { app.MapOpenApi(); @@ -20,4 +42,19 @@ app.MapGet("/", () => }) .WithName("GetVersion"); +app.MapGet("/health/db", async (SqliteConnection connection) => +{ + await connection.OpenAsync(); + await using var command = connection.CreateCommand(); + command.CommandText = "SELECT 1"; + var result = await command.ExecuteScalarAsync(); + + return Results.Ok(new + { + Database = "ok", + Result = result + }); +}) +.WithName("GetDatabaseHealth"); + app.Run(); diff --git a/api/Public/Public.csproj b/api/Public/Public.csproj index e1f290f..305ef0b 100644 --- a/api/Public/Public.csproj +++ b/api/Public/Public.csproj @@ -8,6 +8,7 @@ + diff --git a/api/Public/appsettings.Development.json b/api/Public/appsettings.Development.json index 0c208ae..14a99ec 100644 --- a/api/Public/appsettings.Development.json +++ b/api/Public/appsettings.Development.json @@ -1,4 +1,7 @@ { + "ConnectionStrings": { + "DefaultConnection": "Data Source=../Database/klapi.db" + }, "Logging": { "LogLevel": { "Default": "Information", diff --git a/api/Public/appsettings.json b/api/Public/appsettings.json index 10f68b8..6d2b9db 100644 --- a/api/Public/appsettings.json +++ b/api/Public/appsettings.json @@ -1,4 +1,7 @@ { + "ConnectionStrings": { + "DefaultConnection": "Data Source=../Database/klapi.db" + }, "Logging": { "LogLevel": { "Default": "Information", diff --git a/api/Tests/Http/Health-Db.http b/api/Tests/Http/Health-Db.http new file mode 100644 index 0000000..c5740c5 --- /dev/null +++ b/api/Tests/Http/Health-Db.http @@ -0,0 +1,4 @@ +@Public_HostAddress = http://localhost:5013 + +GET {{Public_HostAddress}}/health/db +Accept: application/json \ No newline at end of file diff --git a/api/Tests/Http/Version.http b/api/Tests/Http/Version.http index c8655aa..476a26b 100644 --- a/api/Tests/Http/Version.http +++ b/api/Tests/Http/Version.http @@ -2,5 +2,3 @@ GET {{Public_HostAddress}}/ Accept: application/json - -### diff --git a/start.sh b/start.sh index 9110a76..7db9d36 100755 --- a/start.sh +++ b/start.sh @@ -5,23 +5,51 @@ SESSION_NAME="klapi" ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" API_DIR="$ROOT_DIR/api" UI_DIR="$ROOT_DIR/ui" +RESTART=false + +if [[ "${1:-}" == "--restart" ]]; then + RESTART=true +elif [[ -n "${1:-}" ]]; then + echo "Usage: $0 [--restart]" >&2 + exit 1 +fi if ! command -v tmux >/dev/null 2>&1; then echo "tmux is not installed or not in PATH" >&2 exit 1 fi +ensure_app_window() { + if ! tmux list-windows -t "$SESSION_NAME" -F '#{window_name}' | grep -qx 'app'; then + tmux new-window -t "$SESSION_NAME" -n app -c "$UI_DIR" + fi + + local pane_count + pane_count="$(tmux list-panes -t "$SESSION_NAME":app | wc -l | tr -d ' ')" + if [[ "$pane_count" -lt 2 ]]; then + tmux split-window -v -t "$SESSION_NAME":app -c "$API_DIR" + fi +} + +start_or_restart_services() { + ensure_app_window + tmux respawn-pane -k -t "$SESSION_NAME":app.0 -c "$UI_DIR" "bun dev" + tmux respawn-pane -k -t "$SESSION_NAME":app.1 -c "$API_DIR" "dotnet run --project $API_DIR/Public/Public.csproj" + tmux select-pane -t "$SESSION_NAME":app.0 + tmux select-window -t "$SESSION_NAME":app +} + if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then - echo "Session '$SESSION_NAME' already exists. Attaching..." - exec tmux attach -t "$SESSION_NAME" + if [[ "$RESTART" == "true" ]]; then + echo "Restarting services in existing session '$SESSION_NAME'..." + start_or_restart_services + exec tmux attach -t "$SESSION_NAME" + else + echo "Session '$SESSION_NAME' already exists. Attaching..." + exec tmux attach -t "$SESSION_NAME" + fi fi tmux new-session -d -s "$SESSION_NAME" -n app -c "$UI_DIR" -tmux send-keys -t "$SESSION_NAME":app "bun dev" C-m - -tmux split-window -v -t "$SESSION_NAME":app -c "$API_DIR" -tmux send-keys -t "$SESSION_NAME":app.1 "dotnet run --project $API_DIR/Public/Public.csproj" C-m - -tmux select-pane -t "$SESSION_NAME":app.0 -tmux select-window -t "$SESSION_NAME":app +start_or_restart_services exec tmux attach -t "$SESSION_NAME"