Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ let package = Package(
.package(url: "https://github.com/vapor/core.git", .exact("3.0.0-beta.1")),

// Swift ORM framework (queries, models, and relations) for building NoSQL and SQL database integrations.
.package(url: "https://github.com/vapor/fluent.git", .exact("3.0.0-beta.1")),
.package(url: "https://github.com/vapor/fluent.git", .exact("3.0.0-beta.2")),

// Pure Swift, async/non-blocking client for PostgreSQL.
.package(url: "https://github.com/vapor/postgresql.git", .exact("1.0.0-beta.1")),
.package(url: "https://github.com/vapor/postgresql.git", .exact("1.0.0-beta.2")),
],
targets: [
.target(name: "FluentPostgreSQL", dependencies: ["Async", "CodableKit", "Fluent", "FluentSQL", "PostgreSQL"]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,23 +77,27 @@ extension PostgreSQLDatabase: QuerySupporting {
}

/// See `QuerySupporting.modelEvent`
public static func modelEvent<M>(event: ModelEvent, model: M, on connection: PostgreSQLConnection) -> Future<Void>
public static func modelEvent<M>(event: ModelEvent, model: M, on connection: PostgreSQLConnection) -> Future<M>
where PostgreSQLDatabase == M.Database, M: Model
{
switch event {
case .willCreate:
if M.ID.self == UUID.self {
var model = model
model.fluentID = UUID() as? M.ID
return Future(model)
}
case .didCreate:
if M.ID.self == Int.self {
return connection.simpleQuery("SELECT LASTVAL();").map(to: Void.self) { row in
try! model.fluentID = row[0]["lastval"]?.decode(Int.self) as? M.ID
return connection.simpleQuery("SELECT LASTVAL();").map(to: M.self) { row in
var model = model
try model.fluentID = row[0]["lastval"]?.decode(Int.self) as? M.ID
return model
}
}
default: break
}

return .done
return Future(model)
}
}
17 changes: 15 additions & 2 deletions Sources/FluentPostgreSQL/PostgreSQLRowEncoder.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Foundation

internal final class PostgreSQLRowEncoder: Encoder {
var codingPath: [CodingKey]
var userInfo: [CodingUserInfoKey : Any]
Expand Down Expand Up @@ -43,7 +45,7 @@ fileprivate struct PostgreSQLRowKeyedEncodingContainer<K>: KeyedEncodingContaine
self.codingPath = []
}

mutating func encodeNil(forKey key: K) throws { encoder.data[key.stringValue] = PostgreSQLData(type: .void) }
mutating func encodeNil(forKey key: K) throws { encoder.data[key.stringValue] = PostgreSQLData(type: .void, data: nil) }
mutating func encode(_ value: Bool, forKey key: K) throws { encoder.data[key.stringValue] = try value.convertToPostgreSQLData() }
mutating func encode(_ value: Int, forKey key: K) throws { encoder.data[key.stringValue] = try value.convertToPostgreSQLData() }
mutating func encode(_ value: Int16, forKey key: K) throws { encoder.data[key.stringValue] = try value.convertToPostgreSQLData() }
Expand All @@ -59,7 +61,18 @@ fileprivate struct PostgreSQLRowKeyedEncodingContainer<K>: KeyedEncodingContaine
mutating func encode(_ value: String, forKey key: K) throws { encoder.data[key.stringValue] = try value.convertToPostgreSQLData() }
mutating func superEncoder() -> Encoder { return encoder }
mutating func superEncoder(forKey key: K) -> Encoder { return encoder }
mutating func encode<T>(_ value: T, forKey key: K) throws where T : Encodable {
mutating func encodeIfPresent<T>(_ value: T?, forKey key: K) throws where T : Encodable {
if let value = value {
try encode(value, forKey: key)
} else {
if let convertibleType = T.self as? PostgreSQLDataCustomConvertible.Type {
encoder.data[key.stringValue] = PostgreSQLData(type: convertibleType.postgreSQLDataType, data: nil)
} else {
try encodeNil(forKey: key)
}
}
}
mutating func encode<T>(_ value: T, forKey key: K) throws where T: Encodable {
guard let convertible = value as? PostgreSQLDataCustomConvertible else {
let type = Swift.type(of: value)
throw PostgreSQLError(
Expand Down
22 changes: 21 additions & 1 deletion Tests/FluentPostgreSQLTests/FluentPostgreSQLTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,22 @@ class FluentPostgreSQLTests: XCTestCase {
try benchmarker.benchmarkAutoincrement_withSchema()
}

func testCache() throws {
try benchmarker.benchmarkCache_withSchema()
}

func testJoins() throws {
try benchmarker.benchmarkJoins_withSchema()
}

func testSoftDeletable() throws {
try benchmarker.benchmarkSoftDeletable_withSchema()
}

func testReferentialActions() throws {
try benchmarker.benchmarkReferentialActions_withSchema()
}

func testNestedStruct() throws {
/// Swift runtime does not yet support dynamically querying conditional conformance ('Swift.Array<Swift.String>': 'CodableKit.AnyKeyStringDecodable')
return;
Expand Down Expand Up @@ -72,6 +88,10 @@ class FluentPostgreSQLTests: XCTestCase {
("testTransactions", testTransactions),
("testChunking", testChunking),
("testAutoincrement", testAutoincrement),
("testCache", testCache),
("testJoins", testJoins),
("testSoftDeletable", testSoftDeletable),
("testReferentialActions", testReferentialActions),
]
}

Expand All @@ -80,7 +100,7 @@ struct Pet: PostgreSQLJSONType {
}

final class User: PostgreSQLModel, Migration {
static let idKey = \User.id
static let idKey: WritableKeyPath<User, Int?> = \User.id
var id: Int?
var name: String
var age: Int?
Expand Down