V2 #36

Merged
danieljsummers merged 17 commits from v2-out-the-door into main 2023-02-26 18:01:21 +00:00
8 changed files with 57 additions and 78 deletions
Showing only changes of commit bb12d2525e - Show all commits

View File

@ -200,11 +200,11 @@ type DistributedCache (connStr : string) =
}
interface IDistributedCache with
member this.Get key = get key CancellationToken.None |> sync
member this.GetAsync (key, token) = get key token
member this.Refresh key = refresh key CancellationToken.None |> sync
member this.RefreshAsync (key, token) = refresh key token
member this.Remove key = remove key CancellationToken.None |> sync
member this.RemoveAsync (key, token) = remove key token
member this.Set (key, value, options) = set key value options CancellationToken.None |> sync
member this.SetAsync (key, value, options, token) = set key value options token
member _.Get key = get key CancellationToken.None |> sync
member _.GetAsync (key, token) = get key token
member _.Refresh key = refresh key CancellationToken.None |> sync
member _.RefreshAsync (key, token) = refresh key token
member _.Remove key = remove key CancellationToken.None |> sync
member _.RemoveAsync (key, token) = remove key token
member _.Set (key, value, options) = set key value options CancellationToken.None |> sync
member _.SetAsync (key, value, options, token) = set key value options token

View File

@ -9,18 +9,15 @@ open Npgsql.FSharp.Documents
/// PostgreSQL myWebLog category data implementation
type PostgresCategoryData (source : NpgsqlDataSource) =
/// Shorthand for turning a web log ID into a string
let wls = WebLogId.toString
/// Count all categories for the given web log
let countAll webLogId =
Sql.fromDataSource source
|> Query.countByContains Table.Category {| WebLogId = wls webLogId |}
|> Query.countByContains Table.Category (webLogDoc webLogId)
/// Count all top-level categories for the given web log
let countTopLevel webLogId =
Sql.fromDataSource source
|> Query.countByContains Table.Category {| WebLogId = wls webLogId; ParentId = None |}
|> Query.countByContains Table.Category {| webLogDoc webLogId with ParentId = None |}
/// Retrieve all categories for the given web log in a DotLiquid-friendly format
let findAllForView webLogId = backgroundTask {
@ -30,7 +27,7 @@ type PostgresCategoryData (source : NpgsqlDataSource) =
{Query.selectFromTable Table.Category}
WHERE {Query.whereDataContains "@criteria"}
ORDER BY LOWER(data->>'{nameof Category.empty.Name}')"""
|> Sql.parameters [ "@criteria", webLogContains webLogId ]
|> Sql.parameters [ webLogContains webLogId ]
|> Sql.executeAsync fromData<Category>
let ordered = Utils.orderByHierarchy cats None None []
let counts =
@ -53,7 +50,7 @@ type PostgresCategoryData (source : NpgsqlDataSource) =
AND ({catIdSql})"""
|> Sql.parameters (
("@criteria",
Query.jsonbDocParam {| WebLogId = wls webLogId; Status = PostStatus.toString Published |})
Query.jsonbDocParam {| webLogDoc webLogId with Status = PostStatus.toString Published |})
:: catIdParams)
|> Sql.executeRowAsync Map.toCount
|> Async.AwaitTask

View File

