Skip to content

Instantly share code, notes, and snippets.

@vzsg
Created March 4, 2018 20:57
Show Gist options
  • Select an option

  • Save vzsg/d1bb9e7db395fa7bc3aabcc5d1dcf6d1 to your computer and use it in GitHub Desktop.

Select an option

Save vzsg/d1bb9e7db395fa7bc3aabcc5d1dcf6d1 to your computer and use it in GitHub Desktop.
Using a single database connection in Vapor 2
// 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)
}
}
}
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
}
}
{
"//": "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