@@ -14,7 +14,7 @@ import AWSPluginsCore
14
14
/// an integration layer between the AppSyncLocal `StorageEngine` and SQLite for local storage.
15
15
final class SQLiteStorageEngineAdapter : StorageEngineAdapter {
16
16
17
- internal var connection : Connection !
17
+ internal var connection : Connection ?
18
18
private var dbFilePath : URL ?
19
19
static let dbVersionKey = " com.amazonaws.DataStore.dbVersion "
20
20
@@ -89,6 +89,10 @@ final class SQLiteStorageEngineAdapter: StorageEngineAdapter {
89
89
}
90
90
91
91
func setUp( modelSchemas: [ ModelSchema ] ) throws {
92
+ guard let connection = connection else {
93
+ throw DataStoreError . invalidOperation ( causedBy: nil )
94
+ }
95
+
92
96
log. debug ( " Setting up \( modelSchemas. count) models " )
93
97
94
98
let createTableStatements = modelSchemas
@@ -130,6 +134,10 @@ final class SQLiteStorageEngineAdapter: StorageEngineAdapter {
130
134
modelSchema: ModelSchema ,
131
135
condition: QueryPredicate ? = nil ,
132
136
completion: DataStoreCallback < M > ) {
137
+ guard let connection = connection else {
138
+ completion ( . failure( DataStoreError . nilSQLiteConnection ( ) ) )
139
+ return
140
+ }
133
141
do {
134
142
let modelType = type ( of: model)
135
143
let modelExists = try exists ( modelSchema, withId: model. id)
@@ -189,6 +197,10 @@ final class SQLiteStorageEngineAdapter: StorageEngineAdapter {
189
197
modelSchema: ModelSchema ,
190
198
predicate: QueryPredicate ,
191
199
completion: ( DataStoreResult < [ M ] > ) -> Void ) {
200
+ guard let connection = connection else {
201
+ completion ( . failure( DataStoreError . nilSQLiteConnection ( ) ) )
202
+ return
203
+ }
192
204
do {
193
205
let statement = DeleteStatement ( modelSchema: modelSchema, predicate: predicate)
194
206
_ = try connection. prepare ( statement. stringValue) . run ( statement. variables)
@@ -218,6 +230,10 @@ final class SQLiteStorageEngineAdapter: StorageEngineAdapter {
218
230
withId id: Model . Identifier ,
219
231
predicate: QueryPredicate ? = nil ,
220
232
completion: DataStoreCallback < Void > ) {
233
+ guard let connection = connection else {
234
+ completion ( . failure( DataStoreError . nilSQLiteConnection ( ) ) )
235
+ return
236
+ }
221
237
do {
222
238
let statement = DeleteStatement ( modelSchema: modelSchema, withId: id, predicate: predicate)
223
239
_ = try connection. prepare ( statement. stringValue) . run ( statement. variables)
@@ -246,6 +262,10 @@ final class SQLiteStorageEngineAdapter: StorageEngineAdapter {
246
262
sort: [ QuerySortDescriptor ] ? = nil ,
247
263
paginationInput: QueryPaginationInput ? = nil ,
248
264
completion: DataStoreCallback < [ M ] > ) {
265
+ guard let connection = connection else {
266
+ completion ( . failure( DataStoreError . nilSQLiteConnection ( ) ) )
267
+ return
268
+ }
249
269
do {
250
270
let statement = SelectStatement ( from: modelSchema,
251
271
predicate: predicate,
@@ -264,6 +284,9 @@ final class SQLiteStorageEngineAdapter: StorageEngineAdapter {
264
284
func exists( _ modelSchema: ModelSchema ,
265
285
withId id: Model . Identifier ,
266
286
predicate: QueryPredicate ? = nil ) throws -> Bool {
287
+ guard let connection = connection else {
288
+ throw DataStoreError . nilSQLiteConnection ( )
289
+ }
267
290
let primaryKey = modelSchema. primaryKey. sqlName
268
291
var sql = " select count( \( primaryKey) ) from \" \( modelSchema. name) \" where \( primaryKey) = ? "
269
292
var variables : [ Binding ? ] = [ id]
@@ -294,6 +317,9 @@ final class SQLiteStorageEngineAdapter: StorageEngineAdapter {
294
317
}
295
318
296
319
func queryMutationSync( for models: [ Model ] , modelName: String ) throws -> [ MutationSync < AnyModel > ] {
320
+ guard let connection = connection else {
321
+ throw DataStoreError . nilSQLiteConnection ( )
322
+ }
297
323
let statement = SelectStatement ( from: MutationSyncMetadata . schema)
298
324
let primaryKey = MutationSyncMetadata . schema. primaryKey. sqlName
299
325
// This is a temp workaround since we don't currently support the "in" operator
@@ -327,6 +353,9 @@ final class SQLiteStorageEngineAdapter: StorageEngineAdapter {
327
353
}
328
354
329
355
func queryMutationSyncMetadata( for modelIds: [ Model . Identifier ] , modelName: String ) throws -> [ MutationSyncMetadata ] {
356
+ guard let connection = connection else {
357
+ throw DataStoreError . nilSQLiteConnection ( )
358
+ }
330
359
let modelType = MutationSyncMetadata . self
331
360
let modelSchema = MutationSyncMetadata . schema
332
361
let fields = MutationSyncMetadata . keys
@@ -352,6 +381,9 @@ final class SQLiteStorageEngineAdapter: StorageEngineAdapter {
352
381
}
353
382
354
383
func queryModelSyncMetadata( for modelSchema: ModelSchema ) throws -> ModelSyncMetadata ? {
384
+ guard let connection = connection else {
385
+ throw DataStoreError . nilSQLiteConnection ( )
386
+ }
355
387
let statement = SelectStatement ( from: ModelSyncMetadata . schema,
356
388
predicate: field ( " id " ) . eq ( modelSchema. name) )
357
389
let rows = try connection. prepare ( statement. stringValue) . run ( statement. variables)
@@ -362,6 +394,9 @@ final class SQLiteStorageEngineAdapter: StorageEngineAdapter {
362
394
}
363
395
364
396
func transaction( _ transactionBlock: BasicThrowableClosure ) throws {
397
+ guard let connection = connection else {
398
+ throw DataStoreError . nilSQLiteConnection ( )
399
+ }
365
400
try connection. transaction {
366
401
try transactionBlock ( )
367
402
}
@@ -431,4 +466,15 @@ private func getDocumentPath() -> URL? {
431
466
return FileManager . default. urls ( for: . documentDirectory, in: . userDomainMask) . first
432
467
}
433
468
469
+ extension DataStoreError {
470
+
471
+ static func nilSQLiteConnection( ) -> DataStoreError {
472
+ . internalOperation( " SQLite connection is `nil` " ,
473
+ """
474
+ This is expected if DataStore.clear is called while syncing as the SQLite connection is closed.
475
+ Call DataStore.start to restart the sync process.
476
+ """ , nil )
477
+ }
478
+ }
479
+
434
480
extension SQLiteStorageEngineAdapter : DefaultLogger { }
0 commit comments