@ -68,16 +68,17 @@ open Npgsql
open Npgsql.FSharp
open Npgsql.FSharp.Documents
/// Create a WHERE clause fragment for the web log ID
let webLogWhere = "data ->> 'WebLogId' = @webLogId"
/// Create a SQL parameter for the web log ID
let webLogIdParam webLogId =
"@webLogId", Sql.string (WebLogId.toString webLogId)
/// Create an anonymous record with the given web log ID
let webLogDoc webLogId =
{| WebLogId = WebLogId.toString webLogId |}
/// Create a parameter for a web log document-contains query
let webLogContains webLogId =
Query.jsonbDocParam {| WebLogId = WebLogId.toString webLogId |}
"@criteria", Query.jsonbDocParam (webLogDoc webLogId)
/// The name of the field to select to be able to use Map.toCount
let countName = "the_count"
@ -179,21 +180,21 @@ module Document =
SELECT EXISTS (
SELECT 1 FROM %s{table} WHERE id = @id AND {Query.whereDataContains "@criteria"}
) AS {existsName}"""
|> Sql.parameters [ "@id", Sql.string (keyFunc key); webLogIdParam webLogId ]
|> Sql.parameters [ "@id", Sql.string (keyFunc key); webLogContains webLogId ]
|> Sql.executeRowAsync Map.toExists
/// Find a document by its ID for the given web log
let findByIdAndWebLog<'TKey, 'TDoc> source table (key : 'TKey) (keyFunc : 'TKey -> string) webLogId =
Sql.fromDataSource source
|> Sql.query $"""{Query.selectFromTable table} WHERE id = @id AND {Query.whereDataContains "@criteria"}"""
|> Sql.parameters [ "@id", Sql.string (keyFunc key); "@criteria", webLogContains webLogId ]
|> Sql.parameters [ "@id", Sql.string (keyFunc key); webLogContains webLogId ]
|> Sql.executeAsync fromData<'TDoc>
|> tryHead
/// Find a document by its ID for the given web log
let findByWebLog<'TDoc> source table webLogId : Task<'TDoc list> =
Sql.fromDataSource source
|> Query.findByContains table {| WebLogId = WebLogId.toString webLogId |}
|> Query.findByContains table (webLogDoc webLogId)
/// Functions to support revisions
@ -209,13 +210,13 @@ module Revisions =
/// Find all revisions for all posts for the given web log
let findByWebLog<'TKey> source revTable entityTable (keyFunc : string -> 'TKey) webLogId =
Sql.fromDataSource source
|> Sql.query $"
|> Sql.query $"""
SELECT pr.*
FROM %s{revTable} pr
INNER JOIN %s{entityTable} p ON p.id = pr.{entityTable}_id
WHERE p.{webLogWhere}
ORDER BY as_of DESC"
|> Sql.parameters [ webLogIdParam webLogId ]
WHERE p.{Query.whereDataContains "@criteria"}
ORDER BY as_of DESC"""
|> Sql.parameters [ webLogContains webLogId ]
|> Sql.executeAsync (fun row -> keyFunc (row.string $"{entityTable}_id"), Map.toRevision row)
/// Parameters for a revision INSERT statement

View File

@ -11,9 +11,6 @@ type PostgresPageData (source : NpgsqlDataSource) =
// SUPPORT FUNCTIONS
/// Shorthand for turning a web log ID into a string
let wls = WebLogId.toString
/// Append revisions to a page
let appendPageRevisions (page : Page) = backgroundTask {
let! revisions = Revisions.findByEntityId source Table.PageRevision Table.Page page.Id PageId.toString
@ -32,27 +29,28 @@ type PostgresPageData (source : NpgsqlDataSource) =
let pageExists pageId webLogId =
Document.existsByWebLog source Table.Page pageId PageId.toString webLogId
/// Select pages via a JSON document containment query
let pageByCriteria =
$"""{Query.selectFromTable Table.Page} WHERE {Query.whereDataContains "@criteria"}"""
// IMPLEMENTATION FUNCTIONS
/// Get all pages for a web log (without text or revisions)
let all webLogId =
Sql.fromDataSource source
|> Sql.query $"""
{Query.selectFromTable Table.Page}
WHERE {Query.whereDataContains "@criteria"}
ORDER BY LOWER(data->>'{nameof Page.empty.Title}')"""
|> Sql.parameters [ "@criteria", webLogContains webLogId ]
|> Sql.query $"{pageByCriteria} ORDER BY LOWER(data->>'{nameof Page.empty.Title}')"
|> Sql.parameters [ webLogContains webLogId ]
|> Sql.executeAsync fromData<Page>
/// Count all pages for the given web log
let countAll webLogId =
Sql.fromDataSource source
|> Query.countByContains Table.Page {| WebLogId = wls webLogId |}
|> Query.countByContains Table.Page (webLogDoc webLogId)
/// Count all pages shown in the page list for the given web log
let countListed webLogId =
Sql.fromDataSource source
|> Query.countByContains Table.Page {| WebLogId = wls webLogId; IsInPageList = true |}
|> Query.countByContains Table.Page {| webLogDoc webLogId with IsInPageList = true |}
/// Find a page by its ID (without revisions)
let findById pageId webLogId =
@ -79,7 +77,7 @@ type PostgresPageData (source : NpgsqlDataSource) =
/// Find a page by its permalink for the given web log
let findByPermalink permalink webLogId =
Sql.fromDataSource source
|> Query.findByContains<Page> Table.Page {| WebLogId = wls webLogId; Permalink = Permalink.toString permalink |}
|> Query.findByContains<Page> Table.Page {| webLogDoc webLogId with Permalink = Permalink.toString permalink |}
|> tryHead
/// Find the current permalink within a set of potential prior permalinks for the given web log
@ -96,7 +94,7 @@ type PostgresPageData (source : NpgsqlDataSource) =
FROM page
WHERE {Query.whereDataContains "@criteria"}
AND ({linkSql})"""
|> Sql.parameters (("@criteria", webLogContains webLogId) :: linkParams)
|> Sql.parameters (webLogContains webLogId :: linkParams)
|> Sql.executeAsync Map.toPermalink
|> tryHead
}
@ -114,26 +112,18 @@ type PostgresPageData (source : NpgsqlDataSource) =
/// Get all listed pages for the given web log (without revisions or text)
let findListed webLogId =
Sql.fromDataSource source
|> Sql.query $"""
{Query.selectFromTable Table.Page}
WHERE {Query.whereDataContains "@criteria"}
ORDER BY LOWER(data->>'{nameof Page.empty.Title}')"""
|> Sql.parameters [ "@criteria", Query.jsonbDocParam {| WebLogId = wls webLogId; IsInPageList = true |} ]
|> Sql.query $"{pageByCriteria} ORDER BY LOWER(data->>'{nameof Page.empty.Title}')"
|> Sql.parameters [ "@criteria", Query.jsonbDocParam {| webLogDoc webLogId with IsInPageList = true |} ]
|> Sql.executeAsync pageWithoutText
/// Get a page of pages for the given web log (without revisions)
let findPageOfPages webLogId pageNbr =
Sql.fromDataSource source
|> Sql.query $"""
{Query.selectFromTable Table.Page}
WHERE {Query.whereDataContains "@criteria"}
|> Sql.query $"
{pageByCriteria}
ORDER BY LOWER(data->>'{nameof Page.empty.Title}')
LIMIT @pageSize OFFSET @toSkip"""
|> Sql.parameters
[ "@criteria", webLogContains webLogId
"@pageSize", Sql.int 26
"@toSkip", Sql.int ((pageNbr - 1) * 25)
]
LIMIT @pageSize OFFSET @toSkip"
|> Sql.parameters [ webLogContains webLogId; "@pageSize", Sql.int 26; "@toSkip", Sql.int ((pageNbr - 1) * 25) ]
|> Sql.executeAsync fromData<Page>
/// The parameters for saving a page

