feat: complete legacy UI and playout parity migration
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
#nullable enable
|
||||
|
||||
using System.Data;
|
||||
using MMoneyCoderSharp.Data;
|
||||
|
||||
namespace MBN_STOCK_WEBVIEW.DbWriteSmoke;
|
||||
|
||||
/// <summary>
|
||||
/// The legacy deletion workflows remove child rows by numeric parent key. This
|
||||
/// read-only guard proves a newly suggested key has no pre-existing orphaned
|
||||
/// children before a smoke record can adopt that key.
|
||||
/// </summary>
|
||||
internal sealed class ExistingChildRowGuard
|
||||
{
|
||||
private const string ResultColumn = "ROW_COUNT";
|
||||
|
||||
private readonly IDataQueryExecutor _executor;
|
||||
|
||||
internal ExistingChildRowGuard(IDataQueryExecutor executor)
|
||||
{
|
||||
_executor = executor ?? throw new ArgumentNullException(nameof(executor));
|
||||
}
|
||||
|
||||
internal Task EnsureNamedPlaylistChildrenAbsentAsync(
|
||||
string programCode,
|
||||
CancellationToken cancellationToken) =>
|
||||
EnsureZeroAsync(
|
||||
DataSourceKind.Oracle,
|
||||
"DB_WRITE_SMOKE_PLAYLIST_CHILD_PREFLIGHT",
|
||||
"SELECT TO_CHAR(COUNT(*)) ROW_COUNT FROM PLAY_LIST WHERE PG_CODE = :parent_code",
|
||||
programCode,
|
||||
cancellationToken);
|
||||
|
||||
internal Task EnsureThemeChildrenAbsentAsync(
|
||||
ThemeMarket market,
|
||||
string themeCode,
|
||||
CancellationToken cancellationToken) =>
|
||||
market switch
|
||||
{
|
||||
ThemeMarket.Krx => EnsureZeroAsync(
|
||||
DataSourceKind.Oracle,
|
||||
"DB_WRITE_SMOKE_KRX_THEME_CHILD_PREFLIGHT",
|
||||
"SELECT TO_CHAR(COUNT(*)) ROW_COUNT FROM SB_ITEM WHERE SB_M_CODE = :parent_code",
|
||||
themeCode,
|
||||
cancellationToken),
|
||||
ThemeMarket.Nxt => EnsureZeroAsync(
|
||||
DataSourceKind.MariaDb,
|
||||
"DB_WRITE_SMOKE_NXT_THEME_CHILD_PREFLIGHT",
|
||||
"SELECT CAST(COUNT(*) AS CHAR) ROW_COUNT FROM SB_ITEM WHERE SB_M_CODE = @parent_code",
|
||||
themeCode,
|
||||
cancellationToken),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(market))
|
||||
};
|
||||
|
||||
internal Task EnsureExpertChildrenAbsentAsync(
|
||||
string expertCode,
|
||||
CancellationToken cancellationToken) =>
|
||||
EnsureZeroAsync(
|
||||
DataSourceKind.Oracle,
|
||||
"DB_WRITE_SMOKE_EXPERT_CHILD_PREFLIGHT",
|
||||
"SELECT TO_CHAR(COUNT(*)) ROW_COUNT FROM RECOMMEND_LIST WHERE RC_CODE = :parent_code",
|
||||
expertCode,
|
||||
cancellationToken);
|
||||
|
||||
private async Task EnsureZeroAsync(
|
||||
DataSourceKind source,
|
||||
string queryName,
|
||||
string sql,
|
||||
string parentCode,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(parentCode);
|
||||
var spec = new DataQuerySpec(
|
||||
sql,
|
||||
[new DataQueryParameter("parent_code", parentCode, DbType.String)]);
|
||||
spec.ValidateFor(source);
|
||||
var table = await _executor.ExecuteAsync(
|
||||
source,
|
||||
queryName,
|
||||
spec,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (table is null ||
|
||||
table.Columns.Count != 1 ||
|
||||
table.Rows.Count != 1 ||
|
||||
!string.Equals(
|
||||
table.Columns[0].ColumnName,
|
||||
ResultColumn,
|
||||
StringComparison.Ordinal) ||
|
||||
table.Columns[0].DataType != typeof(string) ||
|
||||
table.Rows[0][0] is not string count ||
|
||||
!string.Equals(count, "0", StringComparison.Ordinal))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"A suggested numeric key has existing child rows or an invalid preflight result.");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user