|
1 | 1 | #if canImport(CloudKit) |
2 | | - import CloudKit |
3 | | - |
4 | | - /// A table that tracks metadata related to synchronized data. |
5 | | - /// |
6 | | - /// Each row of this table represents a synchronized record across all tables synchronized with |
7 | | - /// CloudKit. This means that the sum of the count of rows across all synchronized tables in your |
8 | | - /// application is the number of rows this one single table holds. However, this table is held |
9 | | - /// in a database separate from your app's database. |
| 2 | +import CloudKit |
| 3 | + |
| 4 | +/// A table that tracks metadata related to synchronized data. |
| 5 | +/// |
| 6 | +/// Each row of this table represents a synchronized record across all tables synchronized with |
| 7 | +/// CloudKit. This means that the sum of the count of rows across all synchronized tables in your |
| 8 | +/// application is the number of rows this one single table holds. However, this table is held |
| 9 | +/// in a database separate from your app's database. |
| 10 | +/// |
| 11 | +/// |
| 12 | +@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) |
| 13 | +// @Table("\(String.sqliteDataCloudKitSchemaName)_metadata") |
| 14 | +public struct SyncMetadata: Hashable, Sendable { |
| 15 | + /// The unique identifier of the record synchronized. |
| 16 | + public var recordPrimaryKey: String |
| 17 | + |
| 18 | + /// The type of the record synchronized, _i.e._ its table name. |
| 19 | + public var recordType: String |
| 20 | + |
| 21 | + /// The name of the record synchronized. |
10 | 22 | /// |
| 23 | + /// This field encodes both the table name and primary key of the record synchronized in |
| 24 | + /// the format "primaryKey:tableName", for example: |
11 | 25 | /// |
12 | | - @available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) |
13 | | - // @Table("\(String.sqliteDataCloudKitSchemaName)_metadata") |
14 | | - public struct SyncMetadata: Hashable, Sendable { |
15 | | - /// The unique identifier of the record synchronized. |
16 | | - public var recordPrimaryKey: String |
17 | | - |
18 | | - /// The type of the record synchronized, _i.e._ its table name. |
19 | | - public var recordType: String |
20 | | - |
21 | | - /// The name of the record synchronized. |
22 | | - /// |
23 | | - /// This field encodes both the table name and primary key of the record synchronized in |
24 | | - /// the format "primaryKey:tableName", for example: |
25 | | - /// |
26 | | - /// ```swift |
27 | | - /// "8c4d1e4e-49b2-4f60-b6df-3c23881b87c6:reminders" |
28 | | - /// ``` |
29 | | - // @Column(generated: .virtual) |
30 | | - public let recordName: String |
31 | | - |
32 | | - /// The unique identifier of this record's parent, if any. |
33 | | - public var parentRecordPrimaryKey: String? |
34 | | - |
35 | | - /// The type of this record's parent, _i.e._ its table name, if any. |
36 | | - public var parentRecordType: String? |
37 | | - |
38 | | - /// The name of this record's parent, if any. |
39 | | - /// |
40 | | - /// This field encodes both the table name and primary key of the parent record in the format |
41 | | - /// "primaryKey:tableName", for example: |
42 | | - /// |
43 | | - /// ```swift |
44 | | - /// "d35e1f81-46e4-45d1-904b-2b7df1661e3e:remindersLists" |
45 | | - /// ``` |
46 | | - // @Column(generated: .virtual) |
47 | | - public let parentRecordName: String? |
48 | | - |
49 | | - /// The last known `CKRecord` received from the server. |
50 | | - /// |
51 | | - /// This record holds only the fields that are archived when using `encodeSystemFields(with:)`. |
52 | | - // @Column(as: CKRecord?.SystemFieldsRepresentation.self) |
53 | | - public var lastKnownServerRecord: CKRecord? |
| 26 | + /// ```swift |
| 27 | + /// "8c4d1e4e-49b2-4f60-b6df-3c23881b87c6:reminders" |
| 28 | + /// ``` |
| 29 | + // @Column(generated: .virtual) |
| 30 | + public let recordName: String |
54 | 31 |
|
55 | | - /// The last known `CKRecord` received from the server with all fields archived. |
56 | | - // @Column(as: CKRecord?.SystemFieldsRepresentation.self) |
57 | | - package var _lastKnownServerRecordAllFields: CKRecord? |
58 | | - |
59 | | - /// The `CKShare` associated with this record, if it is shared. |
60 | | - // @Column(as: CKShare?.SystemFieldsRepresentation.self) |
61 | | - public var share: CKShare? |
62 | | - |
63 | | - // @Column(generated: .virtual) |
64 | | - public let isShared: Bool |
65 | | - |
66 | | - /// The date the user last modified the record. |
67 | | - public var userModificationDate: Date |
68 | | - |
69 | | - package init( |
70 | | - recordPrimaryKey: String, |
71 | | - recordType: String, |
72 | | - parentRecordPrimaryKey: String? = nil, |
73 | | - parentRecordType: String? = nil, |
74 | | - lastKnownServerRecord: CKRecord? = nil, |
75 | | - _lastKnownServerRecordAllFields: CKRecord? = nil, |
76 | | - share: CKShare? = nil, |
77 | | - userModificationDate: Date |
78 | | - ) { |
79 | | - self.recordPrimaryKey = recordPrimaryKey |
80 | | - self.recordType = recordType |
81 | | - self.recordName = "\(recordPrimaryKey):\(recordType)" |
82 | | - self.parentRecordPrimaryKey = parentRecordPrimaryKey |
83 | | - self.parentRecordType = parentRecordType |
84 | | - if let parentRecordPrimaryKey, let parentRecordType { |
85 | | - self.parentRecordName = "\(parentRecordPrimaryKey):\(parentRecordType)" |
86 | | - } else { |
87 | | - self.parentRecordName = nil |
88 | | - } |
89 | | - self.lastKnownServerRecord = lastKnownServerRecord |
90 | | - self._lastKnownServerRecordAllFields = _lastKnownServerRecordAllFields |
91 | | - self.share = share |
92 | | - self.isShared = share != nil |
93 | | - self.userModificationDate = userModificationDate |
94 | | - } |
| 32 | + /// The unique identifier of this record's parent, if any. |
| 33 | + public var parentRecordPrimaryKey: String? |
95 | 34 |
|
96 | | - // @Selection @Table |
97 | | - struct AncestorMetadata { |
98 | | - let recordName: String |
99 | | - let parentRecordName: String? |
100 | | - // @Column(as: CKRecord?.SystemFieldsRepresentation.self) |
101 | | - let lastKnownServerRecord: CKRecord? |
102 | | - } |
103 | | - } |
| 35 | + /// The type of this record's parent, _i.e._ its table name, if any. |
| 36 | + public var parentRecordType: String? |
| 37 | + |
| 38 | + /// The name of this record's parent, if any. |
| 39 | + /// |
| 40 | + /// This field encodes both the table name and primary key of the parent record in the format |
| 41 | + /// "primaryKey:tableName", for example: |
| 42 | + /// |
| 43 | + /// ```swift |
| 44 | + /// "d35e1f81-46e4-45d1-904b-2b7df1661e3e:remindersLists" |
| 45 | + /// ``` |
| 46 | + // @Column(generated: .virtual) |
| 47 | + public let parentRecordName: String? |
104 | 48 |
|
105 | | - @available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) |
106 | | - extension SyncMetadata { |
107 | | - package static func find<T: PrimaryKeyedTable>( |
108 | | - _ primaryKey: T.PrimaryKey.QueryOutput, |
109 | | - table _: T.Type, |
110 | | - ) |
111 | | - -> Where<Self> |
112 | | - where T.PrimaryKey: IdentifierStringConvertible { |
113 | | - T.metadata(for: primaryKey) |
| 49 | + /// The last known `CKRecord` received from the server. |
| 50 | + /// |
| 51 | + /// This record holds only the fields that are archived when using `encodeSystemFields(with:)`. |
| 52 | + // @Column(as: CKRecord?.SystemFieldsRepresentation.self) |
| 53 | + public var lastKnownServerRecord: CKRecord? |
| 54 | + |
| 55 | + /// The last known `CKRecord` received from the server with all fields archived. |
| 56 | + // @Column(as: CKRecord?.SystemFieldsRepresentation.self) |
| 57 | + package var _lastKnownServerRecordAllFields: CKRecord? |
| 58 | + |
| 59 | + /// The `CKShare` associated with this record, if it is shared. |
| 60 | + // @Column(as: CKShare?.SystemFieldsRepresentation.self) |
| 61 | + public var share: CKShare? |
| 62 | + |
| 63 | + // @Column(generated: .virtual) |
| 64 | + public let isShared: Bool |
| 65 | + |
| 66 | + /// The date the user last modified the record. |
| 67 | + public var userModificationDate: Date |
| 68 | + |
| 69 | + package init( |
| 70 | + recordPrimaryKey: String, |
| 71 | + recordType: String, |
| 72 | + parentRecordPrimaryKey: String? = nil, |
| 73 | + parentRecordType: String? = nil, |
| 74 | + lastKnownServerRecord: CKRecord? = nil, |
| 75 | + _lastKnownServerRecordAllFields: CKRecord? = nil, |
| 76 | + share: CKShare? = nil, |
| 77 | + userModificationDate: Date |
| 78 | + ) { |
| 79 | + self.recordPrimaryKey = recordPrimaryKey |
| 80 | + self.recordType = recordType |
| 81 | + self.recordName = "\(recordPrimaryKey):\(recordType)" |
| 82 | + self.parentRecordPrimaryKey = parentRecordPrimaryKey |
| 83 | + self.parentRecordType = parentRecordType |
| 84 | + if let parentRecordPrimaryKey, let parentRecordType { |
| 85 | + self.parentRecordName = "\(parentRecordPrimaryKey):\(parentRecordType)" |
| 86 | + } else { |
| 87 | + self.parentRecordName = nil |
114 | 88 | } |
| 89 | + self.lastKnownServerRecord = lastKnownServerRecord |
| 90 | + self._lastKnownServerRecordAllFields = _lastKnownServerRecordAllFields |
| 91 | + self.share = share |
| 92 | + self.isShared = share != nil |
| 93 | + self.userModificationDate = userModificationDate |
115 | 94 | } |
116 | 95 |
|
117 | | - @available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) |
118 | | - extension PrimaryKeyedTable where PrimaryKey: IdentifierStringConvertible { |
119 | | - public static func metadata(for primaryKey: PrimaryKey.QueryOutput) -> Where<SyncMetadata> { |
120 | | - SyncMetadata.where { |
121 | | - SQLQueryExpression( |
122 | | - """ |
123 | | - \($0.recordPrimaryKey) = \(PrimaryKey(queryOutput: primaryKey)) \ |
124 | | - AND \($0.recordType) = \(bind: tableName) |
125 | | - """ |
126 | | - ) |
127 | | - } |
| 96 | + // @Selection @Table |
| 97 | + struct AncestorMetadata { |
| 98 | + let recordName: String |
| 99 | + let parentRecordName: String? |
| 100 | + // @Column(as: CKRecord?.SystemFieldsRepresentation.self) |
| 101 | + let lastKnownServerRecord: CKRecord? |
| 102 | + } |
| 103 | +} |
| 104 | + |
| 105 | +@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) |
| 106 | +extension SyncMetadata { |
| 107 | + package static func find<T: PrimaryKeyedTable>( |
| 108 | + _ primaryKey: T.PrimaryKey.QueryOutput, |
| 109 | + table _: T.Type, |
| 110 | + ) -> Where<Self> { |
| 111 | + Self.where { |
| 112 | + SQLQueryExpression( |
| 113 | + """ |
| 114 | + \($0.recordPrimaryKey) = \(T.PrimaryKey(queryOutput: primaryKey)) \ |
| 115 | + AND \($0.recordType) = \(bind: T.tableName) |
| 116 | + """ |
| 117 | + ) |
128 | 118 | } |
129 | 119 | } |
| 120 | +} |
130 | 121 |
|
131 | | - @available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) |
132 | | - extension PrimaryKeyedTable where PrimaryKey.QueryOutput: IdentifierStringConvertible { |
133 | | - /// Constructs a ``SyncMetadata/RecordName-swift.struct`` for a primary keyed table give an ID. |
134 | | - /// |
135 | | - /// - Parameter id: The ID of the record. |
136 | | - package static func recordName(for id: PrimaryKey.QueryOutput) -> String { |
137 | | - "\(id.rawIdentifier):\(tableName)" |
138 | | - } |
| 122 | +@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) |
| 123 | +extension PrimaryKeyedTable where PrimaryKey.QueryOutput: IdentifierStringConvertible { |
| 124 | + /// Constructs a ``SyncMetadata/RecordName-swift.struct`` for a primary keyed table give an ID. |
| 125 | + /// |
| 126 | + /// - Parameter id: The ID of the record. |
| 127 | + package static func recordName(for id: PrimaryKey.QueryOutput) -> String { |
| 128 | + "\(id.rawIdentifier):\(tableName)" |
| 129 | + } |
139 | 130 |
|
140 | | - var recordName: String { |
141 | | - Self.recordName(for: self[keyPath: Self.columns.primaryKey.keyPath]) |
142 | | - } |
| 131 | + var recordName: String { |
| 132 | + Self.recordName(for: self[keyPath: Self.columns.primaryKey.keyPath]) |
143 | 133 | } |
| 134 | +} |
144 | 135 |
|
145 | | - @available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) |
146 | | - extension PrimaryKeyedTableDefinition where PrimaryKey.QueryOutput: IdentifierStringConvertible { |
147 | | - public var recordName: some QueryExpression<String> { |
148 | | - _recordName |
149 | | - } |
| 136 | +@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) |
| 137 | +extension PrimaryKeyedTableDefinition where PrimaryKey.QueryOutput: IdentifierStringConvertible { |
| 138 | + public var recordName: some QueryExpression<String> { |
| 139 | + _recordName |
150 | 140 | } |
| 141 | +} |
151 | 142 |
|
152 | | - @available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) |
153 | | - extension PrimaryKeyedTableDefinition { |
154 | | - var _recordName: some QueryExpression<String> { |
155 | | - SQLQueryExpression("\(primaryKey) || ':' || \(quote: QueryValue.tableName, delimiter: .text)") |
156 | | - } |
| 143 | +@available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) |
| 144 | +extension PrimaryKeyedTableDefinition { |
| 145 | + var _recordName: some QueryExpression<String> { |
| 146 | + SQLQueryExpression("\(primaryKey) || ':' || \(quote: QueryValue.tableName, delimiter: .text)") |
157 | 147 | } |
| 148 | +} |
158 | 149 | #endif |
0 commit comments