feat: add F# tryQueryFirst

This commit is contained in:
Kyle Ratti 2024-09-05 23:03:43 -04:00
parent 4dbba5c2f3
commit ad62629a1d
No known key found for this signature in database
GPG Key ID: 4D429B6287C68DD9
9 changed files with 43 additions and 0 deletions

View File

@ -21,7 +21,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Base\Base.csproj" />
<ProjectReference Include="..\FruityFoundation.DataAccess.Abstractions\FruityFoundation.DataAccess.Abstractions.csproj" /> <ProjectReference Include="..\FruityFoundation.DataAccess.Abstractions\FruityFoundation.DataAccess.Abstractions.csproj" />
<ProjectReference Include="..\FsBase\FsBase.fsproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -5,6 +5,7 @@ open System.Collections.Generic
open System.Threading open System.Threading
open FSharp.Control open FSharp.Control
open FruityFoundation.DataAccess.Abstractions open FruityFoundation.DataAccess.Abstractions
open FruityFoundation.FsBase
let private toKeyValuePair (parms : (string * obj) seq) = let private toKeyValuePair (parms : (string * obj) seq) =
parms parms
@ -22,6 +23,11 @@ let querySingle<'a> (connection : IDatabaseConnection<ReadOnly>) (cancellationTo
return! connection.QuerySingle<'a>(sql, parms |> toKeyValuePair, cancellationToken) return! connection.QuerySingle<'a>(sql, parms |> toKeyValuePair, cancellationToken)
} }
let tryQueryFirst<'a> (connection : ReadOnly IDatabaseConnection) (cancellationToken : CancellationToken) (sql : string) (parms : (string * obj) seq) = task {
let! result = connection.TryQueryFirst(sql, parms |> toKeyValuePair, cancellationToken)
return result |> Option.fromMaybe
}
let execute (connection : IDatabaseConnection<ReadOnly>) (cancellationToken : CancellationToken) (sql : string) (parms : (string * obj) seq) = task { let execute (connection : IDatabaseConnection<ReadOnly>) (cancellationToken : CancellationToken) (sql : string) (parms : (string * obj) seq) = task {
return! connection.Execute(sql, parms |> toKeyValuePair, cancellationToken) return! connection.Execute(sql, parms |> toKeyValuePair, cancellationToken)
} }

View File

@ -5,6 +5,7 @@ open System.Collections.Generic
open System.Threading open System.Threading
open FSharp.Control open FSharp.Control
open FruityFoundation.DataAccess.Abstractions open FruityFoundation.DataAccess.Abstractions
open FruityFoundation.FsBase
let private toKeyValuePair (parms : (string * obj) seq) = let private toKeyValuePair (parms : (string * obj) seq) =
parms parms
@ -22,6 +23,11 @@ let querySingle<'a> (connection : IDatabaseConnection<ReadWrite>) (cancellationT
return! connection.QuerySingle<'a>(sql, parms |> toKeyValuePair, cancellationToken) return! connection.QuerySingle<'a>(sql, parms |> toKeyValuePair, cancellationToken)
} }
let tryQueryFirst<'a> (connection : ReadOnly IDatabaseConnection) (cancellationToken : CancellationToken) (sql : string) (parms : (string * obj) seq) = task {
let! result = connection.TryQueryFirst(sql, parms |> toKeyValuePair, cancellationToken)
return result |> Option.fromMaybe
}
let execute (connection : IDatabaseConnection<ReadWrite>) (cancellationToken : CancellationToken) (sql : string) (parms : (string * obj) seq) = task { let execute (connection : IDatabaseConnection<ReadWrite>) (cancellationToken : CancellationToken) (sql : string) (parms : (string * obj) seq) = task {
return! connection.Execute(sql, parms |> toKeyValuePair, cancellationToken) return! connection.Execute(sql, parms |> toKeyValuePair, cancellationToken)
} }

View File

@ -16,4 +16,8 @@
<None Include="..\LICENSE" Pack="true" PackagePath="" /> <None Include="..\LICENSE" Pack="true" PackagePath="" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Base\Base.csproj" />
</ItemGroup>
</Project> </Project>

View File

