using Microsoft.Data.SqlClient;
namespace ZB.MOM.WW.Auth.ApiKeys.SqlServer;
///
/// Opens connections to the shared SQL Server API-key database and carries the settings every
/// command needs (schema name, command timeout).
///
/// The SQL Server API-key store options; validated in the constructor.
/// is not usable.
public sealed class AuthSqlServerConnectionFactory(SqlServerApiKeyOptions options)
{
private readonly SqlServerApiKeyOptions _options = Validate(options);
private static SqlServerApiKeyOptions Validate(SqlServerApiKeyOptions options)
{
ArgumentNullException.ThrowIfNull(options);
options.Validate();
return options;
}
/// The schema that owns the three API-key tables.
public string Schema => _options.Schema;
/// Command timeout, in whole seconds, for every command issued against this store.
public int CommandTimeoutSeconds => Math.Max(1, (int)_options.CommandTimeout.TotalSeconds);
/// Opens a connection to the shared API-key database.
/// A token to cancel the connect.
/// An opened connection. The caller owns disposal.
public async Task OpenConnectionAsync(CancellationToken cancellationToken)
{
var connection = new SqlConnection(_options.ConnectionString);
try
{
await connection.OpenAsync(cancellationToken).ConfigureAwait(false);
return connection;
}
catch
{
await connection.DisposeAsync().ConfigureAwait(false);
throw;
}
}
///
/// Creates a command on with the configured timeout applied.
///
/// The open connection.
/// The command text.
/// The ambient transaction, if any.
/// The configured command. The caller owns disposal.
public SqlCommand CreateCommand(
SqlConnection connection, string commandText, SqlTransaction? transaction = null)
{
ArgumentNullException.ThrowIfNull(connection);
SqlCommand command = connection.CreateCommand();
command.CommandText = commandText;
command.CommandTimeout = CommandTimeoutSeconds;
command.Transaction = transaction;
return command;
}
}