View File

@ -12,9 +12,6 @@ type PostgresPostData (source : NpgsqlDataSource) =
// SUPPORT FUNCTIONS
/// Shorthand for turning a web log ID into a string
let wls = WebLogId.toString
/// Append revisions to a post
let appendPostRevisions (post : Post) = backgroundTask {
let! revisions = Revisions.findByEntityId source Table.PostRevision Table.Post post.Id PostId.toString
@ -45,7 +42,7 @@ type PostgresPostData (source : NpgsqlDataSource) =
|> Sql.query
$"""SELECT COUNT(id) AS {countName} FROM {Table.Post} WHERE {Query.whereDataContains "@criteria"}"""
|> Sql.parameters
[ "@criteria", Query.jsonbDocParam {| WebLogId = wls webLogId; Status = PostStatus.toString status |} ]
[ "@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)
@ -57,7 +54,7 @@ type PostgresPostData (source : NpgsqlDataSource) =
Sql.fromDataSource source
|> Sql.query postsByCriteria
|> Sql.parameters
[ "@criteria", Query.jsonbDocParam {| WebLogId = wls webLogId; Permalink = Permalink.toString permalink |} ]
[ "@criteria", Query.jsonbDocParam {| webLogDoc webLogId with Permalink = Permalink.toString permalink |} ]
|> Sql.executeAsync fromData<Post>
|> tryHead
@ -99,7 +96,7 @@ type PostgresPostData (source : NpgsqlDataSource) =
FROM {Table.Post}
WHERE {Query.whereDataContains "@criteria"}
AND ({linkSql})"""
|> Sql.parameters (("@criteria", webLogContains webLogId) :: linkParams)
|> Sql.parameters (webLogContains webLogId :: linkParams)
|> Sql.executeAsync Map.toPermalink
|> tryHead
}
@ -124,7 +121,7 @@ type PostgresPostData (source : NpgsqlDataSource) =
ORDER BY published_on DESC
LIMIT {postsPerPage + 1} OFFSET {(pageNbr - 1) * postsPerPage}"
|> Sql.parameters (
("@criteria", Query.jsonbDocParam {| WebLogId = wls webLogId; Status = PostStatus.toString Published |})
("@criteria", Query.jsonbDocParam {| webLogDoc webLogId with Status = PostStatus.toString Published |})
:: catParams)
|> Sql.executeAsync fromData<Post>
@ -136,7 +133,7 @@ type PostgresPostData (source : NpgsqlDataSource) =
ORDER BY data->>'{nameof Post.empty.PublishedOn}' DESC NULLS FIRST,
data->>'{nameof Post.empty.UpdatedOn}'
LIMIT {postsPerPage + 1} OFFSET {(pageNbr - 1) * postsPerPage}"
|> Sql.parameters [ "@criteria", webLogContains webLogId ]
|> Sql.parameters [ webLogContains webLogId ]
|> Sql.executeAsync postWithoutText
/// Get a page of published posts for the given web log (excludes revisions)
@ -147,7 +144,7 @@ type PostgresPostData (source : NpgsqlDataSource) =
ORDER BY data->>'{nameof Post.empty.PublishedOn}' DESC
LIMIT {postsPerPage + 1} OFFSET {(pageNbr - 1) * postsPerPage}"
|> Sql.parameters
[ "@criteria", Query.jsonbDocParam {| WebLogId = wls webLogId; Status = PostStatus.toString Published |} ]
[ "@criteria", Query.jsonbDocParam {| webLogDoc webLogId with Status = PostStatus.toString Published |} ]
|> Sql.executeAsync fromData<Post>
/// Get a page of tagged posts for the given web log (excludes revisions and prior permalinks)
@ -159,7 +156,7 @@ type PostgresPostData (source : NpgsqlDataSource) =
ORDER BY data->>'{nameof Post.empty.PublishedOn}' DESC
LIMIT {postsPerPage + 1} OFFSET {(pageNbr - 1) * postsPerPage}"
|> Sql.parameters
[ "@criteria", Query.jsonbDocParam {| WebLogId = wls webLogId; Status = PostStatus.toString Published |}
[ "@criteria", Query.jsonbDocParam {| webLogDoc webLogId with Status = PostStatus.toString Published |}
"@tag", Sql.jsonb tag
]
|> Sql.executeAsync fromData<Post>
@ -167,7 +164,7 @@ type PostgresPostData (source : NpgsqlDataSource) =
/// Find the next newest and oldest post from a publish date for the given web log
let findSurroundingPosts webLogId (publishedOn : Instant) = backgroundTask {
let queryParams () = Sql.parameters [
"@criteria", Query.jsonbDocParam {| WebLogId = wls webLogId; Status = PostStatus.toString Published |}
"@criteria", Query.jsonbDocParam {| webLogDoc webLogId with Status = PostStatus.toString Published |}
typedParam "publishedOn" publishedOn
]
let! older =

View File

@ -9,9 +9,6 @@ open Npgsql.FSharp.Documents
/// PostgreSQL myWebLog tag mapping data implementation
type PostgresTagMapData (source : NpgsqlDataSource) =
/// Shorthand for turning a web log ID into a string
let wls = WebLogId.toString
/// A query to select tag map(s) by JSON document containment criteria
let tagMapByCriteria =
$"""{Query.selectFromTable Table.TagMap} WHERE {Query.whereDataContains "@criteria"}"""
@ -33,7 +30,7 @@ type PostgresTagMapData (source : NpgsqlDataSource) =
let findByUrlValue (urlValue : string) webLogId =
Sql.fromDataSource source
|> Sql.query tagMapByCriteria
|> Sql.parameters [ "@criteria", Query.jsonbDocParam {| WebLogId = wls webLogId; UrlValue = urlValue |} ]
|> Sql.parameters [ "@criteria", Query.jsonbDocParam {| webLogDoc webLogId with UrlValue = urlValue |} ]
|> Sql.executeAsync fromData<TagMap>
|> tryHead
@ -41,7 +38,7 @@ type PostgresTagMapData (source : NpgsqlDataSource) =
let findByWebLog webLogId =
Sql.fromDataSource source
|> Sql.query $"{tagMapByCriteria} ORDER BY data->>'tag'"
|> Sql.parameters [ "@criteria", webLogContains webLogId ]
|> Sql.parameters [ webLogContains webLogId ]
|> Sql.executeAsync fromData<TagMap>
/// Find any tag mappings in a list of tags for the given web log
@ -49,7 +46,7 @@ type PostgresTagMapData (source : NpgsqlDataSource) =
let tagSql, tagParams = jsonArrayInClause (nameof TagMap.empty.Tag) id tags
Sql.fromDataSource source
|> Sql.query $"{tagMapByCriteria} AND ({tagSql})"
|> Sql.parameters (("@criteria", webLogContains webLogId) :: tagParams)
|> Sql.parameters (webLogContains webLogId :: tagParams)
|> Sql.executeAsync fromData<TagMap>
/// The parameters for saving a tag mapping

View File

@ -33,7 +33,7 @@ type PostgresWebLogData (source : NpgsqlDataSource) =
DELETE FROM {Table.Upload} WHERE web_log_id = @webLogId;
DELETE FROM {Table.WebLogUser} WHERE {criteria};
DELETE FROM {Table.WebLog} WHERE id = @webLogId"
|> Sql.parameters [ webLogIdParam webLogId; "@criteria", webLogContains webLogId ]
|> Sql.parameters [ webLogIdParam webLogId; webLogContains webLogId ]
|> Sql.executeNonQueryAsync
()
}

View File

@ -9,9 +9,6 @@ open Npgsql.FSharp.Documents
/// PostgreSQL myWebLog user data implementation
type PostgresWebLogUserData (source : NpgsqlDataSource) =
/// Shorthand for making a web log ID into a string
let wls = WebLogId.toString
/// Query to get users by JSON document containment criteria
let userByCriteria =
$"""{Query.selectFromTable Table.WebLogUser} WHERE {Query.whereDataContains "@criteria"}"""
@ -51,7 +48,7 @@ type PostgresWebLogUserData (source : NpgsqlDataSource) =
let findByEmail (email : string) webLogId =
Sql.fromDataSource source
|> Sql.query userByCriteria
|> Sql.parameters [ "@criteria", Query.jsonbDocParam {| WebLogId = wls webLogId; Email = email |} ]
|> Sql.parameters [ "@criteria", Query.jsonbDocParam {| webLogDoc webLogId with Email = email |} ]
|> Sql.executeAsync fromData<WebLogUser>
|> tryHead
@ -59,7 +56,7 @@ type PostgresWebLogUserData (source : NpgsqlDataSource) =
let findByWebLog webLogId =
Sql.fromDataSource source
|> Sql.query $"{userByCriteria} ORDER BY LOWER(data->>'{nameof WebLogUser.empty.PreferredName}')"
|> Sql.parameters [ "@criteria", webLogContains webLogId ]
|> Sql.parameters [ webLogContains webLogId ]
|> Sql.executeAsync fromData<WebLogUser>
/// Find the names of users by their IDs for the given web log
@ -68,7 +65,7 @@ type PostgresWebLogUserData (source : NpgsqlDataSource) =
let! users =
Sql.fromDataSource source
|> Sql.query $"{userByCriteria} {idSql}"
|> Sql.parameters (("@criteria", webLogContains webLogId) :: idParams)
|> Sql.parameters (webLogContains webLogId :: idParams)
|> Sql.executeAsync fromData<WebLogUser>
return
users