@ -1,4 +1,5 @@
using System.Data.Common; using System.Data.Common;
using FruityFoundation.Base.Structures;
namespace FruityFoundation.DataAccess.Abstractions; namespace FruityFoundation.DataAccess.Abstractions;
@ -8,6 +9,7 @@ public interface IDatabaseConnection<out TConnectionType> where TConnectionType
public Task<IEnumerable<T>> Query<T>(string sql, object? param = null, CancellationToken cancellationToken = default); public Task<IEnumerable<T>> Query<T>(string sql, object? param = null, CancellationToken cancellationToken = default);
public IAsyncEnumerable<T> QueryUnbuffered<T>(string sql, object? param = null, CancellationToken cancellationToken = default); public IAsyncEnumerable<T> QueryUnbuffered<T>(string sql, object? param = null, CancellationToken cancellationToken = default);
public Task<T> QuerySingle<T>(string sql, object? param = null, CancellationToken cancellationToken = default); public Task<T> QuerySingle<T>(string sql, object? param = null, CancellationToken cancellationToken = default);
public Task<Maybe<T>> TryQueryFirst<T>(string sql, object? param = null, CancellationToken cancellationToken = default);
public Task Execute(string sql, object? param = null, CancellationToken cancellationToken = default); public Task Execute(string sql, object? param = null, CancellationToken cancellationToken = default);
public Task<T?> ExecuteScalar<T>(string sql, object? param = null, CancellationToken cancellationToken = default); public Task<T?> ExecuteScalar<T>(string sql, object? param = null, CancellationToken cancellationToken = default);
public Task<DbDataReader> ExecuteReader(string sql, object? param = null, CancellationToken cancellationToken = default); public Task<DbDataReader> ExecuteReader(string sql, object? param = null, CancellationToken cancellationToken = default);

View File

@ -1,4 +1,5 @@
using System.Data; using System.Data;
using FruityFoundation.Base.Structures;
namespace FruityFoundation.DataAccess.Abstractions; namespace FruityFoundation.DataAccess.Abstractions;

View File

@ -1,6 +1,7 @@
using System.Data.Common; using System.Data.Common;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Dapper; using Dapper;
using FruityFoundation.Base.Structures;
using FruityFoundation.DataAccess.Abstractions; using FruityFoundation.DataAccess.Abstractions;
namespace FruityFoundation.DataAccess.Core; namespace FruityFoundation.DataAccess.Core;
@ -59,6 +60,16 @@ public class DbTransaction<TConnectionType> : IDatabaseTransactionConnection<TCo
return await conn.QuerySingleAsync<T>(command); return await conn.QuerySingleAsync<T>(command);
} }
/// <inheritdoc />
public async Task<Maybe<T>> TryQueryFirst<T>(string sql, object? param = null, CancellationToken cancellationToken = default)
{
if (_transaction.Connection is not { } conn)
throw new InvalidOperationException("Transaction connection cannot be null");
return await conn.QueryUnbufferedAsync<T>(sql, param, transaction: _transaction)
.FirstOrEmptyAsync(cancellationToken);
}
/// <inheritdoc /> /// <inheritdoc />
public async Task Execute(string sql, object? param = null, CancellationToken cancellationToken = default) public async Task Execute(string sql, object? param = null, CancellationToken cancellationToken = default)
{ {

View File

@ -17,6 +17,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Base\Base.csproj" />
<ProjectReference Include="..\FruityFoundation.DataAccess.Abstractions\FruityFoundation.DataAccess.Abstractions.csproj" /> <ProjectReference Include="..\FruityFoundation.DataAccess.Abstractions\FruityFoundation.DataAccess.Abstractions.csproj" />
</ItemGroup> </ItemGroup>

View File

@ -2,6 +2,7 @@
using System.Data.Common; using System.Data.Common;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Dapper; using Dapper;
using FruityFoundation.Base.Structures;
using FruityFoundation.DataAccess.Abstractions; using FruityFoundation.DataAccess.Abstractions;
namespace FruityFoundation.DataAccess.Core; namespace FruityFoundation.DataAccess.Core;
@ -48,6 +49,15 @@ public class NonTransactionalDbConnection<TConnectionType> : INonTransactionalDb
CancellationToken cancellationToken = default CancellationToken cancellationToken = default
) => await _connection.QuerySingleAsync<T>(new CommandDefinition(sql, param, cancellationToken: cancellationToken)); ) => await _connection.QuerySingleAsync<T>(new CommandDefinition(sql, param, cancellationToken: cancellationToken));
/// <inheritdoc />
public async Task<Maybe<T>> TryQueryFirst<T>(
string sql,
object? param = null,
CancellationToken cancellationToken = default
) =>
await _connection.QueryUnbufferedAsync<T>(sql, param, transaction: null)
.FirstOrEmptyAsync(cancellationToken);
/// <inheritdoc /> /// <inheritdoc />
public async Task Execute( public async Task Execute(
string sql, string sql,