Skip to content

Commit a545847

Browse files
DominicGBauerDominicGBauer
and
DominicGBauer
authored
fix: transactions resulting in error when using different threads (#3)
* fix: tranasactions resulting in error when using different threads * fix: remove need for main thread * fix: remove need for main thread * chore: update kotlin package: * fix: failing test * chore: remove unused protocol --------- Co-authored-by: DominicGBauer <[email protected]>
1 parent 7591c29 commit a545847

File tree

7 files changed

+277
-82
lines changed

7 files changed

+277
-82
lines changed

Demo/PowerSyncExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

+9
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@
1010
"version" : "0.6.7"
1111
}
1212
},
13+
{
14+
"identity" : "powersync-kotlin",
15+
"kind" : "remoteSourceControl",
16+
"location" : "https://github.com/powersync-ja/powersync-kotlin.git",
17+
"state" : {
18+
"revision" : "b547389faf77d0c79f30887b5d82489ee3f4de4b",
19+
"version" : "1.0.0-BETA9.0"
20+
}
21+
},
1322
{
1423
"identity" : "powersync-sqlite-core-swift",
1524
"kind" : "remoteSourceControl",

Package.resolved

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
"kind" : "remoteSourceControl",
66
"location" : "https://github.com/powersync-ja/powersync-kotlin.git",
77
"state" : {
8-
"revision" : "7fb870f4530e5629b11f1a9b079644b200385985",
9-
"version" : "1.0.0-BETA6.0"
8+
"revision" : "b547389faf77d0c79f30887b5d82489ee3f4de4b",
9+
"version" : "1.0.0-BETA9.0"
1010
}
1111
},
1212
{

Package.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ let package = Package(
1717
targets: ["PowerSyncSwift"]),
1818
],
1919
dependencies: [
20-
.package(url: "https://github.com/powersync-ja/powersync-kotlin.git", exact: "1.0.0-BETA6.0"),
20+
.package(url: "https://github.com/powersync-ja/powersync-kotlin.git", exact: "1.0.0-BETA9.0"),
2121
.package(url: "https://github.com/powersync-ja/powersync-sqlite-core-swift.git", "0.3.1"..<"0.4.0"),
2222
],
2323
targets: [

Sources/PowerSyncSwift/Kotlin/KotlinPowerSyncDatabaseImpl.swift

+32-47
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import PowerSync
33

44
final class KotlinPowerSyncDatabaseImpl: PowerSyncDatabaseProtocol {
55
private let kotlinDatabase: PowerSync.PowerSyncDatabase
6-
6+
77
var currentStatus: SyncStatus {
88
get { kotlinDatabase.currentStatus }
99
}
10-
10+
1111
init(
1212
schema: Schema,
1313
dbFilename: String
@@ -19,55 +19,55 @@ final class KotlinPowerSyncDatabaseImpl: PowerSyncDatabaseProtocol {
1919
dbFilename: dbFilename
2020
)
2121
}
22-
22+
2323
init(kotlinDatabase: KotlinPowerSyncDatabase) {
2424
self.kotlinDatabase = kotlinDatabase
2525
}
26-
26+
2727
func waitForFirstSync() async throws {
2828
try await kotlinDatabase.waitForFirstSync()
2929
}
30-
30+
3131
func connect(
3232
connector: PowerSyncBackendConnector,
3333
crudThrottleMs: Int64 = 1000,
3434
retryDelayMs: Int64 = 5000,
3535
params: [String: JsonParam?] = [:]
3636
) async throws {
37-
let connectorProxy = PowerSyncBackendConnectorAdapter(swiftBackendConnector: connector)
38-
37+
let connectorAdapter = PowerSyncBackendConnectorAdapter(swiftBackendConnector: connector)
38+
3939
try await kotlinDatabase.connect(
40-
connector: connectorProxy,
40+
connector: connectorAdapter,
4141
crudThrottleMs: crudThrottleMs,
4242
retryDelayMs: retryDelayMs,
4343
params: params
4444
)
4545
}
46-
46+
4747
func getCrudBatch(limit: Int32 = 100) async throws -> CrudBatch? {
4848
try await kotlinDatabase.getCrudBatch(limit: limit)
4949
}
50-
50+
5151
func getNextCrudTransaction() async throws -> CrudTransaction? {
5252
try await kotlinDatabase.getNextCrudTransaction()
5353
}
54-
54+
5555
func getPowerSyncVersion() async throws -> String {
5656
try await kotlinDatabase.getPowerSyncVersion()
5757
}
58-
58+
5959
func disconnect() async throws {
6060
try await kotlinDatabase.disconnect()
6161
}
62-
62+
6363
func disconnectAndClear(clearLocal: Bool = true) async throws {
6464
try await kotlinDatabase.disconnectAndClear(clearLocal: clearLocal)
6565
}
66-
66+
6767
func execute(sql: String, parameters: [Any]?) async throws -> Int64 {
6868
Int64(truncating: try await kotlinDatabase.execute(sql: sql, parameters: parameters))
6969
}
70-
70+
7171
func get<RowType>(
7272
sql: String,
7373
parameters: [Any]?,
@@ -79,7 +79,7 @@ final class KotlinPowerSyncDatabaseImpl: PowerSyncDatabaseProtocol {
7979
mapper: mapper
8080
) as! RowType
8181
}
82-
82+
8383
func getAll<RowType>(
8484
sql: String,
8585
parameters: [Any]?,
@@ -91,7 +91,7 @@ final class KotlinPowerSyncDatabaseImpl: PowerSyncDatabaseProtocol {
9191
mapper: mapper
9292
) as! [RowType]
9393
}
94-
94+
9595
func getOptional<RowType>(
9696
sql: String,
9797
parameters: [Any]?,
@@ -103,7 +103,7 @@ final class KotlinPowerSyncDatabaseImpl: PowerSyncDatabaseProtocol {
103103
mapper: mapper
104104
) as! RowType?
105105
}
106-
106+
107107
func watch<RowType>(
108108
sql: String,
109109
parameters: [Any]?,
@@ -122,31 +122,17 @@ final class KotlinPowerSyncDatabaseImpl: PowerSyncDatabaseProtocol {
122122
}
123123
}
124124
}
125-
126-
func writeTransaction<R>(callback: @escaping (any PowerSyncTransactionProtocol) async throws -> R) async throws -> R {
127-
let wrappedCallback = SuspendTaskWrapper { [kotlinDatabase] in
128-
// Create a wrapper that converts the KMP transaction to our Swift protocol
129-
if let kmpTransaction = kotlinDatabase as? PowerSyncTransactionProtocol {
130-
return try await callback(kmpTransaction)
131-
} else {
132-
throw PowerSyncError.invalidTransaction
133-
}
134-
}
135-
136-
return try await kotlinDatabase.writeTransaction(callback: wrappedCallback) as! R
137-
}
138-
139-
func readTransaction<R>(callback: @escaping (any PowerSyncTransactionProtocol) async throws -> R) async throws -> R {
140-
let wrappedCallback = SuspendTaskWrapper { [kotlinDatabase] in
141-
// Create a wrapper that converts the KMP transaction to our Swift protocol
142-
if let kmpTransaction = kotlinDatabase as? PowerSyncTransactionProtocol {
143-
return try await callback(kmpTransaction)
144-
} else {
145-
throw PowerSyncError.invalidTransaction
146-
}
147-
}
148-
149-
return try await kotlinDatabase.readTransaction(callback: wrappedCallback) as! R
125+
126+
public func writeTransaction<R>(callback: @escaping (any PowerSyncTransaction) async throws -> R) async throws -> R {
127+
return try await kotlinDatabase.writeTransaction(callback: SuspendTaskWrapper { transaction in
128+
return try await callback(transaction)
129+
}) as! R
130+
}
131+
132+
public func readTransaction<R>(callback: @escaping (any PowerSyncTransaction) async throws -> R) async throws -> R {
133+
return try await kotlinDatabase.writeTransaction(callback: SuspendTaskWrapper { transaction in
134+
return try await callback(transaction)
135+
}) as! R
150136
}
151137
}
152138

@@ -155,17 +141,16 @@ enum PowerSyncError: Error {
155141
}
156142

157143
class SuspendTaskWrapper: KotlinSuspendFunction1 {
158-
let handle: () async throws -> Any
144+
let handle: (any PowerSyncTransaction) async throws -> Any
159145

160-
init(_ handle: @escaping () async throws -> Any) {
146+
init(_ handle: @escaping (any PowerSyncTransaction) async throws -> Any) {
161147
self.handle = handle
162148
}
163149

164-
@MainActor
165150
func __invoke(p1: Any?, completionHandler: @escaping (Any?, Error?) -> Void) {
166151
Task {
167152
do {
168-
let result = try await self.handle()
153+
let result = try await self.handle(p1 as! any PowerSyncTransaction)
169154
completionHandler(result, nil)
170155
} catch {
171156
completionHandler(nil, error)

Sources/PowerSyncSwift/PowerSyncTransactionProtocol.swift

-29
This file was deleted.

Sources/PowerSyncSwift/QueriesProtocol.swift

+38-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Foundation
22
import Combine
3+
import PowerSync
34

45
public protocol Queries {
56
/// Execute a write query (INSERT, UPDATE, DELETE)
@@ -37,8 +38,42 @@ public protocol Queries {
3738
) -> AsyncStream<[RowType]>
3839

3940
/// Execute a write transaction with the given callback
40-
func writeTransaction<R>(callback: @escaping (PowerSyncTransactionProtocol) async throws -> R) async throws -> R
41-
41+
func writeTransaction<R>(callback: @escaping (any PowerSyncTransaction) async throws -> R) async throws -> R
42+
4243
/// Execute a read transaction with the given callback
43-
func readTransaction<R>(callback: @escaping (PowerSyncTransactionProtocol) async throws -> R) async throws -> R
44+
func readTransaction<R>(callback: @escaping (any PowerSyncTransaction) async throws -> R) async throws -> R
45+
}
46+
47+
extension Queries {
48+
public func execute(_ sql: String) async throws -> Int64 {
49+
return try await execute(sql: sql, parameters: [])
50+
}
51+
52+
public func get<RowType>(
53+
_ sql: String,
54+
mapper: @escaping (SqlCursor) -> RowType
55+
) async throws -> RowType {
56+
return try await get(sql: sql, parameters: [], mapper: mapper)
57+
}
58+
59+
public func getAll<RowType>(
60+
_ sql: String,
61+
mapper: @escaping (SqlCursor) -> RowType
62+
) async throws -> [RowType] {
63+
return try await getAll(sql: sql, parameters: [], mapper: mapper)
64+
}
65+
66+
public func getOptional<RowType>(
67+
_ sql: String,
68+
mapper: @escaping (SqlCursor) -> RowType
69+
) async throws -> RowType? {
70+
return try await getOptional(sql: sql, parameters: [], mapper: mapper)
71+
}
72+
73+
public func watch<RowType>(
74+
_ sql: String,
75+
mapper: @escaping (SqlCursor) -> RowType
76+
) -> AsyncStream<[RowType]> {
77+
return watch(sql: sql, parameters: [], mapper: mapper)
78+
}
4479
}

0 commit comments

Comments
 (0)