Skip to content

Commit bb3ab8e

Browse files
authoredMay 11, 2023
Warn about deprecation of old config methods instead of breaking existing code (#212)
* Yield deprecation warnings (instead of compiler errors) for previously working code using the old postgres configuration methods, while setting it up so the compiler correctly defaults to the new ones in ambiguous cases.
1 parent 0aa809c commit bb3ab8e

File tree

4 files changed

+103
-72
lines changed

4 files changed

+103
-72
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
API breakage: func DatabaseConfigurationFactory.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:) has removed default argument from parameter 3
2+
API breakage: func DatabaseConfigurationFactory.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:) has removed default argument from parameter 4
3+
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
4+
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
5+
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
6+
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
7+
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
8+
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<some PostgresNIO.PostgresJSONEncoder>
9+
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
10+
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
11+
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
12+
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<some PostgresNIO.PostgresJSONDecoder>
13+
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
14+
API breakage: func DatabaseConfigurationFactory.postgres(hostname:port:username:password:database:tlsConfiguration:maxConnectionsPerEventLoop:connectionPoolTimeout:sqlLogLevel:) has been renamed to func postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:sqlLogLevel:)
15+
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:)
16+
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:)
17+
API breakage: func DatabaseConfigurationFactory.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encoder:sqlLogLevel:) has been removed
18+
API breakage: func DatabaseConfigurationFactory.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:decoder:sqlLogLevel:) has been removed

‎Sources/FluentPostgresDriver/Deprecations/FluentPostgresConfiguration+Deprecated.swift

+10-68
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,11 @@ extension DatabaseConfigurationFactory {
4444
public static func postgres(
4545
hostname: String, port: Int = PostgresConfiguration.ianaPortNumber,
4646
username: String, password: String, database: String? = nil, tlsConfiguration: TLSConfiguration? = nil,
47-
maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10),
48-
encoder: PostgresDataEncoder, decoder: PostgresDataDecoder, sqlLogLevel: Logger.Level = .debug
47+
maxConnectionsPerEventLoop: Int = 1,
48+
connectionPoolTimeout: TimeAmount = .seconds(10),
49+
encoder: PostgresDataEncoder = .init(),
50+
decoder: PostgresDataDecoder = .init(),
51+
sqlLogLevel: Logger.Level = .debug
4952
) -> DatabaseConfigurationFactory {
5053
.postgres(configuration: .init(
5154
hostname: hostname, port: port, username: username, password: password, database: database, tlsConfiguration: tlsConfiguration),
@@ -57,8 +60,11 @@ extension DatabaseConfigurationFactory {
5760
@available(*, deprecated, message: "Use `.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)` instead.")
5861
public static func postgres(
5962
configuration: PostgresConfiguration,
60-
maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10),
61-
encoder: PostgresDataEncoder, decoder: PostgresDataDecoder, sqlLogLevel: Logger.Level = .debug
63+
maxConnectionsPerEventLoop: Int = 1,
64+
connectionPoolTimeout: TimeAmount = .seconds(10),
65+
encoder: PostgresDataEncoder = .init(),
66+
decoder: PostgresDataDecoder = .init(),
67+
sqlLogLevel: Logger.Level = .debug
6268
) -> DatabaseConfigurationFactory {
6369
.postgres(
6470
configuration: .init(legacyConfiguration: configuration),
@@ -115,70 +121,6 @@ extension DatabaseConfigurationFactory {
115121
encoder: .init(), decoder: decoder, sqlLogLevel: sqlLogLevel
116122
)
117123
}
118-
119-
@available(*, deprecated, message: "Use `.postgres(configuration:.init(hostname:port:username:password:database:tls:),maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)` instead.")
120-
public static func postgres(
121-
hostname: String, port: Int = PostgresConfiguration.ianaPortNumber,
122-
username: String, password: String, database: String? = nil, tlsConfiguration: TLSConfiguration? = nil,
123-
maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10),
124-
sqlLogLevel: Logger.Level = .debug
125-
) -> DatabaseConfigurationFactory {
126-
.postgres(
127-
hostname: hostname, port: port, username: username, password: password, database: database, tlsConfiguration: tlsConfiguration,
128-
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop, connectionPoolTimeout: connectionPoolTimeout,
129-
encoder: .init(), decoder: .init(), sqlLogLevel: sqlLogLevel
130-
)
131-
}
132-
133-
@available(*, deprecated, message: "Use `.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)` instead.")
134-
public static func postgres(
135-
hostname: String, port: Int = PostgresConfiguration.ianaPortNumber,
136-
username: String, password: String, database: String? = nil, tlsConfiguration: TLSConfiguration? = nil,
137-
maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10),
138-
encoder: PostgresDataEncoder, sqlLogLevel: Logger.Level = .debug
139-
) -> DatabaseConfigurationFactory {
140-
.postgres(
141-
hostname: hostname, port: port, username: username, password: password, database: database, tlsConfiguration: tlsConfiguration,
142-
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop, connectionPoolTimeout: connectionPoolTimeout,
143-
encoder: encoder, decoder: .init(), sqlLogLevel: sqlLogLevel
144-
)
145-
}
146-
147-
@available(*, deprecated, message: "Use `.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)` instead.")
148-
public static func postgres(
149-
hostname: String, port: Int = PostgresConfiguration.ianaPortNumber,
150-
username: String, password: String, database: String? = nil, tlsConfiguration: TLSConfiguration? = nil,
151-
maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10),
152-
decoder: PostgresDataDecoder, sqlLogLevel: Logger.Level = .debug
153-
) -> DatabaseConfigurationFactory {
154-
.postgres(
155-
hostname: hostname, port: port, username: username, password: password, database: database, tlsConfiguration: tlsConfiguration,
156-
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop, connectionPoolTimeout: connectionPoolTimeout,
157-
encoder: .init(), decoder: decoder, sqlLogLevel: sqlLogLevel
158-
)
159-
}
160-
161-
@available(*, deprecated, message: "Use `.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)` instead.")
162-
public static func postgres(
163-
configuration: PostgresConfiguration, maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10),
164-
encoder: PostgresDataEncoder, sqlLogLevel: Logger.Level = .debug
165-
) -> DatabaseConfigurationFactory {
166-
.postgres(configuration: configuration,
167-
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop, connectionPoolTimeout: connectionPoolTimeout,
168-
encoder: encoder, decoder: .init(), sqlLogLevel: sqlLogLevel
169-
)
170-
}
171-
172-
@available(*, deprecated, message: "Use `.postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)` instead.")
173-
public static func postgres(
174-
configuration: PostgresConfiguration, maxConnectionsPerEventLoop: Int = 1, connectionPoolTimeout: TimeAmount = .seconds(10),
175-
decoder: PostgresDataDecoder, sqlLogLevel: Logger.Level = .debug
176-
) -> DatabaseConfigurationFactory {
177-
.postgres(configuration: configuration,
178-
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop, connectionPoolTimeout: connectionPoolTimeout,
179-
encoder: .init(), decoder: decoder, sqlLogLevel: sqlLogLevel
180-
)
181-
}
182124
}
183125

