Files
DbFirst/DbFirst.API/Dashboards/SqlDashboardStorage.cs
OlgunR 292ce02370 Refactor using statements for clearer layer boundaries
Clean up and reorganize using/import statements across the solution. Remove unnecessary DTO imports from Application and Infrastructure layers, and ensure Contracts DTOs are only referenced in API and BlazorWebApp layers. No business logic is changed; these updates improve code organization, reduce coupling, and clarify architectural separation between layers.
2026-04-23 13:55:05 +02:00

139 lines
5.7 KiB
C#

using DevExpress.DashboardWeb;
using Microsoft.Data.SqlClient;
using System.Data;
using System.Text;
using System.Xml.Linq;
namespace DbFirst.API.Dashboards;
public sealed class SqlDashboardStorage : IEditableDashboardStorage
{
private readonly string _connectionString;
private readonly string _tableName;
private readonly Func<string?>? _userProvider;
private readonly IDashboardChangeNotifier? _notifier;
public SqlDashboardStorage(string connectionString, string tableName = "TBDD_SMF_CONFIG", Func<string?>? userProvider = null, IDashboardChangeNotifier? notifier = null)
{
_connectionString = connectionString;
_tableName = tableName;
_userProvider = userProvider;
_notifier = notifier;
}
public IEnumerable<DashboardInfo> GetAvailableDashboardsInfo()
{
var dashboards = new List<DashboardInfo>();
using var connection = new SqlConnection(_connectionString);
using var command = new SqlCommand($"SELECT DashboardId, DashboardName FROM dbo.[{_tableName}] WHERE ACTIVE = 1 ORDER BY DashboardName", connection);
connection.Open();
using var reader = command.ExecuteReader();
while (reader.Read())
{
var id = reader.GetString(0);
var name = reader.GetString(1);
dashboards.Add(new DashboardInfo { ID = id, Name = name });
}
return dashboards;
}
public XDocument LoadDashboard(string dashboardId)
{
using var connection = new SqlConnection(_connectionString);
using var command = new SqlCommand($"SELECT DashboardData FROM dbo.[{_tableName}] WHERE DashboardId = @Id AND ACTIVE = 1", connection);
command.Parameters.Add(new SqlParameter("@Id", SqlDbType.NVarChar, 128) { Value = dashboardId });
connection.Open();
var data = command.ExecuteScalar() as byte[];
if (data == null)
{
throw new ArgumentException($"Dashboard '{dashboardId}' not found.");
}
var xml = Encoding.UTF8.GetString(data);
var doc = XDocument.Parse(xml);
NormalizeCatalogDateDimensions(doc);
return doc;
}
private static void NormalizeCatalogDateDimensions(XDocument doc)
{
var dateMembers = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"AddedWhen",
"ChangedWhen"
};
foreach (var dimension in doc.Descendants("Dimension"))
{
var member = dimension.Attribute("DataMember")?.Value;
if (member == null || !dateMembers.Contains(member))
{
continue;
}
var interval = dimension.Attribute("DateTimeGroupInterval")?.Value;
if (string.IsNullOrWhiteSpace(interval) || string.Equals(interval, "Year", StringComparison.OrdinalIgnoreCase))
{
dimension.SetAttributeValue("DateTimeGroupInterval", "DayMonthYear");
}
}
}
public string AddDashboard(XDocument dashboard, string dashboardName)
{
var id = string.IsNullOrWhiteSpace(dashboardName)
? Guid.NewGuid().ToString("N")
: dashboardName;
var payload = Encoding.UTF8.GetBytes(dashboard.ToString(SaveOptions.DisableFormatting));
var userName = _userProvider?.Invoke();
using var connection = new SqlConnection(_connectionString);
using var command = new SqlCommand($"INSERT INTO dbo.[{_tableName}] (ACTIVE, DashboardId, DashboardName, DashboardData, ADDED_WHO, ADDED_WHEN) VALUES (1, @Id, @Name, @Data, COALESCE(@User, SUSER_SNAME()), SYSUTCDATETIME())", connection);
command.Parameters.Add(new SqlParameter("@Id", SqlDbType.NVarChar, 128) { Value = id });
command.Parameters.Add(new SqlParameter("@Name", SqlDbType.NVarChar, 256) { Value = string.IsNullOrWhiteSpace(dashboardName) ? id : dashboardName });
command.Parameters.Add(new SqlParameter("@Data", SqlDbType.VarBinary, -1) { Value = payload });
command.Parameters.Add(new SqlParameter("@User", SqlDbType.NVarChar, 50) { Value = (object?)userName ?? DBNull.Value });
connection.Open();
command.ExecuteNonQuery();
_ = _notifier?.NotifyChangedAsync();
return id;
}
public void SaveDashboard(string dashboardId, XDocument dashboard)
{
var payload = Encoding.UTF8.GetBytes(dashboard.ToString(SaveOptions.DisableFormatting));
var userName = _userProvider?.Invoke();
using var connection = new SqlConnection(_connectionString);
using var command = new SqlCommand($"UPDATE dbo.[{_tableName}] SET DashboardData = @Data, CHANGED_WHO = COALESCE(@User, SUSER_SNAME()), CHANGED_WHEN = SYSUTCDATETIME() WHERE DashboardId = @Id", connection);
command.Parameters.Add(new SqlParameter("@Id", SqlDbType.NVarChar, 128) { Value = dashboardId });
command.Parameters.Add(new SqlParameter("@Data", SqlDbType.VarBinary, -1) { Value = payload });
command.Parameters.Add(new SqlParameter("@User", SqlDbType.NVarChar, 50) { Value = (object?)userName ?? DBNull.Value });
connection.Open();
var rows = command.ExecuteNonQuery();
if (rows == 0)
{
throw new ArgumentException($"Dashboard '{dashboardId}' not found.");
}
_ = _notifier?.NotifyChangedAsync();
}
public void DeleteDashboard(string dashboardId)
{
using var connection = new SqlConnection(_connectionString);
using var command = new SqlCommand($"DELETE FROM dbo.[{_tableName}] WHERE DashboardId = @Id", connection);
command.Parameters.Add(new SqlParameter("@Id", SqlDbType.NVarChar, 128) { Value = dashboardId });
connection.Open();
command.ExecuteNonQuery();
_ = _notifier?.NotifyChangedAsync();
}
}