using System.Data.Common; using System.Runtime.CompilerServices; using Dapper; using FruityFoundation.DataAccess.Abstractions; using Microsoft.Data.Sqlite; namespace FruityFoundation.DataAccess.Sqlite; public class DbTransaction : IDatabaseTransactionConnection where TConnectionType : ConnectionType { private readonly SqliteTransaction _transaction; internal DbTransaction(SqliteTransaction transaction) { _transaction = transaction; } /// /// public async Task> Query( string sql, object? param = null, CancellationToken cancellationToken = default ) { if (_transaction.Connection is not { } conn) throw new InvalidOperationException("Transaction connection cannot be null"); var command = new CommandDefinition(sql, param, transaction: _transaction, cancellationToken: cancellationToken); return await conn.QueryAsync(command); } /// public async IAsyncEnumerable QueryUnbuffered( string sql, object? param = null, [EnumeratorCancellation] CancellationToken cancellationToken = default ) { if (_transaction.Connection is not { } conn) throw new InvalidOperationException("Transaction connection cannot be null"); var query = conn.QueryUnbufferedAsync(sql, param, transaction: _transaction) .WithCancellation(cancellationToken); await foreach (var item in query) yield return item; } /// public async Task QuerySingle(string sql, object? param = null, CancellationToken cancellationToken = default) { if (_transaction.Connection is not { } conn) throw new InvalidOperationException("Transaction connection cannot be null"); var command = new CommandDefinition(sql, param, transaction: _transaction, cancellationToken: cancellationToken); return await conn.QuerySingleAsync(command); } /// public async Task Execute(string sql, object? param = null, CancellationToken cancellationToken = default) { if (_transaction.Connection is not { } conn) throw new InvalidOperationException("Transaction connection cannot be null"); var command = new CommandDefinition(sql, param, transaction: _transaction, cancellationToken: cancellationToken); await conn.ExecuteAsync(command); } /// public async Task ExecuteScalar(string sql, object? param = null, CancellationToken cancellationToken = default) { if (_transaction.Connection is not { } conn) throw new InvalidOperationException("Transaction connection cannot be null"); var command = new CommandDefinition(sql, param, transaction: _transaction, cancellationToken: cancellationToken); return await conn.ExecuteScalarAsync(command); } /// public async Task ExecuteReader( string sql, object? param = null, CancellationToken cancellationToken = default ) { if (_transaction.Connection is not { } conn) throw new InvalidOperationException("Transaction connection cannot be null"); var command = new CommandDefinition(sql, param, transaction: _transaction, cancellationToken: cancellationToken); return await conn.ExecuteReaderAsync(command); } /// public async Task Commit(CancellationToken cancellationToken) { await _transaction.CommitAsync(cancellationToken); } /// public async Task Rollback(CancellationToken cancellationToken) { await _transaction.RollbackAsync(cancellationToken); } /// public void Dispose() { _transaction.Dispose(); GC.SuppressFinalize(this); } /// public async ValueTask DisposeAsync() { await _transaction.DisposeAsync(); GC.SuppressFinalize(this); } }