184126
// N.B.: If you change something in these two types, update the copies in PostgresKit too.

‎Sources/FluentPostgresDriver/FluentPostgresConfiguration.swift

+73-2
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ extension DatabaseConfigurationFactory {
7777
configuration: SQLPostgresConfiguration,
7878
maxConnectionsPerEventLoop: Int = 1,
7979
connectionPoolTimeout: TimeAmount = .seconds(10),
80-
encodingContext: PostgresEncodingContext<some PostgresJSONEncoder> = .default,
81-
decodingContext: PostgresDecodingContext<some PostgresJSONDecoder> = .default,
80+
encodingContext: PostgresEncodingContext<some PostgresJSONEncoder>,
81+
decodingContext: PostgresDecodingContext<some PostgresJSONDecoder>,
8282
sqlLogLevel: Logger.Level = .debug
8383
) -> DatabaseConfigurationFactory {
8484
.init {
@@ -93,6 +93,77 @@ extension DatabaseConfigurationFactory {
9393
}
9494
}
9595

96+
/// We'd like to just default the context parameters of the "actual" method. Unfortunately, there are a few
97+
/// cases involving the UNIX domain socket initalizer where usage can resolve to either the new
98+
/// ``SQLPostgresConfiguration``-based method or the deprecated ``PostgresConfiguration``-based method, with no
99+
/// obvious way to disambiguate which to call. Because the context parameters are generic, if they are defaulted,
100+
/// the compiler resolves the ambiguity in favor of the deprecated method (which has no generic parameters).
101+
/// However, by adding the non-defaulted-parameter variant which takes neither context, we've provided a version
102+
/// which has no generic parameters either, which allows the compiler to resolve the ambiguity in favor of
103+
/// the one with better availability (i.e. the one that isn't deprecated).
104+
///
105+
/// Example affected code:
106+
///
107+
/// _ = DatabaseConfigurationFactory.postgres(configuration: .init(unixDomainSocketPath: "", username: ""))
108+
extension DatabaseConfigurationFactory {
109+
/// ``postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)``
110+
/// with the `decodingContext` defaulted.
111+
public static func postgres(
112+
configuration: SQLPostgresConfiguration,
113+
maxConnectionsPerEventLoop: Int = 1,
114+
connectionPoolTimeout: TimeAmount = .seconds(10),
115+
encodingContext: PostgresEncodingContext<some PostgresJSONEncoder>,
116+
sqlLogLevel: Logger.Level = .debug
117+
) -> DatabaseConfigurationFactory {
118+
.postgres(
119+
configuration: configuration,
120+
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop,
121+
connectionPoolTimeout: connectionPoolTimeout,
122+
encodingContext: encodingContext,
123+
decodingContext: .default,
124+
sqlLogLevel: sqlLogLevel
125+
)
126+
}
127+
128+
/// ``postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)``
129+
/// with the `encodingContext` defaulted.
130+
public static func postgres(
131+
configuration: SQLPostgresConfiguration,
132+
maxConnectionsPerEventLoop: Int = 1,
133+
connectionPoolTimeout: TimeAmount = .seconds(10),
134+
decodingContext: PostgresDecodingContext<some PostgresJSONDecoder>,
135+
sqlLogLevel: Logger.Level = .debug
136+
) -> DatabaseConfigurationFactory {
137+
.postgres(
138+
configuration: configuration,
139+
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop,
140+
connectionPoolTimeout: connectionPoolTimeout,
141+
encodingContext: .default,
142+
decodingContext: decodingContext,
143+
sqlLogLevel: sqlLogLevel
144+
)
145+
}
146+
147+
/// ``postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)``
148+
/// with both `encodingContext` and `decodingContext` defaulted.
149+
public static func postgres(
150+
configuration: SQLPostgresConfiguration,
151+
maxConnectionsPerEventLoop: Int = 1,
152+
connectionPoolTimeout: TimeAmount = .seconds(10),
153+
sqlLogLevel: Logger.Level = .debug
154+
) -> DatabaseConfigurationFactory {
155+
.postgres(
156+
configuration: configuration,
157+
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop,
158+
connectionPoolTimeout: connectionPoolTimeout,
159+
encodingContext: .default,
160+
decodingContext: .default,
161+
sqlLogLevel: sqlLogLevel
162+
)
163+
}
164+
}
165+
166+
/// The actual concrete configuration type produced by a configuration factory.
96167
struct FluentPostgresConfiguration<E: PostgresJSONEncoder, D: PostgresJSONDecoder>: DatabaseConfiguration {
97168
var middleware: [any AnyModelMiddleware] = []
98169
let configuration: SQLPostgresConfiguration

‎Sources/FluentPostgresDriver/FluentPostgresDatabase.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ extension _FluentPostgresDatabase: Database {
6565
return self.withConnection { conn in
6666
guard let sqlConn = conn as? any SQLDatabase else {
6767
fatalError("""
68-
Connection yieled by a Fluent+Postgres database is not also an SQLDatabase.
68+
Connection yielded by a Fluent+Postgres database is not also an SQLDatabase.
6969
This is a bug in Fluent; please report it at https://github.com/vapor/fluent-postgres-driver/issues
7070
""")
7171
}
@@ -124,7 +124,7 @@ extension _FluentPostgresDatabase: PostgresDatabase {
124124
func withConnection<T>(_ closure: @escaping (PostgresConnection) -> EventLoopFuture<T>) -> EventLoopFuture<T> {
125125
guard let psqlDb: any PostgresDatabase = self.database as? any PostgresDatabase else {
126126
fatalError("""
127-
Connection yieled by a Fluent+Postgres database is not also a PostgresDatabase.
127+
Connection yielded by a Fluent+Postgres database is not also a PostgresDatabase.
128128
This is a bug in Fluent; please report it at https://github.com/vapor/fluent-postgres-driver/issues
129129
""")
130130
}

0 commit comments

Comments
 (0)
Please sign in to comment.