Skip to content

Commit a701bb1

Browse files
authored
refactor: make PostgrestClient a class and not an actor (#282)
1 parent f167264 commit a701bb1

File tree

3 files changed

+32
-29
lines changed

3 files changed

+32
-29
lines changed

Sources/PostgREST/Deprecated.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ extension PostgrestClient {
5959
deprecated,
6060
message: "Replace usages of this initializer with new init(url:schema:headers:logger:fetch:encoder:decoder:)"
6161
)
62-
public init(
62+
public convenience init(
6363
url: URL,
6464
schema: String? = nil,
6565
headers: [String: String] = [:],

Sources/PostgREST/PostgrestClient.swift

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Foundation
22
@_spi(Internal) import _Helpers
3+
import ConcurrencyExtras
34

45
public typealias PostgrestError = _Helpers.PostgrestError
56

@@ -8,7 +9,7 @@ public typealias PostgrestError = _Helpers.PostgrestError
89
#endif
910

1011
/// PostgREST client.
11-
public actor PostgrestClient {
12+
public final class PostgrestClient: Sendable {
1213
public typealias FetchHandler = @Sendable (_ request: URLRequest) async throws -> (
1314
Data, URLResponse
1415
)
@@ -52,14 +53,16 @@ public actor PostgrestClient {
5253
}
5354
}
5455

55-
public private(set) var configuration: Configuration
56+
let _configuration: LockIsolated<Configuration>
57+
public var configuration: Configuration { _configuration.value }
5658

5759
/// Creates a PostgREST client with the specified configuration.
5860
/// - Parameter configuration: The configuration for the client.
5961
public init(configuration: Configuration) {
60-
var configuration = configuration
61-
configuration.headers.merge(Configuration.defaultHeaders) { l, _ in l }
62-
self.configuration = configuration
62+
_configuration = LockIsolated(configuration)
63+
_configuration.withValue {
64+
$0.headers.merge(Configuration.defaultHeaders) { l, _ in l }
65+
}
6366
}
6467

6568
/// Creates a PostgREST client with the specified parameters.
@@ -71,7 +74,7 @@ public actor PostgrestClient {
7174
/// - session: The URLSession to use for requests.
7275
/// - encoder: The JSONEncoder to use for encoding.
7376
/// - decoder: The JSONDecoder to use for decoding.
74-
public init(
77+
public convenience init(
7578
url: URL,
7679
schema: String? = nil,
7780
headers: [String: String] = [:],
@@ -99,9 +102,9 @@ public actor PostgrestClient {
99102
@discardableResult
100103
public func setAuth(_ token: String?) -> PostgrestClient {
101104
if let token {
102-
configuration.headers["Authorization"] = "Bearer \(token)"
105+
_configuration.withValue { $0.headers["Authorization"] = "Bearer \(token)" }
103106
} else {
104-
configuration.headers.removeValue(forKey: "Authorization")
107+
_ = _configuration.withValue { $0.headers.removeValue(forKey: "Authorization") }
105108
}
106109
return self
107110
}

Tests/PostgRESTTests/BuildURLRequestTests.swift

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,16 @@ final class BuildURLRequestTests: XCTestCase {
7777

7878
let testCases: [TestCase] = [
7979
TestCase(name: "select all users where email ends with '@supabase.co'") { client in
80-
await client.from("users")
80+
client.from("users")
8181
.select()
8282
.like("email", value: "%@supabase.co")
8383
},
8484
TestCase(name: "insert new user") { client in
85-
try await client.from("users")
85+
try client.from("users")
8686
.insert(User(email: "[email protected]"))
8787
},
8888
TestCase(name: "bulk insert users") { client in
89-
try await client.from("users")
89+
try client.from("users")
9090
.insert(
9191
[
9292
User(email: "[email protected]"),
@@ -95,16 +95,16 @@ final class BuildURLRequestTests: XCTestCase {
9595
)
9696
},
9797
TestCase(name: "call rpc") { client in
98-
try await client.rpc("test_fcn", params: ["KEY": "VALUE"])
98+
try client.rpc("test_fcn", params: ["KEY": "VALUE"])
9999
},
100100
TestCase(name: "call rpc without parameter") { client in
101-
try await client.rpc("test_fcn")
101+
try client.rpc("test_fcn")
102102
},
103103
TestCase(name: "call rpc with filter") { client in
104-
try await client.rpc("test_fcn").eq("id", value: 1)
104+
try client.rpc("test_fcn").eq("id", value: 1)
105105
},
106106
TestCase(name: "test all filters and count") { client in
107-
var query = await client.from("todos").select()
107+
var query = client.from("todos").select()
108108

109109
for op in PostgrestFilterBuilder.Operator.allCases {
110110
query = query.filter("column", operator: op, value: "Some value")
@@ -113,28 +113,28 @@ final class BuildURLRequestTests: XCTestCase {
113113
return query
114114
},
115115
TestCase(name: "test in filter") { client in
116-
await client.from("todos").select().in("id", value: [1, 2, 3])
116+
client.from("todos").select().in("id", value: [1, 2, 3])
117117
},
118118
TestCase(name: "test contains filter with dictionary") { client in
119-
await client.from("users").select("name")
119+
client.from("users").select("name")
120120
.contains("address", value: ["postcode": 90210])
121121
},
122122
TestCase(name: "test contains filter with array") { client in
123-
await client.from("users")
123+
client.from("users")
124124
.select()
125125
.contains("name", value: ["is:online", "faction:red"])
126126
},
127127
TestCase(name: "test or filter with referenced table") { client in
128-
await client.from("users")
128+
client.from("users")
129129
.select("*, messages(*)")
130130
.or("public.eq.true,recipient_id.eq.1", referencedTable: "messages")
131131
},
132132
TestCase(name: "test upsert not ignoring duplicates") { client in
133-
try await client.from("users")
133+
try client.from("users")
134134
.upsert(User(email: "[email protected]"))
135135
},
136136
TestCase(name: "bulk upsert") { client in
137-
try await client.from("users")
137+
try client.from("users")
138138
.upsert(
139139
[
140140
User(email: "[email protected]"),
@@ -143,27 +143,27 @@ final class BuildURLRequestTests: XCTestCase {
143143
)
144144
},
145145
TestCase(name: "test upsert ignoring duplicates") { client in
146-
try await client.from("users")
146+
try client.from("users")
147147
.upsert(User(email: "[email protected]"), ignoreDuplicates: true)
148148
},
149149
TestCase(name: "query with + character") { client in
150-
await client.from("users")
150+
client.from("users")
151151
.select()
152152
.eq("id", value: "Cigányka-ér (0+400 cskm) vízrajzi állomás")
153153
},
154154
TestCase(name: "query with timestampz") { client in
155-
await client.from("tasks")
155+
client.from("tasks")
156156
.select()
157157
.gt("received_at", value: "2023-03-23T15:50:30.511743+00:00")
158158
.order("received_at")
159159
},
160160
TestCase(name: "query non-default schema") { client in
161-
await client.schema("storage")
161+
client.schema("storage")
162162
.from("objects")
163163
.select()
164164
},
165165
TestCase(name: "select after an insert") { client in
166-
try await client.from("users")
166+
try client.from("users")
167167
.insert(User(email: "[email protected]"))
168168
.select("id,email")
169169
},
@@ -176,9 +176,9 @@ final class BuildURLRequestTests: XCTestCase {
176176
}
177177
}
178178

179-
func testSessionConfiguration() async {
179+
func testSessionConfiguration() {
180180
let client = PostgrestClient(url: url, schema: nil, logger: nil)
181-
let clientInfoHeader = await client.configuration.headers["X-Client-Info"]
181+
let clientInfoHeader = client.configuration.headers["X-Client-Info"]
182182
XCTAssertNotNil(clientInfoHeader)
183183
}
184184
}

0 commit comments

Comments
 (0)