@@ -131,18 +131,18 @@ version.
131131
132132#### Primary keys
133133
134- > TLDR : Primary keys should be globally unique identifiers, such as UUID. We further recommend
135- > specifying a " NOT NULL" constraint with a " ON CONFLICT REPLACE" action.
134+ > TL;DR : Primary keys should be globally unique identifiers, such as UUID. We further recommend
135+ > specifying a ` NOT NULL ` constraint with a ` ON CONFLICT REPLACE ` action.
136136
137137Primary keys are an important concept in SQL schema design, and SQLite makes it easy to add a
138- primary key by using an "autoincrement" integer. This makes it so that newly inserted rows get
138+ primary key by using an ` AUTOINCREMENT ` integer. This makes it so that newly inserted rows get
139139a unique ID by simply adding 1 to the largest ID in the table. However, that does not play nicely
140140with distributed schemas. That would make it possible for two devices to create a record with
141141` id: 1 ` , and when those records synchronize there would be an irreconcilable conflict.
142142
143143For this reason, primary keys in SQLite tables should be globally unique, such as a UUID. The
144- easiest way to do this is to store your table's ID in a " TEXT" column, adding a
145- default with a freshly generated UUID, and further adding a " ON CONFLICT REPLACE" constraint:
144+ easiest way to do this is to store your table's ID in a ` TEXT ` column, adding a
145+ default with a freshly generated UUID, and further adding a ` ON CONFLICT REPLACE ` constraint:
146146
147147``` sql
148148CREATE TABLE "reminders " (
@@ -151,7 +151,7 @@ CREATE TABLE "reminders" (
151151)
152152```
153153
154- > Tip: The " ON CONFLICT REPLACE" clause must be placed directly after " NOT NULL" .
154+ > Tip: The ` ON CONFLICT REPLACE ` clause must be placed directly after ` NOT NULL ` .
155155
156156This allows you to insert a row with a NULL value for the primary key and SQLite will compute
157157the primary key from the default value specified. This kind of pattern is commonly used with the
@@ -160,10 +160,10 @@ the primary key from the default value specified. This kind of pattern is common
160160``` swift
161161try database.write { db in
162162 try Reminder.upsert {
163- // Do not provide 'id', let database initialize it for you.
164- Reminder.Draft (title : " Get milk" )
165- }
166- .execute (db)
163+ // Do not provide 'id', let database initialize it for you.
164+ Reminder.Draft (title : " Get milk" )
165+ }
166+ .execute (db)
167167}
168168```
169169
@@ -182,7 +182,7 @@ CREATE TABLE "reminders" (
182182
183183#### Primary keys on every table
184184
185- > TLDR : Each synchronized table must have a single, non-compound primary key to aid in
185+ > TL;DR : Each synchronized table must have a single, non-compound primary key to aid in
186186> synchronization, even if it is not used by your app.
187187
188188_ Every_ table being synchronized must have a single primary key and cannot have compound primary
@@ -206,7 +206,7 @@ TODO: think more about this
206206
207207#### Default values for columns
208208
209- > TLDR : All columns must have a default in order to allow for multiple devices to run your
209+ > TL;DR : All columns must have a default in order to allow for multiple devices to run your
210210> app with different versions of the schema.
211211
212212Your tables' schemas should be defined to provide a default for every non-null column. To see why
@@ -221,7 +221,7 @@ a ``NonNullColumnMustHaveDefault`` error will be thrown.
221221
222222#### Unique constraints
223223
224- > TLDR : SQLite tables cannot have " UNIQUE" constraints on their columns in order to allow
224+ > TL;DR : SQLite tables cannot have ` UNIQUE` constraints on their columns in order to allow
225225> for distributed creation of records.
226226
227227Tables with unique constraints on their columns, other than on the primary key, cannot be
@@ -238,7 +238,7 @@ when a ``SyncEngine`` is first created. If a uniqueness constraint is detected a
238238
239239#### Foreign key relationships
240240
241- > TLDR : Foreign key constraints can be enabled and you can use " ON DELETE" actions to
241+ > TL;DR : Foreign key constraints can be enabled and you can use ` ON DELETE ` actions to
242242> cascade deletions.
243243
244244SharingGRDB can synchronize many-to-one and many-to-many relationships to CloudKit,
@@ -248,13 +248,13 @@ such as receiving a child record before its parent, the sync engine will cache t
248248until the parent record has been synchronized, at which point the child record will also be
249249synchronized.
250250
251- Currently the only actions supported for " ON DELETE" are " CASCADE", " SET NULL" and " SET DEFAULT" .
252- In particular, " RESTRICT" and " NO ACTION" are not supported, and if you try to use those actions
253- in your schema an `` InvalidParentForeignKey `` error will be thrown when constructing `` SyncEngine `` .
251+ Currently the only actions supported for ` ON DELETE ` are ` CASCADE ` , ` SET NULL ` and ` SET DEFAULT ` .
252+ In particular, ` RESTRICT ` and ` NO ACTION ` are not supported, and if you try to use those actions
253+ in your schema an error will be thrown when constructing `` SyncEngine `` .
254254
255255## Record conflicts
256256
257- > TLDR : Conflicts are handled automatically using a "last edit wins" strategy for each
257+ > TL;DR : Conflicts are handled automatically using a "last edit wins" strategy for each
258258> column of the record.
259259
260260Conflicts between record edits will inevitably happen, and it's just a fact of dealing with
@@ -269,7 +269,7 @@ the only strategy available and we feel serves the needs of the most number of p
269269
270270## Backwards compatible migrations
271271
272- > TLDR : Database migrations should be done carefully and with full backwards compatibility
272+ > TL;DR : Database migrations should be done carefully and with full backwards compatibility
273273> in mind in order to support multiple devices running with different schema versions.
274274
275275Migrations of a distributed schema come with even more complications than what is mentioned above.
@@ -286,9 +286,9 @@ has been added to the schema, it will populate the table with the cached records
286286
287287#### Adding columns
288288
289- > TLDR : When adding columns to a table that has already been deployed to user's devices, you will
290- either need to make the column nullable, or it can be " NOT NULL" but a default value must be
291- provided with an " ON CONFLICT REPLACE" clause.
289+ > TL;DR : When adding columns to a table that has already been deployed to user's devices, you will
290+ either need to make the column nullable, or it can be ` NOT NULL ` but a default value must be
291+ provided with an ` ON CONFLICT REPLACE ` clause.
292292
293293As an example, suppose the 1.0 of your app shipped a table for a reminders list:
294294
@@ -338,18 +338,18 @@ VALUES
338338(NULL , ' Personal' , NULL )
339339```
340340
341- This will generate a SQL error because the "position" column was declared as " NOT NULL" , and so this
341+ This will generate a SQL error because the "position" column was declared as ` NOT NULL ` , and so this
342342record will not properly synchronize to devices running a newer version of the app.
343343
344- The fix is to allow for inserting " NULL" values into " NOT NULL" columns by using the default of the
344+ The fix is to allow for inserting ` NULL ` values into ` NOT NULL ` columns by using the default of the
345345column. This can be done like so:
346346
347347``` sql
348348ALTER TABLE " remindersLists"
349349ADD COLUMN " position" INTEGER NOT NULL ON CONFLICT REPLACE DEFAULT 0
350350```
351351
352- > Important: The " ON CONFLICT REPLACE" clause must come directly after " NOT NULL" because it
352+ > Important: The ` ON CONFLICT REPLACE ` clause must come directly after ` NOT NULL ` because it
353353> modifies that constraint.
354354
355355Now when this query is executed:
@@ -361,7 +361,7 @@ VALUES
361361(NULL , ' Personal' , NULL )
362362```
363363
364- …it will use 0 for the " position" column.
364+ …it will use 0 for the ` position ` column.
365365
366366Sometimes it is not possible to specify a default for a newly added column. Suppose in version 1.2
367367of your app you add groups for reminders lists. This can be expressed as a new field on the
@@ -410,7 +410,7 @@ And your migration will need to add a nullable column to the table:
410410 REFERENCES "remindersListGroups"("id")
411411```
412412
413- It may be disappointing to have to weaken your domain modeling to accomodate synchronization, but
413+ It may be disappointing to have to weaken your domain modeling to accommodate synchronization, but
414414that is the unfortunate reality of a distributed schema. In order to allow multiple versions of your
415415schema to be run on devices so that each device can create new records and edit existing records
416416that all devices can see, you will need to make some compromises.
@@ -420,9 +420,9 @@ that all devices can see, you will need to make some compromises.
420420Certain kinds of migrations are simply not allowed when synchronizing your schema to multiple
421421devices. They are:
422422
423- * Removing columns
424- * Renaming columns
425- * Renaming tables
423+ * Removing columns
424+ * Renaming columns
425+ * Renaming tables
426426
427427## Sharing records with other iCloud users
428428
@@ -436,7 +436,7 @@ See <doc:CloudKitSharing> for more information.
436436
437437## Assets
438438
439- > TLDR : The library packages all BLOB columns in a table into ` CKAsset ` s and seamlessly decodes
439+ > TL;DR : The library packages all BLOB columns in a table into ` CKAsset ` s and seamlessly decodes
440440> ` CKAsset ` s back into your tables. We recommend putting large binary blobs of data in their own
441441> tables.
442442
@@ -495,7 +495,7 @@ to construct a SQL query for fetching the meta data associated with one of your
495495
496496For example, if you want to retrieve the ` CKRecord ` that is associated with a particular row in
497497one of your tables, say a reminder, then you can use `` SyncMetadata/lastKnownServerRecord `` to
498- retreive the ` CKRecord ` and then invoke a CloudKit database function to retreive all of the details:
498+ retrieve the ` CKRecord ` and then invoke a CloudKit database function to retrieve all of the details:
499499
500500``` swift
501501let lastKnownServerRecord = try database.read { db in
@@ -516,12 +516,12 @@ let ckRecord = try await container.privateCloudDatabase
516516> a shared record, which can be determined from [ SyncMetadata.share] ( < doc:SyncMetadata/share > ) ,
517517> then you must use ` sharedCloudDatabase ` to fetch the newest record.
518518
519- You are free to invoke any CloudKit functions you want with the ` CKRecord ` retreived from
519+ You are free to invoke any CloudKit functions you want with the ` CKRecord ` retrieved from
520520`` SyncMetadata `` . Any changes made directly with CloudKit will be automatically synced to your
521521SQLite database by the `` SyncEngine `` .
522522
523523It is also possible to fetch the ` CKShare ` associated with a record if it has been shared, which
524- will give you access to the most current list of paricipants and permissions for the shared record:
524+ will give you access to the most current list of participants and permissions for the shared record:
525525
526526``` swift
527527let share = try database.read { db in
@@ -586,14 +586,16 @@ return true if the write to your database originates from the sync engine. You c
586586trigger like so:
587587
588588``` swift
589- #sql ("""
589+ #sql (
590+ """
590591 CREATE TEMPORARY TRIGGER "…"
591- AFTER DELETE ON "…""
592+ AFTER DELETE ON "…"
592593 FOR EACH ROW WHEN NOT \( SyncEngine.isSynchronizingChanges () )
593594 BEGIN
594595 …
595596 END
596- """ )
597+ """
598+ )
597599```
598600
599601Or if you are using the trigger building tools from [ StructuredQueries] you can use it like so:
@@ -602,9 +604,8 @@ Or if you are using the trigger building tools from [StructuredQueries] you can
602604
603605``` swift
604606Model.createTemporaryTrigger (
605- " …" ,
606607 after : .insert { new in
607- …
608+ // ...
608609 } when : { _ in
609610 ! SyncEngine.isSynchronizingChanges ()
610611 }
0 commit comments