Created
March 4, 2018 20:57
-
-
Save vzsg/d1bb9e7db395fa7bc3aabcc5d1dcf6d1 to your computer and use it in GitHub Desktop.
Using a single database connection in Vapor 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Add this file to your App target | |
| import Fluent | |
| import Vapor | |
| import Dispatch | |
| final class SingleDriver: Fluent.Driver, ConfigInitializable { | |
| private let log: LogProtocol | |
| private var backendDriver: Fluent.Driver | |
| private let queue = DispatchQueue(label: "database-queue", qos: .utility) | |
| private var connection: Connection | |
| init(config: Config) throws { | |
| log = try config.resolveLog() | |
| backendDriver = try config.customResolve( | |
| unique: "driver", | |
| file: "fluent", | |
| keyPath: ["backend"], | |
| as: Driver.self, | |
| default: MemoryDriver.init | |
| ) | |
| connection = try backendDriver.makeConnection(.readWrite) | |
| } | |
| var idKey: String { | |
| return backendDriver.idKey | |
| } | |
| var idType: IdentifierType { | |
| return backendDriver.idType | |
| } | |
| var keyNamingConvention: KeyNamingConvention { | |
| return backendDriver.keyNamingConvention | |
| } | |
| var queryLogger: QueryLogger? { | |
| get { | |
| return backendDriver.queryLogger | |
| } | |
| set { | |
| backendDriver.queryLogger = newValue | |
| } | |
| } | |
| func makeConnection(_ type: ConnectionType) throws -> Connection { | |
| if connection.isClosed { | |
| log.verbose("Connection was closed! Recreating...") | |
| connection = try queue.sync(flags: .barrier) { | |
| try self.backendDriver.makeConnection(.readWrite) | |
| } | |
| } | |
| return DispatchedConnection(connection: connection, queue: queue) | |
| } | |
| } | |
| private class DispatchedConnection: Connection { | |
| private var connection: Connection | |
| private let queue: DispatchQueue | |
| var queryLogger: QueryLogger? | |
| init(connection: Connection, queue: DispatchQueue) { | |
| self.connection = connection | |
| self.queue = queue | |
| } | |
| var isClosed: Bool { | |
| return connection.isClosed | |
| } | |
| func query<E>(_ query: RawOr<Query<E>>) throws -> Node { | |
| return try queue.sync { | |
| try self.connection.query(query) | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import FluentProvider | |
| import PostgreSQLProvider | |
| extension Config { | |
| // ... other setup unchanged and left out for brevity | |
| private func setupProviders() throws { | |
| try addProvider(FluentProvider.Provider.self) | |
| try addProvider(PostgreSQLProvider.Provider.self) // <-- Be sure to register your original DB provider | |
| addConfigurable(driver: SingleDriver.init, name: "single") // <-- Add this line | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "//": "Change driver to 'single' to activate SingleDriver", | |
| "driver": "single", | |
| "//": "Select your original driver using the backend key" | |
| "backend": "postgresql", | |
| "//": "Other settings unchanged and left out for brevity" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment