From b69b6c37a4b9ba25419d48b5c1faf1e28de144b4 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Wed, 3 Jan 2024 22:29:27 -0500 Subject: [PATCH] WIP on testing SQLite data store --- src/MyWebLog.Data/PostgresData.fs | 10 +++------- src/MyWebLog.Data/SQLite/SQLiteCategoryData.fs | 10 +++++----- src/MyWebLog.Data/SQLite/SQLiteHelpers.fs | 6 +++--- src/MyWebLog.Data/SQLite/SQLitePageData.fs | 4 ++-- src/MyWebLog.Data/SQLite/SQLitePostData.fs | 2 +- src/MyWebLog.Data/SQLite/SQLiteThemeData.fs | 2 +- src/MyWebLog.Domain/SupportTypes.fs | 2 +- src/MyWebLog/Handlers/Admin.fs | 2 +- src/MyWebLog/Handlers/Routes.fs | 2 +- src/MyWebLog/Program.fs | 2 +- 10 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/MyWebLog.Data/PostgresData.fs b/src/MyWebLog.Data/PostgresData.fs index b332065..6bfce4e 100644 --- a/src/MyWebLog.Data/PostgresData.fs +++ b/src/MyWebLog.Data/PostgresData.fs @@ -17,16 +17,13 @@ type PostgresData(log: ILogger, ser: JsonSerializer) = Configuration.useSerializer (Utils.createDocumentSerializer ser) let! tables = - Custom.list "SELECT tablename FROM pg_tables WHERE schemaname = 'public'" [] - (fun row -> row.string "tablename") + Custom.list + "SELECT tablename FROM pg_tables WHERE schemaname = 'public'" [] (fun row -> row.string "tablename") let needsTable table = not (List.contains table tables) - // Create a document table - let mutable isNew = false let sql = seq { // Theme tables if needsTable Table.Theme then - isNew <- true Query.Definition.ensureTable Table.Theme Query.Definition.ensureKey Table.Theme if needsTable Table.ThemeAsset then @@ -152,8 +149,7 @@ type PostgresData(log: ILogger, ser: JsonSerializer) = " - Drop all tables from the database" " - Use this executable to restore each backup"; "" "Commands to back up all web logs:" - yield! webLogs |> List.map (fun (url, slug) -> $"./myWebLog backup {url} v2-rc2.{slug}.json") - ] + yield! webLogs |> List.map (fun (url, slug) -> $"./myWebLog backup {url} v2-rc2.{slug}.json") ] |> String.concat "\n" |> log.LogWarning diff --git a/src/MyWebLog.Data/SQLite/SQLiteCategoryData.fs b/src/MyWebLog.Data/SQLite/SQLiteCategoryData.fs index 425bd8c..e1fb304 100644 --- a/src/MyWebLog.Data/SQLite/SQLiteCategoryData.fs +++ b/src/MyWebLog.Data/SQLite/SQLiteCategoryData.fs @@ -24,7 +24,7 @@ type SQLiteCategoryData(conn: SqliteConnection, ser: JsonSerializer, log: ILogge let countTopLevel webLogId = log.LogTrace "Category.countTopLevel" conn.customScalar - $"{Document.Query.countByWebLog} AND data ->> '{parentIdField}' IS NULL" + $"{Document.Query.countByWebLog Table.Category} AND data ->> '{parentIdField}' IS NULL" [ webLogParam webLogId ] (toCount >> int) @@ -79,11 +79,11 @@ 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 catId + let! children = conn.countByField Table.Category parentIdField EQ (string catId) if children > 0 then - do! conn.patchByField Table.Category parentIdField EQ catId {| ParentId = cat.ParentId |} + do! conn.patchByField Table.Category parentIdField EQ (string catId) {| ParentId = cat.ParentId |} // Delete the category off all posts where it is assigned, and the category itself - let catIdField = Post.Empty.CategoryIds + let catIdField = nameof Post.Empty.CategoryIds let! posts = conn.customList $"SELECT data ->> '{Post.Empty.Id}', data -> '{catIdField}' @@ -94,7 +94,7 @@ type SQLiteCategoryData(conn: SqliteConnection, ser: JsonSerializer, log: ILogge FROM json_each({Table.Post}.data -> '{catIdField}') WHERE json_each.value = @id)" [ idParam catId; webLogParam webLogId ] - (fun rdr -> rdr.GetString(0), Utils.deserialize ser (rdr.GetString(1))) + (fun rdr -> rdr.GetString 0, Utils.deserialize ser (rdr.GetString 1)) for postId, cats in posts do do! conn.patchById Table.Post postId {| CategoryIds = cats |> List.filter (fun it -> it <> string catId) |} diff --git a/src/MyWebLog.Data/SQLite/SQLiteHelpers.fs b/src/MyWebLog.Data/SQLite/SQLiteHelpers.fs index b1008d3..07e23e7 100644 --- a/src/MyWebLog.Data/SQLite/SQLiteHelpers.fs +++ b/src/MyWebLog.Data/SQLite/SQLiteHelpers.fs @@ -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 webLogId conn + let! count = Count.byField table "WebLogId" EQ (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 webLogId conn + Find.byField<'TDoc> table "WebLogId" EQ (string webLogId) conn /// Functions to support revisions @@ -302,6 +302,6 @@ module Revisions = for addRev in toAdd do do! Custom.nonQuery $"INSERT INTO {revTable} VALUES (@id, @asOf, @text)" - [ idParam key; sqlParam "asOf" (instantParam addRev.AsOf); sqlParam "@text" addRev.Text ] + [ idParam key; sqlParam "asOf" (instantParam addRev.AsOf); sqlParam "@text" (string addRev.Text) ] conn } diff --git a/src/MyWebLog.Data/SQLite/SQLitePageData.fs b/src/MyWebLog.Data/SQLite/SQLitePageData.fs index 4427fa8..fd390de 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} AND {Query.whereByField pgListName EQ "'true'"}""" + $"""{Document.Query.countByWebLog Table.Page} AND {Query.whereByField pgListName EQ "'true'"}""" [ webLogParam webLogId ] (toCount >> int) @@ -89,7 +89,7 @@ type SQLitePageData(conn: SqliteConnection, log: ILogger) = let findByPermalink (permalink: Permalink) webLogId = log.LogTrace "Page.findByPermalink" conn.customSingle - $"""{Document.Query.selectByWebLog} AND {Query.whereByField linkName EQ "@link"}""" + $"""{Document.Query.selectByWebLog Table.Page} AND {Query.whereByField linkName EQ "@link"}""" [ webLogParam webLogId; SqliteParameter("@link", string permalink) ] fromData diff --git a/src/MyWebLog.Data/SQLite/SQLitePostData.fs b/src/MyWebLog.Data/SQLite/SQLitePostData.fs index 7990818..e5ab713 100644 --- a/src/MyWebLog.Data/SQLite/SQLitePostData.fs +++ b/src/MyWebLog.Data/SQLite/SQLitePostData.fs @@ -47,7 +47,7 @@ type SQLitePostData(conn: SqliteConnection, log: ILogger) = let countByStatus (status: PostStatus) webLogId = log.LogTrace "Post.countByStatus" conn.customScalar - $"""{Document.Query.countByWebLog} AND {Query.whereByField statName EQ "@status"}""" + $"""{Document.Query.countByWebLog Table.Post} AND {Query.whereByField statName EQ "@status"}""" [ webLogParam webLogId; SqliteParameter("@status", string status) ] (toCount >> int) diff --git a/src/MyWebLog.Data/SQLite/SQLiteThemeData.fs b/src/MyWebLog.Data/SQLite/SQLiteThemeData.fs index cb41ddc..7ff48f3 100644 --- a/src/MyWebLog.Data/SQLite/SQLiteThemeData.fs +++ b/src/MyWebLog.Data/SQLite/SQLiteThemeData.fs @@ -122,7 +122,7 @@ type SQLiteThemeAssetData(conn : SqliteConnection, log: ILogger) = $"INSERT INTO {Table.ThemeAsset} ( theme_id, path, updated_on, data ) VALUES ( - @themeId, @path, @updatedOn, ZEROBLOB(@dataLength) + @id, @path, @updatedOn, ZEROBLOB(@dataLength) ) ON CONFLICT (theme_id, path) DO UPDATE SET updated_on = @updatedOn, data = ZEROBLOB(@dataLength)" diff --git a/src/MyWebLog.Domain/SupportTypes.fs b/src/MyWebLog.Domain/SupportTypes.fs index 8a9c98b..eab1488 100644 --- a/src/MyWebLog.Domain/SupportTypes.fs +++ b/src/MyWebLog.Domain/SupportTypes.fs @@ -13,7 +13,7 @@ module private Helpers = /// Create a new ID (short GUID) // https://www.madskristensen.net/blog/A-shorter-and-URL-friendly-GUID let newId () = - Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Replace('/', '_').Replace('+', '-')[..22] + Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Replace('/', '_').Replace('+', '-')[..21] /// Pipeline with most extensions enabled let markdownPipeline = MarkdownPipelineBuilder().UseSmartyPants().UseAdvancedExtensions().UseColorCode().Build() diff --git a/src/MyWebLog/Handlers/Admin.fs b/src/MyWebLog/Handlers/Admin.fs index 136d793..f535f84 100644 --- a/src/MyWebLog/Handlers/Admin.fs +++ b/src/MyWebLog/Handlers/Admin.fs @@ -443,7 +443,7 @@ module Theme = let themeName = fileName.Split(".").[0].ToLowerInvariant().Replace(" ", "-") if themeName.EndsWith "-theme" then if Regex.IsMatch(themeName, """^[a-z0-9\-]+$""") then - Ok(ThemeId(themeName[..themeName.Length - 6])) + Ok(ThemeId(themeName[..themeName.Length - 7])) else Error $"Theme ID {fileName} is invalid" else Error "Theme .zip file name must end in \"-theme.zip\"" diff --git a/src/MyWebLog/Handlers/Routes.fs b/src/MyWebLog/Handlers/Routes.fs index d103a00..996553c 100644 --- a/src/MyWebLog/Handlers/Routes.fs +++ b/src/MyWebLog/Handlers/Routes.fs @@ -18,7 +18,7 @@ module CatchAll = let textLink = let extra = webLog.ExtraPath let url = string ctx.Request.Path - (if extra = "" then url else url[..extra.Length]).ToLowerInvariant() + (if extra = "" then url else url[extra.Length..]).ToLowerInvariant() let await it = (Async.AwaitTask >> Async.RunSynchronously) it seq { debug (fun () -> $"Considering URL {textLink}") diff --git a/src/MyWebLog/Program.fs b/src/MyWebLog/Program.fs index 884fe55..382a013 100644 --- a/src/MyWebLog/Program.fs +++ b/src/MyWebLog/Program.fs @@ -79,7 +79,7 @@ module DataImplementation = let createSQLite connStr : IData = Sqlite.Configuration.useConnectionString connStr let log = sp.GetRequiredService>() - let conn = new SqliteConnection(connStr) + let conn = Sqlite.Configuration.dbConn () log.LogInformation $"Using SQLite database {conn.DataSource}" SQLiteData(conn, log, Json.configure (JsonSerializer.CreateDefault()))