Skip to content

Commit b92c2b8

Browse files
authored
FetchOne Optional with bare initializer (#71)
Previously, `@FetchOne var authUser: AuthUser?` would not work because it was using a `FetchOne` initializer which did not create a query. This change adds another overloaded initializer that creates a `Select` statement limiting the results to just 1. Considerations: - The statement does not provide a default ordering, so if there are multiple records, it will just return the first one. Added some tests to cover the original failure.
1 parent 27aa920 commit b92c2b8

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

Sources/SharingGRDBCore/FetchOne.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,22 @@ public struct FetchOne<Value: Sendable>: Sendable {
7979
) {
8080
sharedReader = SharedReader(value: wrappedValue)
8181
}
82+
83+
/// Initializes this property with a query that fetches a single row from a table.
84+
///
85+
/// - Parameters:
86+
/// - wrappedValue: A default value to associate with this property.
87+
/// - database: The database to read from. A value of `nil` will use the default database
88+
/// (`@Dependency(\.defaultDatabase)`).
89+
public init(
90+
wrappedValue: sending Value,
91+
database: (any DatabaseReader)? = nil
92+
) where Value: StructuredQueriesCore.Table,
93+
Value.QueryOutput == Value
94+
{
95+
let statement = Value.all.selectStar().asSelect().limit(1)
96+
self.init(wrappedValue: wrappedValue, statement, database: database)
97+
}
8298

8399
/// Initializes this property with a wrapped value.
84100
///

Tests/SharingGRDBTests/FetchTests.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,23 @@ struct FetchTests {
2020
#expect(records == [Record(id: 2), Record(id: 3)])
2121
}
2222

23-
@Test func fetchCountWithQuery() async throws {
23+
@Test func fetchOneCountWithQuery() async throws {
2424
@FetchOne(Record.where { $0.id > 1 }.count()) var recordsCount = 0
2525
try await Task.sleep(nanoseconds: 100_000_000)
2626
#expect(recordsCount == 2)
2727
}
28+
29+
@Test func bareFetchOneOptional() async throws {
30+
@FetchOne var record: Record?
31+
try await Task.sleep(nanoseconds: 100_000_000)
32+
#expect(record != nil)
33+
}
34+
35+
@Test func fetchOneOptionalWithQuery() async throws {
36+
@FetchOne(#sql("SELECT * FROM records LIMIT 1")) var record: Record?
37+
try await Task.sleep(nanoseconds: 100_000_000)
38+
#expect(record != nil)
39+
}
2840
}
2941

3042
@Table

0 commit comments

Comments
 (0)