Skip to content

Commit cc0d525

Browse files
committed
Convert QueryBuilder and related ELFs to a/a
1 parent 01f8d42 commit cc0d525

File tree

6 files changed

+66
-69
lines changed

6 files changed

+66
-69
lines changed

Sources/App/Controllers/KeywordController.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import Vapor
1919

2020
enum KeywordController {
2121

22-
static func query(on database: Database, keyword: String, page: Int, pageSize: Int) -> EventLoopFuture<Page<Joined3<Package, Repository, Version>>> {
23-
Joined3<Package, Repository, Version>
22+
static func query(on database: Database, keyword: String, page: Int, pageSize: Int) async throws -> Page<Joined3<Package, Repository, Version>> {
23+
try await Joined3<Package, Repository, Version>
2424
.query(on: database, version: .defaultBranch)
2525
.filter(Repository.self, \.$keywords, .custom("@>"), [keyword])
2626
.sort(\.$score, .descending)
@@ -53,7 +53,7 @@ enum KeywordController {
5353
throw Abort(.notFound)
5454
}
5555
let query = try req.query.decode(Query.self)
56-
let page = try await Self.query(on: req.db, keyword: keyword, page: query.page, pageSize: query.pageSize).get()
56+
let page = try await Self.query(on: req.db, keyword: keyword, page: query.page, pageSize: query.pageSize)
5757

5858
guard !page.results.isEmpty else {
5959
throw Abort(.notFound)

Sources/App/Core/Extensions/QueryBuilder+paginate.swift

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,15 @@ extension QueryBuilder {
2828
/// - page: requested page, first page is 1
2929
/// - pageSize: number of elements per page
3030
/// - Returns: a `QueryBuilder`
31-
func page(_ page: Int, size pageSize: Int) -> EventLoopFuture<Page<Model>> {
31+
func page(_ page: Int, size pageSize: Int) async throws -> Page<Model> {
3232
// page is one-based, clamp it to ensure we get a >=0 offset
3333
let page = page.clamped(to: 1...)
3434
let offset = (page - 1) * pageSize
3535
let limit = pageSize + 1 // fetch one more so we can determine `hasMoreResults`
36-
return self
37-
.offset(offset)
36+
let results = try await self.offset(offset)
3837
.limit(limit)
3938
.all()
40-
.map { results in
41-
.init(results: Array(results.prefix(pageSize)),
42-
hasMoreResults: results.count > pageSize)
43-
}
39+
return .init(results: Array(results.prefix(pageSize)),
40+
hasMoreResults: results.count > pageSize)
4441
}
4542
}

Sources/App/Core/Query+Support/JoinedQueryBuilder.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,10 @@ struct JoinedQueryBuilder<J: ModelInitializable> {
149149
.optionalMap(J.init(model:))
150150
}
151151

152-
func page(_ page: Int, size pageSize: Int) -> EventLoopFuture<Page<J>> {
153-
queryBuilder.page(page, size: pageSize)
154-
.map { page in
155-
.init(results: page.results.map(J.init(model:)),
156-
hasMoreResults: page.hasMoreResults)
157-
}
152+
func page(_ page: Int, size pageSize: Int) async throws -> Page<J> {
153+
let page = try await queryBuilder.page(page, size: pageSize)
154+
return .init(results: page.results.map(J.init(model:)),
155+
hasMoreResults: page.hasMoreResults)
158156
}
159157

160158
func serialize(_ processSQL: ((sql: String, binds: [any Encodable])) -> Void) -> Self {

Tests/AppTests/Helpers/TestDatabase.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ final class TestDatabase: @unchecked Sendable, SQLDatabase {
2424
self._dialect = GenericDialect()
2525
}
2626

27+
// We have to keep this EventLoopFuture for now, because the signature is part of Vapor's SQLDatabase protocol
2728
func execute(sql query: SQLExpression, _ onRow: @escaping (SQLRow) -> ()) -> EventLoopFuture<Void> {
2829
var serializer = SQLSerializer(database: self)
2930
query.serialize(to: &serializer)

Tests/AppTests/KeywordControllerTests.swift

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -19,102 +19,102 @@ import XCTest
1919

2020
class KeywordControllerTests: AppTestCase {
2121

22-
func test_query() throws {
22+
func test_query() async throws {
2323
// setup
2424
do {
2525
let p = try savePackage(on: app.db, "0")
26-
try Repository(package: p,
27-
keywords: ["bar"],
28-
name: "0",
29-
owner: "owner")
30-
.save(on: app.db).wait()
31-
try Version(package: p, latest: .defaultBranch).save(on: app.db).wait()
26+
try await Repository(package: p,
27+
keywords: ["bar"],
28+
name: "0",
29+
owner: "owner")
30+
.save(on: app.db)
31+
try await Version(package: p, latest: .defaultBranch).save(on: app.db)
3232
}
3333
do {
3434
let p = try savePackage(on: app.db, "1")
35-
try Repository(package: p,
36-
keywords: ["foo"],
37-
name: "1",
38-
owner: "owner")
39-
.save(on: app.db).wait()
40-
try Version(package: p, latest: .defaultBranch).save(on: app.db).wait()
35+
try await Repository(package: p,
36+
keywords: ["foo"],
37+
name: "1",
38+
owner: "owner")
39+
.save(on: app.db)
40+
try await Version(package: p, latest: .defaultBranch).save(on: app.db)
4141
}
4242
do {
4343
let p = try savePackage(on: app.db, "2")
44-
try Repository(package: p,
45-
name: "2",
46-
owner: "owner")
47-
.save(on: app.db).wait()
48-
try Version(package: p, latest: .defaultBranch).save(on: app.db).wait()
44+
try await Repository(package: p,
45+
name: "2",
46+
owner: "owner")
47+
.save(on: app.db)
48+
try await Version(package: p, latest: .defaultBranch).save(on: app.db)
4949
}
5050
// MUT
51-
let page = try KeywordController.query(on: app.db,
52-
keyword: "foo",
53-
page: 1,
54-
pageSize: 10).wait()
51+
let page = try await KeywordController.query(on: app.db,
52+
keyword: "foo",
53+
page: 1,
54+
pageSize: 10)
5555

5656
// validation
5757
XCTAssertEqual(page.results.map(\.model.url), ["1"])
5858
XCTAssertEqual(page.hasMoreResults, false)
5959
}
6060

61-
func test_query_pagination() throws {
61+
func test_query_pagination() async throws {
6262
// setup
63-
try (0..<9).shuffled().forEach { idx in
63+
for idx in (0..<9).shuffled() {
6464
let p = Package(url: "\(idx)".url, score: 10 - idx)
65-
try p.save(on: app.db).wait()
66-
try Repository(package: p,
67-
keywords: ["foo"],
68-
name: "\(idx)",
69-
owner: "owner").save(on: app.db).wait()
70-
try Version(package: p, latest: .defaultBranch).save(on: app.db).wait()
65+
try await p.save(on: app.db)
66+
try await Repository(package: p,
67+
keywords: ["foo"],
68+
name: "\(idx)",
69+
owner: "owner").save(on: app.db)
70+
try await Version(package: p, latest: .defaultBranch).save(on: app.db)
7171
}
7272
do { // first page
73-
// MUT
74-
let page = try KeywordController.query(on: app.db,
75-
keyword: "foo",
76-
page: 1,
77-
pageSize: 3).wait()
73+
// MUT
74+
let page = try await KeywordController.query(on: app.db,
75+
keyword: "foo",
76+
page: 1,
77+
pageSize: 3)
7878
// validate
7979
XCTAssertEqual(page.results.map(\.model.url), ["0", "1", "2"])
8080
XCTAssertEqual(page.hasMoreResults, true)
8181
}
8282
do { // second page
83-
// MUT
84-
let page = try KeywordController.query(on: app.db,
85-
keyword: "foo",
86-
page: 2,
87-
pageSize: 3).wait()
83+
// MUT
84+
let page = try await KeywordController.query(on: app.db,
85+
keyword: "foo",
86+
page: 2,
87+
pageSize: 3)
8888
// validate
8989
XCTAssertEqual(page.results.map(\.model.url), ["3", "4", "5"])
9090
XCTAssertEqual(page.hasMoreResults, true)
9191
}
9292
do { // last page
93-
// MUT
94-
let page = try KeywordController.query(on: app.db,
95-
keyword: "foo",
96-
page: 3,
97-
pageSize: 3).wait()
93+
// MUT
94+
let page = try await KeywordController.query(on: app.db,
95+
keyword: "foo",
96+
page: 3,
97+
pageSize: 3)
9898
// validate
9999
XCTAssertEqual(page.results.map(\.model.url), ["6", "7", "8"])
100100
XCTAssertEqual(page.hasMoreResults, false)
101101
}
102102
}
103103

104-
func test_show_keyword() throws {
104+
func test_show_keyword() async throws {
105105
// setup
106106
do {
107107
let p = try savePackage(on: app.db, "1")
108-
try Repository(package: p,
109-
keywords: ["foo"],
110-
name: "1",
111-
owner: "owner").save(on: app.db).wait()
112-
try Version(package: p, latest: .defaultBranch).save(on: app.db).wait()
108+
try await Repository(package: p,
109+
keywords: ["foo"],
110+
name: "1",
111+
owner: "owner").save(on: app.db)
112+
try await Version(package: p, latest: .defaultBranch).save(on: app.db)
113113
}
114114
// MUT
115-
try app.test(.GET, "/keywords/foo") {
115+
try await app.test(.GET, "/keywords/foo") { req async in
116116
// validate
117-
XCTAssertEqual($0.status, .ok)
117+
XCTAssertEqual(req.status, .ok)
118118
}
119119
}
120120

Tests/AppTests/Util.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ class MockClient: Client, @unchecked Sendable {
158158
let eventLoopGroup: EventLoopGroup
159159
var updateResponse: (ClientRequest, inout ClientResponse) -> Void
160160

161+
// We have to keep this EventLoopFuture for now, because the signature is part of Vapor's Client protocol
161162
func send(_ request: ClientRequest) -> EventLoopFuture<ClientResponse> {
162163
var response = ClientResponse()
163164
updateResponse(request, &response)

0 commit comments

Comments
 (0)