V2 #36

Merged
danieljsummers merged 17 commits from v2-out-the-door into main 2023-02-26 18:01:21 +00:00
10 changed files with 43 additions and 62 deletions
Showing only changes of commit 612f04accc - Show all commits

View File

@ -2,7 +2,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\MyWebLog.Domain\MyWebLog.Domain.fsproj" /> <ProjectReference Include="..\MyWebLog.Domain\MyWebLog.Domain.fsproj" />
<ProjectReference Include="..\Npgsql.FSharp.Documents\Npgsql.FSharp.Documents.fsproj" /> <ProjectReference Include="..\..\..\Npgsql.Documents\src\Npgsql.FSharp.Documents\Npgsql.FSharp.Documents.fsproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -13,14 +13,12 @@ type PostgresCategoryData (source : NpgsqlDataSource, log : ILogger) =
/// Count all categories for the given web log /// Count all categories for the given web log
let countAll webLogId = let countAll webLogId =
log.LogTrace "Category.countAll" log.LogTrace "Category.countAll"
Sql.fromDataSource source Count.byContains Table.Category (webLogDoc webLogId)
|> Query.countByContains Table.Category (webLogDoc webLogId)
/// Count all top-level categories for the given web log /// Count all top-level categories for the given web log
let countTopLevel webLogId = let countTopLevel webLogId =
log.LogTrace "Category.countTopLevel" log.LogTrace "Category.countTopLevel"
Sql.fromDataSource source Count.byContains Table.Category {| webLogDoc webLogId with ParentId = None |}
|> Query.countByContains Table.Category {| webLogDoc webLogId with ParentId = None |}
/// Retrieve all categories for the given web log in a DotLiquid-friendly format /// Retrieve all categories for the given web log in a DotLiquid-friendly format
let findAllForView webLogId = backgroundTask { let findAllForView webLogId = backgroundTask {
@ -78,7 +76,7 @@ type PostgresCategoryData (source : NpgsqlDataSource, log : ILogger) =
/// Find all categories for the given web log /// Find all categories for the given web log
let findByWebLog webLogId = let findByWebLog webLogId =
log.LogTrace "Category.findByWebLog" log.LogTrace "Category.findByWebLog"
Document.findByWebLog<Category> source Table.Category webLogId Document.findByWebLog<Category> Table.Category webLogId
/// Create parameters for a category insert / update /// Create parameters for a category insert / update
let catParameters (cat : Category) = let catParameters (cat : Category) =
@ -90,15 +88,13 @@ type PostgresCategoryData (source : NpgsqlDataSource, log : ILogger) =
match! findById catId webLogId with match! findById catId webLogId with
| Some cat -> | Some cat ->
// Reassign any children to the category's parent category // Reassign any children to the category's parent category
let! children = let! children = Find.byContains Table.Category {| ParentId = CategoryId.toString catId |}
Sql.fromDataSource source
|> Query.findByContains Table.Category {| ParentId = CategoryId.toString catId |}
let hasChildren = not (List.isEmpty children) let hasChildren = not (List.isEmpty children)
if hasChildren then if hasChildren then
let! _ = let! _ =
Sql.fromDataSource source Sql.fromDataSource source
|> Sql.executeTransactionAsync [ |> Sql.executeTransactionAsync [
Query.updateQuery Table.Category, Query.update Table.Category,
children |> List.map (fun child -> catParameters { child with ParentId = cat.ParentId }) children |> List.map (fun child -> catParameters { child with ParentId = cat.ParentId })
] ]
() ()
@ -112,7 +108,7 @@ type PostgresCategoryData (source : NpgsqlDataSource, log : ILogger) =
let! _ = let! _ =
Sql.fromDataSource source Sql.fromDataSource source
|> Sql.executeTransactionAsync [ |> Sql.executeTransactionAsync [
Query.updateQuery Table.Post, Query.update Table.Post,
posts |> List.map (fun post -> [ posts |> List.map (fun post -> [
"@id", Sql.string (PostId.toString post.Id) "@id", Sql.string (PostId.toString post.Id)
"@data", Query.jsonbDocParam "@data", Query.jsonbDocParam
@ -123,7 +119,7 @@ type PostgresCategoryData (source : NpgsqlDataSource, log : ILogger) =
] ]
() ()
// Delete the category itself // Delete the category itself
do! Sql.fromDataSource source |> Query.deleteById Table.Category (CategoryId.toString catId) do! Delete.byId Table.Category (CategoryId.toString catId)
return if hasChildren then ReassignedChildCategories else CategoryDeleted return if hasChildren then ReassignedChildCategories else CategoryDeleted
| None -> return CategoryNotFound | None -> return CategoryNotFound
} }
@ -131,7 +127,7 @@ type PostgresCategoryData (source : NpgsqlDataSource, log : ILogger) =
/// Save a category /// Save a category
let save (cat : Category) = backgroundTask { let save (cat : Category) = backgroundTask {
log.LogTrace "Category.save" log.LogTrace "Category.save"
do! Sql.fromDataSource source |> Query.save Table.Category (CategoryId.toString cat.Id) cat do! save Table.Category (CategoryId.toString cat.Id) cat
} }
/// Restore categories from a backup /// Restore categories from a backup
@ -140,7 +136,7 @@ type PostgresCategoryData (source : NpgsqlDataSource, log : ILogger) =
let! _ = let! _ =
Sql.fromDataSource source Sql.fromDataSource source
|> Sql.executeTransactionAsync [ |> Sql.executeTransactionAsync [
Query.insertQuery Table.Category, cats |> List.map catParameters Query.insert Table.Category, cats |> List.map catParameters
] ]
() ()
} }

View File

@ -185,9 +185,8 @@ module Document =
|> tryHead |> tryHead
/// Find a document by its ID for the given web log /// Find a document by its ID for the given web log
let findByWebLog<'TDoc> source table webLogId : Task<'TDoc list> = let findByWebLog<'TDoc> table webLogId : Task<'TDoc list> =
Sql.fromDataSource source Find.byContains table (webLogDoc webLogId)
|> Query.findByContains table (webLogDoc webLogId)
/// Functions to support revisions /// Functions to support revisions

View File

@ -46,14 +46,12 @@ type PostgresPageData (source : NpgsqlDataSource, log : ILogger) =
/// Count all pages for the given web log /// Count all pages for the given web log
let countAll webLogId = let countAll webLogId =
log.LogTrace "Page.countAll" log.LogTrace "Page.countAll"
Sql.fromDataSource source Count.byContains Table.Page (webLogDoc webLogId)
|> Query.countByContains Table.Page (webLogDoc webLogId)
/// Count all pages shown in the page list for the given web log /// Count all pages shown in the page list for the given web log
let countListed webLogId = let countListed webLogId =
log.LogTrace "Page.countListed" log.LogTrace "Page.countListed"
Sql.fromDataSource source Count.byContains Table.Page {| webLogDoc webLogId with IsInPageList = true |}
|> Query.countByContains Table.Page {| webLogDoc webLogId with IsInPageList = true |}
/// Find a page by its ID (without revisions) /// Find a page by its ID (without revisions)
let findById pageId webLogId = let findById pageId webLogId =
@ -75,7 +73,7 @@ type PostgresPageData (source : NpgsqlDataSource, log : ILogger) =
log.LogTrace "Page.delete" log.LogTrace "Page.delete"
match! pageExists pageId webLogId with match! pageExists pageId webLogId with
| true -> | true ->
do! Sql.fromDataSource source |> Query.deleteById Table.Page (PageId.toString pageId) do! Delete.byId Table.Page (PageId.toString pageId)
return true return true
| false -> return false | false -> return false
} }
@ -83,8 +81,7 @@ type PostgresPageData (source : NpgsqlDataSource, log : ILogger) =
/// Find a page by its permalink for the given web log /// Find a page by its permalink for the given web log
let findByPermalink permalink webLogId = let findByPermalink permalink webLogId =
log.LogTrace "Page.findByPermalink" log.LogTrace "Page.findByPermalink"
Sql.fromDataSource source Find.byContains<Page> Table.Page {| webLogDoc webLogId with Permalink = Permalink.toString permalink |}
|> Query.findByContains<Page> Table.Page {| webLogDoc webLogId with Permalink = Permalink.toString permalink |}
|> tryHead |> tryHead
/// Find the current permalink within a set of potential prior permalinks for the given web log /// Find the current permalink within a set of potential prior permalinks for the given web log
@ -109,7 +106,7 @@ type PostgresPageData (source : NpgsqlDataSource, log : ILogger) =
/// Get all complete pages for the given web log /// Get all complete pages for the given web log
let findFullByWebLog webLogId = backgroundTask { let findFullByWebLog webLogId = backgroundTask {
log.LogTrace "Page.findFullByWebLog" log.LogTrace "Page.findFullByWebLog"
let! pages = Document.findByWebLog<Page> source Table.Page webLogId let! pages = Document.findByWebLog<Page> Table.Page webLogId
let! revisions = Revisions.findByWebLog source Table.PageRevision Table.Page PageId webLogId let! revisions = Revisions.findByWebLog source Table.PageRevision Table.Page PageId webLogId
return return
pages pages
@ -143,7 +140,7 @@ type PostgresPageData (source : NpgsqlDataSource, log : ILogger) =
let! _ = let! _ =
Sql.fromDataSource source Sql.fromDataSource source
|> Sql.executeTransactionAsync [ |> Sql.executeTransactionAsync [
Query.insertQuery Table.Page, Query.insert Table.Page,
pages pages
|> List.map (fun page -> Query.docParameters (PageId.toString page.Id) { page with Revisions = [] }) |> List.map (fun page -> Query.docParameters (PageId.toString page.Id) { page with Revisions = [] })
Revisions.insertSql Table.PageRevision, Revisions.insertSql Table.PageRevision,
@ -156,7 +153,7 @@ type PostgresPageData (source : NpgsqlDataSource, log : ILogger) =
let save (page : Page) = backgroundTask { let save (page : Page) = backgroundTask {
log.LogTrace "Page.save" log.LogTrace "Page.save"
let! oldPage = findFullById page.Id page.WebLogId let! oldPage = findFullById page.Id page.WebLogId
do! Sql.fromDataSource source |> Query.save Table.Page (PageId.toString page.Id) { page with Revisions = [] } do! save Table.Page (PageId.toString page.Id) { page with Revisions = [] }
do! updatePageRevisions page.Id (match oldPage with Some p -> p.Revisions | None -> []) page.Revisions do! updatePageRevisions page.Id (match oldPage with Some p -> p.Revisions | None -> []) page.Revisions
() ()
} }
@ -166,8 +163,7 @@ type PostgresPageData (source : NpgsqlDataSource, log : ILogger) =
log.LogTrace "Page.updatePriorPermalinks" log.LogTrace "Page.updatePriorPermalinks"
match! findById pageId webLogId with match! findById pageId webLogId with
| Some page -> | Some page ->
do! Sql.fromDataSource source do! update Table.Page (PageId.toString page.Id) { page with PriorPermalinks = permalinks }
|> Query.update Table.Page (PageId.toString page.Id) { page with PriorPermalinks = permalinks }
return true return true
| None -> return false | None -> return false
} }

View File

@ -111,7 +111,7 @@ type PostgresPostData (source : NpgsqlDataSource, log : ILogger) =
/// Get all complete posts for the given web log /// Get all complete posts for the given web log
let findFullByWebLog webLogId = backgroundTask { let findFullByWebLog webLogId = backgroundTask {
log.LogTrace "Post.findFullByWebLog" log.LogTrace "Post.findFullByWebLog"
let! posts = Document.findByWebLog<Post> source Table.Post webLogId let! posts = Document.findByWebLog<Post> Table.Post webLogId
let! revisions = Revisions.findByWebLog source Table.PostRevision Table.Post PostId webLogId let! revisions = Revisions.findByWebLog source Table.PostRevision Table.Post PostId webLogId
return return
posts posts
@ -207,7 +207,7 @@ type PostgresPostData (source : NpgsqlDataSource, log : ILogger) =
let save (post : Post) = backgroundTask { let save (post : Post) = backgroundTask {
log.LogTrace "Post.save" log.LogTrace "Post.save"
let! oldPost = findFullById post.Id post.WebLogId let! oldPost = findFullById post.Id post.WebLogId
do! Sql.fromDataSource source |> Query.save Table.Post (PostId.toString post.Id) { post with Revisions = [] } do! save Table.Post (PostId.toString post.Id) { post with Revisions = [] }
do! updatePostRevisions post.Id (match oldPost with Some p -> p.Revisions | None -> []) post.Revisions do! updatePostRevisions post.Id (match oldPost with Some p -> p.Revisions | None -> []) post.Revisions
} }
@ -218,7 +218,7 @@ type PostgresPostData (source : NpgsqlDataSource, log : ILogger) =
let! _ = let! _ =
Sql.fromDataSource source Sql.fromDataSource source
|> Sql.executeTransactionAsync [ |> Sql.executeTransactionAsync [
Query.insertQuery Table.Post, Query.insert Table.Post,
posts posts
|> List.map (fun post -> Query.docParameters (PostId.toString post.Id) { post with Revisions = [] }) |> List.map (fun post -> Query.docParameters (PostId.toString post.Id) { post with Revisions = [] })
Revisions.insertSql Table.PostRevision, Revisions.insertSql Table.PostRevision,
@ -232,8 +232,7 @@ type PostgresPostData (source : NpgsqlDataSource, log : ILogger) =
log.LogTrace "Post.updatePriorPermalinks" log.LogTrace "Post.updatePriorPermalinks"
match! findById postId webLogId with match! findById postId webLogId with
| Some post -> | Some post ->
do! Sql.fromDataSource source do! update Table.Post (PostId.toString post.Id) { post with PriorPermalinks = permalinks }
|> Query.update Table.Post (PostId.toString post.Id) { post with PriorPermalinks = permalinks }
return true return true
| None -> return false | None -> return false
} }

View File

@ -20,7 +20,7 @@ type PostgresTagMapData (source : NpgsqlDataSource, log : ILogger) =
log.LogTrace "TagMap.delete" log.LogTrace "TagMap.delete"
let! exists = Document.existsByWebLog source Table.TagMap tagMapId TagMapId.toString webLogId let! exists = Document.existsByWebLog source Table.TagMap tagMapId TagMapId.toString webLogId
if exists then if exists then
do! Sql.fromDataSource source |> Query.deleteById Table.TagMap (TagMapId.toString tagMapId) do! Delete.byId Table.TagMap (TagMapId.toString tagMapId)
return true return true
else return false else return false
} }
@ -52,16 +52,15 @@ type PostgresTagMapData (source : NpgsqlDataSource, log : ILogger) =
|> Sql.executeAsync fromData<TagMap> |> Sql.executeAsync fromData<TagMap>
/// Save a tag mapping /// Save a tag mapping
let save (tagMap : TagMap) = backgroundTask { let save (tagMap : TagMap) =
do! Sql.fromDataSource source |> Query.save Table.TagMap (TagMapId.toString tagMap.Id) tagMap save Table.TagMap (TagMapId.toString tagMap.Id) tagMap
}
/// Restore tag mappings from a backup /// Restore tag mappings from a backup
let restore (tagMaps : TagMap list) = backgroundTask { let restore (tagMaps : TagMap list) = backgroundTask {
let! _ = let! _ =
Sql.fromDataSource source Sql.fromDataSource source
|> Sql.executeTransactionAsync [ |> Sql.executeTransactionAsync [
Query.insertQuery Table.TagMap, Query.insert Table.TagMap,
tagMaps |> List.map (fun tagMap -> Query.docParameters (TagMapId.toString tagMap.Id) tagMap) tagMaps |> List.map (fun tagMap -> Query.docParameters (TagMapId.toString tagMap.Id) tagMap)
] ]
() ()

View File

@ -25,14 +25,12 @@ type PostgresThemeData (source : NpgsqlDataSource, log : ILogger) =
/// Does a given theme exist? /// Does a given theme exist?
let exists themeId = let exists themeId =
log.LogTrace "Theme.exists" log.LogTrace "Theme.exists"
Sql.fromDataSource source Exists.byId Table.Theme (ThemeId.toString themeId)
|> Query.existsById Table.Theme (ThemeId.toString themeId)
/// Find a theme by its ID /// Find a theme by its ID
let findById themeId = let findById themeId =
log.LogTrace "Theme.findById" log.LogTrace "Theme.findById"
Sql.fromDataSource source Find.byId<Theme> Table.Theme (ThemeId.toString themeId)
|> Query.tryById<Theme> Table.Theme (ThemeId.toString themeId)
/// Find a theme by its ID (excludes the text of templates) /// Find a theme by its ID (excludes the text of templates)
let findByIdWithoutText themeId = let findByIdWithoutText themeId =
@ -48,7 +46,7 @@ type PostgresThemeData (source : NpgsqlDataSource, log : ILogger) =
log.LogTrace "Theme.delete" log.LogTrace "Theme.delete"
match! exists themeId with match! exists themeId with
| true -> | true ->
do! Sql.fromDataSource source |> Query.deleteById Table.Theme (ThemeId.toString themeId) do! Delete.byId Table.Theme (ThemeId.toString themeId)
return true return true
| false -> return false | false -> return false
} }
@ -56,7 +54,7 @@ type PostgresThemeData (source : NpgsqlDataSource, log : ILogger) =
/// Save a theme /// Save a theme
let save (theme : Theme) = let save (theme : Theme) =
log.LogTrace "Theme.save" log.LogTrace "Theme.save"
Sql.fromDataSource source |> Query.save Table.Theme (ThemeId.toString theme.Id) theme save Table.Theme (ThemeId.toString theme.Id) theme
interface IThemeData with interface IThemeData with
member _.All () = all () member _.All () = all ()

View File

@ -13,13 +13,12 @@ type PostgresWebLogData (source : NpgsqlDataSource, log : ILogger) =
/// Add a web log /// Add a web log
let add (webLog : WebLog) = let add (webLog : WebLog) =
log.LogTrace "WebLog.add" log.LogTrace "WebLog.add"
Sql.fromDataSource source |> Query.insert Table.WebLog (WebLogId.toString webLog.Id) webLog insert Table.WebLog (WebLogId.toString webLog.Id) webLog
/// Retrieve all web logs /// Retrieve all web logs
let all () = let all () =
log.LogTrace "WebLog.all" log.LogTrace "WebLog.all"
Sql.fromDataSource source all<WebLog> Table.WebLog
|> Query.all<WebLog> Table.WebLog
/// Delete a web log by its ID /// Delete a web log by its ID
let delete webLogId = backgroundTask { let delete webLogId = backgroundTask {
@ -54,21 +53,18 @@ type PostgresWebLogData (source : NpgsqlDataSource, log : ILogger) =
/// Find a web log by its ID /// Find a web log by its ID
let findById webLogId = let findById webLogId =
log.LogTrace "WebLog.findById" log.LogTrace "WebLog.findById"
Sql.fromDataSource source Find.byId<WebLog> Table.WebLog (WebLogId.toString webLogId)
|> Query.tryById<WebLog> Table.WebLog (WebLogId.toString webLogId)
/// Update settings for a web log /// Update settings for a web log
let updateSettings (webLog : WebLog) = let updateSettings (webLog : WebLog) =
log.LogTrace "WebLog.updateSettings" log.LogTrace "WebLog.updateSettings"
Sql.fromDataSource source |> Query.update Table.WebLog (WebLogId.toString webLog.Id) webLog update Table.WebLog (WebLogId.toString webLog.Id) webLog
/// Update RSS options for a web log /// Update RSS options for a web log
let updateRssOptions (webLog : WebLog) = backgroundTask { let updateRssOptions (webLog : WebLog) = backgroundTask {
log.LogTrace "WebLog.updateRssOptions" log.LogTrace "WebLog.updateRssOptions"
match! findById webLog.Id with match! findById webLog.Id with
| Some blog -> | Some blog -> do! update Table.WebLog (WebLogId.toString webLog.Id) { blog with Rss = webLog.Rss }
do! Sql.fromDataSource source
|> Query.update Table.WebLog (WebLogId.toString webLog.Id) { blog with Rss = webLog.Rss }
| None -> () | None -> ()
} }

View File

@ -34,7 +34,7 @@ type PostgresWebLogUserData (source : NpgsqlDataSource, log : ILogger) =
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
do! Sql.fromDataSource source |> Query.deleteById Table.WebLogUser usrId do! Delete.byId Table.WebLogUser usrId
return Ok true return Ok true
| None -> return Error "User does not exist" | None -> return Error "User does not exist"
} }
@ -77,7 +77,7 @@ type PostgresWebLogUserData (source : NpgsqlDataSource, log : ILogger) =
let! _ = let! _ =
Sql.fromDataSource source Sql.fromDataSource source
|> Sql.executeTransactionAsync [ |> Sql.executeTransactionAsync [
Query.insertQuery Table.WebLogUser, Query.insert Table.WebLogUser,
users |> List.map (fun user -> Query.docParameters (WebLogUserId.toString user.Id) user) users |> List.map (fun user -> Query.docParameters (WebLogUserId.toString user.Id) user)
] ]
() ()
@ -88,16 +88,14 @@ type PostgresWebLogUserData (source : NpgsqlDataSource, log : ILogger) =
log.LogTrace "WebLogUser.setLastSeen" log.LogTrace "WebLogUser.setLastSeen"
match! findById userId webLogId with match! findById userId webLogId with
| Some user -> | Some user ->
do! Sql.fromDataSource source do! update Table.WebLogUser (WebLogUserId.toString userId) { user with LastSeenOn = Some (Noda.now ()) }
|> Query.update Table.WebLogUser (WebLogUserId.toString userId)
{ user with LastSeenOn = Some (Noda.now ()) }
| None -> () | None -> ()
} }
/// Save a user /// Save a user
let save (user : WebLogUser) = let save (user : WebLogUser) =
log.LogTrace "WebLogUser.save" log.LogTrace "WebLogUser.save"
Sql.fromDataSource source |> Query.save Table.WebLogUser (WebLogUserId.toString user.Id) user save Table.WebLogUser (WebLogUserId.toString user.Id) user
interface IWebLogUserData with interface IWebLogUserData with
member _.Add user = save user member _.Add user = save user

View File

@ -16,7 +16,7 @@ type PostgresData (source : NpgsqlDataSource, log : ILogger<PostgresData>, ser :
// Set up the PostgreSQL document store // Set up the PostgreSQL document store
Configuration.useDataSource source Configuration.useDataSource source
Configuration.useSerializer Configuration.useSerializer
{ new IDocumentSerializer with { new Documents.IDocumentSerializer with
member _.Serialize<'T> (it : 'T) : string = Utils.serialize ser it member _.Serialize<'T> (it : 'T) : string = Utils.serialize ser it
member _.Deserialize<'T> (it : string) : 'T = Utils.deserialize ser it member _.Deserialize<'T> (it : string) : 'T = Utils.deserialize ser it
} }