Use PG lib data source singleton

This commit is contained in:
Daniel J. Summers 2023-07-28 19:41:53 -04:00
parent 9dd6ab70e9
commit ab9f2f577b
2 changed files with 12 additions and 16 deletions

View File

@ -6,16 +6,14 @@ open Microsoft.Extensions.Logging
open MyWebLog open MyWebLog
open MyWebLog.Data.Postgres open MyWebLog.Data.Postgres
open Newtonsoft.Json open Newtonsoft.Json
open Npgsql
open Npgsql.FSharp open Npgsql.FSharp
/// Data implementation for PostgreSQL /// Data implementation for PostgreSQL
type PostgresData (source : NpgsqlDataSource, log : ILogger<PostgresData>, ser : JsonSerializer) = type PostgresData (log : ILogger<PostgresData>, ser : JsonSerializer) =
/// Create any needed tables /// Create any needed tables
let ensureTables () = backgroundTask { let ensureTables () = backgroundTask {
// Set up the PostgreSQL document store // Set up the PostgreSQL document store
Configuration.useDataSource source
Configuration.useSerializer Configuration.useSerializer
{ new IDocumentSerializer with { new IDocumentSerializer with
member _.Serialize<'T> (it : 'T) : string = Utils.serialize ser it member _.Serialize<'T> (it : 'T) : string = Utils.serialize ser it
@ -23,9 +21,8 @@ type PostgresData (source : NpgsqlDataSource, log : ILogger<PostgresData>, ser :
} }
let! tables = let! tables =
Sql.fromDataSource source Custom.list "SELECT tablename FROM pg_tables WHERE schemaname = 'public'" []
|> Sql.query "SELECT tablename FROM pg_tables WHERE schemaname = 'public'" (fun row -> row.string "tablename")
|> Sql.executeAsync (fun row -> row.string "tablename")
let needsTable table = not (List.contains table tables) let needsTable table = not (List.contains table tables)
// Create a document table // Create a document table
let mutable isNew = false let mutable isNew = false
@ -117,7 +114,8 @@ type PostgresData (source : NpgsqlDataSource, log : ILogger<PostgresData>, ser :
$"INSERT INTO {Table.DbVersion} VALUES ('{Utils.currentDbVersion}')" $"INSERT INTO {Table.DbVersion} VALUES ('{Utils.currentDbVersion}')"
} }
Sql.fromDataSource source Configuration.dataSource ()
|> Sql.fromDataSource
|> Sql.executeTransactionAsync |> Sql.executeTransactionAsync
(sql (sql
|> Seq.map (fun s -> |> Seq.map (fun s ->

View File

@ -27,6 +27,7 @@ type WebLogMiddleware (next : RequestDelegate, log : ILogger<WebLogMiddleware>)
open System open System
open BitBadger.Npgsql.FSharp.Documents
open Microsoft.Extensions.DependencyInjection open Microsoft.Extensions.DependencyInjection
open MyWebLog.Data open MyWebLog.Data
open Newtonsoft.Json open Newtonsoft.Json
@ -44,7 +45,7 @@ module DataImplementation =
let builder = NpgsqlDataSourceBuilder (cfg.GetConnectionString "PostgreSQL") let builder = NpgsqlDataSourceBuilder (cfg.GetConnectionString "PostgreSQL")
let _ = builder.UseNodaTime () let _ = builder.UseNodaTime ()
// let _ = builder.UseLoggerFactory(LoggerFactory.Create(fun it -> it.AddConsole () |> ignore)) // let _ = builder.UseLoggerFactory(LoggerFactory.Create(fun it -> it.AddConsole () |> ignore))
builder.Build () (builder.Build >> Configuration.useDataSource) ()
/// Get the configured data implementation /// Get the configured data implementation
let get (sp : IServiceProvider) : IData = let get (sp : IServiceProvider) : IData =
@ -68,11 +69,11 @@ module DataImplementation =
let conn = await (rethinkCfg.CreateConnectionAsync log) let conn = await (rethinkCfg.CreateConnectionAsync log)
RethinkDbData (conn, rethinkCfg, log) RethinkDbData (conn, rethinkCfg, log)
elif hasConnStr "PostgreSQL" then elif hasConnStr "PostgreSQL" then
let source = createNpgsqlDataSource config createNpgsqlDataSource config
use conn = source.CreateConnection () use conn = Configuration.dataSource().CreateConnection ()
let log = sp.GetRequiredService<ILogger<PostgresData>> () let log = sp.GetRequiredService<ILogger<PostgresData>> ()
log.LogInformation $"Using PostgreSQL database {conn.Database}" log.LogInformation $"Using PostgreSQL database {conn.Database}"
PostgresData (source, log, Json.configure (JsonSerializer.CreateDefault ())) PostgresData (log, Json.configure (JsonSerializer.CreateDefault ()))
else else
createSQLite "Data Source=./myweblog.db;Cache=Shared" createSQLite "Data Source=./myweblog.db;Cache=Shared"
@ -99,7 +100,6 @@ let showHelp () =
open System.IO open System.IO
open System.Linq
open BitBadger.AspNetCore.CanonicalDomains open BitBadger.AspNetCore.CanonicalDomains
open Giraffe open Giraffe
open Giraffe.EndpointRouting open Giraffe.EndpointRouting
@ -111,7 +111,7 @@ open NeoSmart.Caching.Sqlite
open RethinkDB.DistributedCache open RethinkDB.DistributedCache
[<EntryPoint>] [<EntryPoint>]
let rec main args = let main args =
let builder = WebApplication.CreateBuilder(args) let builder = WebApplication.CreateBuilder(args)
let _ = builder.Services.Configure<ForwardedHeadersOptions>(fun (opts : ForwardedHeadersOptions) -> let _ = builder.Services.Configure<ForwardedHeadersOptions>(fun (opts : ForwardedHeadersOptions) ->
@ -162,9 +162,7 @@ let rec main args =
() ()
| :? PostgresData as postgres -> | :? PostgresData as postgres ->
// ADO.NET Data Sources are designed to work as singletons // ADO.NET Data Sources are designed to work as singletons
let _ = let _ = builder.Services.AddSingleton<NpgsqlDataSource> (Configuration.dataSource ())
builder.Services.AddSingleton<NpgsqlDataSource> (fun sp ->
DataImplementation.createNpgsqlDataSource (sp.GetRequiredService<IConfiguration> ()))
let _ = builder.Services.AddSingleton<IData> postgres let _ = builder.Services.AddSingleton<IData> postgres
let _ = let _ =
builder.Services.AddSingleton<IDistributedCache> (fun _ -> builder.Services.AddSingleton<IDistributedCache> (fun _ ->