From 01e07e5086f1bbcb19b7147721bbe45d24f3062d Mon Sep 17 00:00:00 2001 From: tanner0101 Date: Fri, 6 Jul 2018 13:39:49 -0600 Subject: [PATCH] add support for ALTER TABLE drop actions --- .../PostgreSQLDatabase+QuerySupporting.swift | 21 -------- .../PostgreSQLDatabase+SchemaSupporting.swift | 28 ++++++++++ .../FluentPostgreSQLTests.swift | 53 +++++++++++++++++++ 3 files changed, 81 insertions(+), 21 deletions(-) diff --git a/Sources/FluentPostgreSQL/PostgreSQLDatabase+QuerySupporting.swift b/Sources/FluentPostgreSQL/PostgreSQLDatabase+QuerySupporting.swift index a85cf7e..cf2c487 100644 --- a/Sources/FluentPostgreSQL/PostgreSQLDatabase+QuerySupporting.swift +++ b/Sources/FluentPostgreSQL/PostgreSQLDatabase+QuerySupporting.swift @@ -115,25 +115,4 @@ extension PostgreSQLDatabase: QuerySupporting { return conn.future(model) } - - /// See `SchemaSupporting`. - public static func schemaExecute(_ fluent: FluentPostgreSQLSchema, on conn: PostgreSQLConnection) -> Future { - let query: PostgreSQLQuery - switch fluent.statement { - case ._createTable: - var createTable: PostgreSQLCreateTable = .createTable(fluent.table) - createTable.columns = fluent.columns - createTable.tableConstraints = fluent.constraints - query = ._createTable(createTable) - case ._alterTable: - var alterTable: PostgreSQLAlterTable = .alterTable(fluent.table) - alterTable.columns = fluent.columns - alterTable.constraints = fluent.constraints - query = ._alterTable(alterTable) - case ._dropTable: - let dropTable: PostgreSQLDropTable = .dropTable(fluent.table) - query = ._dropTable(dropTable) - } - return conn.query(query).transform(to: ()) - } } diff --git a/Sources/FluentPostgreSQL/PostgreSQLDatabase+SchemaSupporting.swift b/Sources/FluentPostgreSQL/PostgreSQLDatabase+SchemaSupporting.swift index e928f2a..1efec61 100644 --- a/Sources/FluentPostgreSQL/PostgreSQLDatabase+SchemaSupporting.swift +++ b/Sources/FluentPostgreSQL/PostgreSQLDatabase+SchemaSupporting.swift @@ -24,6 +24,34 @@ extension PostgreSQLDatabase: SchemaSupporting { /// See `SchemaSupporting`. public typealias SchemaReferenceAction = PostgreSQLForeignKeyAction + /// See `SchemaSupporting`. + public static func schemaExecute(_ fluent: FluentPostgreSQLSchema, on conn: PostgreSQLConnection) -> Future { + let query: PostgreSQLQuery + switch fluent.statement { + case ._createTable: + var createTable: PostgreSQLCreateTable = .createTable(fluent.table) + createTable.columns = fluent.columns + createTable.tableConstraints = fluent.constraints + query = ._createTable(createTable) + case ._alterTable: + var alterTable: PostgreSQLAlterTable = .alterTable(fluent.table) + alterTable.columns = fluent.columns + alterTable.constraints = fluent.constraints + alterTable.dropActions += fluent.deleteColumns.map { .init(.column, $0.identifier) } + alterTable.dropActions += fluent.deleteConstraints.map { + guard let id = $0.identifier else { + fatalError("Cannot drop constraint without identifier: \($0).") + } + return .init(.constraint, id) + } + query = ._alterTable(alterTable) + case ._dropTable: + let dropTable: PostgreSQLDropTable = .dropTable(fluent.table) + query = ._dropTable(dropTable) + } + return conn.query(query).transform(to: ()) + } + /// See `SchemaSupporting`. public static func schemaField(for type: Any.Type, isIdentifier: Bool, _ column: PostgreSQLColumnIdentifier) -> PostgreSQLColumnDefinition { var constraints: [PostgreSQLColumnConstraint] = [] diff --git a/Tests/FluentPostgreSQLTests/FluentPostgreSQLTests.swift b/Tests/FluentPostgreSQLTests/FluentPostgreSQLTests.swift index 7528d46..cd3b1a9 100644 --- a/Tests/FluentPostgreSQLTests/FluentPostgreSQLTests.swift +++ b/Tests/FluentPostgreSQLTests/FluentPostgreSQLTests.swift @@ -406,6 +406,59 @@ class FluentPostgreSQLTests: XCTestCase { XCTAssertEqual(b.id, 1) } + func testAlterDrop() throws { + struct A: PostgreSQLMigration { + static func prepare(on conn: PostgreSQLConnection) -> Future { + return PostgreSQLDatabase.create(Planet.self, on: conn) { builder in + builder.field(for: \.id) + } + } + + static func revert(on conn: PostgreSQLConnection) -> Future { + return PostgreSQLDatabase.delete(Planet.self, on: conn) + } + } + struct B: PostgreSQLMigration { + static func prepare(on conn: PostgreSQLConnection) -> Future { + return PostgreSQLDatabase.update(Planet.self, on: conn) { builder in + builder.field(for: \.name) + builder.deleteField(for: \.id) + } + } + + static func revert(on conn: PostgreSQLConnection) -> Future { + return PostgreSQLDatabase.update(Planet.self, on: conn) { builder in + builder.deleteField(for: \.name) + builder.field(for: \.id) + } + } + } + struct C: PostgreSQLMigration { + static func prepare(on conn: PostgreSQLConnection) -> Future { + return PostgreSQLDatabase.update(Planet.self, on: conn) { builder in + builder.unique(on: \.name) + } + } + + static func revert(on conn: PostgreSQLConnection) -> Future { + return PostgreSQLDatabase.update(Planet.self, on: conn) { builder in + builder.deleteUnique(from: \.name) + } + } + } + + let conn = try benchmarker.pool.requestConnection().wait() + conn.logger = DatabaseLogger(database: .psql, handler: PrintLogHandler()) + defer { benchmarker.pool.releaseConnection(conn) } + + try A.prepare(on: conn).wait() + defer { try? A.revert(on: conn).wait() } + try B.prepare(on: conn).wait() + defer { try? B.revert(on: conn).wait() } + try C.prepare(on: conn).wait() + defer { try? C.revert(on: conn).wait() } + } + static let allTests = [ ("testBenchmark", testBenchmark), ("testNestedStruct", testNestedStruct),