Skip to content

Commit 2c196f6

Browse files
authored
Drop Swift 5.10 (#643)
* Drop Swift 5.10 * Update workflows * Update README * Remove UnsafeMutableTransferBox
1 parent 8baacd7 commit 2c196f6

File tree

8 files changed

+88
-118
lines changed

8 files changed

+88
-118
lines changed

.github/workflows/api-docs.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ on:
44
branches:
55
- main
66

7+
permissions:
8+
contents: read
9+
id-token: write
10+
711
jobs:
812
build-and-deploy:
913
uses: vapor/api-docs/.github/workflows/build-and-deploy-docs-workflow.yml@main

.github/workflows/test.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ on:
88

99
env:
1010
LOG_LEVEL: info
11-
SWIFT_DETERMINISTIC_HASHING: 1
1211
POSTGRES_HOSTNAME: 'psql-a'
1312
POSTGRES_HOSTNAME_A: 'psql-a'
1413
POSTGRES_HOSTNAME_B: 'psql-b'
@@ -37,12 +36,15 @@ env:
3736
MONGO_HOSTNAME_A: 'mongo-a'
3837
MONGO_HOSTNAME_B: 'mongo-b'
3938

39+
permissions:
40+
contents: read
41+
4042
jobs:
4143

4244
linux-integration-sqlite:
4345
if: ${{ !(github.event.pull_request.draft || false) }}
4446
runs-on: ubuntu-latest
45-
container: swift:6.1-noble
47+
container: swift:6.2-noble
4648
steps:
4749
- name: Check out package
4850
uses: actions/checkout@v4
@@ -58,7 +60,7 @@ jobs:
5860
linux-integration-mysql:
5961
if: ${{ !(github.event.pull_request.draft || false) }}
6062
runs-on: ubuntu-latest
61-
container: swift:6.1-noble
63+
container: swift:6.2-noble
6264
services:
6365
mysql-a: { image: 'mysql:9', env: { MYSQL_ALLOW_EMPTY_PASSWORD: true, MYSQL_USER: test_username, MYSQL_PASSWORD: test_password, MYSQL_DATABASE: test_database } }
6466
mysql-b: { image: 'mysql:9', env: { MYSQL_ALLOW_EMPTY_PASSWORD: true, MYSQL_USER: test_username, MYSQL_PASSWORD: test_password, MYSQL_DATABASE: test_database } }
@@ -77,7 +79,7 @@ jobs:
7779
linux-integration-psql:
7880
if: ${{ !(github.event.pull_request.draft || false) }}
7981
runs-on: ubuntu-latest
80-
container: swift:6.1-noble
82+
container: swift:6.2-noble
8183
services:
8284
psql-a: { image: 'postgres:17', env: { POSTGRES_USER: test_username, POSTGRES_PASSWORD: test_password, POSTGRES_DB: test_database, POSTGRES_HOST_AUTH_METHOD: scram-sha-256, POSTGRES_INITDB_ARGS: --auth-host=scram-sha-256 } }
8385
psql-b: { image: 'postgres:17', env: { POSTGRES_USER: test_username, POSTGRES_PASSWORD: test_password, POSTGRES_DB: test_database, POSTGRES_HOST_AUTH_METHOD: scram-sha-256, POSTGRES_INITDB_ARGS: --auth-host=scram-sha-256 } }
@@ -96,7 +98,7 @@ jobs:
9698
linux-integration-mongo:
9799
if: ${{ !(github.event.pull_request.draft || false) }}
98100
runs-on: ubuntu-latest
99-
container: swift:6.1-noble
101+
container: swift:6.2-noble
100102
services:
101103
mongo-a: { image: 'mongo:6' }
102104
mongo-b: { image: 'mongo:6' }

Package.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:5.10
1+
// swift-tools-version:6.0
22
import PackageDescription
33

44
let package = Package(
@@ -73,9 +73,9 @@ let package = Package(
7373

7474
var swiftSettings: [SwiftSetting] { [
7575
.enableUpcomingFeature("ExistentialAny"),
76-
.enableUpcomingFeature("ConciseMagicFile"),
77-
.enableUpcomingFeature("ForwardTrailingClosures"),
78-
.enableUpcomingFeature("DisableOutwardActorInference"),
76+
// .enableUpcomingFeature("InternalImportsByDefault"),
7977
.enableUpcomingFeature("MemberImportVisibility"),
80-
.enableExperimentalFeature("StrictConcurrency=complete"),
78+
.enableUpcomingFeature("InferIsolatedConformances"),
79+
// .enableUpcomingFeature("NonisolatedNonsendingByDefault"),
80+
.enableUpcomingFeature("ImmutableWeakCaptures"),
8181
] }

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<a href="https://discord.gg/vapor"><img src="https://design.vapor.codes/images/discordchat.svg" alt="Team Chat"></a>
77
<a href="LICENSE"><img src="https://design.vapor.codes/images/mitlicense.svg" alt="MIT License"></a>
88
<a href="https://github.com/vapor/fluent-kit/actions/workflows/test.yml"><img src="https://img.shields.io/github/actions/workflow/status/vapor/fluent-kit/test.yml?event=push&style=plastic&logo=github&label=tests&logoColor=%23ccc" alt="Continuous Integration"></a>
9-
<a href="https://codecov.io/github/vapor/fluent-kit"><img src="https://img.shields.io/codecov/c/github/vapor/fluent-kit?style=plastic&logo=codecov&label=codecov"></a>
10-
<a href="https://swift.org"><img src="https://design.vapor.codes/images/swift510up.svg" alt="Swift 5.10+"></a>
9+
<a href="https://codecov.io/github/vapor/fluent-kit"><img src="https://img.shields.io/codecov/c/github/vapor/fluent-kit?style=plastic&logo=codecov&label=codecov" alt="Code Coverage"></a>
10+
<a href="https://swift.org"><img src="https://design.vapor.codes/images/swift60up.svg" alt="Swift 6.0+"></a>
1111
</p>
1212

1313
<br>

Sources/FluentKit/Query/Builder/QueryBuilder.swift

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -146,21 +146,6 @@ public final class QueryBuilder<Model>
146146
// MARK: Fetch
147147

148148
public func chunk(max: Int, closure: @escaping @Sendable ([Result<Model, any Error>]) -> ()) -> EventLoopFuture<Void> {
149-
#if swift(<5.10)
150-
let partial: UnsafeMutableTransferBox<[Result<Model, any Error>]> = .init([])
151-
partial.wrappedValue.reserveCapacity(max)
152-
return self.all { row in
153-
partial.wrappedValue.append(row)
154-
if partial.wrappedValue.count >= max {
155-
closure(partial.wrappedValue)
156-
partial.wrappedValue.removeAll(keepingCapacity: true)
157-
}
158-
}.flatMapThrowing {
159-
if !partial.wrappedValue.isEmpty {
160-
closure(partial.wrappedValue)
161-
}
162-
}
163-
#else
164149
nonisolated(unsafe) var partial: [Result<Model, any Error>] = []
165150
partial.reserveCapacity(max)
166151

@@ -175,7 +160,6 @@ public final class QueryBuilder<Model>
175160
closure(partial)
176161
}
177162
}
178-
#endif
179163
}
180164

181165
public func first() -> EventLoopFuture<Model?> {
@@ -217,19 +201,11 @@ public final class QueryBuilder<Model>
217201
}
218202

219203
public func all() -> EventLoopFuture<[Model]> {
220-
#if swift(<5.10)
221-
let models: UnsafeMutableTransferBox<[Result<Model, any Error>]> = .init([])
222-
223-
return self
224-
.all { models.wrappedValue.append($0) }
225-
.flatMapThrowing { try models.wrappedValue.map { try $0.get() } }
226-
#else
227204
nonisolated(unsafe) var models: [Result<Model, any Error>] = []
228205

229206
return self
230207
.all { models.append($0) }
231208
.flatMapThrowing { try models.map { try $0.get() } }
232-
#endif
233209
}
234210

235211
public func run() -> EventLoopFuture<Void> {
@@ -352,6 +328,4 @@ public final class QueryBuilder<Model>
352328
}
353329
}
354330

