feat: migrate legacy playout workflow and scenes

This commit is contained in:
2026-07-10 23:58:45 +09:00
parent 491a740505
commit 8dae7b8e0d
128 changed files with 39177 additions and 205 deletions

View File

@@ -18,12 +18,28 @@ internal sealed class ConnectionPlan
public int? ObservedCommandTimeoutSeconds { get; set; }
public string? ObservedCommandText { get; set; }
public IReadOnlyList<ObservedDbParameter> ObservedParameters { get; set; } = [];
public CancellationToken ObservedExecuteCancellationToken { get; set; }
public int SynchronousOpenCount { get; set; }
public int SynchronousExecuteCount { get; set; }
public static ConnectionPlan Success(DataTable data) => new()
{
ExecuteReaderAsync = _ => Task.FromResult<DbDataReader>(data.CreateDataReader())
};
}
internal sealed record ObservedDbParameter(
string Name,
object? Value,
DbType? ExplicitDbType,
ParameterDirection Direction);
internal sealed class FakeConnectionFactory : IDatabaseConnectionFactory
{
private readonly Queue<ConnectionPlan> _plans;
@@ -85,7 +101,11 @@ internal sealed class FakeDbConnection(ConnectionPlan plan) : DbConnection
public override void Close() => _state = ConnectionState.Closed;
public override void Open() => OpenAsync(CancellationToken.None).GetAwaiter().GetResult();
public override void Open()
{
plan.SynchronousOpenCount++;
throw new InvalidOperationException("The synchronous open path must not be used.");
}
public override async Task OpenAsync(CancellationToken cancellationToken)
{
@@ -146,20 +166,50 @@ internal sealed class FakeDbCommand(DbConnection connection, ConnectionPlan plan
protected override DbParameter CreateDbParameter() => new FakeDbParameter();
protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior) =>
ExecuteDbDataReaderAsync(behavior, CancellationToken.None).GetAwaiter().GetResult();
throw RecordSynchronousExecution();
protected override Task<DbDataReader> ExecuteDbDataReaderAsync(
CommandBehavior behavior,
CancellationToken cancellationToken)
{
plan.ObservedCommandTimeoutSeconds = CommandTimeout;
plan.ObservedCommandText = CommandText;
plan.ObservedParameters = _parameters
.Cast<DbParameter>()
.Select(parameter => new ObservedDbParameter(
parameter.ParameterName,
parameter.Value,
parameter is FakeDbParameter fakeParameter && fakeParameter.WasDbTypeSet
? parameter.DbType
: null,
parameter.Direction))
.ToArray();
plan.ObservedExecuteCancellationToken = cancellationToken;
return plan.ExecuteReaderAsync(cancellationToken);
}
private Exception RecordSynchronousExecution()
{
plan.SynchronousExecuteCount++;
return new InvalidOperationException("The synchronous command path must not be used.");
}
}
internal sealed class FakeDbParameter : DbParameter
{
public override DbType DbType { get; set; }
private DbType _dbType;
public bool WasDbTypeSet { get; private set; }
public override DbType DbType
{
get => _dbType;
set
{
_dbType = value;
WasDbTypeSet = true;
}
}
public override ParameterDirection Direction { get; set; }
@@ -179,6 +229,8 @@ internal sealed class FakeDbParameter : DbParameter
public override void ResetDbType()
{
_dbType = default;
WasDbTypeSet = false;
}
}