Files
ContentGen_BE/media-worker/Services/DatabaseService.cs
T
Harun CAN 7745102584
Backend Deploy 🚀 / build-and-deploy (push) Has been cancelled
main
2026-04-27 12:50:42 +02:00

152 lines
6.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Npgsql;
namespace SaasMediaWorker.Services;
/// <summary>
/// PostgreSQL veritabanı servisi — RenderJob ve Project durumlarını günceller.
/// NestJS Prisma schema'sıyla uyumlu SQL sorguları kullanır.
///
/// Neden doğrudan SQL (ORM yerine)?
/// - C# Worker minimum footprint olmalı (16GB RPi).
/// - Sadece UPDATE sorguları yapılıyor — ORM gereksiz overhead.
/// - Npgsql ARM64'te native çalışır.
/// </summary>
public class DatabaseService
{
private readonly ILogger<DatabaseService> _logger;
private readonly string _connectionString;
public DatabaseService(
ILogger<DatabaseService> logger,
IConfiguration configuration)
{
_logger = logger;
_connectionString = configuration.GetConnectionString("DefaultConnection")
?? throw new InvalidOperationException("DefaultConnection bağlantı dizesi bulunamadı");
}
/// <summary>
/// RenderJob tablosunun durumunu günceller.
/// </summary>
public async Task UpdateRenderJobStatus(
string renderJobId,
string status,
int progress,
string? currentStage,
string? errorMessage = null,
string? errorStack = null,
long? processingTimeMs = null,
string? workerVersion = null,
string? workerHostname = null)
{
await using var conn = new NpgsqlConnection(_connectionString);
await conn.OpenAsync();
var sql = @"
UPDATE ""RenderJob""
SET ""status"" = @status::""RenderJobStatus"",
""currentStage"" = CASE WHEN @stage IS NOT NULL THEN @stage::""RenderStage"" ELSE ""currentStage"" END,
""errorMessage"" = COALESCE(@errorMessage, ""errorMessage""),
""processingTimeMs"" = COALESCE(@processingTimeMs, ""processingTimeMs""),
""workerHostname"" = COALESCE(@workerHostname, ""workerHostname""),
""updatedAt"" = NOW()
WHERE ""id"" = @id";
await using var cmd = new NpgsqlCommand(sql, conn);
cmd.Parameters.AddWithValue("id", renderJobId);
cmd.Parameters.AddWithValue("status", status);
cmd.Parameters.AddWithValue("progress", progress);
cmd.Parameters.AddWithValue("stage", (object?)currentStage ?? DBNull.Value);
cmd.Parameters.AddWithValue("errorMessage", (object?)errorMessage ?? DBNull.Value);
cmd.Parameters.AddWithValue("errorStack", (object?)errorStack ?? DBNull.Value);
cmd.Parameters.AddWithValue("processingTimeMs", (object?)processingTimeMs ?? DBNull.Value);
cmd.Parameters.AddWithValue("workerVersion", (object?)workerVersion ?? DBNull.Value);
cmd.Parameters.AddWithValue("workerHostname", (object?)workerHostname ?? DBNull.Value);
var affected = await cmd.ExecuteNonQueryAsync();
_logger.LogDebug("RenderJob güncellendi: {Id} → {Status} ({Progress}%)", renderJobId, status, progress);
}
/// <summary>
/// Project tablosunun durumunu günceller.
/// </summary>
public async Task UpdateProjectStatus(
string projectId,
string status,
int progress,
string? finalVideoUrl = null,
string? errorMessage = null)
{
await using var conn = new NpgsqlConnection(_connectionString);
await conn.OpenAsync();
var sql = @"
UPDATE ""Project""
SET ""status"" = @status::""ProjectStatus"",
""progress"" = @progress,
""finalVideoUrl"" = COALESCE(@finalVideoUrl, ""finalVideoUrl""),
""errorMessage"" = @errorMessage,
""completedAt"" = CASE WHEN @status = 'COMPLETED' THEN NOW() ELSE ""completedAt"" END,
""updatedAt"" = NOW()
WHERE ""id"" = @id";
await using var cmd = new NpgsqlCommand(sql, conn);
cmd.Parameters.AddWithValue("id", projectId);
cmd.Parameters.AddWithValue("status", status);
cmd.Parameters.AddWithValue("progress", progress);
cmd.Parameters.AddWithValue("finalVideoUrl", (object?)finalVideoUrl ?? DBNull.Value);
cmd.Parameters.AddWithValue("errorMessage", (object?)errorMessage ?? DBNull.Value);
await cmd.ExecuteNonQueryAsync();
_logger.LogDebug("Project güncellendi: {Id} → {Status} ({Progress}%)", projectId, status, progress);
}
/// <summary>
/// RenderJob tablosundan durumu çeker.
/// İptal edilmiş işleri atlamak için kullanılır.
/// </summary>
public async Task<string?> GetRenderJobStatus(string renderJobId)
{
await using var conn = new NpgsqlConnection(_connectionString);
await conn.OpenAsync();
var sql = @"SELECT ""status"" FROM ""RenderJob"" WHERE ""id"" = @id";
await using var cmd = new NpgsqlCommand(sql, conn);
cmd.Parameters.AddWithValue("id", renderJobId);
var result = await cmd.ExecuteScalarAsync();
return result?.ToString();
}
/// <summary>
/// Render log kaydı ekler.
/// </summary>
public async Task AddRenderLog(
string renderJobId,
string stage,
string message,
string level = "info",
int? durationMs = null,
string? metadata = null)
{
await using var conn = new NpgsqlConnection(_connectionString);
await conn.OpenAsync();
var sql = @"
INSERT INTO ""RenderLog"" (""id"", ""renderJobId"", ""stage"", ""message"", ""level"", ""durationMs"", ""metadata"", ""createdAt"")
VALUES (gen_random_uuid(), @renderJobId, @stage::""RenderStage"", @message, @level, @durationMs, @metadata::jsonb, NOW())";
await using var cmd = new NpgsqlCommand(sql, conn);
cmd.Parameters.AddWithValue("renderJobId", renderJobId);
cmd.Parameters.AddWithValue("stage", stage);
cmd.Parameters.AddWithValue("message", message);
cmd.Parameters.AddWithValue("level", level);
cmd.Parameters.AddWithValue("durationMs", (object?)durationMs ?? DBNull.Value);
cmd.Parameters.AddWithValue("metadata", (object?)metadata ?? DBNull.Value);
await cmd.ExecuteNonQueryAsync();
}
}