From e92588f8f6ea7c582e34d69aee573c96e110bcfc Mon Sep 17 00:00:00 2001
From: Gwynne Raskind
Date: Sun, 28 Jan 2024 04:12:43 -0600
Subject: [PATCH 1/9] The usual round of various package cleanup
---
.../allowlist-branch-update-for-new-pnio.txt | 10 --
.github/dependabot.yml | 22 +++++
.github/workflows/test.yml | 96 +++++++++++--------
Package@swift-5.9.swift | 46 +++++++++
README.md | 32 +++----
.../PostgresKit/ConnectionPool+Postgres.swift | 2 +-
...nnectionSource+PostgresConfiguration.swift | 2 +-
.../Deprecations/PostgresDataEncoder.swift | 2 +-
.../images/vapor-postgreskit-logo.svg | 22 +++++
.../PostgresKit/Docs.docc/theme-settings.json | 21 ++++
.../PostgresKit/PostgresDatabase+SQL.swift | 11 ++-
.../SQLPostgresConfiguration.swift | 2 +-
Tests/PostgresKitTests/PostgresKitTests.swift | 24 +++--
Tests/PostgresKitTests/Utilities.swift | 2 +-
14 files changed, 209 insertions(+), 85 deletions(-)
delete mode 100644 .api-breakage/allowlist-branch-update-for-new-pnio.txt
create mode 100644 .github/dependabot.yml
create mode 100644 Package@swift-5.9.swift
create mode 100644 Sources/PostgresKit/Docs.docc/images/vapor-postgreskit-logo.svg
create mode 100644 Sources/PostgresKit/Docs.docc/theme-settings.json
diff --git a/.api-breakage/allowlist-branch-update-for-new-pnio.txt b/.api-breakage/allowlist-branch-update-for-new-pnio.txt
deleted file mode 100644
index 3b27dbf4..00000000
--- a/.api-breakage/allowlist-branch-update-for-new-pnio.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-API breakage: var PostgresDialect.sharedSelectLockExpression has declared type change from SQLKit.SQLExpression? to (SQLKit.SQLExpression)?
-API breakage: accessor PostgresDialect.sharedSelectLockExpression.Get() has return type change from SQLKit.SQLExpression? to (SQLKit.SQLExpression)?
-API breakage: var PostgresDialect.exclusiveSelectLockExpression has declared type change from SQLKit.SQLExpression? to (SQLKit.SQLExpression)?
-API breakage: accessor PostgresDialect.exclusiveSelectLockExpression.Get() has return type change from SQLKit.SQLExpression? to (SQLKit.SQLExpression)?
-API breakage: func PostgresDatabase.sql(encoder:decoder:) has removed default argument from parameter 0
-API breakage: func PostgresDatabase.sql(encoder:decoder:) has removed default argument from parameter 1
-API breakage: func PostgresRow.sql(decoder:) has removed default argument from parameter 0
-API breakage: func PostgresColumnType.==(_:_:) has been removed
-API breakage: import Foundation has been removed
-
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..68cfb1a5
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,22 @@
+version: 2
+enable-beta-ecosystems: true
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ groups:
+ dependencies:
+ patterns:
+ - "*"
+ - package-ecosystem: "swift"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ open-pull-requests-limit: 6
+ allow:
+ - dependency-type: all
+ groups:
+ all-dependencies:
+ patterns:
+ - "*"
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 2999d9bb..9deff81e 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -25,15 +25,33 @@ env:
jobs:
# Check for API breakage versus main
api-breakage:
- if: ${{ !(github.event.pull_request.draft || false) }}
+ if: ${{ github.event_name == 'pull_request' && !(github.event.pull_request.draft || false) }}
runs-on: ubuntu-latest
container: swift:jammy
steps:
- - name: Check out code
- uses: actions/checkout@v3
+ - name: Checkout
+ uses: actions/checkout@v4
with: { 'fetch-depth': 0 }
- - name: Run API breakage check action
- uses: vapor/ci/.github/actions/ci-swift-check-api-breakage@main
+ - name: API breaking changes
+ run: |
+ git config --global --add safe.directory "${GITHUB_WORKSPACE}"
+ swift package diagnose-api-breaking-changes origin/main
+
+ dependency-graph:
+ if: ${{ github.event_name == 'push' }}
+ runs-on: ubuntu-latest
+ container: swift:jammy
+ permissions:
+ contents: write
+ steps:
+ - name: Check out code
+ uses: actions/checkout@v4
+ - name: Fix Git configuration
+ run: |
+ git config --global --add safe.directory "${GITHUB_WORKSPACE}"
+ apt-get update && apt-get install -y curl
+ - name: Submit dependency graph
+ uses: vapor-community/swift-dependency-submission@v0.1
code-coverage:
if: ${{ !(github.event.pull_request.draft || false) }}
@@ -41,7 +59,7 @@ jobs:
container: swift:jammy
services:
psql-a:
- image: postgres:15
+ image: postgres:16
env:
POSTGRES_USER: test_username
POSTGRES_DB: test_database
@@ -50,7 +68,7 @@ jobs:
POSTGRES_INITDB_ARGS: --auth-host=scram-sha-256
steps:
- name: Check out code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Run unit tests for coverage data
run: swift test --enable-code-coverage
- name: Upload coverage data
@@ -58,29 +76,30 @@ jobs:
gh-codeql:
if: ${{ !(github.event.pull_request.draft || false) }}
- strategy:
- fail-fast: false
- matrix:
- runner_os:
- - ubuntu-latest
- - macos-13
- runs-on: ${{ matrix.runner_os }}
- permissions:
- security-events: write
+ runs-on: ubuntu-latest
+ container:
+ image: swift:5.9-jammy
+ permissions: { actions: write, contents: read, security-events: write }
+ timeout-minutes: 60
steps:
- - name: Select appropriate Xcode version
- if: ${{ startsWith(matrix.runner_os, 'macos') }}
- uses: maxim-lobanov/setup-xcode@v1
- with: { xcode-version: '~14.3' }
- name: Check out code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
+ - name: Mark repo safe in non-fake global config
+ run: |
+ git config --global --add safe.directory "${GITHUB_WORKSPACE}"
+ - name: Check Swift compatibility
+ id: swift-check
+ uses: vapor/ci/.github/actions/check-compatible-swift@main
- name: Initialize CodeQL
- uses: github/codeql-action/init@v2
+ if: ${{ steps.swift-check.outputs.swift-compatible == 'true' }}
+ uses: github/codeql-action/init@v3
with: { languages: swift }
- name: Perform build
+ if: ${{ steps.swift-check.outputs.swift-compatible == 'true' }}
run: swift build
- name: Run CodeQL analyze
- uses: github/codeql-action/analyze@v2
+ if: ${{ steps.swift-check.outputs.swift-compatible == 'true' }}
+ uses: github/codeql-action/analyze@v3
linux-unit:
if: ${{ !(github.event.pull_request.draft || false) }}
@@ -88,20 +107,21 @@ jobs:
fail-fast: false
matrix:
postgres-image:
- - postgres:15
- - postgres:13
- - postgres:11
+ - postgres:16
+ - postgres:14
+ - postgres:12
swift-image:
- swift:5.7-jammy
- swift:5.8-jammy
- - swiftlang/swift:nightly-5.9-jammy
+ - swift:5.9-jammy
+ - swiftlang/swift:nightly-5.10-jammy
- swiftlang/swift:nightly-main-jammy
include:
- - postgres-image: postgres:15
+ - postgres-image: postgres:16
postgres-auth: scram-sha-256
- - postgres-image: postgres:13
+ - postgres-image: postgres:14
postgres-auth: md5
- - postgres-image: postgres:11
+ - postgres-image: postgres:12
postgres-auth: trust
runs-on: ubuntu-latest
container: ${{ matrix.swift-image }}
@@ -116,17 +136,17 @@ jobs:
POSTGRES_INITDB_ARGS: --auth-host=${{ matrix.postgres-auth }}
steps:
- name: Check out package
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Run local tests
run: swift test
linux-integration:
if: ${{ !(github.event.pull_request.draft || false) }}
runs-on: ubuntu-latest
- container: swift:5.8-jammy
+ container: swift:5.9-jammy
services:
psql-a:
- image: postgres:15
+ image: postgres:16
env:
POSTGRES_USER: test_username
POSTGRES_DB: test_database
@@ -143,10 +163,10 @@ jobs:
POSTGRES_INITDB_ARGS: --auth-host=scram-sha-256
steps:
- name: Check out package
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with: { path: 'postgres-kit' }
- name: Check out fluent-postgres-driver dependent
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with: { repository: 'vapor/fluent-postgres-driver', path: 'fluent-postgres-driver' }
- name: Use local package
run: swift package --package-path fluent-postgres-driver edit postgres-kit --path postgres-kit
@@ -160,7 +180,7 @@ jobs:
matrix:
xcode-version:
- '~14.3'
- - '15.0-beta'
+ - 'latest'
runs-on: macos-13
env:
POSTGRES_HOSTNAME: 127.0.0.1
@@ -173,11 +193,11 @@ jobs:
- name: Install Postgres, setup DB and auth, and wait for server start
run: |
export PATH="$(brew --prefix)/opt/postgresql@14/bin:$PATH" PGDATA=/tmp/vapor-postgres-test
- (brew unlink postgresql || true) && brew install "postgresql@14" && brew link --force "postgresql@14"
+ (brew unlink postgresql || true) && brew install "postgresql@15" && brew link --force "postgresql@15"
initdb --locale=C --auth-host "scram-sha-256" -U "${POSTGRES_USER}" --pwfile=<(echo "${POSTGRES_PASSWORD}")
pg_ctl start --wait
timeout-minutes: 2
- name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Run local tests
run: swift test
diff --git a/Package@swift-5.9.swift b/Package@swift-5.9.swift
new file mode 100644
index 00000000..228587ea
--- /dev/null
+++ b/Package@swift-5.9.swift
@@ -0,0 +1,46 @@
+// swift-tools-version:5.9
+import PackageDescription
+
+let swiftSettings: [SwiftSetting] = [
+ .enableUpcomingFeature("ExistentialAny"),
+ .enableUpcomingFeature("ConciseMagicFile"),
+ .enableUpcomingFeature("ForwardTrailingClosures"),
+ .enableUpcomingFeature("DisableOutwardActorInference"),
+ .enableExperimentalFeature("StrictConcurrency=complete"),
+]
+
+let package = Package(
+ name: "postgres-kit",
+ platforms: [
+ .macOS(.v10_15),
+ .iOS(.v13),
+ .watchOS(.v6),
+ .tvOS(.v13),
+ ],
+ dependencies: [
+ .package(url: "https://github.com/vapor/postgres-nio.git", from: "1.20.0"),
+ .package(url: "https://github.com/vapor/sql-kit.git", from: "3.28.0"),
+ .package(url: "https://github.com/vapor/async-kit.git", from: "1.19.0"),
+ .package(url: "https://github.com/apple/swift-atomics.git", from: "1.2.0")
+ ],
+ targets: [
+ .target(
+ name: "PostgresKit",
+ dependencies: [
+ .product(name: "AsyncKit", package: "async-kit"),
+ .product(name: "PostgresNIO", package: "postgres-nio"),
+ .product(name: "SQLKit", package: "sql-kit"),
+ .product(name: "Atomics", package: "swift-atomics"),
+ ],
+ swiftSettings: swiftSettings
+ ),
+ .testTarget(
+ name: "PostgresKitTests",
+ dependencies: [
+ .target(name: "PostgresKit"),
+ .product(name: "SQLKitBenchmark", package: "sql-kit"),
+ ],
+ swiftSettings: swiftSettings
+ ),
+ ]
+)
diff --git a/README.md b/README.md
index c103a680..4feeaae0 100644
--- a/README.md
+++ b/README.md
@@ -1,21 +1,19 @@
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
🐘 Non-blocking, event-driven Swift client for PostgreSQL.
@@ -39,7 +37,7 @@ Use the SPM string to easily include the dependendency in your `Package.swift` f
PostgresKit supports the following platforms:
-- Ubuntu 16.04+
+- Ubuntu 20.04+
- macOS 10.15+
## Overview
diff --git a/Sources/PostgresKit/ConnectionPool+Postgres.swift b/Sources/PostgresKit/ConnectionPool+Postgres.swift
index 6dd11f9f..547d811e 100644
--- a/Sources/PostgresKit/ConnectionPool+Postgres.swift
+++ b/Sources/PostgresKit/ConnectionPool+Postgres.swift
@@ -1,6 +1,6 @@
import NIOCore
import PostgresNIO
-import AsyncKit
+@preconcurrency import AsyncKit
import Logging
extension EventLoopGroupConnectionPool where Source == PostgresConnectionSource {
diff --git a/Sources/PostgresKit/Deprecations/PostgresConnectionSource+PostgresConfiguration.swift b/Sources/PostgresKit/Deprecations/PostgresConnectionSource+PostgresConfiguration.swift
index 80c07b52..4a03461a 100644
--- a/Sources/PostgresKit/Deprecations/PostgresConnectionSource+PostgresConfiguration.swift
+++ b/Sources/PostgresKit/Deprecations/PostgresConnectionSource+PostgresConfiguration.swift
@@ -34,7 +34,7 @@ extension PostgresConnectionSource {
}
@available(*, deprecated, message: "Use `sqlConfiguration` instead.")
- public var sslContext: Result { .success(self.sqlConfiguration.coreConfiguration.tls.sslContext) }
+ public var sslContext: Result { .success(self.sqlConfiguration.coreConfiguration.tls.sslContext) }
@available(*, deprecated, message: "Use `init(sqlConfiguration:)` instead.")
public init(configuration: PostgresConfiguration) {
diff --git a/Sources/PostgresKit/Deprecations/PostgresDataEncoder.swift b/Sources/PostgresKit/Deprecations/PostgresDataEncoder.swift
index aafdc1cc..057b545f 100644
--- a/Sources/PostgresKit/Deprecations/PostgresDataEncoder.swift
+++ b/Sources/PostgresKit/Deprecations/PostgresDataEncoder.swift
@@ -9,7 +9,7 @@ public final class PostgresDataEncoder {
self.json = json
}
- public func encode(_ value: Encodable) throws -> PostgresData {
+ public func encode(_ value: any Encodable) throws -> PostgresData {
if let custom = value as? any PostgresDataConvertible, let data = custom.postgresData {
return data
} else {
diff --git a/Sources/PostgresKit/Docs.docc/images/vapor-postgreskit-logo.svg b/Sources/PostgresKit/Docs.docc/images/vapor-postgreskit-logo.svg
new file mode 100644
index 00000000..a84b3f88
--- /dev/null
+++ b/Sources/PostgresKit/Docs.docc/images/vapor-postgreskit-logo.svg
@@ -0,0 +1,22 @@
+
diff --git a/Sources/PostgresKit/Docs.docc/theme-settings.json b/Sources/PostgresKit/Docs.docc/theme-settings.json
new file mode 100644
index 00000000..b147e23d
--- /dev/null
+++ b/Sources/PostgresKit/Docs.docc/theme-settings.json
@@ -0,0 +1,21 @@
+{
+ "theme": {
+ "aside": { "border-radius": "6px", "border-style": "double", "border-width": "3px" },
+ "border-radius": "0",
+ "button": { "border-radius": "16px", "border-width": "1px", "border-style": "solid" },
+ "code": { "border-radius": "16px", "border-width": "1px", "border-style": "solid" },
+ "color": {
+ "psqlkit": "#336791",
+ "documentation-intro-fill": "radial-gradient(circle at top, var(--color-psqlkit) 30%, #000 100%)",
+ "documentation-intro-accent": "var(--color-psqlkit)",
+ "logo-base": { "dark": "#fff", "light": "#000" },
+ "logo-shape": { "dark": "#000", "light": "#fff" },
+ "fill": { "dark": "#000", "light": "#fff" }
+ },
+ "icons": { "technology": "/postgreskit/images/vapor-postgreskit-logo.svg" }
+ },
+ "features": {
+ "quickNavigation": { "enable": true },
+ "i18n": { "enable": true }
+ }
+}
diff --git a/Sources/PostgresKit/PostgresDatabase+SQL.swift b/Sources/PostgresKit/PostgresDatabase+SQL.swift
index f7bb7ac7..85a5516d 100644
--- a/Sources/PostgresKit/PostgresDatabase+SQL.swift
+++ b/Sources/PostgresKit/PostgresDatabase+SQL.swift
@@ -1,6 +1,13 @@
import PostgresNIO
import Logging
-import SQLKit
+@preconcurrency import SQLKit
+
+// https://github.com/vapor/postgres-nio/pull/450
+#if compiler(>=5.10) && $RetroactiveAttribute
+extension PostgresEncodingContext: @retroactive @unchecked Sendable {}
+#else
+extension PostgresEncodingContext: @unchecked Sendable {}
+#endif
extension PostgresDatabase {
@inlinable
@@ -37,7 +44,7 @@ extension _PostgresSQLDatabase: SQLDatabase, PostgresDatabase {
var version: (any SQLDatabaseReportedVersion)? { nil } // PSQL doesn't send version in wire protocol, must use SQL to read it
var dialect: any SQLDialect { PostgresDialect() }
- func execute(sql query: any SQLExpression, _ onRow: @escaping (any SQLRow) -> ()) -> EventLoopFuture {
+ func execute(sql query: any SQLExpression, _ onRow: @escaping @Sendable (any SQLRow) -> ()) -> EventLoopFuture {
let (sql, binds) = self.serialize(query)
if let queryLogLevel {
diff --git a/Sources/PostgresKit/SQLPostgresConfiguration.swift b/Sources/PostgresKit/SQLPostgresConfiguration.swift
index 5a11c7ef..6169f344 100644
--- a/Sources/PostgresKit/SQLPostgresConfiguration.swift
+++ b/Sources/PostgresKit/SQLPostgresConfiguration.swift
@@ -146,7 +146,7 @@ public struct SQLPostgresConfiguration {
/// This is provided for calling code which wants to manage the underlying connection transport on its
/// own, such as when tunneling a connection through SSH.
public init(
- establishedChannel: Channel,
+ establishedChannel: any Channel,
username: String, password: String? = nil,
database: String? = nil
) {
diff --git a/Tests/PostgresKitTests/PostgresKitTests.swift b/Tests/PostgresKitTests/PostgresKitTests.swift
index af1074a8..7d20d0b1 100644
--- a/Tests/PostgresKitTests/PostgresKitTests.swift
+++ b/Tests/PostgresKitTests/PostgresKitTests.swift
@@ -19,7 +19,7 @@ final class PostgresKitTests: XCTestCase {
let pool = EventLoopGroupConnectionPool(
source: db,
maxConnectionsPerEventLoop: 2,
- on: self.eventLoopGroup
+ on: MultiThreadedEventLoopGroup.singleton
)
defer { pool.shutdown() }
// Postgres seems to take much longer on initial connections when using SCRAM-SHA-256 auth,
@@ -27,13 +27,13 @@ final class PostgresKitTests: XCTestCase {
// Spin the pool a bit before running the measurement to warm it up.
for _ in 1...25 {
_ = try pool.withConnection { conn in
- conn.query("SELECT 1;")
+ conn.query("SELECT 1")
}.wait()
}
self.measure {
for _ in 1...100 {
_ = try! pool.withConnection { conn in
- conn.query("SELECT 1;")
+ conn.query("SELECT 1")
}.wait()
}
}
@@ -125,12 +125,12 @@ final class PostgresKitTests: XCTestCase {
var configuration = SQLPostgresConfiguration.test
configuration.searchPath = ["foo", "bar", "baz"]
let source = PostgresConnectionSource(sqlConfiguration: configuration)
- let pool = EventLoopGroupConnectionPool(source: source, on: self.eventLoopGroup)
+ let pool = EventLoopGroupConnectionPool(source: source, on: MultiThreadedEventLoopGroup.singleton)
defer { pool.shutdown() }
let db = pool.database(logger: .init(label: "test")).sql()
- let rows = try db.raw("SELECT version();").all().wait()
- print(rows)
+ let rows = try db.raw("SELECT version()").all().wait()
+ XCTAssertEqual(rows.count, 1)
}
func testIntegerArrayEncoding() throws {
@@ -225,19 +225,17 @@ final class PostgresKitTests: XCTestCase {
XCTAssertEqual(numericValue, Double(Decimal(12345.6789).description))
}
- var eventLoop: any EventLoop { self.eventLoopGroup.any() }
- var eventLoopGroup: (any EventLoopGroup)!
+ var eventLoop: any EventLoop { MultiThreadedEventLoopGroup.singleton.any() }
override func setUpWithError() throws {
try super.setUpWithError()
XCTAssertTrue(isLoggingConfigured)
- self.eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 2)
}
+}
- override func tearDownWithError() throws {
- try self.eventLoopGroup.syncShutdownGracefully()
- self.eventLoopGroup = nil
- try super.tearDownWithError()
+extension PostgresCell {
+ fileprivate init(with data: PostgresData) {
+ self.init(bytes: data.value, dataType: data.type, format: data.formatCode, columnName: "", columnIndex: -1)
}
}
diff --git a/Tests/PostgresKitTests/Utilities.swift b/Tests/PostgresKitTests/Utilities.swift
index 01e3a54e..3c52f2d9 100644
--- a/Tests/PostgresKitTests/Utilities.swift
+++ b/Tests/PostgresKitTests/Utilities.swift
@@ -31,7 +31,7 @@ func env(_ name: String) -> String? {
let isLoggingConfigured: Bool = {
LoggingSystem.bootstrap { label in
var handler = StreamLogHandler.standardOutput(label: label)
- handler.logLevel = env("LOG_LEVEL").flatMap { Logger.Level(rawValue: $0) } ?? .info
+ handler.logLevel = env("LOG_LEVEL").flatMap { .init(rawValue: $0) } ?? .info
return handler
}
return true
From b8afa635016ae1f81d615c3d267b81da76846f30 Mon Sep 17 00:00:00 2001
From: Gwynne Raskind
Date: Sun, 28 Jan 2024 04:13:57 -0600
Subject: [PATCH 2/9] Fix mishandling of Foundation.URL by
PostgresDataTranslation, including support for the broken encoding we were
previously generating.
---
.../PostgresKit/PostgresDataTranslation.swift | 32 +++++++++++++++++++
Tests/PostgresKitTests/PostgresKitTests.swift | 12 +++++++
2 files changed, 44 insertions(+)
diff --git a/Sources/PostgresKit/PostgresDataTranslation.swift b/Sources/PostgresKit/PostgresDataTranslation.swift
index 10560905..9fbee68f 100644
--- a/Sources/PostgresKit/PostgresDataTranslation.swift
+++ b/Sources/PostgresKit/PostgresDataTranslation.swift
@@ -14,6 +14,38 @@ private extension PostgresCell {
var codingKey: any CodingKey { SomeCodingKey(stringValue: !self.columnName.isEmpty ? "\(self.columnName) (\(self.columnIndex))" : "\(self.columnIndex)") }
}
+/// Sidestep problems with URL coding behavior by making it conform directly to Postgres coding.
+extension URL: PostgresNonThrowingEncodable {
+ public static var psqlType: PostgresDataType { String.psqlType }
+ public static var psqlFormat: PostgresFormat { String.psqlFormat }
+
+ @inlinable
+ public func encode(into byteBuffer: inout ByteBuffer, context: PostgresEncodingContext) {
+ self.absoluteString.encode(into: &byteBuffer, context: context)
+ }
+}
+
+/// Sidestep problems with URL coding behavior by making it conform directly to Postgres coding.
+extension URL: PostgresDecodable {
+ @inlinable
+ public init(
+ from buffer: inout ByteBuffer, type: PostgresDataType, format: PostgresFormat,
+ context: PostgresDecodingContext
+ ) throws {
+ let string = try String(from: &buffer, type: type, format: format, context: context)
+
+ if let url = URL(string: string) {
+ self = url
+ }
+ // Also support the broken encoding we were emitting for awhile there.
+ else if string.hasPrefix("\""), string.hasSuffix("\""), let url = URL(string: String(string.dropFirst().dropLast())) {
+ self = url
+ } else {
+ throw PostgresDecodingError.Code.failure
+ }
+ }
+}
+
struct PostgresDataTranslation {
/// This typealias serves to limit the deprecation noise caused by ``PostgresDataConvertible`` to a single
/// warning, down from what would otherwise be a minimum of two. It has no other purpose.
diff --git a/Tests/PostgresKitTests/PostgresKitTests.swift b/Tests/PostgresKitTests/PostgresKitTests.swift
index 7d20d0b1..e7ac17fe 100644
--- a/Tests/PostgresKitTests/PostgresKitTests.swift
+++ b/Tests/PostgresKitTests/PostgresKitTests.swift
@@ -224,6 +224,18 @@ final class PostgresKitTests: XCTestCase {
XCTAssertNoThrow(numericValue = try PostgresDataTranslation.decode(Double.self, from: .init(bytes: numericBuffer, dataType: .numeric, format: .binary, columnName: "", columnIndex: -1), in: .default))
XCTAssertEqual(numericValue, Double(Decimal(12345.6789).description))
}
+
+ func testURLWorkaroundDecoding() throws {
+ let url = URL(string: "https://user:pass@www.example.com:8080/path/to/endpoint?query=value#fragment")!
+
+ let encodedNormal = try PostgresDataTranslation.encode(codingPath: [], userInfo: [:], value: url, in: .default, file: #fileID, line: #line)
+ XCTAssertEqual(encodedNormal.value?.getString(at: 0, length: encodedNormal.value?.readableBytes ?? 0), url.absoluteString)
+
+ let encodedBroken = try PostgresDataTranslation.encode(codingPath: [], userInfo: [:], value: "\"\(url.absoluteString)\"", in: .default, file: #fileID, line: #line)
+
+ XCTAssertEqual(try PostgresDataTranslation.decode(URL.self, from: .init(with: encodedNormal), in: .default), url)
+ XCTAssertEqual(try PostgresDataTranslation.decode(URL.self, from: .init(with: encodedBroken), in: .default), url)
+ }
var eventLoop: any EventLoop { MultiThreadedEventLoopGroup.singleton.any() }
From 2d962c9a0c674181a3fa84e424f7a220a20e4bbf Mon Sep 17 00:00:00 2001
From: Gwynne Raskind
Date: Sun, 28 Jan 2024 04:28:51 -0600
Subject: [PATCH 3/9] Fix typo
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 4feeaae0..5b969ff7 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
-
+
From 9b539691b60f7f40ce881b19eda78e6b0085d729 Mon Sep 17 00:00:00 2001
From: Gwynne Raskind
Date: Sun, 28 Jan 2024 04:31:56 -0600
Subject: [PATCH 4/9] Fix accidental deletion
---
Package@swift-5.9.swift | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Package@swift-5.9.swift b/Package@swift-5.9.swift
index 228587ea..271f6837 100644
--- a/Package@swift-5.9.swift
+++ b/Package@swift-5.9.swift
@@ -17,6 +17,9 @@ let package = Package(
.watchOS(.v6),
.tvOS(.v13),
],
+ products: [
+ .library(name: "PostgresKit", targets: ["PostgresKit"]),
+ ],
dependencies: [
.package(url: "https://github.com/vapor/postgres-nio.git", from: "1.20.0"),
.package(url: "https://github.com/vapor/sql-kit.git", from: "3.28.0"),
From b99ccc531bc1b0410d5013c70308dd121585be03 Mon Sep 17 00:00:00 2001
From: Gwynne Raskind
Date: Tue, 30 Jan 2024 10:43:34 -0600
Subject: [PATCH 5/9] Apply suggestions from code review
Co-authored-by: Mahdi Bahrami
---
.github/dependabot.yml | 1 -
1 file changed, 1 deletion(-)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 68cfb1a5..998fd4c5 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,5 +1,4 @@
version: 2
-enable-beta-ecosystems: true
updates:
- package-ecosystem: "github-actions"
directory: "/"
From b9bdb82c33ca6ba2687ae40f502cf0ce8e5bfaae Mon Sep 17 00:00:00 2001
From: Gwynne Raskind
Date: Tue, 30 Jan 2024 11:36:37 -0600
Subject: [PATCH 6/9] Logo tweak
---
README.md | 6 +++---
.../PostgresKit/Docs.docc/images/vapor-postgreskit-logo.svg | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 5b969ff7..fe0c827e 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
-
-
-
+
+
+
diff --git a/Sources/PostgresKit/Docs.docc/images/vapor-postgreskit-logo.svg b/Sources/PostgresKit/Docs.docc/images/vapor-postgreskit-logo.svg
index a84b3f88..cdb1a8ed 100644
--- a/Sources/PostgresKit/Docs.docc/images/vapor-postgreskit-logo.svg
+++ b/Sources/PostgresKit/Docs.docc/images/vapor-postgreskit-logo.svg
@@ -7,7 +7,7 @@
-
+
From ac9ed3ff479d49ad102b887d4f72b19d2706c619 Mon Sep 17 00:00:00 2001
From: Gwynne Raskind
Date: Wed, 31 Jan 2024 01:59:28 -0600
Subject: [PATCH 7/9] Apply suggestions from code review
Co-authored-by: Mahdi Bahrami
---
.github/dependabot.yml | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 998fd4c5..998a0ebe 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -8,14 +8,3 @@ updates:
dependencies:
patterns:
- "*"
- - package-ecosystem: "swift"
- directory: "/"
- schedule:
- interval: "daily"
- open-pull-requests-limit: 6
- allow:
- - dependency-type: all
- groups:
- all-dependencies:
- patterns:
- - "*"
From 17287868e3493a2932e9261c55e364ebfe12b3ad Mon Sep 17 00:00:00 2001
From: Gwynne Raskind
Date: Wed, 31 Jan 2024 02:13:38 -0600
Subject: [PATCH 8/9] Update test.yml
---
.github/workflows/test.yml | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 9deff81e..b41c0d2a 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -178,10 +178,12 @@ jobs:
strategy:
fail-fast: false
matrix:
- xcode-version:
- - '~14.3'
- - 'latest'
- runs-on: macos-13
+ include:
+ - macos-version: macos-13
+ xcode-version: '~14.3'
+ - macos-version: macos-14
+ xcode-version: latest
+ runs-on: ${{ matrix.macos-version }}
env:
POSTGRES_HOSTNAME: 127.0.0.1
POSTGRES_DB: postgres
From ccba0647c7ef9106b501b2d17696d1ac245c32fd Mon Sep 17 00:00:00 2001
From: Gwynne Raskind
Date: Wed, 31 Jan 2024 02:22:00 -0600
Subject: [PATCH 9/9] Disable CodeQL for now
---
.github/workflows/test.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index b41c0d2a..4fb24ecf 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -75,7 +75,7 @@ jobs:
uses: vapor/swift-codecov-action@v0.2
gh-codeql:
- if: ${{ !(github.event.pull_request.draft || false) }}
+ if: ${{ false && !(github.event.pull_request.draft || false) }}
runs-on: ubuntu-latest
container:
image: swift:5.9-jammy