Skip to content

Commit 0490348

Browse files
authored
Added db migrations example
1 parent 2f2f97b commit 0490348

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

README.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,109 @@ let main argv =
311311
|> Async.RunSynchronously
312312
```
313313

314+
### Passing Dependencies to Commands
315+
316+
This real-life example for running database migrations demonstrates the following features:
317+
* Uses Microsoft.Extensions.Hosting.
318+
* Passes the `ILogger` to the commands.
319+
* Uses async/task commands.
320+
* Shows help if no command is passed.
321+
322+
```F#
323+
module Program
324+
325+
open EvolveDb
326+
open System.Data.SqlClient
327+
open System.IO
328+
open Microsoft.Extensions.Hosting
329+
open Microsoft.Extensions.Configuration
330+
open Microsoft.Extensions.DependencyInjection
331+
open Serilog
332+
open EvolveDb.Configuration
333+
open FSharp.SystemCommandLine
334+
open System.CommandLine.Invocation
335+
open System.CommandLine.Help
336+
337+
let buildHost (argv: string[]) =
338+
Host.CreateDefaultBuilder(argv)
339+
.ConfigureHostConfiguration(fun configHost ->
340+
configHost.SetBasePath(Directory.GetCurrentDirectory()) |> ignore
341+
configHost.AddJsonFile("appsettings.json", optional = false) |> ignore
342+
)
343+
.UseSerilog(fun hostingContext configureLogger ->
344+
configureLogger
345+
.MinimumLevel.Information()
346+
.Enrich.FromLogContext()
347+
.WriteTo.Console()
348+
.WriteTo.File(
349+
path = "logs/log.txt",
350+
rollingInterval = RollingInterval.Year
351+
)
352+
|> ignore
353+
)
354+
.Build()
355+
356+
let repairCmd (logger: ILogger) =
357+
let handler (env: string) =
358+
task {
359+
logger.Information($"Environment: {env}")
360+
logger.Information("Starting EvolveDb Repair (correcting checksums).")
361+
let! connStr = KeyVault.getConnectionString env
362+
use conn = new SqlConnection(connStr)
363+
let evolve = Evolve(conn, fun msg -> printfn "%s" msg)
364+
evolve.TransactionMode <- TransactionKind.CommitAll
365+
evolve.Locations <- [| "Scripts" |]
366+
evolve.IsEraseDisabled <- true
367+
evolve.MetadataTableName <- "_EvolveChangelog"
368+
evolve.Repair()
369+
}
370+
371+
command "repair" {
372+
description "Corrects checksums in the database."
373+
inputs (Input.Argument<string>("env", "The keyvault environment: [dev, beta, prod]."))
374+
setHandler handler
375+
}
376+
377+
let migrateCmd (logger: ILogger) =
378+
let handler (env: string) =
379+
task {
380+
logger.Information($"Environment: {env}")
381+
logger.Information("Starting EvolveDb Migrate.")
382+
let! connStr = KeyVault.getConnectionString env
383+
use conn = new SqlConnection(connStr)
384+
let evolve = Evolve(conn, fun msg -> printfn "%s" msg)
385+
evolve.TransactionMode <- TransactionKind.CommitAll
386+
evolve.Locations <- [| "Scripts" |]
387+
evolve.IsEraseDisabled <- true
388+
evolve.MetadataTableName <- "_EvolveChangelog"
389+
evolve.Migrate()
390+
}
391+
392+
command "migrate" {
393+
description "Migrates the database."
394+
inputs (Input.Argument<string>("env", "The keyvault environment: [dev, beta, prod]."))
395+
setHandler handler
396+
}
397+
398+
let showHelp (ctx: InvocationContext) =
399+
let hc = HelpContext(ctx.HelpBuilder, ctx.Parser.Configuration.RootCommand, System.Console.Out)
400+
ctx.HelpBuilder.Write(hc)
401+
402+
[<EntryPoint>]
403+
let main argv =
404+
let host = buildHost argv
405+
let logger = host.Services.GetService<ILogger>()
406+
407+
rootCommand argv {
408+
description "Database Migrations"
409+
inputs (Input.Context())
410+
setHandler (showHelp)
411+
addCommand (repairCmd logger)
412+
addCommand (migrateCmd logger)
413+
}
414+
415+
```
416+
314417
### Creating a Root Command Parser
315418

316419
If you want to manually invoke your root command, use the `rootCommandParser` CE (because the `rootCommand` CE is auto-executing).

0 commit comments

Comments
 (0)