Skip to content

Commit 2843438

Browse files
committed
Remove Foreign Key support
1 parent 8155b5b commit 2843438

File tree

3 files changed

+9
-65
lines changed

3 files changed

+9
-65
lines changed

Harmony/Core/Harmonic.swift

+5-28
Original file line numberDiff line numberDiff line change
@@ -275,48 +275,25 @@ private extension Harmonic {
275275
func handleFetchedRecordZoneChanges(_ event: CKSyncEngine.Event.FetchedRecordZoneChanges) {
276276
Logger.database.info("Handle fetched record zone changes \(event)")
277277

278-
var deferredRecords = [any HRecord]()
279278
for modification in event.modifications {
280279
// The sync engine fetched a record, and we want to merge it into our local persistence.
281280
// If we already have this object locally, let's merge the data from the server.
282281
// Otherwise, let's create a new local object.
283282
let record = modification.record
284283
if let id = record.recordID.parsedRecordID,
285284
let modelType = modelType(for: record) {
286-
try! database.writeWithDeferredForeignKeys { db in
285+
try! database.write { db in
287286
if var localRecord = try modelType.fetchOne(db, key: UUID(uuidString: id)) {
288287
try localRecord.updateChanges(db: db, ckRecord: record)
289288
} else {
290289
if let model = modelType.parseFrom(record: record) {
291-
// By catching `SQLITE_CONSTRAINT_FOREIGNKEY` it allows us to defer this records to the end of this batch.
292-
// This will fail to handle if the parent record isn't in the same batch. Maybe a instance-wide "deferred" array to check each time.
293-
// Alternatively, we could use this method and just YOLO it into the database anyway.
294-
// https://github.com/groue/GRDB.swift/issues/172
295-
do {
296-
try model.save(db)
297-
} catch ResultCode.SQLITE_CONSTRAINT_FOREIGNKEY {
298-
// Defer and try again later
299-
deferredRecords.append(model)
300-
} catch {
301-
throw error
302-
}
290+
try model.save(db)
303291
}
304292
}
305293
}
306294
}
307295
}
308296

309-
// Write deferred records with no foreign key checks to avoid conflicts for now.
310-
do {
311-
try database.writeWithDeferredForeignKeys { db in
312-
for deferredRecord in deferredRecords {
313-
try deferredRecord.save(db)
314-
}
315-
}
316-
} catch {
317-
print(error.localizedDescription)
318-
}
319-
320297
for deletion in event.deletions {
321298

322299
// A record was deleted on the server, so let's remove it from our local persistence.
@@ -348,7 +325,7 @@ private extension Harmonic {
348325
for savedRecord in event.savedRecords {
349326
if let id = savedRecord.recordID.parsedRecordID,
350327
let modelType = modelType(for: savedRecord) {
351-
try! database.writeWithDeferredForeignKeys { db in
328+
try! database.write { db in
352329
var localRecord = try? modelType.fetchOne(db, key: UUID(uuidString: id))
353330
localRecord?.setLastKnownRecordIfNewer(savedRecord)
354331
try! localRecord?.save(db)
@@ -375,7 +352,7 @@ private extension Harmonic {
375352
continue
376353
}
377354

378-
try? database.writeWithDeferredForeignKeys { db in
355+
try? database.write { db in
379356
var localRecord = try modelType.fetchOne(db, key: UUID(uuidString: id))
380357
// Merge from server...
381358
try localRecord?.updateChanges(db: db, ckRecord: serverRecord)
@@ -411,7 +388,7 @@ private extension Harmonic {
411388
}
412389

413390
if shouldClearServerRecord {
414-
try? database.writeWithDeferredForeignKeys { db in
391+
try? database.write { db in
415392
var localRecord = try? modelType.fetchOne(db, key: UUID(uuidString: id))
416393
// Merge from server...
417394
localRecord?.archivedRecord = nil

Harmony/Extensions/DatabaseWriter+WriteDeferred.swift

-37
This file was deleted.

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,7 @@ You can then access your Harmony instance from anywhere for writing or reading b
2929
Harmony provides access to write methods that will automatically sync to CloudKit and hides direct database writing access for this purpose. If you write via another means to your GRDB database, Harmony will not see those changes.
3030

3131
Harmony also provides direct access to your `DatabaseReader` if you wish to read directly. I highly suggest seeing if GRDBQuery will fit your needs first.
32+
33+
### Foreign Keys
34+
35+
Harmony does not support usage of foreign keys in GRDB. This is due to CloudKit being a system of eventual consistency. Records can return in sets where they don't have the related data within the same set or out of order. Foreign keys are incompatible with this style of system so we have taken the choice to not support foreign keys after many attempts to do so.

0 commit comments

Comments
 (0)