|
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. |
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. |
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? |
| 2 | + import CloudKit |
34 | 3 |
|
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. |
| 4 | + /// A table that tracks metadata related to synchronized data. |
39 | 5 | /// |
40 | | - /// This field encodes both the table name and primary key of the parent record in the format |
41 | | - /// "primaryKey:tableName", for example: |
| 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. |
42 | 10 | /// |
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 | 11 | /// |
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 |
88 | | - } |
89 | | - self.lastKnownServerRecord = lastKnownServerRecord |
90 | | - self._lastKnownServerRecordAllFields = _lastKnownServerRecordAllFields |
91 | | - self.share = share |
92 | | - self.isShared = share != nil |
93 | | - self.userModificationDate = userModificationDate |
94 | | - } |
| 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? |
95 | 54 |
|
96 | | - // @Selection @Table |
97 | | - struct AncestorMetadata { |
98 | | - let recordName: String |
99 | | - let parentRecordName: String? |
| 55 | + /// The last known `CKRecord` received from the server with all fields archived. |
100 | 56 | // @Column(as: CKRecord?.SystemFieldsRepresentation.self) |
101 | | - let lastKnownServerRecord: CKRecord? |
| 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 | + } |
| 95 | + |
| 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 | + } |
102 | 103 | } |
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 | | - ) |
| 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 | + ) |
| 111 | + -> Where<Self> |
| 112 | + where T.PrimaryKey: IdentifierStringConvertible { |
| 113 | + T.metadata(for: primaryKey) |
118 | 114 | } |
119 | 115 | } |
120 | | -} |
121 | 116 |
|
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)" |
| 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 | + } |
| 128 | + } |
129 | 129 | } |
130 | 130 |
|
131 | | - var recordName: String { |
132 | | - Self.recordName(for: self[keyPath: Self.columns.primaryKey.keyPath]) |
| 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 | + } |
| 139 | + |
| 140 | + var recordName: String { |
| 141 | + Self.recordName(for: self[keyPath: Self.columns.primaryKey.keyPath]) |
| 142 | + } |
133 | 143 | } |
134 | | -} |
135 | 144 |
|
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 |
| 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 | + } |
140 | 150 | } |
141 | | -} |
142 | 151 |
|
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)") |
| 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 | + } |
147 | 157 | } |
148 | | -} |
149 | 158 | #endif |
0 commit comments