@@ -4,16 +4,14 @@ import PowerSyncKotlin
4
4
final class KotlinPowerSyncDatabaseImpl : PowerSyncDatabaseProtocol {
5
5
private let kotlinDatabase : PowerSyncKotlin . PowerSyncDatabase
6
6
7
- var currentStatus : SyncStatus {
8
- get { kotlinDatabase. currentStatus }
9
- }
7
+ var currentStatus : SyncStatus { kotlinDatabase. currentStatus }
10
8
11
9
init (
12
10
schema: Schema ,
13
11
dbFilename: String
14
12
) {
15
13
let factory = PowerSyncKotlin . DatabaseDriverFactory ( )
16
- self . kotlinDatabase = PowerSyncDatabase (
14
+ kotlinDatabase = PowerSyncDatabase (
17
15
factory: factory,
18
16
schema: KotlinAdapter . Schema. toKotlin ( schema) ,
19
17
dbFilename: dbFilename
@@ -65,85 +63,97 @@ final class KotlinPowerSyncDatabaseImpl: PowerSyncDatabaseProtocol {
65
63
}
66
64
67
65
func execute( sql: String , parameters: [ Any ] ? ) async throws -> Int64 {
68
- Int64 ( truncating: try await kotlinDatabase. execute ( sql: sql, parameters: parameters) )
66
+ try Int64 ( truncating: await kotlinDatabase. execute ( sql: sql, parameters: parameters) )
69
67
}
70
68
71
69
func get< RowType> (
72
70
sql: String ,
73
71
parameters: [ Any ] ? ,
74
72
mapper: @escaping ( SqlCursor ) -> RowType
75
73
) async throws -> RowType {
76
- try await kotlinDatabase. get (
74
+ try safeCast ( await kotlinDatabase. get (
77
75
sql: sql,
78
76
parameters: parameters,
79
77
mapper: mapper
80
- ) as! RowType
78
+ ) , to : RowType . self )
81
79
}
82
80
83
81
func get< RowType> (
84
82
sql: String ,
85
83
parameters: [ Any ] ? ,
86
84
mapper: @escaping ( SqlCursor ) throws -> RowType
87
85
) async throws -> RowType {
88
- try await kotlinDatabase. get (
89
- sql: sql,
90
- parameters: parameters,
91
- mapper: { cursor in
92
- try ! mapper ( cursor)
93
- }
94
- ) as! RowType
86
+ return try await wrapQueryCursorTyped (
87
+ mapper: mapper,
88
+ executor: { wrappedMapper in
89
+ try await self . kotlinDatabase. get (
90
+ sql: sql,
91
+ parameters: parameters,
92
+ mapper: wrappedMapper
93
+ )
94
+ } ,
95
+ resultType: RowType . self
96
+ )
95
97
}
96
98
97
99
func getAll< RowType> (
98
100
sql: String ,
99
101
parameters: [ Any ] ? ,
100
102
mapper: @escaping ( SqlCursor ) -> RowType
101
103
) async throws -> [ RowType ] {
102
- try await kotlinDatabase. getAll (
104
+ try safeCast ( await kotlinDatabase. getAll (
103
105
sql: sql,
104
106
parameters: parameters,
105
107
mapper: mapper
106
- ) as! [ RowType ]
108
+ ) , to : [ RowType ] . self )
107
109
}
108
110
109
111
func getAll< RowType> (
110
112
sql: String ,
111
113
parameters: [ Any ] ? ,
112
114
mapper: @escaping ( SqlCursor ) throws -> RowType
113
115
) async throws -> [ RowType ] {
114
- try await kotlinDatabase. getAll (
115
- sql: sql,
116
- parameters: parameters,
117
- mapper: { cursor in
118
- try ! mapper ( cursor)
119
- }
120
- ) as! [ RowType ]
116
+ try await wrapQueryCursorTyped (
117
+ mapper: mapper,
118
+ executor: { wrappedMapper in
119
+ try await self . kotlinDatabase. getAll (
120
+ sql: sql,
121
+ parameters: parameters,
122
+ mapper: wrappedMapper
123
+ )
124
+ } ,
125
+ resultType: [ RowType ] . self
126
+ )
121
127
}
122
128
123
129
func getOptional< RowType> (
124
130
sql: String ,
125
131
parameters: [ Any ] ? ,
126
132
mapper: @escaping ( SqlCursor ) -> RowType
127
133
) async throws -> RowType ? {
128
- try await kotlinDatabase. getOptional (
134
+ try safeCast ( await kotlinDatabase. getOptional (
129
135
sql: sql,
130
136
parameters: parameters,
131
137
mapper: mapper
132
- ) as! RowType ?
138
+ ) , to : RowType ? . self )
133
139
}
134
140
135
141
func getOptional< RowType> (
136
142
sql: String ,
137
143
parameters: [ Any ] ? ,
138
144
mapper: @escaping ( SqlCursor ) throws -> RowType
139
145
) async throws -> RowType ? {
140
- try await kotlinDatabase. getOptional (
141
- sql: sql,
142
- parameters: parameters,
143
- mapper: { cursor in
144
- try ! mapper ( cursor)
145
- }
146
- ) as! RowType ?
146
+ try await wrapQueryCursorTyped (
147
+ mapper: mapper,
148
+ executor: { wrappedMapper in
149
+ try await self . kotlinDatabase. getOptional (
150
+ sql: sql,
151
+ parameters: parameters,
152
+ mapper: wrappedMapper
153
+ )
154
+ } ,
155
+ resultType: RowType ? . self
156
+ )
147
157
}
148
158
149
159
func watch< RowType> (
@@ -159,7 +169,7 @@ final class KotlinPowerSyncDatabaseImpl: PowerSyncDatabaseProtocol {
159
169
parameters: parameters,
160
170
mapper: mapper
161
171
) {
162
- continuation. yield ( values as! [ RowType ] )
172
+ try continuation. yield ( safeCast ( values, to : [ RowType ] . self ) )
163
173
}
164
174
continuation. finish ( )
165
175
} catch {
@@ -177,14 +187,23 @@ final class KotlinPowerSyncDatabaseImpl: PowerSyncDatabaseProtocol {
177
187
AsyncThrowingStream { continuation in
178
188
Task {
179
189
do {
180
- for await values in try self . kotlinDatabase. watch (
190
+ var mapperError : Error ?
191
+ for try await values in try self . kotlinDatabase. watch (
181
192
sql: sql,
182
193
parameters: parameters,
183
- mapper: { cursor in
184
- try ! mapper ( cursor)
185
- }
194
+ mapper: { cursor in do {
195
+ return try mapper ( cursor)
196
+ } catch {
197
+ mapperError = error
198
+ // The value here does not matter. We will throw the exception later
199
+ // This is not ideal, this is only a workaround until we expose fine grained access to Kotlin SDK internals.
200
+ return nil as RowType ?
201
+ } }
186
202
) {
187
- continuation. yield ( values as! [ RowType ] )
203
+ if mapperError != nil {
204
+ throw mapperError!
205
+ }
206
+ try continuation. yield ( safeCast ( values, to: [ RowType ] . self) )
188
207
}
189
208
continuation. finish ( )
190
209
} catch {
@@ -195,33 +214,11 @@ final class KotlinPowerSyncDatabaseImpl: PowerSyncDatabaseProtocol {
195
214
}
196
215
197
216
public func writeTransaction< R> ( callback: @escaping ( any PowerSyncTransaction ) throws -> R ) async throws -> R {
198
- return try await kotlinDatabase. writeTransaction ( callback: TransactionCallback ( callback: callback) ) as! R
217
+ return try safeCast ( await kotlinDatabase. writeTransaction ( callback: TransactionCallback ( callback: callback) ) , to : R . self )
199
218
}
200
219
201
220
public func readTransaction< R> ( callback: @escaping ( any PowerSyncTransaction ) throws -> R ) async throws -> R {
202
- return try await kotlinDatabase. readTransaction ( callback: TransactionCallback ( callback: callback) ) as! R
203
- }
204
- }
205
-
206
- class TransactionCallback < R> : PowerSyncKotlin . ThrowableTransactionCallback {
207
- let callback : ( PowerSyncTransaction ) throws -> R
208
-
209
- init ( callback: @escaping ( PowerSyncTransaction ) throws -> R ) {
210
- self . callback = callback
211
- }
212
-
213
- func execute( transaction: PowerSyncKotlin . PowerSyncTransaction ) throws -> Any {
214
- do {
215
- return try callback ( transaction)
216
- } catch let error {
217
- return PowerSyncKotlin . PowerSyncException (
218
- message: error. localizedDescription,
219
- cause: PowerSyncKotlin . KotlinThrowable ( message: error. localizedDescription)
220
- )
221
- }
221
+ return try safeCast ( await kotlinDatabase. readTransaction ( callback: TransactionCallback ( callback: callback) ) , to: R . self)
222
222
}
223
223
}
224
224
225
- enum PowerSyncError : Error {
226
- case invalidTransaction
227
- }
0 commit comments