355-
#if swift(<6) || !$InferSendableFromCaptures
356-
extension Swift.KeyPath: @unchecked Swift.Sendable {}
357-
#endif
331+
extension KeyPath: @unchecked @retroactive Sendable {}

Sources/FluentKit/Utilities/UnsafeMutableTransferBox.swift

Lines changed: 0 additions & 10 deletions
This file was deleted.

Tests/FluentKitTests/AsyncTests/AsyncQueryBuilderTests.swift

Lines changed: 35 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import FluentKit
21
import FluentBenchmark
2+
import FluentKit
33
import Foundation
44
import SQLKit
55
import XCTFluent
@@ -27,7 +27,7 @@ final class AsyncQueryBuilderTests: XCTestCase {
2727
TestOutput([
2828
"id": planet.id as any Sendable,
2929
"name": planet.name,
30-
"star_id": UUID()
30+
"star_id": UUID(),
3131
])
3232
])
3333

@@ -44,13 +44,13 @@ final class AsyncQueryBuilderTests: XCTestCase {
4444
TestOutput([
4545
"id": planet.id as any Sendable,
4646
"name": planet.name,
47-
"star_id": UUID()
47+
"star_id": UUID(),
4848
]),
4949
TestOutput([
5050
"id": UUID(),
5151
"name": "Nupeter",
52-
"star_id": UUID()
53-
])
52+
"star_id": UUID(),
53+
]),
5454
])
5555

