Work with Postgres with SwifQL through its pure NIO driver.
.package(url: "https://github.com/SwifQL/PostgresBridge.git", from:"1.0.0-rc"),
.package(url: "https://github.com/SwifQL/VaporBridges.git", from:"1.0.0-rc"),
.target(name: "App", dependencies: [
.product(name: "Vapor", package: "vapor"),
.product(name: "PostgresBridge", package: "PostgresBridge"),
.product(name: "VaporBridges", package: "VaporBridges")
]),
For more info please take a look at the Bridges
repo.
If want to use custom identifiers which under the hood stores any kind of core Swift data type like Int
, String
, UUID
etc. they won't be decoded from PostgreSQL table without conforming this identifier to PostgresDataConvertible
Below is example of Identifier implementation described in this blog post with added Encodable conformance.
struct IdentifierType<T, KeyType: Codable>: Codable, PostgresDataConvertible where KeyType: PostgresDataConvertible {
let wrappedValue: KeyType
// PostgresDataConvertible requirement
public static var postgresDataType: PostgresDataType {
KeyType.postgresDataType
}
// PostgresDataConvertible requirement
public init?(postgresData: PostgresData) {
guard let wrappedValue = KeyType.init(postgresData: postgresData) else { return nil }
self.init(wrappedValue)
}
// PostgresDataConvertible requirement
public var postgresData: PostgresData? {
wrappedValue.postgresData
}
init(_ wrappedValue: KeyType) {
self.wrappedValue = wrappedValue
}
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
self.wrappedValue = try container.decode(KeyType.self)
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(wrappedValue)
}
}
struct Author: Codable {
typealias Identifier = IdentifierType<Author, UUID>
let id: Identifier
// ...
}
struct Category: Codable {
typealias Identifier = IdentifierType<Category, UUID>
let id: Identifier
// ...
}
struct Book: Codable {
typealias Identifier = IdentifierType<Book, UUID>
let id: Identifier
// ...
let categoryID: Category.Identifier
let authorIds: [Author.Identifier]
}
With such implementation both categoryID
and authorIds
will be properly decoded to form Book
object. Without such addition only categoryID
is properly decoded