Skip to content

Commit 9d65a9d

Browse files
committed
Add possibility to update multiple fields within one partial update request
1 parent 8e4310b commit 9d65a9d

File tree

4 files changed

+603
-83
lines changed

4 files changed

+603
-83
lines changed
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
//
2+
// AltPartialUpdate.swift
3+
//
4+
//
5+
// Created by Vladislav Fitc on 31/07/2020.
6+
//
7+
8+
import Foundation
9+
10+
public enum AltPartialUpdate {
11+
case value([String: JSON])
12+
case operation(Attribute, OperationWrapper)
13+
}
14+
15+
extension AltPartialUpdate: Codable {
16+
17+
public init(from decoder: Decoder) throws {
18+
self = .value(["": ""])
19+
}
20+
21+
public func encode(to encoder: Encoder) throws {
22+
switch self {
23+
case .value(let value):
24+
try value.encode(to: encoder)
25+
26+
case .operation(let attribute, let operation):
27+
var container = encoder.container(keyedBy: DynamicKey.self)
28+
let key = DynamicKey(stringValue: attribute.rawValue)
29+
try container.encode(operation, forKey: key)
30+
}
31+
}
32+
33+
public struct OperationWrapper: Codable {
34+
let value: JSON
35+
let operation: Operation
36+
37+
enum CodingKeys: String, CodingKey {
38+
case value
39+
case operation = "_operation"
40+
}
41+
}
42+
43+
}
44+
45+
extension AltPartialUpdate {
46+
47+
/// Partially update an object field.
48+
/// - Parameter attribute: Attribute name to update
49+
/// - Parameter value: Updated value
50+
static func update(attribute: Attribute, value: JSON) -> Self {
51+
return .value([attribute.rawValue: value])
52+
}
53+
54+
}
55+
56+
public extension AltPartialUpdate {
57+
58+
/// Increment a numeric attribute
59+
/// - Parameter attribute: Attribute name to update
60+
/// - Parameter value: Value to increment by
61+
static func increment(attribute: Attribute, value: Int) -> Self {
62+
.operation(attribute: attribute, operation: .increment, value: .init(value))
63+
}
64+
65+
/// Increment a numeric attribute
66+
/// - Parameter attribute: Attribute name to update
67+
/// - Parameter value: Value to increment by
68+
static func increment(attribute: Attribute, value: Float) -> Self {
69+
.operation(attribute: attribute, operation: .increment, value: .init(value))
70+
}
71+
72+
/// Increment a numeric attribute
73+
/// - Parameter attribute: Attribute name to update
74+
/// - Parameter value: Value to increment by
75+
static func increment(attribute: Attribute, value: Double) -> Self {
76+
.operation(attribute: attribute, operation: .increment, value: .init(value))
77+
}
78+
79+
}
80+
81+
public extension AltPartialUpdate {
82+
83+
/**
84+
Increment a numeric integer attribute only if the provided value matches the current value,
85+
and otherwise ignore the whole object update.
86+
87+
For example, if you pass an IncrementFrom value of 2 for the version attribute,
88+
but the current value of the attribute is 1, the engine ignores the update.
89+
If the object doesn’t exist, the engine only creates it if you pass an IncrementFrom value of 0.
90+
91+
- Parameter attribute: Attribute name to update
92+
- Parameter value: Current value to increment
93+
*/
94+
static func incrementFrom(attribute: Attribute, value: Int) -> Self {
95+
.operation(attribute: attribute, operation: .incrementFrom, value: .init(value))
96+
}
97+
98+
/**
99+
Increment a numeric integer attribute only if the provided value is greater than the current value,
100+
and otherwise ignore the whole object update.
101+
102+
For example, if you pass an IncrementSet value of 2 for the version attribute,
103+
and the current value of the attribute is 1, the engine updates the object.
104+
If the object doesn’t exist yet, the engine only creates it if you pass an IncrementSet value that’s greater than 0.
105+
106+
- Parameter attribute: Attribute name to update
107+
- Parameter value: Value to set
108+
*/
109+
static func incrementSet(attribute: Attribute, value: Int) -> Self {
110+
.operation(attribute: attribute, operation: .incrementSet, value: .init(value))
111+
}
112+
113+
}
114+
115+
116+
public extension AltPartialUpdate {
117+
118+
/// Decrement a numeric attribute
119+
/// - Parameter attribute: Attribute name to update
120+
/// - Parameter value: Value to decrement by
121+
static func decrement(attribute: Attribute, value: Int) -> Self {
122+
.operation(attribute: attribute, operation: .decrement, value: .init(value))
123+
}
124+
125+
/// Decrement a numeric attribute
126+
/// - Parameter attribute: Attribute name to update
127+
/// - Parameter value: Value to decrement by
128+
static func decrement(attribute: Attribute, value: Float) -> Self {
129+
.operation(attribute: attribute, operation: .decrement, value: .init(value))
130+
}
131+
132+
/// Decrement a numeric attribute
133+
/// - Parameter attribute: Attribute name to update
134+
/// - Parameter value: Value to decrement by
135+
static func decrement(attribute: Attribute, value: Double) -> Self {
136+
.operation(attribute: attribute, operation: .decrement, value: .init(value))
137+
}
138+
139+
}
140+
141+
public extension AltPartialUpdate {
142+
143+
/// Append a string element to an array attribute
144+
/// - Parameter attribute: Attribute name of an array to update
145+
/// - Parameter value: Value to append
146+
/// - Parameter unique: If true, append an element only if it’s not already present
147+
static func add(attribute: Attribute, value: String, unique: Bool) -> Self {
148+
.operation(attribute: attribute, operation: unique ? .addUnique : .add, value: .init(value))
149+
}
150+
151+
/// Append a number element to an array attribute
152+
/// - Parameter attribute: Attribute name of an array to update
153+
/// - Parameter value: Value to append
154+
/// - Parameter unique: If true, append an element only if it’s not already present
155+
static func add(attribute: Attribute, value: Int, unique: Bool) -> Self {
156+
.operation(attribute: attribute, operation: unique ? .addUnique : .add, value: .init(value))
157+
}
158+
159+
/// Append a number element to an array attribute
160+
/// - Parameter attribute: Attribute name of an array to update
161+
/// - Parameter value: Value to append
162+
/// - Parameter unique: If true, append an element only if it’s not already present
163+
static func add(attribute: Attribute, value: Float, unique: Bool) -> Self {
164+
.operation(attribute: attribute, operation: unique ? .addUnique : .add, value: .init(value))
165+
}
166+
167+
/// Append a number element to an array attribute
168+
/// - Parameter attribute: Attribute name of an array to update
169+
/// - Parameter value: Value to append
170+
/// - Parameter unique: If true, append an element only if it’s not already present
171+
static func add(attribute: Attribute, value: Double, unique: Bool) -> Self {
172+
.operation(attribute: attribute, operation: unique ? .addUnique : .add, value: .init(value))
173+
}
174+
175+
}
176+
177+
public extension AltPartialUpdate {
178+
179+
/// Remove all matching string elements from an array attribute
180+
/// - Parameter attribute: Attribute name of an array to update
181+
/// - Parameter value: Value to remove
182+
static func remove(attribute: Attribute, value: String) -> Self {
183+
.operation(attribute: attribute, operation: .remove, value: .init(value))
184+
}
185+
186+
/// Remove all matching number elements from an array attribute
187+
/// - Parameter attribute: Attribute name of an array to update
188+
/// - Parameter value: Value to remove
189+
static func remove(attribute: Attribute, value: Int) -> Self {
190+
.operation(attribute: attribute, operation: .remove, value: .init(value))
191+
}
192+
193+
/// Remove all matching number elements from an array attribute
194+
/// - Parameter attribute: Attribute name of an array to update
195+
/// - Parameter value: Value to remove
196+
static func remove(attribute: Attribute, value: Float) -> Self {
197+
.operation(attribute: attribute, operation: .remove, value: .init(value))
198+
}
199+
200+
/// Remove all matching number elements from an array attribute
201+
/// - Parameter attribute: Attribute name of an array to update
202+
/// - Parameter value: Value to remove
203+
static func remove(attribute: Attribute, value: Double) -> Self {
204+
.operation(attribute: attribute, operation: .remove, value: .init(value))
205+
}
206+
207+
}
208+
209+
extension AltPartialUpdate {
210+
211+
static func operation(attribute: Attribute, operation: Operation, value: JSON) -> Self {
212+
return .operation(attribute, .init(value: value, operation: operation))
213+
}
214+
215+
}
216+
217+
extension AltPartialUpdate {
218+
219+
enum Operation: String, Codable {
220+
/// Increment a numeric attribute
221+
case increment = "Increment"
222+
223+
/**
224+
Increment a numeric integer attribute only if the provided value matches the current value,
225+
and otherwise ignore the whole object update.
226+
227+
For example, if you pass an IncrementFrom value of 2 for the version attribute,
228+
but the current value of the attribute is 1, the engine ignores the update.
229+
If the object doesn’t exist, the engine only creates it if you pass an IncrementFrom value of 0.
230+
*/
231+
case incrementFrom = "IncrementFrom"
232+
233+
/**
234+
Increment a numeric integer attribute only if the provided value is greater than the current value,
235+
and otherwise ignore the whole object update.
236+
237+
For example, if you pass an IncrementSet value of 2 for the version attribute,
238+
and the current value of the attribute is 1, the engine updates the object.
239+
If the object doesn’t exist yet, the engine only creates it if you pass an IncrementSet value that’s greater than 0.
240+
*/
241+
case incrementSet = "IncrementSet"
242+
243+
/// Decrement a numeric attribute
244+
case decrement = "Decrement"
245+
246+
/// Append a number or string element to an array attribute
247+
case add = "Add"
248+
249+
/// Remove all matching number or string elements from an array attribute
250+
case remove = "Remove"
251+
252+
/// Add a number or string element to an array attribute only if it’s not already present
253+
case addUnique = "AddUnique"
254+
}
255+
256+
}

0 commit comments

Comments
 (0)