5656
let retrievedPlanet = try await Planet.query(on: test.db).first()
@@ -64,7 +64,7 @@ final class AsyncQueryBuilderTests: XCTestCase {
6464
let planets = [
6565
Planet(id: UUID(), name: "P1", starId: starId),
6666
Planet(id: UUID(), name: "P2", starId: starId),
67-
Planet(id: UUID(), name: "P3", starId: starId)
67+
Planet(id: UUID(), name: "P3", starId: starId),
6868
]
6969
let test = ArrayTestDatabase()
7070
test.append(planets.map(TestOutput.init))
@@ -80,10 +80,11 @@ final class AsyncQueryBuilderTests: XCTestCase {
8080
let planets = [
8181
Planet(id: UUID(), name: "P1", starId: starId),
8282
Planet(id: UUID(), name: "P2", starId: starId),
83-
Planet(id: UUID(), name: "P3", starId: starId)
83+
Planet(id: UUID(), name: "P3", starId: starId),
8484
]
8585
let test = ArrayTestDatabase()
86-
let db = test.database(context: .init(configuration: test.configuration, logger: test.db.logger, eventLoop: test.db.eventLoop, history: .init()))
86+
let db = test.database(
87+
context: .init(configuration: test.configuration, logger: test.db.logger, eventLoop: test.db.eventLoop, history: .init()))
8788
test.append(planets.map(TestOutput.init))
8889

8990
let retrievedPlanets = try await Planet.query(on: db).all()
@@ -105,11 +106,10 @@ final class AsyncQueryBuilderTests: XCTestCase {
105106
let test = CallbackTestDatabase { query in
106107
XCTAssertEqual(query.schema, "planets")
107108
let result: [TestOutput]
108-
if
109-
let limit = query.limits.first,
110-
case let DatabaseQuery.Limit.count(limitValue) = limit,
109+
if let limit = query.limits.first,
110+
case DatabaseQuery.Limit.count(let limitValue) = limit,
111111
let offset = query.offsets.first,
112-
case let DatabaseQuery.Offset.count(offsetValue) = offset
112+
case DatabaseQuery.Offset.count(let offsetValue) = offset
113113
{
114114
result = [TestOutput](rows[min(offsetValue, rows.count - 1)..<min(offsetValue + limitValue, rows.count)])
115115
} else {
@@ -140,9 +140,9 @@ final class AsyncQueryBuilderTests: XCTestCase {
140140
XCTAssertEqual(retrievedPlanets.items.count, pageSizeLimit, "Page size limit should be respected.")
141141
XCTAssertEqual(retrievedPlanets.items.first?.name, "c", "Page size limit should determine offset")
142142
}
143-
143+
144144
func testPaginationInvalidLowerPageBoundary() async throws {
145-
145+
146146
// Given - a dataset with 5 items
147147
let starId = UUID()
148148
let rows = [
@@ -156,11 +156,10 @@ final class AsyncQueryBuilderTests: XCTestCase {
156156
let test = CallbackTestDatabase { query in
157157
XCTAssertEqual(query.schema, "planets")
158158
let result: [TestOutput]
159-
if
160-
let limit = query.limits.first,
161-
case let DatabaseQuery.Limit.count(limitValue) = limit,
159+
if let limit = query.limits.first,
160+
case DatabaseQuery.Limit.count(let limitValue) = limit,
162161
let offset = query.offsets.first,
163-
case let DatabaseQuery.Offset.count(offsetValue) = offset
162+
case DatabaseQuery.Offset.count(let offsetValue) = offset
164163
{
165164
result = [TestOutput](rows[min(offsetValue, rows.count - 1)..<min(offsetValue + limitValue, rows.count)])
166165
} else {
@@ -186,17 +185,17 @@ final class AsyncQueryBuilderTests: XCTestCase {
186185
pageSizeLimit: pageSizeLimit
187186
)
188187
)
189-
188+
190189
// When - query for invalid lower boundary page index
191190
let retrievedPlanets = try await Planet.query(on: db).page(withIndex: -1, size: 2)
192-
191+
193192
// Then - the first page should be retrieved
194193
XCTAssertEqual(retrievedPlanets.items.first?.name, "a", "First page should be minimum.")
195194
XCTAssertEqual(retrievedPlanets.items.count, 2, "Expecting first page to have a two items.")
196195
}
197-
196+
198197
func testPaginationInvalidUpperPageBoundary() async throws {
199-
198+
200199
// Given - a dataset with 5 items
201200
let starId = UUID()
202201
let rows = [
@@ -210,11 +209,10 @@ final class AsyncQueryBuilderTests: XCTestCase {
210209
let test = CallbackTestDatabase { query in
211210
XCTAssertEqual(query.schema, "planets")
212211
let result: [TestOutput]
213-
if
214-
let limit = query.limits.first,
215-
case let DatabaseQuery.Limit.count(limitValue) = limit,
212+
if let limit = query.limits.first,
213+
case DatabaseQuery.Limit.count(let limitValue) = limit,
216214
let offset = query.offsets.first,
217-
case let DatabaseQuery.Offset.count(offsetValue) = offset
215+
case DatabaseQuery.Offset.count(let offsetValue) = offset
218216
{
219217
result = [TestOutput](rows[min(offsetValue, rows.count - 1)..<min(offsetValue + limitValue, rows.count)])
220218
} else {
@@ -240,25 +238,20 @@ final class AsyncQueryBuilderTests: XCTestCase {
240238
pageSizeLimit: pageSizeLimit
241239
)
242240
)
243-
241+
244242
// When - query for invalid upper boundary page index
245243
let retrievedPlanets = try await Planet.query(on: db).page(withIndex: 4, size: 2)
246-
244+
247245
// Then - the last page should be retrieved
248246
XCTAssertEqual(retrievedPlanets.items.first?.name, "e", "Last page should be maximum.")
249247
XCTAssertEqual(retrievedPlanets.items.count, 1, "Expecting last page to have a single item.")
250248
}
251249

252250
// https://github.com/vapor/fluent-kit/issues/310
253251
func testJoinOverloads() async throws {
254-
final class UnsafeMutableTransferBox<Wrapped>: @unchecked Sendable {
255-
var wrappedValue: Wrapped
256-
init(_ wrappedValue: Wrapped) { self.wrappedValue = wrappedValue }
257-
}
258-
259-
let query = UnsafeMutableTransferBox<DatabaseQuery?>(nil)
252+
nonisolated(unsafe) var query: DatabaseQuery? = nil
260253
let test = CallbackTestDatabase {
261-
query.wrappedValue = $0
254+
query = $0
262255
return []
263256
}
264257
let planets = try await Planet.query(on: test.db)
@@ -267,8 +260,8 @@ final class AsyncQueryBuilderTests: XCTestCase {
267260
.filter(Star.self, \.$name, .custom("ilike"), "Sol")
268261
.all()
269262
XCTAssertEqual(planets.count, 0)
270-
XCTAssertNotNil(query.wrappedValue?.filters[1])
271-
switch query.wrappedValue?.filters[1] {
263+
XCTAssertNotNil(query?.filters[1])
264+
switch query?.filters[1] {
272265
case .value(let field, let method, let value):
273266
switch field {
274267
case .path(let path, let schema):
@@ -300,11 +293,14 @@ final class AsyncQueryBuilderTests: XCTestCase {
300293

301294
func testComplexJoinOperators() async throws {
302295
let db = DummyDatabaseForTestSQLSerializer()
303-
296+
304297
_ = try await Planet.query(on: db)
305298
.join(Star.self, on: \Star.$id == \Planet.$star.$id && \Star.$name != \Planet.$name)
306299
.all()
307300
XCTAssertEqual(db.sqlSerializers.count, 1)
308-
XCTAssertEqual(try db.sqlSerializers.xctAt(0).sql, #"SELECT "planets"."id" AS "planets_id", "planets"."name" AS "planets_name", "planets"."star_id" AS "planets_star_id", "planets"."possible_star_id" AS "planets_possible_star_id", "planets"."deleted_at" AS "planets_deleted_at", "stars"."id" AS "stars_id", "stars"."name" AS "stars_name", "stars"."galaxy_id" AS "stars_galaxy_id", "stars"."deleted_at" AS "stars_deleted_at" FROM "planets" INNER JOIN "stars" ON "stars"."id" = "planets"."star_id" AND "stars"."name" <> "planets"."name" WHERE ("planets"."deleted_at" IS NULL OR "planets"."deleted_at" > $1) AND ("stars"."deleted_at" IS NULL OR "stars"."deleted_at" > $2)"#)
301+
XCTAssertEqual(
302+
try db.sqlSerializers.xctAt(0).sql,
303+
#"SELECT "planets"."id" AS "planets_id", "planets"."name" AS "planets_name", "planets"."star_id" AS "planets_star_id", "planets"."possible_star_id" AS "planets_possible_star_id", "planets"."deleted_at" AS "planets_deleted_at", "stars"."id" AS "stars_id", "stars"."name" AS "stars_name", "stars"."galaxy_id" AS "stars_galaxy_id", "stars"."deleted_at" AS "stars_deleted_at" FROM "planets" INNER JOIN "stars" ON "stars"."id" = "planets"."star_id" AND "stars"."name" <> "planets"."name" WHERE ("planets"."deleted_at" IS NULL OR "planets"."deleted_at" > $1) AND ("stars"."deleted_at" IS NULL OR "stars"."deleted_at" > $2)"#
304+
)
309305
}
310306
}

0 commit comments

Comments
 (0)