Replaced file-based dashboard storage with SQL Server-backed storage using the new SqlDashboardStorage class and TBDD_SMF_CONFIG table. Updated Program.cs to use the new storage and ensure default dashboards are loaded into the database. Simplified DefaultDashboard.xml to remove old items. Added SQL script for the dashboard storage table. Cleaned up unused folder references in the project file. This centralizes dashboard management and supports multi-instance scenarios.
107 lines
4.6 KiB
C#
107 lines
4.6 KiB
C#
using System.Data;
|
|
using System.Text;
|
|
using System.Xml.Linq;
|
|
using DevExpress.DashboardWeb;
|
|
using Microsoft.Data.SqlClient;
|
|
|
|
namespace DbFirst.API.Dashboards;
|
|
|
|
public sealed class SqlDashboardStorage : IEditableDashboardStorage
|
|
{
|
|
private readonly string _connectionString;
|
|
private readonly string _tableName;
|
|
private readonly Func<string?>? _userProvider;
|
|
|
|
public SqlDashboardStorage(string connectionString, string tableName = "TBDD_SMF_CONFIG", Func<string?>? userProvider = null)
|
|
{
|
|
_connectionString = connectionString;
|
|
_tableName = tableName;
|
|
_userProvider = userProvider;
|
|
}
|
|
|
|
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);
|
|
return XDocument.Parse(xml);
|
|
}
|
|
|
|
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();
|
|
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.");
|
|
}
|
|
}
|
|
|
|
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();
|
|
}
|
|
}
|