Skip to content

Commit

Permalink
Fix API breakages
Browse files Browse the repository at this point in the history
  • Loading branch information
gwynne committed May 14, 2024
1 parent f8cdec6 commit 7107315
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 5 deletions.
69 changes: 64 additions & 5 deletions Sources/FluentSQLiteDriver/FluentSQLiteConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,74 @@ import NIO
import FluentKit
import SQLiteKit
import AsyncKit
import Logging

// Hint: Yes, I know what default arguments are. This ridiculous spelling out of each alternative avoids public API
// breakage from adding the defaults. And yes, `maxConnectionsPerEventLoop` is not forwarded on purpose, it's not
// an oversight or an omission. We no longer support it for SQLite because increasing it past one causes thread
// conntention but can never increase parallelism.

extension DatabaseConfigurationFactory {
/// Shorthand for ``sqlite(_:maxConnectionsPerEventLoop:connectionPoolTimeout:dataEncoder:dataDecoder:sqlLogLevel:)``.
public static func sqlite(_ config: SQLiteConfiguration = .memory, maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10)) -> Self {
self.sqlite(config, connectionPoolTimeout: connectionPoolTimeout, dataEncoder: .init(), dataDecoder: .init(), sqlLogLevel: .debug)
}
/// Shorthand for ``sqlite(_:maxConnectionsPerEventLoop:connectionPoolTimeout:dataEncoder:dataDecoder:sqlLogLevel:)``.
public static func sqlite(
_ config: SQLiteConfiguration = .memory, maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10), dataEncoder: SQLiteDataEncoder
) -> Self {
self.sqlite(config, connectionPoolTimeout: connectionPoolTimeout, dataEncoder: dataEncoder, dataDecoder: .init(), sqlLogLevel: .debug)
}
/// Shorthand for ``sqlite(_:maxConnectionsPerEventLoop:connectionPoolTimeout:dataEncoder:dataDecoder:sqlLogLevel:)``.
public static func sqlite(
_ config: SQLiteConfiguration = .memory, maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10), dataDecoder: SQLiteDataDecoder
) -> Self {
self.sqlite(config, connectionPoolTimeout: connectionPoolTimeout, dataEncoder: .init(), dataDecoder: dataDecoder, sqlLogLevel: .debug)
}
/// Shorthand for ``sqlite(_:maxConnectionsPerEventLoop:connectionPoolTimeout:dataEncoder:dataDecoder:sqlLogLevel:)``.
public static func sqlite(
_ config: SQLiteConfiguration = .memory, maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10),
dataEncoder: SQLiteDataEncoder, dataDecoder: SQLiteDataDecoder
) -> Self {
self.sqlite(config, connectionPoolTimeout: connectionPoolTimeout, dataEncoder: dataEncoder, dataDecoder: dataDecoder, sqlLogLevel: .debug)
}
/// Shorthand for ``sqlite(_:maxConnectionsPerEventLoop:connectionPoolTimeout:dataEncoder:dataDecoder:sqlLogLevel:)``.
public static func sqlite(
_ config: SQLiteConfiguration = .memory, maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10), sqlLogLevel: Logger.Level?
) -> Self {
self.sqlite(config, connectionPoolTimeout: connectionPoolTimeout, dataEncoder: .init(), dataDecoder: .init(), sqlLogLevel: sqlLogLevel)
}
/// Shorthand for ``sqlite(_:maxConnectionsPerEventLoop:connectionPoolTimeout:dataEncoder:dataDecoder:sqlLogLevel:)``.
public static func sqlite(
_ config: SQLiteConfiguration = .memory, maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10),
dataEncoder: SQLiteDataEncoder, sqlLogLevel: Logger.Level?
) -> Self {
self.sqlite(config, connectionPoolTimeout: connectionPoolTimeout, dataEncoder: dataEncoder, dataDecoder: .init(), sqlLogLevel: sqlLogLevel)
}
/// Shorthand for ``sqlite(_:maxConnectionsPerEventLoop:connectionPoolTimeout:dataEncoder:dataDecoder:sqlLogLevel:)``.
public static func sqlite(
_ config: SQLiteConfiguration = .memory, maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10),
dataDecoder: SQLiteDataDecoder, sqlLogLevel: Logger.Level?
) -> Self {
self.sqlite(config, connectionPoolTimeout: connectionPoolTimeout, dataEncoder: .init(), dataDecoder: dataDecoder, sqlLogLevel: sqlLogLevel)
}

/// Return a configuration factory using the provided parameters.
///
/// - Parameters:
/// - configuration: The underlying `SQLiteConfiguration`.
/// - maxConnnectionsPerEventLoop: Ignored. The value is always treated as 1.
/// - dataEncoder: An ``SQLiteDataEncoder`` used to translate bound query parameters into `SQLiteData` values.
/// - dataDecoder: An ``SQLiteDataDecoder`` used to translate `SQLiteData` values into output values.
/// - queryLogLevel: The level at which SQL queries issued through the Fluent or SQLKit interfaces will be logged.
/// - Returns: A configuration factory,
public static func sqlite(
_ configuration: SQLiteConfiguration = .init(storage: .memory),
_ configuration: SQLiteConfiguration = .memory,
maxConnectionsPerEventLoop: Int = 1,
connectionPoolTimeout: NIO.TimeAmount = .seconds(10),
dataEncoder: SQLiteDataEncoder = .init(),
dataDecoder: SQLiteDataDecoder = .init(),
sqlLogLevel: Logger.Level = .debug
connectionPoolTimeout: TimeAmount = .seconds(10),
dataEncoder: SQLiteDataEncoder,
dataDecoder: SQLiteDataDecoder,
sqlLogLevel: Logger.Level?
) -> Self {
.init {
FluentSQLiteConfiguration(
Expand Down
27 changes: 27 additions & 0 deletions Sources/FluentSQLiteDriver/SQLiteRow+Database.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,30 @@ private struct SQLRowDatabaseOutput: DatabaseOutput {
try self.row.decode(column: self.adjust(key: key), as: T.self)
}
}

/// A legacy deprecated conformance of `SQLiteRow` directly to `DatabaseOutput`. This interface exists solely
/// because its absence would be a public API break.
///
/// Do not use these methods.
@available(*, deprecated, message: "Do not use this conformance.")
extension SQLiteNIO.SQLiteRow: FluentKit.DatabaseOutput {
// See `DatabaseOutput.schema(_:)`.
public func schema(_ schema: String) -> any DatabaseOutput {
self.databaseOutput().schema(schema)
}

// See `DatabaseOutput.contains(_:)`.
public func contains(_ key: FieldKey) -> Bool {
self.databaseOutput().contains(key)
}

// See `DatabaseOutput.decodeNil(_:)`.
public func decodeNil(_ key: FieldKey) throws -> Bool {
try self.databaseOutput().decodeNil(key)
}

// See `DatabaseOutput.decode(_:as:)`.
public func decode<T: Decodable>(_ key: FieldKey, as: T.Type) throws -> T {
try self.databaseOutput().decode(key, as: T.self)
}
}

0 comments on commit 7107315

Please sign in to comment.