Skip to content

Commit 8e3c5b0

Browse files
Merge pull request #652 from algolia/feat/partial-update-improvement
Patch 7.0.1
2 parents 8e4310b + 6816469 commit 8e3c5b0

File tree

11 files changed

+397
-114
lines changed

11 files changed

+397
-114
lines changed

Sources/AlgoliaSearchClient/Models/Search/Indexing/PartialUpdate.swift

Lines changed: 61 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,28 @@
88
import Foundation
99

1010
public struct PartialUpdate: Equatable {
11+
12+
typealias Storage = [Attribute: Action]
1113

12-
let attribute: Attribute
13-
let content: PartialUpdate.Content
14+
let storage: Storage
1415

1516
}
1617

18+
extension PartialUpdate: ExpressibleByDictionaryLiteral {
19+
20+
public init(dictionaryLiteral elements: (Attribute, Action)...) {
21+
self.init(storage: .init(uniqueKeysWithValues: elements))
22+
}
23+
24+
}
25+
1726
public extension PartialUpdate {
1827

1928
/// Partially update an object field.
2029
/// - Parameter attribute: Attribute name to update
2130
/// - Parameter value: Updated value
2231
static func update(attribute: Attribute, value: JSON) -> Self {
23-
.init(attribute: attribute, content: .init(value: value, operation: nil))
32+
.init(storage: [attribute: .set(value)])
2433
}
2534

2635
}
@@ -180,105 +189,74 @@ public extension PartialUpdate {
180189

181190
extension PartialUpdate {
182191

183-
static func operation(attribute: Attribute, operation: PartialUpdate.Operation, value: JSON) -> Self {
184-
.init(attribute: attribute, content: .init(value: value, operation: operation))
192+
static func operation(attribute: Attribute, operation: Operation.Kind, value: JSON) -> Self {
193+
return .init(storage: [attribute: .init(operation: operation, value: value)])
185194
}
186195

187196
}
188197

189198
extension PartialUpdate: Codable {
190199

191200
public init(from decoder: Decoder) throws {
192-
let container = try decoder.container(keyedBy: DynamicKey.self)
193-
guard let rawAttribute = container.allKeys.first else { throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "No attribute found")) }
194-
self.attribute = Attribute(rawValue: rawAttribute.stringValue)
195-
self.content = try container.decode(PartialUpdate.Content.self, forKey: rawAttribute)
201+
let rawStorage = try [String: Action](from: decoder)
202+
storage = rawStorage.mapKeys(Attribute.init)
196203
}
197204

198205
public func encode(to encoder: Encoder) throws {
199-
var container = encoder.container(keyedBy: DynamicKey.self)
200-
let key = DynamicKey(stringValue: attribute.rawValue)
201-
try container.encode(content, forKey: key)
206+
try storage.mapKeys(\.rawValue).encode(to: encoder)
202207
}
203208

204209
}
205210

206211
extension PartialUpdate {
207-
208-
enum Operation: String, Codable {
209-
/// Increment a numeric attribute
210-
case increment = "Increment"
211-
212-
/**
213-
Increment a numeric integer attribute only if the provided value matches the current value,
214-
and otherwise ignore the whole object update.
215-
216-
For example, if you pass an IncrementFrom value of 2 for the version attribute,
217-
but the current value of the attribute is 1, the engine ignores the update.
218-
If the object doesn’t exist, the engine only creates it if you pass an IncrementFrom value of 0.
219-
*/
220-
case incrementFrom = "IncrementFrom"
221-
222-
/**
223-
Increment a numeric integer attribute only if the provided value is greater than the current value,
224-
and otherwise ignore the whole object update.
225-
226-
For example, if you pass an IncrementSet value of 2 for the version attribute,
227-
and the current value of the attribute is 1, the engine updates the object.
228-
If the object doesn’t exist yet, the engine only creates it if you pass an IncrementSet value that’s greater than 0.
229-
*/
230-
case incrementSet = "IncrementSet"
231-
232-
/// Decrement a numeric attribute
233-
case decrement = "Decrement"
234-
235-
/// Append a number or string element to an array attribute
236-
case add = "Add"
237-
238-
/// Remove all matching number or string elements from an array attribute
239-
case remove = "Remove"
212+
213+
struct Operation: Codable, Equatable {
240214

241-
/// Add a number or string element to an array attribute only if it’s not already present
242-
case addUnique = "AddUnique"
243-
}
244-
245-
}
246-
247-
extension PartialUpdate {
248-
249-
struct Content: Equatable {
215+
let kind: Kind
250216
let value: JSON
251-
let operation: Operation?
252-
}
253-
254-
}
255-
256-
extension PartialUpdate.Content: Codable {
257-
258-
enum CodingKeys: String, CodingKey {
259-
case value
260-
case operation = "_operation"
261-
}
262-
263-
public init(from decoder: Decoder) throws {
264-
guard let container = try? decoder.container(keyedBy: CodingKeys.self), container.contains(.operation) else {
265-
self.operation = nil
266-
self.value = try JSON(from: decoder)
267-
return
217+
218+
enum CodingKeys: String, CodingKey {
219+
case value
220+
case kind = "_operation"
268221
}
269-
self.operation = try container.decode(forKey: .operation)
270-
self.value = try container.decode(forKey: .value)
271-
}
272-
273-
public func encode(to encoder: Encoder) throws {
274-
if let operation = operation {
275-
var container = encoder.container(keyedBy: CodingKeys.self)
276-
try container.encode(operation, forKey: .operation)
277-
try container.encode(value, forKey: .value)
278-
} else {
279-
try value.encode(to: encoder)
222+
223+
enum Kind: String, Codable {
224+
/// Increment a numeric attribute
225+
case increment = "Increment"
226+
227+
/**
228+
Increment a numeric integer attribute only if the provided value matches the current value,
229+
and otherwise ignore the whole object update.
230+
231+
For example, if you pass an IncrementFrom value of 2 for the version attribute,
232+
but the current value of the attribute is 1, the engine ignores the update.
233+
If the object doesn’t exist, the engine only creates it if you pass an IncrementFrom value of 0.
234+
*/
235+
case incrementFrom = "IncrementFrom"
236+
237+
/**
238+
Increment a numeric integer attribute only if the provided value is greater than the current value,
239+
and otherwise ignore the whole object update.
240+
241+
For example, if you pass an IncrementSet value of 2 for the version attribute,
242+
and the current value of the attribute is 1, the engine updates the object.
243+
If the object doesn’t exist yet, the engine only creates it if you pass an IncrementSet value that’s greater than 0.
244+
*/
245+
case incrementSet = "IncrementSet"
246+
247+
/// Decrement a numeric attribute
248+
case decrement = "Decrement"
249+
250+
/// Append a number or string element to an array attribute
251+
case add = "Add"
252+
253+
/// Remove all matching number or string elements from an array attribute
254+
case remove = "Remove"
255+
256+
/// Add a number or string element to an array attribute only if it’s not already present
257+
case addUnique = "AddUnique"
280258
}
281-
259+
282260
}
283261

284262
}

0 commit comments

Comments
 (0)