Punt RethinkDB migration
- Backup/restore works; otherwise, it would have required near full replacement of several document types. Backup/restore is well-tested and less error-prone.
This commit is contained in:
parent
e0e2d97ac2
commit
2f8ec5a54b
@ -84,10 +84,6 @@ module private RethinkHelpers =
|
||||
|
||||
/// Cast a strongly-typed list to an object list
|
||||
let objList<'T> (objects : 'T list) = objects |> List.map (fun it -> it :> obj)
|
||||
|
||||
/// A simple type for the database version table
|
||||
[<CLIMutable; NoComparison; NoEquality>]
|
||||
type DbVersion = { Id : string }
|
||||
|
||||
|
||||
open System
|
||||
@ -204,11 +200,32 @@ type RethinkDbData (conn : Net.IConnection, config : DataConfig, log : ILogger<R
|
||||
}
|
||||
do! rethink {
|
||||
withTable Table.DbVersion
|
||||
insert { Id = version }
|
||||
insert {| Id = version |}
|
||||
write; withRetryOnce; ignoreResult conn
|
||||
}
|
||||
}
|
||||
|
||||
/// Migrate from v2-rc1 to v2-rc2
|
||||
let migrateV2Rc1ToV2Rc2 () = backgroundTask {
|
||||
let logStep = Utils.logMigrationStep log "v2-rc1 to v2-rc2"
|
||||
logStep "**IMPORTANT**"
|
||||
logStep "See release notes about required backup/restoration for RethinkDB."
|
||||
logStep "If there is an error immediately below this message, this is why."
|
||||
logStep "Setting database version to v2-rc2"
|
||||
do! setDbVersion "v2-rc2"
|
||||
}
|
||||
|
||||
/// Migrate data between versions
|
||||
let migrate version = backgroundTask {
|
||||
match version with
|
||||
| Some v when v = "v2-rc2" -> ()
|
||||
| Some v when v = "v2-rc1" -> do! migrateV2Rc1ToV2Rc2 ()
|
||||
| Some _
|
||||
| None ->
|
||||
log.LogWarning $"Unknown database version; assuming {Utils.currentDbVersion}"
|
||||
do! setDbVersion Utils.currentDbVersion
|
||||
}
|
||||
|
||||
/// The connection for this instance
|
||||
member _.Conn = conn
|
||||
|
||||
@ -1138,6 +1155,14 @@ type RethinkDbData (conn : Net.IConnection, config : DataConfig, log : ILogger<R
|
||||
log.LogInformation $"Creating table {tbl}..."
|
||||
do! rethink { tableCreate tbl [ PrimaryKey "Id" ]; write; withRetryOnce; ignoreResult conn }
|
||||
|
||||
if not (List.contains Table.DbVersion tables) then
|
||||
// Version table added in v2-rc2; this will flag that migration to be run
|
||||
do! rethink {
|
||||
withTable Table.DbVersion
|
||||
insert {| Id = "v2-rc1" |}
|
||||
write; withRetryOnce; ignoreResult conn
|
||||
}
|
||||
|
||||
do! ensureIndexes Table.Category [ nameof Category.empty.WebLogId ]
|
||||
do! ensureIndexes Table.Comment [ nameof Comment.empty.PostId ]
|
||||
do! ensureIndexes Table.Page [ nameof Page.empty.WebLogId; nameof Page.empty.AuthorId ]
|
||||
@ -1147,15 +1172,12 @@ type RethinkDbData (conn : Net.IConnection, config : DataConfig, log : ILogger<R
|
||||
do! ensureIndexes Table.WebLog [ nameof WebLog.empty.UrlBase ]
|
||||
do! ensureIndexes Table.WebLogUser [ nameof WebLogUser.empty.WebLogId ]
|
||||
|
||||
let! version = rethink<DbVersion list> {
|
||||
let! version = rethink<{| Id : string |} list> {
|
||||
withTable Table.DbVersion
|
||||
limit 1
|
||||
result; withRetryOnce conn
|
||||
}
|
||||
match List.tryHead version with
|
||||
| Some v when v.Id = "v2-rc2" -> ()
|
||||
// Future migrations will be checked here
|
||||
| Some _
|
||||
| None ->
|
||||
log.LogWarning $"Unknown database version; assuming {Utils.currentDbVersion}"
|
||||
do! setDbVersion Utils.currentDbVersion
|
||||
| it -> do! migrate (it |> Option.map (fun x -> x.Id))
|
||||
}
|
||||
|
@ -228,13 +228,9 @@ type SQLiteData (conn : SqliteConnection, log : ILogger<SQLiteData>, ser : JsonS
|
||||
do! write cmd
|
||||
}
|
||||
|
||||
/// Log a migration step
|
||||
let logMigrationStep migration message =
|
||||
log.LogInformation $"Migrating %s{migration}: %s{message}"
|
||||
|
||||
/// Implement the changes between v2-rc1 and v2-rc2
|
||||
let migrateV2Rc1ToV2Rc2 () = backgroundTask {
|
||||
let logStep = logMigrationStep "v2-rc1 to v2-rc2"
|
||||
let logStep = Utils.logMigrationStep log "v2-rc1 to v2-rc2"
|
||||
// Move meta items, podcast settings, and episode details to JSON-encoded text fields
|
||||
use cmd = conn.CreateCommand ()
|
||||
logStep "Adding new columns"
|
||||
@ -529,7 +525,7 @@ type SQLiteData (conn : SqliteConnection, log : ILogger<SQLiteData>, ser : JsonS
|
||||
DROP TABLE web_log_feed_podcast"
|
||||
do! write cmd
|
||||
|
||||
logStep "Setting database version"
|
||||
logStep "Setting database version to v2-rc2"
|
||||
do! setDbVersion "v2-rc2"
|
||||
}
|
||||
|
||||
|
@ -50,3 +50,9 @@ let serialize<'T> ser (item : 'T) =
|
||||
/// Deserialize a JSON string
|
||||
let deserialize<'T> (ser : JsonSerializer) value =
|
||||
JsonConvert.DeserializeObject<'T> (value, Json.settings ser)
|
||||
|
||||
open Microsoft.Extensions.Logging
|
||||
|
||||
/// Log a migration step
|
||||
let logMigrationStep<'T> (log : ILogger<'T>) migration message =
|
||||
log.LogInformation $"Migrating %s{migration}: %s{message}"
|
||||
|
@ -22,6 +22,7 @@ module Noda =
|
||||
/// The Unix epoch
|
||||
let epoch = Instant.FromUnixTimeSeconds 0L
|
||||
|
||||
|
||||
/// Truncate an instant to remove fractional seconds
|
||||
let toSecondsPrecision (value : Instant) =
|
||||
Instant.FromUnixTimeSeconds (value.ToUnixTimeSeconds ())
|
||||
@ -29,6 +30,10 @@ module Noda =
|
||||
/// The current Instant, with fractional seconds truncated
|
||||
let now () =
|
||||
toSecondsPrecision (clock.GetCurrentInstant ())
|
||||
|
||||
/// Convert a date/time to an Instant with whole seconds
|
||||
let fromDateTime (dt : DateTime) =
|
||||
toSecondsPrecision (Instant.FromDateTimeUtc (DateTime (dt.Ticks, DateTimeKind.Utc)))
|
||||
|
||||
|
||||
/// A user's access level
|
||||
|
Loading…
Reference in New Issue
Block a user