Use scalar for custom count/exists

This commit is contained in:
Daniel J. Summers 2023-02-24 21:51:51 -05:00
parent d1f3442118
commit 4b43305746
6 changed files with 21 additions and 40 deletions

View File

@ -5,7 +5,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="BitBadger.Npgsql.FSharp.Documents" Version="1.0.0-beta" /> <PackageReference Include="BitBadger.Npgsql.FSharp.Documents" Version="1.0.0-beta2" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.8" /> <PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.8" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="6.0.0" /> <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" />

View File

@ -48,13 +48,10 @@ type DistributedCache () =
do do
task { task {
let! exists = let! exists =
Configuration.dataSource () Custom.scalar
|> Sql.fromDataSource $"SELECT EXISTS
|> Sql.query $"
SELECT EXISTS
(SELECT 1 FROM pg_tables WHERE schemaname = 'public' AND tablename = 'session') (SELECT 1 FROM pg_tables WHERE schemaname = 'public' AND tablename = 'session')
AS {existsName}" AS {existsName}" [] Map.toExists
|> Sql.executeRowAsync Map.toExists
if not exists then if not exists then
do! Custom.nonQuery do! Custom.nonQuery
"CREATE TABLE session ( "CREATE TABLE session (

View File

@ -38,19 +38,15 @@ type PostgresCategoryData (log : ILogger) =
|> List.ofSeq |> List.ofSeq
|> arrayContains (nameof Post.empty.CategoryIds) id |> arrayContains (nameof Post.empty.CategoryIds) id
let postCount = let postCount =
Configuration.dataSource () Custom.scalar
|> Sql.fromDataSource $"""SELECT COUNT(DISTINCT id) AS {countName}
|> Sql.query $"""
SELECT COUNT(DISTINCT id) AS {countName}
FROM {Table.Post} FROM {Table.Post}
WHERE {Query.whereDataContains "@criteria"} WHERE {Query.whereDataContains "@criteria"}
AND {catIdSql}""" AND {catIdSql}"""
|> Sql.parameters
[ "@criteria", [ "@criteria",
Query.jsonbDocParam {| webLogDoc webLogId with Status = PostStatus.toString Published |} Query.jsonbDocParam {| webLogDoc webLogId with Status = PostStatus.toString Published |}
catIdParams catIdParams
] ] Map.toCount
|> Sql.executeRowAsync Map.toCount
|> Async.AwaitTask |> Async.AwaitTask
|> Async.RunSynchronously |> Async.RunSynchronously
it.Id, postCount) it.Id, postCount)

View File

@ -168,14 +168,11 @@ module Document =
/// Determine whether a document exists with the given key for the given web log /// Determine whether a document exists with the given key for the given web log
let existsByWebLog<'TKey> table (key : 'TKey) (keyFunc : 'TKey -> string) webLogId = let existsByWebLog<'TKey> table (key : 'TKey) (keyFunc : 'TKey -> string) webLogId =
Configuration.dataSource () Custom.scalar
|> Sql.fromDataSource $""" SELECT EXISTS (
|> Sql.query $"""
SELECT EXISTS (
SELECT 1 FROM %s{table} WHERE id = @id AND {Query.whereDataContains "@criteria"} SELECT 1 FROM %s{table} WHERE id = @id AND {Query.whereDataContains "@criteria"}
) AS {existsName}""" ) AS {existsName}"""
|> Sql.parameters [ "@id", Sql.string (keyFunc key); webLogContains webLogId ] [ "@id", Sql.string (keyFunc key); webLogContains webLogId ] Map.toExists
|> Sql.executeRowAsync Map.toExists
/// Find a document by its ID for the given web log /// Find a document by its ID for the given web log
let findByIdAndWebLog<'TKey, 'TDoc> table (key : 'TKey) (keyFunc : 'TKey -> string) webLogId = let findByIdAndWebLog<'TKey, 'TDoc> table (key : 'TKey) (keyFunc : 'TKey -> string) webLogId =

View File

@ -38,13 +38,7 @@ type PostgresPostData (log : ILogger) =
/// Count posts in a status for the given web log /// Count posts in a status for the given web log
let countByStatus status webLogId = let countByStatus status webLogId =
log.LogTrace "Post.countByStatus" log.LogTrace "Post.countByStatus"
Configuration.dataSource () Count.byContains Table.Post {| webLogDoc webLogId with Status = PostStatus.toString status |}
|> Sql.fromDataSource
|> Sql.query
$"""SELECT COUNT(id) AS {countName} FROM {Table.Post} WHERE {Query.whereDataContains "@criteria"}"""
|> Sql.parameters
[ "@criteria", Query.jsonbDocParam {| webLogDoc webLogId with Status = PostStatus.toString status |} ]
|> Sql.executeRowAsync Map.toCount
/// Find a post by its ID for the given web log (excluding revisions) /// Find a post by its ID for the given web log (excluding revisions)
let findById postId webLogId = let findById postId webLogId =

View File

@ -21,14 +21,11 @@ type PostgresWebLogUserData (log : ILogger) =
| Some _ -> | Some _ ->
let criteria = Query.whereDataContains "@criteria" let criteria = Query.whereDataContains "@criteria"
let! isAuthor = let! isAuthor =
Configuration.dataSource () Custom.scalar
|> Sql.fromDataSource $" SELECT ( EXISTS (SELECT 1 FROM {Table.Page} WHERE {criteria}
|> Sql.query $" OR EXISTS (SELECT 1 FROM {Table.Post} WHERE {criteria})
SELECT ( EXISTS (SELECT 1 FROM {Table.Page} WHERE {criteria} ) AS {existsName}"
OR EXISTS (SELECT 1 FROM {Table.Post} WHERE {criteria})) [ "@criteria", Query.jsonbDocParam {| AuthorId = userId |} ] Map.toExists
AS {existsName}"
|> Sql.parameters [ "@criteria", Query.jsonbDocParam {| AuthorId = userId |} ]
|> Sql.executeRowAsync Map.toExists
if isAuthor then if isAuthor then
return Error "User has pages or posts; cannot delete" return Error "User has pages or posts; cannot delete"
else else