Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track Migrations Per Database #271

Merged
merged 29 commits into from
May 18, 2020
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
e81d831
Pass ID of database to migrate into Migrator
calebkleveter May 8, 2020
6c0a579
Migrate each registered DatabaseID unless a specific database is spec…
calebkleveter May 11, 2020
0a2fd3d
Removed Migrator.run(on:_:) method that passes Database instance into…
calebkleveter May 11, 2020
5e155d0
Removed MigrationError enum
calebkleveter May 11, 2020
8f83338
Skip subsequent queries if a previous error has occured in Migrator p…
calebkleveter May 11, 2020
dc88144
Pass in default database ID (nil) to Migrator.run 'query' closure arg…
calebkleveter May 11, 2020
1aaf1fd
Changed Migrations.databases type from an Array to a Set
calebkleveter May 11, 2020
466cff6
Use .whenAllSucceed instead of .andAllSync to complete Migrator.run '…
calebkleveter May 11, 2020
83a4fae
Defined MigratorTests test cases
calebkleveter May 11, 2020
2f5239c
Use 'guard' statements to check failed errors in Migrator preview met…
calebkleveter May 11, 2020
6c0ad52
Use .recover instead of .flatMapErrorThrowing to capture failures in …
calebkleveter May 11, 2020
0803c7a
Use !contains instead of count check in Migrator.unpreparedMigrations…
calebkleveter May 11, 2020
aeb0e4f
Cleanup newlines in Migrator.run(on:_:) method
calebkleveter May 11, 2020
c48b0ca
Give database configurations access to database ID in DatabaseConfigu…
calebkleveter May 12, 2020
0599e61
Run MigrationLog queries on Migration.Item database
calebkleveter May 12, 2020
3b48ba7
Require DatabaseIDs for FluentBenchmarker to access separate databases
calebkleveter May 12, 2020
899abb8
Created FluentBenchmarker.testMigrator_sequence test case
calebkleveter May 12, 2020
cc9d222
Removed FluentKit MigratorTests
calebkleveter May 12, 2020
74c9337
Assert database2 log count is 0 if no errors are throw from query
calebkleveter May 12, 2020
faa0662
Fixed typo in MigrationLog database2 query catch block comment
calebkleveter May 12, 2020
46ef28d
Removed DatabaseID injection from DatabaseConfigurationFactory
calebkleveter May 14, 2020
6b6f98f
Change Migrations.databases to a computed property
calebkleveter May 14, 2020
9af4e1f
Added .ids() method to Databases type
calebkleveter May 14, 2020
ba290bc
Get database IDs for FluentBenchmark.testMigrator_sequence from Datab…
calebkleveter May 14, 2020
1921982
Allow nil in Migrations.databases set
calebkleveter May 14, 2020
86c4641
Use underlying DatabaseMigrator type to run migrations in Migrator
calebkleveter May 14, 2020
297d83d
Removed stray use of .andAllSync from QueryBuilder
calebkleveter May 14, 2020
e4e6760
Add missing AsyncKit dependency requirement (breaks the build, why wa…
gwynne May 15, 2020
8de1431
Fix typo in Package.swift. Now I have to wonder not only why was this…
gwynne May 15, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Sources/FluentBenchmark/FluentBenchmarker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import XCTest

public final class FluentBenchmarker {
public let databases: Databases
public let ids: (DatabaseID, DatabaseID)
calebkleveter marked this conversation as resolved.
Show resolved Hide resolved

public var database: Database {
self.databases.database(
Expand All @@ -13,8 +14,11 @@ public final class FluentBenchmarker {
)!
}

public init(databases: Databases) {
public init(databases: Databases, _ ids: (DatabaseID, DatabaseID)) {
precondition(ids.0 != ids.1, "FluentBecnhmarker DatabaseIDs must be non-equivalent")

self.databases = databases
self.ids = ids
}

public func testAll() throws {
Expand Down
75 changes: 75 additions & 0 deletions Sources/FluentBenchmark/Tests/MigratorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ extension FluentBenchmarker {
public func testMigrator() throws {
try self.testMigrator_success()
try self.testMigrator_error()
try self.testMigrator_sequence()
}

private func testMigrator_success() throws {
Expand Down Expand Up @@ -53,6 +54,80 @@ extension FluentBenchmarker {
try migrator.revertAllBatches().wait()
}
}

private func testMigrator_sequence() throws {
try self.runTest(#function, []) {

calebkleveter marked this conversation as resolved.
Show resolved Hide resolved
// Setup
let database1 = try XCTUnwrap(
self.databases.database(
self.ids.0,
logger: Logger(label: "codes.vapor.tests"),
on: self.databases.eventLoopGroup.next()
)
)
let database2 = try XCTUnwrap(
self.databases.database(
self.ids.1,
logger: Logger(label: "codes.vapor.tests"),
on: self.databases.eventLoopGroup.next()
)
)

let migrations = Migrations()


// Migration #1
migrations.add(GalaxyMigration(), to: self.ids.0)

let migrator = Migrator(
databases: self.databases,
migrations: migrations,
logger: Logger(label: "codes.vapor.tests"),
on: self.databases.eventLoopGroup.next()
)

try migrator.setupIfNeeded().wait()
try migrator.prepareBatch().wait()

let logs1 = try MigrationLog.query(on: database1).all().wait()
XCTAssertEqual(logs1.count, 1)
let log1 = try XCTUnwrap(logs1.first)
XCTAssertEqual(log1.batch, 1)
XCTAssertEqual(log1.name, "\(GalaxyMigration.self)")

do {
let count = try MigrationLog.query(on: database2).count().wait()

// This is a valid state to enter. Unlike database in the SQL family,
// some databases such as MongoDB won't throw an error if the table doesn't exist.
XCTAssertEqual(count, 0)
} catch let error {
// This is a valid state to enter. A SQL database with throw an error
// because the `_fluent_migrations` table on the `database2` database
// will have not been created yet.
}


// Migration #2
migrations.add(GalaxyMigration(), to: self.ids.1)

try migrator.setupIfNeeded().wait()
try migrator.prepareBatch().wait()

let logs2 = try MigrationLog.query(on: database2).all().wait()
XCTAssertEqual(logs2.count, 1)
let log2 = try XCTUnwrap(logs2.first)
XCTAssertEqual(log2.batch, 1)
XCTAssertEqual(log2.name, "\(GalaxyMigration.self)")

try XCTAssertEqual(MigrationLog.query(on: database1).count().wait(), 1)


// Teardown
try migrator.revertAllBatches().wait()
}
}
}

private struct ErrorMigration: Migration {
Expand Down
18 changes: 15 additions & 3 deletions Sources/FluentKit/Database/Databases.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,22 @@ import class NIOConcurrencyHelpers.Lock
@_exported import class NIO.NIOThreadPool

public struct DatabaseConfigurationFactory {
public let make: () -> DatabaseConfiguration
private let build: (DatabaseID?) -> DatabaseConfiguration
calebkleveter marked this conversation as resolved.
Show resolved Hide resolved

public var make: () -> DatabaseConfiguration {
return { self.build(nil) }
}

public init(make: @escaping () -> DatabaseConfiguration) {
self.make = make
self.build = { _ in make() }
}

public init(make: @escaping (DatabaseID?) -> DatabaseConfiguration) {
self.build = make
}

public func make(_ id: DatabaseID?) -> DatabaseConfiguration {
return self.build(id)
}
}

Expand Down Expand Up @@ -57,7 +69,7 @@ public final class Databases {
as id: DatabaseID,
isDefault: Bool? = nil
) {
self.use(configuration.make(), as: id, isDefault: isDefault)
self.use(configuration.make(id), as: id, isDefault: isDefault)
}

public func use(
Expand Down
3 changes: 3 additions & 0 deletions Sources/FluentKit/Migration/Migrations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ public final class Migrations {
}

var storage: [Item]
var databases: Set<DatabaseID>
calebkleveter marked this conversation as resolved.
Show resolved Hide resolved

public init() {
self.storage = []
self.databases = []
}

public func add(_ migration: Migration, to id: DatabaseID? = nil) {
self.storage.append(.init(id: id, migration: migration))
if let id = id { self.databases.insert(id) }
}
}
Loading