Skip to content

Commit 1fdf878

Browse files
authored
beta 2: fluent db updates (#125)
* beta 2: fluent db updates * psql id * add withConnection * withConnection updates * sqlkit updates * fix tests * regen linuxmain
1 parent cc9d712 commit 1fdf878

File tree

8 files changed

+179
-117
lines changed

8 files changed

+179
-117
lines changed

Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ let package = Package(
77
.library(name: "FluentPostgresDriver", targets: ["FluentPostgresDriver"]),
88
],
99
dependencies: [
10-
.package(url: "https://github.com/vapor/fluent-kit.git", from: "1.0.0-alpha.2"),
11-
.package(url: "https://github.com/vapor/postgres-kit.git", from: "2.0.0-alpha.2"),
10+
.package(url: "https://github.com/vapor/fluent-kit.git", .branch("master")),
11+
.package(url: "https://github.com/vapor/postgres-kit.git", .branch("master")),
1212
],
1313
targets: [
1414
.target(name: "FluentPostgresDriver", dependencies: [

Sources/FluentPostgresDriver/Databases+Postgres.swift

Lines changed: 0 additions & 25 deletions
This file was deleted.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
11
@_exported import FluentKit
22
@_exported import PostgresKit
3+
4+
extension DatabaseID {
5+
public static var psql: DatabaseID {
6+
return .init(string: "psql")
7+
}
8+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import FluentSQL
2+
3+
struct _FluentPostgresDatabase {
4+
let database: PostgresDatabase
5+
let context: DatabaseContext
6+
}
7+
8+
extension _FluentPostgresDatabase: Database {
9+
func execute(query: DatabaseQuery, onRow: @escaping (DatabaseRow) -> ()) -> EventLoopFuture<Void> {
10+
var expression = SQLQueryConverter(delegate: PostgresConverterDelegate())
11+
.convert(query)
12+
switch query.action {
13+
case .create:
14+
expression = PostgresReturning(expression)
15+
default: break
16+
}
17+
let (sql, binds) = self.serialize(expression)
18+
do {
19+
return try self.query(sql, binds.map { try PostgresDataEncoder().encode($0) }) {
20+
onRow($0)
21+
}
22+
} catch {
23+
return self.eventLoop.makeFailedFuture(error)
24+
}
25+
}
26+
27+
func execute(schema: DatabaseSchema) -> EventLoopFuture<Void> {
28+
let expression = SQLSchemaConverter(delegate: PostgresConverterDelegate())
29+
.convert(schema)
30+
let (sql, binds) = self.serialize(expression)
31+
do {
32+
return try self.query(sql, binds.map { try PostgresDataEncoder().encode($0) }) {
33+
fatalError("unexpected row: \($0)")
34+
}
35+
} catch {
36+
return self.eventLoop.makeFailedFuture(error)
37+
}
38+
}
39+
40+
func withConnection<T>(_ closure: @escaping (Database) -> EventLoopFuture<T>) -> EventLoopFuture<T> {
41+
self.database.withConnection {
42+
closure(_FluentPostgresDatabase(database: $0, context: self.context))
43+
}
44+
}
45+
}
46+
47+
extension _FluentPostgresDatabase: SQLDatabase {
48+
var dialect: SQLDialect {
49+
PostgresDialect()
50+
}
51+
52+
public func execute(
53+
sql query: SQLExpression,
54+
_ onRow: @escaping (SQLRow) -> ()
55+
) -> EventLoopFuture<Void> {
56+
self.sql().execute(sql: query, onRow)
57+
}
58+
}
59+
60+
extension _FluentPostgresDatabase: PostgresDatabase {
61+
func send(_ request: PostgresRequest, logger: Logger) -> EventLoopFuture<Void> {
62+
self.database.send(request, logger: logger)
63+
}
64+
65+
func withConnection<T>(_ closure: @escaping (PostgresConnection) -> EventLoopFuture<T>) -> EventLoopFuture<T> {
66+
self.database.withConnection(closure)
67+
}
68+
}
69+
70+
private struct PostgresReturning: SQLExpression {
71+
let base: SQLExpression
72+
init(_ base: SQLExpression) {
73+
self.base = base
74+
}
75+
76+
func serialize(to serializer: inout SQLSerializer) {
77+
self.base.serialize(to: &serializer)
78+
serializer.write(#" RETURNING id as "fluentID""#)
79+
}
80+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
extension DatabaseDriverFactory {
2+
public static func postgres(
3+
url: URL,
4+
maxConnectionsPerEventLoop: Int = 1
5+
) throws -> DatabaseDriverFactory {
6+
guard let configuration = PostgresConfiguration(url: url) else {
7+
throw FluentPostgresError.invalidURL(url)
8+
}
9+
return .postgres(
10+
configuration: configuration,
11+
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop
12+
)
13+
}
14+
15+
public static func postgres(
16+
hostname: String,
17+
port: Int = 5432,
18+
username: String,
19+
password: String,
20+
database: String? = nil,
21+
tlsConfiguration: TLSConfiguration? = nil,
22+
maxConnectionsPerEventLoop: Int = 1
23+
) -> DatabaseDriverFactory {
24+
return .postgres(
25+
configuration: .init(
26+
hostname: hostname,
27+
port: port,
28+
username: username,
29+
password: password,
30+
database: database,
31+
tlsConfiguration: tlsConfiguration
32+
),
33+
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop
34+
)
35+
}
36+
37+
public static func postgres(
38+
configuration: PostgresConfiguration,
39+
maxConnectionsPerEventLoop: Int = 1
40+
) -> DatabaseDriverFactory {
41+
return DatabaseDriverFactory { databases in
42+
let db = PostgresConnectionSource(
43+
configuration: configuration
44+
)
45+
let pool = EventLoopGroupConnectionPool(
46+
source: db,
47+
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop,
48+
on: databases.eventLoopGroup
49+
)
50+
return _FluentPostgresDriver(pool: pool)
51+
}
52+
}
53+
}
54+
55+
enum FluentPostgresError: Error {
56+
case invalidURL(URL)
57+
}
58+
59+
struct _FluentPostgresDriver: DatabaseDriver {
60+
let pool: EventLoopGroupConnectionPool<PostgresConnectionSource>
61+
62+
var eventLoopGroup: EventLoopGroup {
63+
self.pool.eventLoopGroup
64+
}
65+
66+
func makeDatabase(with context: DatabaseContext) -> Database {
67+
_FluentPostgresDatabase(
68+
database: self.pool.pool(for: context.eventLoop).database(logger: context.logger),
69+
context: context
70+
)
71+
}
72+
73+
func shutdown() {
74+
self.pool.shutdown()
75+
}
76+
}

Sources/FluentPostgresDriver/PostgresConnection+Database.swift

Lines changed: 0 additions & 76 deletions
This file was deleted.

Tests/FluentPostgresDriverTests/FluentPostgresDriverTests.swift

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ final class FluentPostgresDriverTests: XCTestCase {
100100
try self.benchmarker.testTimestampable()
101101
}
102102

103-
func testLifecycleHooks() throws {
104-
try self.benchmarker.testLifecycleHooks()
103+
func testModelMiddleware() throws {
104+
try self.benchmarker.testModelMiddleware()
105105
}
106106

107107
func testSort() throws {
@@ -207,9 +207,10 @@ final class FluentPostgresDriverTests: XCTestCase {
207207
return .init(database: self.db)
208208
}
209209
var eventLoopGroup: EventLoopGroup!
210+
var threadPool: NIOThreadPool!
210211
var dbs: Databases!
211212
var db: Database {
212-
return self.dbs.default()
213+
self.dbs.database(logger: .init(label: "codes.vapor.test"), on: self.eventLoopGroup.next())!
213214
}
214215

215216
override func setUp() {
@@ -221,20 +222,14 @@ final class FluentPostgresDriverTests: XCTestCase {
221222
#else
222223
hostname = "localhost"
223224
#endif
224-
let configuration = PostgresConfiguration(
225-
hostname: hostname,
226-
port: 5432,
227-
username: "vapor_username",
228-
password: "vapor_password",
229-
database: "vapor_database",
230-
tlsConfiguration: nil
231-
)
232-
self.dbs = Databases()
233-
self.dbs.postgres(configuration: configuration, poolConfiguration: .init(maxConnections: 1), on: self.eventLoopGroup)
225+
self.threadPool = NIOThreadPool(numberOfThreads: 1)
226+
self.dbs = Databases(threadPool: threadPool, on: self.eventLoopGroup)
227+
self.dbs.use(.postgres(hostname: hostname, username: "vapor_username", password: "vapor_password", database: "vapor_database"))
234228
}
235229

236230
override func tearDown() {
237231
self.dbs.shutdown()
232+
try! self.threadPool.syncShutdownGracefully()
238233
try! self.eventLoopGroup.syncShutdownGracefully()
239234
}
240235
}

Tests/FluentPostgresDriverTests/XCTestManifests.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,19 @@ extension FluentPostgresDriverTests {
2222
("testEagerLoadParentJSON", testEagerLoadParentJSON),
2323
("testIdentifierGeneration", testIdentifierGeneration),
2424
("testJoin", testJoin),
25-
("testLifecycleHooks", testLifecycleHooks),
2625
("testMigrator", testMigrator),
2726
("testMigratorError", testMigratorError),
27+
("testModelMiddleware", testModelMiddleware),
28+
("testMultipleJoinSameTable", testMultipleJoinSameTable),
2829
("testNestedModel", testNestedModel),
30+
("testNewModelDecode", testNewModelDecode),
2931
("testNullifyField", testNullifyField),
32+
("testParentGet", testParentGet),
33+
("testParentSerialization", testParentSerialization),
3034
("testRead", testRead),
3135
("testSaveModelWithBool", testSaveModelWithBool),
36+
("testSiblingsAttach", testSiblingsAttach),
37+
("testSiblingsEagerLoad", testSiblingsEagerLoad),
3238
("testSoftDelete", testSoftDelete),
3339
("testSort", testSort),
3440
("testTimestampable", testTimestampable),

0 commit comments

Comments
 (0)