-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* migration prototype MigrationService - runs list of Migration objects that are passed in Migration - protocol to define metadata about Migration and `perform` method * Updates tests to check for migration that duplicates table definition * Adds test to check migrations run multiple times * Adds migration to create SpanRecord table * Adds 'AddSpanRecordMigration' to list of defined migrations Removes `defineTable` method from SpanRecord. * Adds AddSessionRecordMigrationTests Renames test file to include date * Adds `AddMetadataRecordMigration`. Updates filenames to account for multiple migrations in the same day * Adds AddLogRecordMigration * Removes `defineTable` methods from LogRecord, MetadataRecord, SessionRecord These are now performed by migrations * Adds tests for Migration identifiers and Migrations+Current definition * Updates EmbraceStorage+Options to use `fileURL` computed property * Updates EmbraceStorage to reset database if migrations fail * Fixes typo in tests * Re-adds missing `databaseTableName` override to each record * Adds explict check for databaseTableName in each record test * Adds changelog entry --------- Co-authored-by: Fernando Draghi <fdraghi@FDraghi-Embrace-MBP.local> Co-authored-by: Austin Emmons <austin.emmons@embrace.io>
- Loading branch information
1 parent
b8ef540
commit 258362d
Showing
30 changed files
with
1,165 additions
and
216 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// | ||
// Copyright © 2023 Embrace Mobile, Inc. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import GRDB | ||
|
||
public protocol Migration { | ||
/// The identifier to register this migration under. Must be unique | ||
static var identifier: StringLiteralType { get } | ||
|
||
/// Controls how this migration handles foreign key constraints. Defaults to `immediate`. | ||
static var foreignKeyChecks: DatabaseMigrator.ForeignKeyChecks { get } | ||
|
||
/// Operation that performs migration. | ||
/// See [GRDB Reference](https://swiftpackageindex.com/groue/grdb.swift/master/documentation/grdb/migrations). | ||
func perform(_ db: Database) throws | ||
} | ||
|
||
extension Migration { | ||
var identifier: StringLiteralType { Self.identifier } | ||
var foreignKeyChecks: DatabaseMigrator.ForeignKeyChecks { Self.foreignKeyChecks } | ||
} | ||
|
||
extension Migration { | ||
static var foreignKeyChecks: DatabaseMigrator.ForeignKeyChecks { .immediate } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// | ||
// Copyright © 2023 Embrace Mobile, Inc. All rights reserved. | ||
// | ||
|
||
import GRDB | ||
import EmbraceCommon | ||
|
||
public protocol MigrationServiceProtocol { | ||
func perform(_ dbQueue: DatabaseWriter, migrations: [Migration]) throws | ||
} | ||
|
||
final public class MigrationService: MigrationServiceProtocol { | ||
public init() { } | ||
|
||
public func perform(_ dbQueue: DatabaseWriter, migrations: [Migration]) throws { | ||
guard migrations.count > 0 else { | ||
ConsoleLog.debug("No migrations to perform") | ||
return | ||
} | ||
|
||
var migrator = DatabaseMigrator() | ||
migrations.forEach { migration in | ||
migrator.registerMigration(migration.identifier, | ||
foreignKeyChecks: migration.foreignKeyChecks, | ||
migrate: migration.perform(_:)) | ||
} | ||
|
||
try dbQueue.read { db in | ||
if try migrator.hasCompletedMigrations(db) { | ||
ConsoleLog.debug("DB is up to date") | ||
return | ||
} else { | ||
ConsoleLog.debug("Running up to \(migrations.count) migrations") | ||
} | ||
} | ||
|
||
try migrator.migrate(dbQueue) | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
Sources/EmbraceStorage/Migration/Migrations/20240509_00_AddSpanRecordMigration.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// | ||
// Copyright © 2023 Embrace Mobile, Inc. All rights reserved. | ||
// | ||
|
||
import GRDB | ||
|
||
struct AddSpanRecordMigration: Migration { | ||
static let identifier = "CreateSpanRecordTable" // DEV: Must not change | ||
|
||
func perform(_ db: GRDB.Database) throws { | ||
try db.create(table: SpanRecord.databaseTableName, options: .ifNotExists) { t in | ||
t.column(SpanRecord.Schema.id.name, .text).notNull() | ||
t.column(SpanRecord.Schema.name.name, .text).notNull() | ||
t.column(SpanRecord.Schema.traceId.name, .text).notNull() | ||
t.primaryKey([SpanRecord.Schema.traceId.name, SpanRecord.Schema.id.name]) | ||
|
||
t.column(SpanRecord.Schema.type.name, .text).notNull() | ||
t.column(SpanRecord.Schema.startTime.name, .datetime).notNull() | ||
t.column(SpanRecord.Schema.endTime.name, .datetime) | ||
|
||
t.column(SpanRecord.Schema.data.name, .blob).notNull() | ||
} | ||
|
||
let preventClosedSpanModification = """ | ||
CREATE TRIGGER IF NOT EXISTS prevent_closed_span_modification | ||
BEFORE UPDATE ON \(SpanRecord.databaseTableName) | ||
WHEN OLD.end_time IS NOT NULL | ||
BEGIN | ||
SELECT RAISE(ABORT,'Attempted to modify an already closed span.'); | ||
END; | ||
""" | ||
|
||
try db.execute(sql: preventClosedSpanModification) | ||
} | ||
|
||
} |
39 changes: 39 additions & 0 deletions
39
Sources/EmbraceStorage/Migration/Migrations/20240510_00_AddSessionRecordMigration.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// | ||
// Copyright © 2023 Embrace Mobile, Inc. All rights reserved. | ||
// | ||
|
||
import GRDB | ||
|
||
struct AddSessionRecordMigration: Migration { | ||
static var identifier = "CreateSessionRecordTable" // DEV: Must not change | ||
|
||
func perform(_ db: GRDB.Database) throws { | ||
try db.create(table: SessionRecord.databaseTableName, options: .ifNotExists) { t in | ||
|
||
t.primaryKey(SessionRecord.Schema.id.name, .text).notNull() | ||
|
||
t.column(SessionRecord.Schema.state.name, .text).notNull() | ||
t.column(SessionRecord.Schema.processId.name, .text).notNull() | ||
t.column(SessionRecord.Schema.traceId.name, .text).notNull() | ||
t.column(SessionRecord.Schema.spanId.name, .text).notNull() | ||
|
||
t.column(SessionRecord.Schema.startTime.name, .datetime).notNull() | ||
t.column(SessionRecord.Schema.endTime.name, .datetime) | ||
t.column(SessionRecord.Schema.lastHeartbeatTime.name, .datetime).notNull() | ||
|
||
t.column(SessionRecord.Schema.coldStart.name, .boolean) | ||
.notNull() | ||
.defaults(to: false) | ||
|
||
t.column(SessionRecord.Schema.cleanExit.name, .boolean) | ||
.notNull() | ||
.defaults(to: false) | ||
|
||
t.column(SessionRecord.Schema.appTerminated.name, .boolean) | ||
.notNull() | ||
.defaults(to: false) | ||
|
||
t.column(SessionRecord.Schema.crashReportId.name, .text) | ||
} | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
Sources/EmbraceStorage/Migration/Migrations/20240510_01_AddMetadataRecordMigration.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// | ||
// Copyright © 2023 Embrace Mobile, Inc. All rights reserved. | ||
// | ||
|
||
import GRDB | ||
|
||
struct AddMetadataRecordMigration: Migration { | ||
|
||
static var identifier = "CreateMetadataRecordTable" // DEV: Must not change | ||
|
||
func perform(_ db: Database) throws { | ||
try db.create(table: MetadataRecord.databaseTableName, options: .ifNotExists) { t in | ||
|
||
t.column(MetadataRecord.Schema.key.name, .text).notNull() | ||
t.column(MetadataRecord.Schema.value.name, .text).notNull() | ||
t.column(MetadataRecord.Schema.type.name, .text).notNull() | ||
t.column(MetadataRecord.Schema.lifespan.name, .text).notNull() | ||
t.column(MetadataRecord.Schema.lifespanId.name, .text).notNull() | ||
t.column(MetadataRecord.Schema.collectedAt.name, .datetime).notNull() | ||
|
||
t.primaryKey([ | ||
MetadataRecord.Schema.key.name, | ||
MetadataRecord.Schema.type.name, | ||
MetadataRecord.Schema.lifespan.name, | ||
MetadataRecord.Schema.lifespanId.name | ||
]) | ||
} | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
Sources/EmbraceStorage/Migration/Migrations/20240510_02_AddLogRecordMigration.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// | ||
// Copyright © 2023 Embrace Mobile, Inc. All rights reserved. | ||
// | ||
|
||
import GRDB | ||
|
||
struct AddLogRecordMigration: Migration { | ||
|
||
static var identifier = "CreateLogRecordTable" // DEV: Must not change | ||
|
||
func perform(_ db: Database) throws { | ||
try db.create(table: LogRecord.databaseTableName, options: .ifNotExists) { t in | ||
t.primaryKey(LogRecord.Schema.identifier.name, .text).notNull() | ||
t.column(LogRecord.Schema.processIdentifier.name, .integer).notNull() | ||
t.column(LogRecord.Schema.severity.name, .integer).notNull() | ||
t.column(LogRecord.Schema.body.name, .text).notNull() | ||
t.column(LogRecord.Schema.timestamp.name, .datetime).notNull() | ||
t.column(LogRecord.Schema.attributes.name, .text).notNull() | ||
} | ||
} | ||
} |
Oops, something went wrong.