From 409b1def321ffba219ffab4ec0e70f91cc5c0259 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Wed, 22 Jun 2022 20:31:20 -0400 Subject: [PATCH] Implement default SQLite connection - Add logging to SQLite table creation - Create common admin layout template --- src/MyWebLog.Data/RethinkDbData.fs | 4 +- src/MyWebLog.Data/SQLiteData.fs | 10 +++- src/MyWebLog/Program.fs | 84 ++++++++++++++------------- src/admin-theme/_layout.liquid | 54 +++++++++++++++++ src/admin-theme/layout-partial.liquid | 57 +----------------- src/admin-theme/layout.liquid | 57 +----------------- src/default-theme/index.liquid | 12 ++-- src/default-theme/layout.liquid | 4 +- 8 files changed, 122 insertions(+), 160 deletions(-) create mode 100644 src/admin-theme/_layout.liquid diff --git a/src/MyWebLog.Data/RethinkDbData.fs b/src/MyWebLog.Data/RethinkDbData.fs index 05ab827..4357247 100644 --- a/src/MyWebLog.Data/RethinkDbData.fs +++ b/src/MyWebLog.Data/RethinkDbData.fs @@ -866,13 +866,13 @@ type RethinkDbData (conn : Net.IConnection, config : DataConfig, log : ILogger { dbList; result; withRetryOnce conn } if not (dbs |> List.contains config.Database) then - log.LogInformation($"Creating database {config.Database}...") + log.LogInformation $"Creating database {config.Database}..." do! rethink { dbCreate config.Database; write; withRetryOnce; ignoreResult conn } let! tables = rethink { tableList; result; withRetryOnce conn } for tbl in Table.all do if not (tables |> List.contains tbl) then - log.LogInformation($"Creating table {tbl}...") + log.LogInformation $"Creating table {tbl}..." do! rethink { tableCreate tbl; write; withRetryOnce; ignoreResult conn } do! ensureIndexes Table.Category [ "webLogId" ] diff --git a/src/MyWebLog.Data/SQLiteData.fs b/src/MyWebLog.Data/SQLiteData.fs index 49c6e7f..67433e0 100644 --- a/src/MyWebLog.Data/SQLiteData.fs +++ b/src/MyWebLog.Data/SQLiteData.fs @@ -4,6 +4,7 @@ open System open System.IO open System.Threading.Tasks open Microsoft.Data.Sqlite +open Microsoft.Extensions.Logging open MyWebLog open MyWebLog.ViewModels @@ -235,7 +236,7 @@ module private SqliteHelpers = /// SQLite myWebLog data implementation -type SQLiteData (conn : SqliteConnection) = +type SQLiteData (conn : SqliteConnection, log : ILogger) = /// Add parameters for category INSERT or UPDATE statements let addCategoryParameters (cmd : SqliteCommand) (cat : Category) = @@ -1800,6 +1801,7 @@ type SQLiteData (conn : SqliteConnection) = let! exists = tableExists "theme" if not exists then + log.LogInformation "Creating theme tables..." use cmd = conn.CreateCommand () cmd.CommandText <- """CREATE TABLE theme ( @@ -1825,6 +1827,7 @@ type SQLiteData (conn : SqliteConnection) = let! exists = tableExists "web_log" if not exists then + log.LogInformation "Creating web log tables..." use cmd = conn.CreateCommand () cmd.CommandText <- """CREATE TABLE web_log ( @@ -1870,6 +1873,7 @@ type SQLiteData (conn : SqliteConnection) = let! exists = tableExists "category" if not exists then + log.LogInformation "Creating category table..." use cmd = conn.CreateCommand () cmd.CommandText <- """CREATE TABLE category ( @@ -1883,6 +1887,7 @@ type SQLiteData (conn : SqliteConnection) = let! exists = tableExists "web_log_user" if not exists then + log.LogInformation "Creating user table..." use cmd = conn.CreateCommand () cmd.CommandText <- """CREATE TABLE web_log_user ( @@ -1900,6 +1905,7 @@ type SQLiteData (conn : SqliteConnection) = let! exists = tableExists "page" if not exists then + log.LogInformation "Creating page tables..." use cmd = conn.CreateCommand () cmd.CommandText <- """CREATE TABLE page ( @@ -1937,6 +1943,7 @@ type SQLiteData (conn : SqliteConnection) = let! exists = tableExists "post" if not exists then + log.LogInformation "Creating post tables..." use cmd = conn.CreateCommand () cmd.CommandText <- """CREATE TABLE post ( @@ -1998,6 +2005,7 @@ type SQLiteData (conn : SqliteConnection) = let! exists = tableExists "tag_map" if not exists then + log.LogInformation "Creating tag map tables..." use cmd = conn.CreateCommand () cmd.CommandText <- """CREATE TABLE tag_map ( diff --git a/src/MyWebLog/Program.fs b/src/MyWebLog/Program.fs index 33abe8f..35adc22 100644 --- a/src/MyWebLog/Program.fs +++ b/src/MyWebLog/Program.fs @@ -38,19 +38,23 @@ module DataImplementation = open RethinkDb.Driver.Net /// Get the configured data implementation - let get (sp : IServiceProvider) : IData option = + let get (sp : IServiceProvider) : IData = let config = sp.GetRequiredService () - if (config.GetSection "RethinkDB").Exists () then + if (config.GetConnectionString >> isNull >> not) "SQLite" then + let conn = new SqliteConnection (config.GetConnectionString "SQLite") + SQLiteData.setUpConnection conn |> Async.AwaitTask |> Async.RunSynchronously + upcast SQLiteData (conn, sp.GetRequiredService> ()) + elif (config.GetSection "RethinkDB").Exists () then Json.all () |> Seq.iter Converter.Serializer.Converters.Add let rethinkCfg = DataConfig.FromConfiguration (config.GetSection "RethinkDB") let conn = rethinkCfg.CreateConnectionAsync () |> Async.AwaitTask |> Async.RunSynchronously - Some (upcast RethinkDbData (conn, rethinkCfg, sp.GetRequiredService> ())) - elif (config.GetConnectionString >> isNull >> not) "SQLite" then - let conn = new SqliteConnection (config.GetConnectionString "SQLite") - SQLiteData.setUpConnection conn |> Async.AwaitTask |> Async.RunSynchronously - Some (upcast SQLiteData conn) + upcast RethinkDbData (conn, rethinkCfg, sp.GetRequiredService> ()) else - None + let log = sp.GetRequiredService> () + log.LogInformation "Using default SQLite database myweblog.db" + let conn = new SqliteConnection ("Data Source=./myweblog.db;Cache=Shared") + SQLiteData.setUpConnection conn |> Async.AwaitTask |> Async.RunSynchronously + upcast SQLiteData (conn, log) open Giraffe @@ -78,39 +82,37 @@ let rec main args = let _ = builder.Services.AddAuthorization () let _ = builder.Services.AddAntiforgery () - let sp = builder.Services.BuildServiceProvider () - match DataImplementation.get sp with - | Some data -> - task { - do! data.startUp () - do! WebLogCache.fill data - do! ThemeAssetCache.fill data - } |> Async.AwaitTask |> Async.RunSynchronously - - // Define distributed cache implementation based on data implementation - match data with - | :? RethinkDbData as rethink -> - // A RethinkDB connection is designed to work as a singleton - builder.Services.AddSingleton data |> ignore - builder.Services.AddDistributedRethinkDBCache (fun opts -> - opts.TableName <- "Session" - opts.Connection <- rethink.Conn) - |> ignore - | :? SQLiteData -> - // ADO.NET connections are designed to work as per-request instantiation - let cfg = sp.GetRequiredService () - builder.Services.AddScoped (fun sp -> - let conn = new SqliteConnection (cfg.GetConnectionString "SQLite") - SQLiteData.setUpConnection conn |> Async.AwaitTask |> Async.RunSynchronously - conn) - |> ignore - builder.Services.AddScoped () |> ignore - // Use SQLite for caching as well - let cachePath = defaultArg (Option.ofObj (cfg.GetConnectionString "SQLiteCachePath")) "./session.db" - builder.Services.AddSqliteCache (fun o -> o.CachePath <- cachePath) |> ignore - | _ -> () - | None -> - invalidOp "There is no data configuration present; please add a RethinkDB section or LiteDB connection string" + let sp = builder.Services.BuildServiceProvider () + let data = DataImplementation.get sp + + task { + do! data.startUp () + do! WebLogCache.fill data + do! ThemeAssetCache.fill data + } |> Async.AwaitTask |> Async.RunSynchronously + + // Define distributed cache implementation based on data implementation + match data with + | :? RethinkDbData as rethink -> + // A RethinkDB connection is designed to work as a singleton + builder.Services.AddSingleton data |> ignore + builder.Services.AddDistributedRethinkDBCache (fun opts -> + opts.TableName <- "Session" + opts.Connection <- rethink.Conn) + |> ignore + | :? SQLiteData as sql -> + // ADO.NET connections are designed to work as per-request instantiation + let cfg = sp.GetRequiredService () + builder.Services.AddScoped (fun sp -> + let conn = new SqliteConnection (sql.Conn.ConnectionString) + SQLiteData.setUpConnection conn |> Async.AwaitTask |> Async.RunSynchronously + conn) + |> ignore + builder.Services.AddScoped () |> ignore + // Use SQLite for caching as well + let cachePath = Option.ofObj (cfg.GetConnectionString "SQLiteCachePath") |> Option.defaultValue "./session.db" + builder.Services.AddSqliteCache (fun o -> o.CachePath <- cachePath) |> ignore + | _ -> () let _ = builder.Services.AddSession(fun opts -> opts.IdleTimeout <- TimeSpan.FromMinutes 60 diff --git a/src/admin-theme/_layout.liquid b/src/admin-theme/_layout.liquid new file mode 100644 index 0000000..46737cb --- /dev/null +++ b/src/admin-theme/_layout.liquid @@ -0,0 +1,54 @@ +
+ +
+
+
+ {% for msg in messages %} + + {% endfor %} +
+ {{ content }} +
+
+
+
+
+ myWebLog +
+
+
+
diff --git a/src/admin-theme/layout-partial.liquid b/src/admin-theme/layout-partial.liquid index 13e3ace..4b273a6 100644 --- a/src/admin-theme/layout-partial.liquid +++ b/src/admin-theme/layout-partial.liquid @@ -1,63 +1,10 @@ - {{ page_title | escape }} « Admin « {{ web_log.name | escape }} + {{ page_title | strip_html }} « Admin « {{ web_log.name | strip_html }} -
- -
-
-
- {% for msg in messages %} - - {% endfor %} -
- {{ content }} -
-
-
-
-
- myWebLog -
-
-
-
+ {% include_template "_layout" %} diff --git a/src/admin-theme/layout.liquid b/src/admin-theme/layout.liquid index ecac8df..a556a5b 100644 --- a/src/admin-theme/layout.liquid +++ b/src/admin-theme/layout.liquid @@ -3,66 +3,13 @@ - {{ page_title | escape }} « Admin « {{ web_log.name | escape }} + {{ page_title | strip_html }} « Admin « {{ web_log.name | strip_html }} -
- -
-
-
- {% for msg in messages %} - - {% endfor %} -
- {{ content }} -
-
-
-
-
- myWebLog -
-
-
-
+ {% include_template "_layout" %} diff --git a/src/default-theme/index.liquid b/src/default-theme/index.liquid index 3c71f6e..f59b409 100644 --- a/src/default-theme/index.liquid +++ b/src/default-theme/index.liquid @@ -1,7 +1,11 @@ -{% if model.subtitle %} -

{{ model.subtitle.value }}

-{% endif %} -
+{%- if is_category or is_tag %} +

{{ page_title }}

+ {%- if is_category %} + {%- assign cat = categories | where: "slug", slug | first -%} + {%- if cat.description %}

{{ cat.description.value }}

{% endif -%} + {%- endif %} +{%- endif %} +
{% for post in model.posts %}

diff --git a/src/default-theme/layout.liquid b/src/default-theme/layout.liquid index 01aea34..9e6760b 100644 --- a/src/default-theme/layout.liquid +++ b/src/default-theme/layout.liquid @@ -5,7 +5,7 @@ - {{ page_title | escape }}{% if page_title %} « {% endif %}{{ web_log.name | escape }} + {{ page_title | strip_html }}{% if page_title %} « {% endif %}{{ web_log.name | strip_html }} {% page_head -%} @@ -19,7 +19,7 @@