diff --git a/src/MyWebLog.Data/MyWebLog.Data.fsproj b/src/MyWebLog.Data/MyWebLog.Data.fsproj
index 0aa40b8..804465b 100644
--- a/src/MyWebLog.Data/MyWebLog.Data.fsproj
+++ b/src/MyWebLog.Data/MyWebLog.Data.fsproj
@@ -5,9 +5,9 @@
-
-
-
+
+
+
diff --git a/src/MyWebLog.Data/Postgres/PostgresCategoryData.fs b/src/MyWebLog.Data/Postgres/PostgresCategoryData.fs
index d127585..60afe53 100644
--- a/src/MyWebLog.Data/Postgres/PostgresCategoryData.fs
+++ b/src/MyWebLog.Data/Postgres/PostgresCategoryData.fs
@@ -81,15 +81,26 @@ type PostgresCategoryData(log: ILogger) =
let! children = Find.byContains Table.Category {| ParentId = catId |}
let hasChildren = not (List.isEmpty children)
if hasChildren then
- let! _ =
- Configuration.dataSource ()
- |> Sql.fromDataSource
- |> Sql.executeTransactionAsync
- [ Query.Patch.byId Table.Category,
- children
- |> List.map (fun child ->
- [ idParam child.Id; jsonParam "@data" {| ParentId = cat.ParentId |} ]) ]
- ()
+ if cat.ParentId.IsSome then
+ let! _ =
+ Configuration.dataSource ()
+ |> Sql.fromDataSource
+ |> Sql.executeTransactionAsync
+ [ Query.Patch.byId Table.Category,
+ children
+ |> List.map (fun child ->
+ [ idParam child.Id; jsonParam "@data" {| ParentId = cat.ParentId |} ]) ]
+ ()
+ else
+ let! _ =
+ Configuration.dataSource ()
+ |> Sql.fromDataSource
+ |> Sql.executeTransactionAsync
+ [ Query.RemoveFields.byId Table.Category,
+ children
+ |> List.map (fun child ->
+ [ idParam child.Id; fieldNameParam [ nameof Category.Empty.ParentId ] ]) ]
+ ()
// Delete the category off all posts where it is assigned
let! posts =
Custom.list
diff --git a/src/MyWebLog.Data/SQLite/SQLiteCategoryData.fs b/src/MyWebLog.Data/SQLite/SQLiteCategoryData.fs
index 66d325f..4cf6104 100644
--- a/src/MyWebLog.Data/SQLite/SQLiteCategoryData.fs
+++ b/src/MyWebLog.Data/SQLite/SQLiteCategoryData.fs
@@ -53,7 +53,7 @@ type SQLiteCategoryData(conn: SqliteConnection, ser: JsonSerializer, log: ILogge
SELECT COUNT(DISTINCT data ->> '{nameof Post.Empty.Id}')
FROM {Table.Post}
WHERE {Document.Query.whereByWebLog}
- AND {Query.whereByField (nameof Post.Empty.Status) EQ $"'{string Published}'"}
+ AND {Query.whereByField (Field.EQ (nameof Post.Empty.Status) "") $"'{string Published}'"}
AND {catSql}"""
let! postCount = conn.customScalar query (webLogParam webLogId :: catParams) toCount
return it.Id, int postCount
@@ -79,17 +79,12 @@ type SQLiteCategoryData(conn: SqliteConnection, ser: JsonSerializer, log: ILogge
match! findById catId webLogId with
| Some cat ->
// Reassign any children to the category's parent category
- let! children = conn.countByField Table.Category parentIdField EQ (string catId)
+ let! children = conn.countByField Table.Category (Field.EQ parentIdField (string catId))
if children > 0L then
+ let parent = Field.EQ parentIdField (string catId)
match cat.ParentId with
- | Some _ ->
- do! conn.patchByField Table.Category parentIdField EQ (string catId) {| ParentId = cat.ParentId |}
- | None ->
- do! conn.customNonQuery
- $"""UPDATE {Table.Category}
- SET data = json_remove(data, '$.ParentId')
- WHERE {Query.whereByField parentIdField EQ "@field"}"""
- [ fieldParam (string catId) ]
+ | Some _ -> do! conn.patchByField Table.Category parent {| ParentId = cat.ParentId |}
+ | None -> do! conn.removeFieldsByField Table.Category parent [ parentIdField ]
// Delete the category off all posts where it is assigned, and the category itself
let catIdField = nameof Post.Empty.CategoryIds
let! posts =
diff --git a/src/MyWebLog.Data/SQLite/SQLiteHelpers.fs b/src/MyWebLog.Data/SQLite/SQLiteHelpers.fs
index 07e23e7..bfb8952 100644
--- a/src/MyWebLog.Data/SQLite/SQLiteHelpers.fs
+++ b/src/MyWebLog.Data/SQLite/SQLiteHelpers.fs
@@ -239,7 +239,7 @@ module Document =
/// Fragment to add a web log ID condition to a WHERE clause (parameter @webLogId)
let whereByWebLog =
- Query.whereByField "WebLogId" EQ "@webLogId"
+ Query.whereByField (Field.EQ "WebLogId" "") "@webLogId"
/// A SELECT query to count documents for a given web log ID
let countByWebLog table =
@@ -255,7 +255,7 @@ module Document =
/// Count documents for the given web log ID
let countByWebLog table (webLogId: WebLogId) conn = backgroundTask {
- let! count = Count.byField table "WebLogId" EQ (string webLogId) conn
+ let! count = Count.byField table (Field.EQ "WebLogId" (string webLogId)) conn
return int count
}
@@ -265,7 +265,7 @@ module Document =
/// Find documents for the given web log
let findByWebLog<'TDoc> table (webLogId: WebLogId) conn =
- Find.byField<'TDoc> table "WebLogId" EQ (string webLogId) conn
+ Find.byField<'TDoc> table (Field.EQ "WebLogId" (string webLogId)) conn
/// Functions to support revisions
diff --git a/src/MyWebLog.Data/SQLite/SQLitePageData.fs b/src/MyWebLog.Data/SQLite/SQLitePageData.fs
index e76448c..dde7b02 100644
--- a/src/MyWebLog.Data/SQLite/SQLitePageData.fs
+++ b/src/MyWebLog.Data/SQLite/SQLitePageData.fs
@@ -53,7 +53,7 @@ type SQLitePageData(conn: SqliteConnection, log: ILogger) =
let countListed webLogId =
log.LogTrace "Page.countListed"
conn.customScalar
- $"""{Document.Query.countByWebLog Table.Page} AND {Query.whereByField pgListName EQ "true"}"""
+ $"""{Document.Query.countByWebLog Table.Page} AND {Query.whereByField (Field.EQ pgListName "") "true"}"""
[ webLogParam webLogId ]
(toCount >> int)
@@ -88,9 +88,10 @@ type SQLitePageData(conn: SqliteConnection, log: ILogger) =
/// Find a page by its permalink for the given web log
let findByPermalink (permalink: Permalink) webLogId =
log.LogTrace "Page.findByPermalink"
+ let linkParam = Field.EQ linkName (string permalink)
conn.customSingle
- $"""{Document.Query.selectByWebLog Table.Page} AND {Query.whereByField linkName EQ "@link"}"""
- [ webLogParam webLogId; SqliteParameter("@link", string permalink) ]
+ $"""{Document.Query.selectByWebLog Table.Page} AND {Query.whereByField linkParam "@link"}"""
+ (addFieldParam "@link" linkParam [ webLogParam webLogId ])
fromData
/// Find the current permalink within a set of potential prior permalinks for the given web log
@@ -116,7 +117,7 @@ type SQLitePageData(conn: SqliteConnection, log: ILogger) =
let findListed webLogId =
log.LogTrace "Page.findListed"
conn.customList
- $"""{Document.Query.selectByWebLog Table.Page} AND {Query.whereByField pgListName EQ "true"}
+ $"""{Document.Query.selectByWebLog Table.Page} AND {Query.whereByField (Field.EQ pgListName "") "true"}
ORDER BY LOWER({titleField})"""
[ webLogParam webLogId ]
(fun rdr -> { fromData rdr with Text = "" })
diff --git a/src/MyWebLog.Data/SQLite/SQLitePostData.fs b/src/MyWebLog.Data/SQLite/SQLitePostData.fs
index d2d5f0d..3a67a9c 100644
--- a/src/MyWebLog.Data/SQLite/SQLitePostData.fs
+++ b/src/MyWebLog.Data/SQLite/SQLitePostData.fs
@@ -34,7 +34,8 @@ type SQLitePostData(conn: SqliteConnection, log: ILogger) =
let postByWebLog = Document.Query.selectByWebLog Table.Post
/// The SELECT statement to retrieve published posts with a web log ID parameter
- let publishedPostByWebLog = $"""{postByWebLog} AND {Query.whereByField statName EQ $"'{string Published}'"}"""
+ let publishedPostByWebLog =
+ $"""{postByWebLog} AND {Query.whereByField (Field.EQ statName "") $"'{string Published}'"}"""
/// Update a post's revisions
let updatePostRevisions (postId: PostId) oldRevs newRevs =
@@ -46,9 +47,10 @@ type SQLitePostData(conn: SqliteConnection, log: ILogger) =
/// Count posts in a status for the given web log
let countByStatus (status: PostStatus) webLogId =
log.LogTrace "Post.countByStatus"
+ let statParam = Field.EQ statName (string status)
conn.customScalar
- $"""{Document.Query.countByWebLog Table.Post} AND {Query.whereByField statName EQ "@status"}"""
- [ webLogParam webLogId; SqliteParameter("@status", string status) ]
+ $"""{Document.Query.countByWebLog Table.Post} AND {Query.whereByField statParam "@status"}"""
+ (addFieldParam "@status" statParam [ webLogParam webLogId ])
(toCount >> int)
/// Find a post by its ID for the given web log (excluding revisions)
@@ -59,9 +61,10 @@ type SQLitePostData(conn: SqliteConnection, log: ILogger) =
/// Find a post by its permalink for the given web log (excluding revisions)
let findByPermalink (permalink: Permalink) webLogId =
log.LogTrace "Post.findByPermalink"
+ let linkParam = Field.EQ linkName (string permalink)
conn.customSingle
- $"""{Document.Query.selectByWebLog Table.Post} AND {Query.whereByField linkName EQ "@link"}"""
- [ webLogParam webLogId; SqliteParameter("@link", string permalink) ]
+ $"""{Document.Query.selectByWebLog Table.Post} AND {Query.whereByField linkParam "@link"}"""
+ (addFieldParam "@link" linkParam [ webLogParam webLogId ])
fromData
/// Find a complete post by its ID for the given web log
@@ -82,7 +85,7 @@ type SQLitePostData(conn: SqliteConnection, log: ILogger) =
do! conn.customNonQuery
$"""DELETE FROM {Table.PostRevision} WHERE post_id = @id;
DELETE FROM {Table.PostComment}
- WHERE {Query.whereByField (nameof Comment.Empty.PostId) EQ "@id"};
+ WHERE {Query.whereByField (Field.EQ (nameof Comment.Empty.PostId) "") "@id"};
{Query.Delete.byId Table.Post}"""
[ idParam postId ]
return true
diff --git a/src/MyWebLog.Data/SQLite/SQLiteTagMapData.fs b/src/MyWebLog.Data/SQLite/SQLiteTagMapData.fs
index 50a4b04..f71c61e 100644
--- a/src/MyWebLog.Data/SQLite/SQLiteTagMapData.fs
+++ b/src/MyWebLog.Data/SQLite/SQLiteTagMapData.fs
@@ -28,10 +28,10 @@ type SQLiteTagMapData(conn: SqliteConnection, log: ILogger) =
/// Find a tag mapping by its URL value for the given web log
let findByUrlValue (urlValue: string) webLogId =
log.LogTrace "TagMap.findByUrlValue"
+ let urlParam = Field.EQ (nameof TagMap.Empty.UrlValue) urlValue
conn.customSingle
- $"""{Document.Query.selectByWebLog Table.TagMap}
- AND {Query.whereByField (nameof TagMap.Empty.UrlValue) EQ "@urlValue"}"""
- [ webLogParam webLogId; SqliteParameter("@urlValue", urlValue) ]
+ $"""{Document.Query.selectByWebLog Table.TagMap} AND {Query.whereByField urlParam "@urlValue"}"""
+ (addFieldParam "@urlValue" urlParam [ webLogParam webLogId ])
fromData
/// Get all tag mappings for the given web log
diff --git a/src/MyWebLog.Data/SQLite/SQLiteWebLogData.fs b/src/MyWebLog.Data/SQLite/SQLiteWebLogData.fs
index a9d1d17..93af895 100644
--- a/src/MyWebLog.Data/SQLite/SQLiteWebLogData.fs
+++ b/src/MyWebLog.Data/SQLite/SQLiteWebLogData.fs
@@ -23,25 +23,25 @@ type SQLiteWebLogData(conn: SqliteConnection, log: ILogger) =
/// Delete a web log by its ID
let delete webLogId =
log.LogTrace "WebLog.delete"
- let subQuery table =
- $"""(SELECT data ->> 'Id' FROM {table} WHERE {Query.whereByField "WebLogId" EQ "@webLogId"}"""
+ let webLogMatches = Query.whereByField (Field.EQ "WebLogId" "") "@webLogId"
+ let subQuery table = $"(SELECT data ->> 'Id' FROM {table} WHERE {webLogMatches}"
Custom.nonQuery
$"""DELETE FROM {Table.PostComment} WHERE data ->> 'PostId' IN {subQuery Table.Post};
DELETE FROM {Table.PostRevision} WHERE post_id IN {subQuery Table.Post};
DELETE FROM {Table.PageRevision} WHERE page_id IN {subQuery Table.Page};
- DELETE FROM {Table.Post} WHERE {Query.whereByField "WebLogId" EQ "@webLogId"};
- DELETE FROM {Table.Page} WHERE {Query.whereByField "WebLogId" EQ "@webLogId"};
- DELETE FROM {Table.Category} WHERE {Query.whereByField "WebLogId" EQ "@webLogId"};
- DELETE FROM {Table.TagMap} WHERE {Query.whereByField "WebLogId" EQ "@webLogId"};
+ DELETE FROM {Table.Post} WHERE {webLogMatches};
+ DELETE FROM {Table.Page} WHERE {webLogMatches};
+ DELETE FROM {Table.Category} WHERE {webLogMatches};
+ DELETE FROM {Table.TagMap} WHERE {webLogMatches};
DELETE FROM {Table.Upload} WHERE web_log_id = @webLogId;
- DELETE FROM {Table.WebLogUser} WHERE {Query.whereByField "WebLogId" EQ "@webLogId"};
+ DELETE FROM {Table.WebLogUser} WHERE {webLogMatches};
DELETE FROM {Table.WebLog} WHERE {Query.whereById "@webLogId"}"""
[ webLogParam webLogId ]
/// Find a web log by its host (URL base)
let findByHost (url: string) =
log.LogTrace "WebLog.findByHost"
- conn.findFirstByField Table.WebLog (nameof WebLog.Empty.UrlBase) EQ url
+ conn.findFirstByField Table.WebLog (Field.EQ (nameof WebLog.Empty.UrlBase) url)
/// Find a web log by its ID
let findById webLogId =
diff --git a/src/MyWebLog.Data/SQLite/SQLiteWebLogUserData.fs b/src/MyWebLog.Data/SQLite/SQLiteWebLogUserData.fs
index 216c29b..f87b6c4 100644
--- a/src/MyWebLog.Data/SQLite/SQLiteWebLogUserData.fs
+++ b/src/MyWebLog.Data/SQLite/SQLiteWebLogUserData.fs
@@ -20,8 +20,8 @@ type SQLiteWebLogUserData(conn: SqliteConnection, log: ILogger) =
log.LogTrace "WebLogUser.delete"
match! findById userId webLogId with
| Some _ ->
- let! pageCount = conn.countByField Table.Page (nameof Page.Empty.AuthorId) EQ (string userId)
- let! postCount = conn.countByField Table.Post (nameof Post.Empty.AuthorId) EQ (string userId)
+ let! pageCount = conn.countByField Table.Page (Field.EQ (nameof Page.Empty.AuthorId) (string userId))
+ let! postCount = conn.countByField Table.Post (Field.EQ (nameof Post.Empty.AuthorId) (string userId))
if pageCount + postCount > 0 then
return Error "User has pages or posts; cannot delete"
else
@@ -33,10 +33,11 @@ type SQLiteWebLogUserData(conn: SqliteConnection, log: ILogger) =
/// Find a user by their e-mail address for the given web log
let findByEmail (email: string) webLogId =
log.LogTrace "WebLogUser.findByEmail"
+ let emailParam = Field.EQ (nameof WebLogUser.Empty.Email) email
conn.customSingle
$"""{Document.Query.selectByWebLog Table.WebLogUser}
- AND {Query.whereByField (nameof WebLogUser.Empty.Email) EQ "@email"}"""
- [ webLogParam webLogId; sqlParam "@email" email ]
+ AND {Query.whereByField emailParam "@email"}"""
+ (addFieldParam "@email" emailParam [ webLogParam webLogId ])
fromData
/// Get all users for the given web log
diff --git a/src/MyWebLog.Domain/MyWebLog.Domain.fsproj b/src/MyWebLog.Domain/MyWebLog.Domain.fsproj
index 9460006..d86aa8a 100644
--- a/src/MyWebLog.Domain/MyWebLog.Domain.fsproj
+++ b/src/MyWebLog.Domain/MyWebLog.Domain.fsproj
@@ -7,10 +7,10 @@
-
+
-
+
diff --git a/src/MyWebLog/MyWebLog.fsproj b/src/MyWebLog/MyWebLog.fsproj
index 4707fa3..076a51b 100644
--- a/src/MyWebLog/MyWebLog.fsproj
+++ b/src/MyWebLog/MyWebLog.fsproj
@@ -26,8 +26,8 @@
-
-
+
+