diff --git a/.api-breakage/allowlist-branch-fix-deprecations.txt b/.api-breakage/allowlist-branch-fix-deprecations.txt new file mode 100644 index 0000000..fb86138 --- /dev/null +++ b/.api-breakage/allowlist-branch-fix-deprecations.txt @@ -0,0 +1,18 @@ +API breakage: func DatabaseConfigurationFactory.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:) has removed default argument from parameter 3 +API breakage: func DatabaseConfigurationFactory.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:) has removed default argument from parameter 4 +API breakage: func DatabaseConfigurationFactory.postgres(hostname:port:username:password:database:tlsConfiguration:maxConnectionsPerEventLoop:connectionPoolTimeout:sqlLogLevel:) has parameter 0 type change from Swift.String to PostgresKit.SQLPostgresConfiguration +API breakage: func DatabaseConfigurationFactory.postgres(hostname:port:username:password:database:tlsConfiguration:maxConnectionsPerEventLoop:connectionPoolTimeout:sqlLogLevel:) has parameter 2 type change from Swift.String to NIOCore.TimeAmount +API breakage: func DatabaseConfigurationFactory.postgres(hostname:port:username:password:database:tlsConfiguration:maxConnectionsPerEventLoop:connectionPoolTimeout:sqlLogLevel:) has parameter 3 type change from Swift.String to Logging.Logger.Level +API breakage: func DatabaseConfigurationFactory.postgres(hostname:port:username:password:database:tlsConfiguration:maxConnectionsPerEventLoop:connectionPoolTimeout:encoder:sqlLogLevel:) has parameter 0 type change from Swift.String to PostgresKit.SQLPostgresConfiguration +API breakage: func DatabaseConfigurationFactory.postgres(hostname:port:username:password:database:tlsConfiguration:maxConnectionsPerEventLoop:connectionPoolTimeout:encoder:sqlLogLevel:) has parameter 2 type change from Swift.String to NIOCore.TimeAmount +API breakage: func DatabaseConfigurationFactory.postgres(hostname:port:username:password:database:tlsConfiguration:maxConnectionsPerEventLoop:connectionPoolTimeout:encoder:sqlLogLevel:) has parameter 3 type change from Swift.String to PostgresNIO.PostgresEncodingContext +API breakage: func DatabaseConfigurationFactory.postgres(hostname:port:username:password:database:tlsConfiguration:maxConnectionsPerEventLoop:connectionPoolTimeout:encoder:sqlLogLevel:) has parameter 4 type change from Swift.String? to Logging.Logger.Level +API breakage: func DatabaseConfigurationFactory.postgres(hostname:port:username:password:database:tlsConfiguration:maxConnectionsPerEventLoop:connectionPoolTimeout:decoder:sqlLogLevel:) has parameter 0 type change from Swift.String to PostgresKit.SQLPostgresConfiguration +API breakage: func DatabaseConfigurationFactory.postgres(hostname:port:username:password:database:tlsConfiguration:maxConnectionsPerEventLoop:connectionPoolTimeout:decoder:sqlLogLevel:) has parameter 2 type change from Swift.String to NIOCore.TimeAmount +API breakage: func DatabaseConfigurationFactory.postgres(hostname:port:username:password:database:tlsConfiguration:maxConnectionsPerEventLoop:connectionPoolTimeout:decoder:sqlLogLevel:) has parameter 3 type change from Swift.String to PostgresNIO.PostgresDecodingContext +API breakage: func DatabaseConfigurationFactory.postgres(hostname:port:username:password:database:tlsConfiguration:maxConnectionsPerEventLoop:connectionPoolTimeout:decoder:sqlLogLevel:) has parameter 4 type change from Swift.String? to Logging.Logger.Level +API breakage: func DatabaseConfigurationFactory.postgres(hostname:port:username:password:database:tlsConfiguration:maxConnectionsPerEventLoop:connectionPoolTimeout:sqlLogLevel:) has been renamed to func postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:sqlLogLevel:) +API breakage: func DatabaseConfigurationFactory.postgres(hostname:port:username:password:database:tlsConfiguration:maxConnectionsPerEventLoop:connectionPoolTimeout:encoder:sqlLogLevel:) has been renamed to func postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:sqlLogLevel:) +API breakage: func DatabaseConfigurationFactory.postgres(hostname:port:username:password:database:tlsConfiguration:maxConnectionsPerEventLoop:connectionPoolTimeout:decoder:sqlLogLevel:) has been renamed to func postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:decodingContext:sqlLogLevel:) +API breakage: func DatabaseConfigurationFactory.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encoder:sqlLogLevel:) has been removed +API breakage: func DatabaseConfigurationFactory.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:decoder:sqlLogLevel:) has been removed diff --git a/Sources/FluentPostgresDriver/Deprecations/FluentPostgresConfiguration+Deprecated.swift b/Sources/FluentPostgresDriver/Deprecations/FluentPostgresConfiguration+Deprecated.swift index 6cfbfa6..600c52c 100644 --- a/Sources/FluentPostgresDriver/Deprecations/FluentPostgresConfiguration+Deprecated.swift +++ b/Sources/FluentPostgresDriver/Deprecations/FluentPostgresConfiguration+Deprecated.swift @@ -44,8 +44,11 @@ extension DatabaseConfigurationFactory { public static func postgres( hostname: String, port: Int = PostgresConfiguration.ianaPortNumber, username: String, password: String, database: String? = nil, tlsConfiguration: TLSConfiguration? = nil, - maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10), - encoder: PostgresDataEncoder, decoder: PostgresDataDecoder, sqlLogLevel: Logger.Level = .debug + maxConnectionsPerEventLoop: Int = 1, + connectionPoolTimeout: TimeAmount = .seconds(10), + encoder: PostgresDataEncoder = .init(), + decoder: PostgresDataDecoder = .init(), + sqlLogLevel: Logger.Level = .debug ) -> DatabaseConfigurationFactory { .postgres(configuration: .init( hostname: hostname, port: port, username: username, password: password, database: database, tlsConfiguration: tlsConfiguration), @@ -57,8 +60,11 @@ extension DatabaseConfigurationFactory { @available(*, deprecated, message: "Use `.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)` instead.") public static func postgres( configuration: PostgresConfiguration, - maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10), - encoder: PostgresDataEncoder, decoder: PostgresDataDecoder, sqlLogLevel: Logger.Level = .debug + maxConnectionsPerEventLoop: Int = 1, + connectionPoolTimeout: TimeAmount = .seconds(10), + encoder: PostgresDataEncoder = .init(), + decoder: PostgresDataDecoder = .init(), + sqlLogLevel: Logger.Level = .debug ) -> DatabaseConfigurationFactory { .postgres( configuration: .init(legacyConfiguration: configuration), @@ -115,70 +121,6 @@ extension DatabaseConfigurationFactory { encoder: .init(), decoder: decoder, sqlLogLevel: sqlLogLevel ) } - - @available(*, deprecated, message: "Use `.postgres(configuration:.init(hostname:port:username:password:database:tls:),maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)` instead.") - public static func postgres( - hostname: String, port: Int = PostgresConfiguration.ianaPortNumber, - username: String, password: String, database: String? = nil, tlsConfiguration: TLSConfiguration? = nil, - maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10), - sqlLogLevel: Logger.Level = .debug - ) -> DatabaseConfigurationFactory { - .postgres( - hostname: hostname, port: port, username: username, password: password, database: database, tlsConfiguration: tlsConfiguration, - maxConnectionsPerEventLoop: maxConnectionsPerEventLoop, connectionPoolTimeout: connectionPoolTimeout, - encoder: .init(), decoder: .init(), sqlLogLevel: sqlLogLevel - ) - } - - @available(*, deprecated, message: "Use `.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)` instead.") - public static func postgres( - hostname: String, port: Int = PostgresConfiguration.ianaPortNumber, - username: String, password: String, database: String? = nil, tlsConfiguration: TLSConfiguration? = nil, - maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10), - encoder: PostgresDataEncoder, sqlLogLevel: Logger.Level = .debug - ) -> DatabaseConfigurationFactory { - .postgres( - hostname: hostname, port: port, username: username, password: password, database: database, tlsConfiguration: tlsConfiguration, - maxConnectionsPerEventLoop: maxConnectionsPerEventLoop, connectionPoolTimeout: connectionPoolTimeout, - encoder: encoder, decoder: .init(), sqlLogLevel: sqlLogLevel - ) - } - - @available(*, deprecated, message: "Use `.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)` instead.") - public static func postgres( - hostname: String, port: Int = PostgresConfiguration.ianaPortNumber, - username: String, password: String, database: String? = nil, tlsConfiguration: TLSConfiguration? = nil, - maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10), - decoder: PostgresDataDecoder, sqlLogLevel: Logger.Level = .debug - ) -> DatabaseConfigurationFactory { - .postgres( - hostname: hostname, port: port, username: username, password: password, database: database, tlsConfiguration: tlsConfiguration, - maxConnectionsPerEventLoop: maxConnectionsPerEventLoop, connectionPoolTimeout: connectionPoolTimeout, - encoder: .init(), decoder: decoder, sqlLogLevel: sqlLogLevel - ) - } - - @available(*, deprecated, message: "Use `.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)` instead.") - public static func postgres( - configuration: PostgresConfiguration, maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10), - encoder: PostgresDataEncoder, sqlLogLevel: Logger.Level = .debug - ) -> DatabaseConfigurationFactory { - .postgres(configuration: configuration, - maxConnectionsPerEventLoop: maxConnectionsPerEventLoop, connectionPoolTimeout: connectionPoolTimeout, - encoder: encoder, decoder: .init(), sqlLogLevel: sqlLogLevel - ) - } - - @available(*, deprecated, message: "Use `.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)` instead.") - public static func postgres( - configuration: PostgresConfiguration, maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10), - decoder: PostgresDataDecoder, sqlLogLevel: Logger.Level = .debug - ) -> DatabaseConfigurationFactory { - .postgres(configuration: configuration, - maxConnectionsPerEventLoop: maxConnectionsPerEventLoop, connectionPoolTimeout: connectionPoolTimeout, - encoder: .init(), decoder: decoder, sqlLogLevel: sqlLogLevel - ) - } } // N.B.: If you change something in these two types, update the copies in PostgresKit too. diff --git a/Sources/FluentPostgresDriver/FluentPostgresConfiguration.swift b/Sources/FluentPostgresDriver/FluentPostgresConfiguration.swift index 7891a7e..b7f835b 100644 --- a/Sources/FluentPostgresDriver/FluentPostgresConfiguration.swift +++ b/Sources/FluentPostgresDriver/FluentPostgresConfiguration.swift @@ -77,8 +77,8 @@ extension DatabaseConfigurationFactory { configuration: SQLPostgresConfiguration, maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10), - encodingContext: PostgresEncodingContext = .default, - decodingContext: PostgresDecodingContext = .default, + encodingContext: PostgresEncodingContext, + decodingContext: PostgresDecodingContext, sqlLogLevel: Logger.Level = .debug ) -> DatabaseConfigurationFactory { .init { @@ -93,6 +93,77 @@ extension DatabaseConfigurationFactory { } } +/// We'd like to just default the context parameters of the "actual" method. Unfortunately, there are a few +/// cases involving the UNIX domain socket initalizer where usage can resolve to either the new +/// ``SQLPostgresConfiguration``-based method or the deprecated ``PostgresConfiguration``-based method, with no +/// obvious way to disambiguate which to call. Because the context parameters are generic, if they are defaulted, +/// the compiler resolves the ambiguity in favor of the deprecated method (which has no generic parameters). +/// However, by adding the non-defaulted-parameter variant which takes neither context, we've provided a version +/// which has no generic parameters either, which allows the compiler to resolve the ambiguity in favor of +/// the one with better availability (i.e. the one that isn't deprecated). +/// +/// Example affected code: +/// +/// _ = DatabaseConfigurationFactory.postgres(configuration: .init(unixDomainSocketPath: "", username: "")) +extension DatabaseConfigurationFactory { + /// ``postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)`` + /// with the `decodingContext` defaulted. + public static func postgres( + configuration: SQLPostgresConfiguration, + maxConnectionsPerEventLoop: Int = 1, + connectionPoolTimeout: TimeAmount = .seconds(10), + encodingContext: PostgresEncodingContext, + sqlLogLevel: Logger.Level = .debug + ) -> DatabaseConfigurationFactory { + .postgres( + configuration: configuration, + maxConnectionsPerEventLoop: maxConnectionsPerEventLoop, + connectionPoolTimeout: connectionPoolTimeout, + encodingContext: encodingContext, + decodingContext: .default, + sqlLogLevel: sqlLogLevel + ) + } + + /// ``postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)`` + /// with the `encodingContext` defaulted. + public static func postgres( + configuration: SQLPostgresConfiguration, + maxConnectionsPerEventLoop: Int = 1, + connectionPoolTimeout: TimeAmount = .seconds(10), + decodingContext: PostgresDecodingContext, + sqlLogLevel: Logger.Level = .debug + ) -> DatabaseConfigurationFactory { + .postgres( + configuration: configuration, + maxConnectionsPerEventLoop: maxConnectionsPerEventLoop, + connectionPoolTimeout: connectionPoolTimeout, + encodingContext: .default, + decodingContext: decodingContext, + sqlLogLevel: sqlLogLevel + ) + } + + /// ``postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)`` + /// with both `encodingContext` and `decodingContext` defaulted. + public static func postgres( + configuration: SQLPostgresConfiguration, + maxConnectionsPerEventLoop: Int = 1, + connectionPoolTimeout: TimeAmount = .seconds(10), + sqlLogLevel: Logger.Level = .debug + ) -> DatabaseConfigurationFactory { + .postgres( + configuration: configuration, + maxConnectionsPerEventLoop: maxConnectionsPerEventLoop, + connectionPoolTimeout: connectionPoolTimeout, + encodingContext: .default, + decodingContext: .default, + sqlLogLevel: sqlLogLevel + ) + } +} + +/// The actual concrete configuration type produced by a configuration factory. struct FluentPostgresConfiguration: DatabaseConfiguration { var middleware: [any AnyModelMiddleware] = [] let configuration: SQLPostgresConfiguration diff --git a/Sources/FluentPostgresDriver/FluentPostgresDatabase.swift b/Sources/FluentPostgresDriver/FluentPostgresDatabase.swift index b2a2bdd..3ec68a7 100644 --- a/Sources/FluentPostgresDriver/FluentPostgresDatabase.swift +++ b/Sources/FluentPostgresDriver/FluentPostgresDatabase.swift @@ -65,7 +65,7 @@ extension _FluentPostgresDatabase: Database { return self.withConnection { conn in guard let sqlConn = conn as? any SQLDatabase else { fatalError(""" - Connection yieled by a Fluent+Postgres database is not also an SQLDatabase. + Connection yielded by a Fluent+Postgres database is not also an SQLDatabase. This is a bug in Fluent; please report it at https://github.com/vapor/fluent-postgres-driver/issues """) } @@ -124,7 +124,7 @@ extension _FluentPostgresDatabase: PostgresDatabase { func withConnection(_ closure: @escaping (PostgresConnection) -> EventLoopFuture) -> EventLoopFuture { guard let psqlDb: any PostgresDatabase = self.database as? any PostgresDatabase else { fatalError(""" - Connection yieled by a Fluent+Postgres database is not also a PostgresDatabase. + Connection yielded by a Fluent+Postgres database is not also a PostgresDatabase. This is a bug in Fluent; please report it at https://github.com/vapor/fluent-postgres-driver/issues """) }