Skip to content

Commit 1a539f1

Browse files
authored
Merge pull request #284 from zapcannon87/developer
fix(storage): batch save can do with empty requests
2 parents c5a9ca9 + 3178112 commit 1a539f1

File tree

2 files changed

+90
-103
lines changed

2 files changed

+90
-103
lines changed

LeanCloudTests/LCObjectTestCase.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ class LCObjectTestCase: BaseTestCase {
2121
XCTAssertNil(wObject)
2222
}
2323

24-
func testSaveObject() {
24+
func testSave() {
2525
let object = TestObject()
2626

2727
XCTAssertTrue(object.save().isSuccess)
2828
XCTAssertNotNil(object.objectId)
29+
30+
XCTAssertTrue(object.save().isSuccess)
2931
}
3032

3133
func testSaveObjectWithOption() {
@@ -90,7 +92,7 @@ class LCObjectTestCase: BaseTestCase {
9092
XCTAssertNotNil(newbornOrphan5.objectId)
9193
}
9294

93-
func testBatchSave() {
95+
func testSaveObjects() {
9496
let object1 = TestObject()
9597
let object2 = TestObject()
9698

@@ -115,6 +117,8 @@ class LCObjectTestCase: BaseTestCase {
115117
XCTAssertNotNil(object4.objectId)
116118
XCTAssertNotNil(newbornOrphan1.objectId)
117119
XCTAssertNotNil(newbornOrphan2.objectId)
120+
121+
XCTAssertTrue(LCObject.save([]).isSuccess)
118122
}
119123

120124
func testPrimitiveProperty() {
@@ -240,6 +244,8 @@ class LCObjectTestCase: BaseTestCase {
240244
XCTAssertEqual(LCError.InternalErrorCode(rawValue: LCObject.fetch([object, newborn]).error!._code), .notFound)
241245
XCTAssertEqual(LCError.ServerErrorCode(rawValue: LCObject.fetch([object, notFound]).error!._code), .objectNotFound)
242246
XCTAssertTrue(LCObject.fetch([object, child]).isSuccess)
247+
248+
XCTAssertTrue(LCObject.fetch([]).isSuccess)
243249
}
244250

245251
func testFetchWithKeys() {
@@ -272,7 +278,7 @@ class LCObjectTestCase: BaseTestCase {
272278
XCTAssertTrue(object.fetch().isFailure)
273279
}
274280

275-
func testDeleteAll() {
281+
func testDeleteObjects() {
276282
let object1 = TestObject()
277283
let object2 = TestObject()
278284

@@ -289,6 +295,8 @@ class LCObjectTestCase: BaseTestCase {
289295
XCTAssertTrue(LCObject.delete([object1, object2]).isSuccess)
290296
XCTAssertFalse(shadow1.save().isSuccess)
291297
XCTAssertFalse(shadow2.save().isSuccess)
298+
299+
XCTAssertTrue(LCObject.delete([]).isSuccess)
292300
}
293301

294302
func testKVO() {

Sources/Foundation/ObjectUpdater.swift

Lines changed: 79 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -62,44 +62,39 @@ class ObjectUpdater {
6262
return jsonRequests
6363
}
6464

65-
/**
66-
Send a list of batch requests synchronously.
67-
68-
- parameter requests: A list of batch requests.
69-
- returns: The response of request.
70-
*/
71-
private static func saveInOneBatchRequest(_ objects: [LCObject], parameters: [String: Any]?, completionInBackground completion: @escaping (LCBooleanResult) -> Void) -> LCRequest {
72-
let httpClient: HTTPClient = (objects.first?.application ?? LCApplication.default).httpClient
73-
74-
var requests: [Any]
75-
76-
do {
77-
requests = try createSaveBatchRequests(objects: objects, parameters: parameters)
78-
} catch let error {
79-
return httpClient.request(error: error, completionHandler: completion)
65+
private static func saveInOneBatchRequest(
66+
_ objects: [LCObject],
67+
parameters: [String: Any]?,
68+
completionInBackground completion: @escaping (LCBooleanResult) -> Void)
69+
-> LCRequest
70+
{
71+
let httpClient: HTTPClient = (objects.first?.application ?? .default).httpClient
72+
guard !objects.isEmpty else {
73+
return httpClient.request(object: .success, completionHandler: completion)
8074
}
81-
82-
let parameters = ["requests": requests]
83-
84-
let request = httpClient.request(.post, "batch/save", parameters: parameters) { response in
85-
let result = LCBooleanResult(response: response)
86-
87-
switch result {
88-
case .success:
89-
updateObjects(objects, response)
90-
91-
objects.forEach { object in
92-
object.discardChanges()
93-
object.objectDidSave()
75+
do {
76+
let requests = try createSaveBatchRequests(objects: objects, parameters: parameters)
77+
if requests.isEmpty {
78+
return httpClient.request(object: .success, completionHandler: completion)
79+
} else {
80+
return httpClient.request(
81+
.post, "batch/save",
82+
parameters: ["requests": requests])
83+
{ response in
84+
let result = LCBooleanResult(response: response)
85+
if case .success = result {
86+
self.updateObjects(objects, response)
87+
objects.forEach { object in
88+
object.discardChanges()
89+
object.objectDidSave()
90+
}
91+
}
92+
completion(result)
9493
}
95-
case .failure:
96-
break
9794
}
98-
99-
completion(result)
95+
} catch {
96+
return httpClient.request(error: error, completionHandler: completion)
10097
}
101-
102-
return request
10398
}
10499

105100
/**
@@ -209,37 +204,33 @@ class ObjectUpdater {
209204

210205
return sequenceRequest
211206
}
212-
213-
/**
214-
Delete a batch of objects in one request synchronously.
215-
216-
- parameter objects: An array of objects to be deleted.
217-
218-
- returns: The response of deletion request.
219-
*/
220-
static func delete(_ objects: [LCObject], completionInBackground completion: @escaping (LCBooleanResult) -> Void) -> LCRequest {
221-
let httpClient: HTTPClient = (objects.first?.application ?? LCApplication.default).httpClient
222-
223-
if objects.isEmpty {
224-
return httpClient.request(object: .success) { result in
225-
completion(result)
207+
208+
static func delete(
209+
_ objects: [LCObject],
210+
completionInBackground completion: @escaping (LCBooleanResult) -> Void)
211+
-> LCRequest
212+
{
213+
let httpClient: HTTPClient = (objects.first?.application ?? .default).httpClient
214+
guard !objects.isEmpty else {
215+
return httpClient.request(object: .success, completionHandler: completion)
216+
}
217+
do {
218+
let requests = try objects.unique.map { object in
219+
try BatchRequest(object: object, method: .delete)
220+
.jsonValue()
226221
}
227-
} else {
228-
var requests: [Any]
229-
230-
do {
231-
requests = try objects.unique.map { object in
232-
try BatchRequest(object: object, method: .delete).jsonValue()
222+
if requests.isEmpty {
223+
return httpClient.request(object: .success, completionHandler: completion)
224+
} else {
225+
return httpClient.request(
226+
.post, "batch",
227+
parameters: ["requests": requests])
228+
{ response in
229+
completion(LCBooleanResult(response: response))
233230
}
234-
} catch let error {
235-
return httpClient.request(error: error, completionHandler: completion)
236-
}
237-
238-
let parameters = ["requests": requests]
239-
240-
return httpClient.request(.post, "batch", parameters: parameters) { response in
241-
completion(LCBooleanResult(response: response))
242231
}
232+
} catch {
233+
return httpClient.request(error: error, completionHandler: completion)
243234
}
244235
}
245236

@@ -305,50 +296,38 @@ class ObjectUpdater {
305296
return result
306297
}
307298
}
308-
309-
/**
310-
Fetch multiple objects in one request synchronously.
311-
312-
- parameter objects: An array of objects to be fetched.
313-
314-
- returns: The response of fetching request.
315-
*/
316-
static func fetch(_ objects: [LCObject], keys: [String]?, completionInBackground completion: @escaping (LCBooleanResult) -> Void) -> LCRequest {
317-
let httpClient: HTTPClient = (objects.first?.application ?? LCApplication.default).httpClient
318-
319-
if objects.isEmpty {
320-
return httpClient.request(object: .success) { result in
321-
completion(result)
299+
300+
static func fetch(
301+
_ objects: [LCObject],
302+
keys: [String]?,
303+
completionInBackground completion: @escaping (LCBooleanResult) -> Void)
304+
-> LCRequest
305+
{
306+
let httpClient: HTTPClient = (objects.first?.application ?? .default).httpClient
307+
guard !objects.isEmpty else {
308+
return httpClient.request(object: .success, completionHandler: completion)
309+
}
310+
do {
311+
var keysParameters: [String: Any]?
312+
if let keys = keys {
313+
keysParameters = ["keys": keys.joined(separator: ",")]
322314
}
323-
} else {
324-
var requests: [Any]
325-
326-
do {
327-
var onlyIncludeKeys: [String: Any]?
328-
if let keys: [String] = keys {
329-
onlyIncludeKeys = ["keys": keys.joined(separator: ",")]
330-
}
331-
requests = try objects.unique.map { object in
332-
try BatchRequest(object: object, method: .get, parameters: onlyIncludeKeys).jsonValue()
333-
}
334-
} catch let error {
335-
return httpClient.request(error: error, completionHandler: completion)
315+
let requests = try objects.unique.map { object in
316+
try BatchRequest(object: object, method: .get, parameters: keysParameters)
317+
.jsonValue()
336318
}
337-
338-
let parameters = ["requests": requests]
339-
340-
return httpClient.request(.post, "batch", parameters: parameters) { response in
319+
return httpClient.request(
320+
.post, "batch",
321+
parameters: ["requests": requests])
322+
{ response in
341323
var result = LCBooleanResult(response: response)
342-
343-
switch result {
344-
case .success:
345-
result = handleObjectFetchedResponse(response, objects)
346-
case .failure:
347-
break
324+
if case .success = result {
325+
result = self.handleObjectFetchedResponse(response, objects)
348326
}
349-
350327
completion(result)
351328
}
329+
} catch {
330+
return httpClient.request(error: error, completionHandler: completion)
352331
}
353332
}
354333
}

0 commit comments

Comments
 (0)