-
Notifications
You must be signed in to change notification settings - Fork 65
/
Copy pathChangeStreamEvent.swift
152 lines (138 loc) · 7.05 KB
/
ChangeStreamEvent.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/// An `UpdateDescription` containing fields that will be present in the change stream document for
/// operations of type `update`.
public struct UpdateDescription: Codable {
/**
* A document containing key:value pairs of names of the fields that were changed (excluding the fields reported
* via `truncatedArrays`), and the new value for those fields.
*
* Despite array fields reported via `truncatedArrays` being excluded from this field, changes to fields of the
* elements of the array values may be reported via this field.
*
* Example:
* original field:
* "arrayField": ["foo", {"a": "bar"}, 1, 2, 3]
* updated field:
* "arrayField": ["foo", {"a": "bar", "b": 3}]
* a potential corresponding UpdateDescription:
* UpdateDescription(
* updatedFields: {
* "arrayField.1.b": 3
* },
* removedFields: [],
* truncatedArrays: [
* TruncatedArrayDescription(
* field: "arrayField",
* newSize: 2
* )
* ]
* )
*
* Modifications to array elements are expressed via dot notation.
* Example: an `update` which sets the element with index 0 in the array field named arrayField to 7 is reported as
* "updatedFields": {"arrayField.0": 7}
*
* - SeeAlso: https://docs.mongodb.com/manual/core/document/#document-dot-notation
*/
public let updatedFields: BSONDocument
/// An array of field names that were removed from the document.
public let removedFields: [String]
/// Describes an array that was truncated via an update operation.
public struct TruncatedArrayDescription: Codable {
/// The name of the array field which was truncated.
public let field: String
/// The new size of the array.
public let newSize: Int
}
/**
* Truncations of arrays may be reported either via this field or via the ‘updatedFields’ field. In the latter
* case, the entire array is considered to be replaced. The method used to report a truncation is a server
* implementation detail.
*
* Example: an `update` which shrinks the array `arrayField.0.nestedArrayField` from size 8 to 5 may be reported
* via this field as [TruncatedArrayDescription(field: "arrayField.0.nestedArrayField", newSize: 5)].
*
* This property will only ever be present on MongoDB server versions >= 5.0.
*/
public let truncatedArrays: [TruncatedArrayDescription]?
}
/// An enum representing the type of operation for this change event.
public enum OperationType: String, Codable {
/// Specifies an operation of type `insert`.
/// - SeeAlso: https://docs.mongodb.com/manual/reference/change-events/index.html#insert-event
case insert
/// Specifies an operation of type `update`.
/// - SeeAlso: https://docs.mongodb.com/manual/reference/change-events/index.html#update-event
case update
/// Specifies an operation of type `replace`.
/// - SeeAlso: https://docs.mongodb.com/manual/reference/change-events/index.html#replace-event
case replace
/// Specifies an operation of type `delete`.
/// - SeeAlso: https://docs.mongodb.com/manual/reference/change-events/index.html#delete-event
case delete
/// Specifies an operation of type `invalidate`.
/// - SeeAlso: https://docs.mongodb.com/manual/reference/change-events/index.html#change-event-invalidate
case invalidate
/// Specifies an operation of type `drop`.
/// - SeeAlso: https://docs.mongodb.com/manual/reference/change-events/index.html#drop-event
case drop
/// Specifies an operation of type `dropDatabase`.
/// - SeeAlso: https://docs.mongodb.com/manual/reference/change-events/index.html#dropdatabase-event
case dropDatabase
/// Specifies an operation of type `rename`.
/// - SeeAlso: https://docs.mongodb.com/manual/reference/change-events/index.html#rename-event
case rename
}
/// The response document type from a `ChangeStream`.
public struct ChangeStreamEvent<T: Codable>: Codable {
/// Describes the type of operation for this change.
public let operationType: OperationType
/// An opaque token for use when resuming an interrupted change stream.
/// - SeeAlso: https://docs.mongodb.com/manual/changeStreams/#resume-a-change-stream
public let _id: ResumeToken
// TODO: SWIFT-981: Make this field optional.
/// A document containing the database and collection names in which this change happened.
public let ns: MongoNamespace
/**
* Only present for options of type `insert`, `update`, `replace` and `delete`. For unsharded collections this
* contains a single field, _id, with the value of the _id of the document updated. For sharded collections, this
* will contain all the components of the shard key in order, followed by the _id if the _id isn’t part of the
* shard key.
*/
public let documentKey: BSONDocument?
/// An `UpdateDescription` containing updated and removed fields in this operation. Only present for operations of
/// type`update`.
public let updateDescription: UpdateDescription?
/**
* Always present for operations of type `insert` and `replace`. Also present for operations of type `update` if
* the user has specified `.updateLookup` for the `fullDocument` option in the `ChangeStreamOptions` used to create
* the change stream that emitted this document.
*
* For operations of type `insert’ and `replace’, this key will contain the document being inserted, or the new
* version of the document that is replacing the existing document, respectively.
*
* For operations of type `update’, this key will contain a copy of the full version of the document from some
* point after the update occurred. If the document was deleted since the updated happened, it will be nil.
*/
public let fullDocument: T?
private enum CodingKeys: String, CodingKey {
case operationType, _id, ns, documentKey, updateDescription, fullDocument
}
// Custom decode method to work around the fact that `invalidate` events do not have an `ns` field in the raw
// document. TODO SWIFT-981: Remove this.
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.operationType = try container.decode(OperationType.self, forKey: .operationType)
self._id = try container.decode(ResumeToken.self, forKey: ._id)
do {
self.ns = try container.decode(MongoNamespace.self, forKey: .ns)
} catch {
guard let ns = decoder.userInfo[changeStreamNamespaceKey] as? MongoNamespace else {
throw error
}
self.ns = ns
}
self.documentKey = try container.decodeIfPresent(BSONDocument.self, forKey: .documentKey)
self.updateDescription = try container.decodeIfPresent(UpdateDescription.self, forKey: .updateDescription)
self.fullDocument = try container.decodeIfPresent(T.self, forKey: .fullDocument)
}
}