Skip to content

Commit 8939e47

Browse files
committed
Add batch transactions
1 parent 0ac301b commit 8939e47

18 files changed

+690
-91
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.1.6...main)
55
* _Contributing to this repo? Add info about your change here to be included in the next release_
66

7+
### 1.1.7
8+
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.1.6...1.1.7)
9+
710
__New features__
11+
- Add transaction support to batch saveAll and deleteAll ([#89](https://github.com/parse-community/Parse-Swift/pull/89)), thanks to [Corey Baker](https://github.com/cbaker6).
812
- Add modifiers to containsString, hasPrefix, hasSuffix ([#85](https://github.com/parse-community/Parse-Swift/pull/85)), thanks to [Corey Baker](https://github.com/cbaker6).
913

1014
__Improvements__

ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,29 @@ var score2ForFetchedLater: GameScore?
101101
}
102102
}
103103

104+
//: Saving multiple GameScores at once using a transaction.
105+
[score, score2].saveAll(transaction: true) { results in
106+
switch results {
107+
case .success(let otherResults):
108+
var index = 0
109+
otherResults.forEach { otherResult in
110+
switch otherResult {
111+
case .success(let savedScore):
112+
print("Saved \"\(savedScore.className)\" with score \(savedScore.score) successfully")
113+
if index == 1 {
114+
score2ForFetchedLater = savedScore
115+
}
116+
index += 1
117+
case .failure(let error):
118+
assertionFailure("Error saving: \(error)")
119+
}
120+
}
121+
122+
case .failure(let error):
123+
assertionFailure("Error saving: \(error)")
124+
}
125+
}
126+
104127
//: Save synchronously (not preferred - all operations on main queue).
105128
let savedScore: GameScore?
106129
do {

ParseSwift.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = "ParseSwift"
3-
s.version = "1.1.6"
3+
s.version = "1.1.7"
44
s.summary = "Parse Pure Swift SDK"
55
s.homepage = "https://github.com/parse-community/Parse-Swift"
66
s.authors = {

ParseSwift.xcodeproj/project.pbxproj

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2261,7 +2261,7 @@
22612261
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
22622262
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
22632263
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2264-
MARKETING_VERSION = 1.1.6;
2264+
MARKETING_VERSION = 1.1.7;
22652265
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
22662266
PRODUCT_NAME = ParseSwift;
22672267
SKIP_INSTALL = YES;
@@ -2285,7 +2285,7 @@
22852285
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
22862286
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
22872287
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2288-
MARKETING_VERSION = 1.1.6;
2288+
MARKETING_VERSION = 1.1.7;
22892289
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
22902290
PRODUCT_NAME = ParseSwift;
22912291
SKIP_INSTALL = YES;
@@ -2351,7 +2351,7 @@
23512351
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
23522352
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
23532353
MACOSX_DEPLOYMENT_TARGET = 10.13;
2354-
MARKETING_VERSION = 1.1.6;
2354+
MARKETING_VERSION = 1.1.7;
23552355
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
23562356
PRODUCT_NAME = ParseSwift;
23572357
SDKROOT = macosx;
@@ -2377,7 +2377,7 @@
23772377
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
23782378
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
23792379
MACOSX_DEPLOYMENT_TARGET = 10.13;
2380-
MARKETING_VERSION = 1.1.6;
2380+
MARKETING_VERSION = 1.1.7;
23812381
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
23822382
PRODUCT_NAME = ParseSwift;
23832383
SDKROOT = macosx;
@@ -2524,7 +2524,7 @@
25242524
INFOPLIST_FILE = "ParseSwift-watchOS/Info.plist";
25252525
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
25262526
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2527-
MARKETING_VERSION = 1.1.6;
2527+
MARKETING_VERSION = 1.1.7;
25282528
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
25292529
MTL_FAST_MATH = YES;
25302530
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-watchOS";
@@ -2553,7 +2553,7 @@
25532553
INFOPLIST_FILE = "ParseSwift-watchOS/Info.plist";
25542554
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
25552555
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2556-
MARKETING_VERSION = 1.1.6;
2556+
MARKETING_VERSION = 1.1.7;
25572557
MTL_FAST_MATH = YES;
25582558
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-watchOS";
25592559
PRODUCT_NAME = ParseSwift;
@@ -2580,7 +2580,7 @@
25802580
INFOPLIST_FILE = "ParseSwift-tvOS/Info.plist";
25812581
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
25822582
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2583-
MARKETING_VERSION = 1.1.6;
2583+
MARKETING_VERSION = 1.1.7;
25842584
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
25852585
MTL_FAST_MATH = YES;
25862586
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-tvOS";
@@ -2608,7 +2608,7 @@
26082608
INFOPLIST_FILE = "ParseSwift-tvOS/Info.plist";
26092609
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
26102610
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2611-
MARKETING_VERSION = 1.1.6;
2611+
MARKETING_VERSION = 1.1.7;
26122612
MTL_FAST_MATH = YES;
26132613
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-tvOS";
26142614
PRODUCT_NAME = ParseSwift;

Scripts/jazzy.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ bundle exec jazzy \
55
--author_url http://parseplatform.org \
66
--github_url https://github.com/parse-community/Parse-Swift \
77
--root-url http://parseplatform.org/Parse-Swift/api/ \
8-
--module-version 1.1.6 \
8+
--module-version 1.1.7 \
99
--theme fullwidth \
1010
--skip-undocumented \
1111
--output ./docs/api \

Sources/ParseSwift/API/API+Commands.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ extension API.Command where T: ParseObject {
410410
return try? body.getEncoder().encode(body, skipKeys: .object)
411411
}
412412

413-
static func batch(commands: [API.Command<T, T>]) -> RESTBatchCommandType<T> {
413+
static func batch(commands: [API.Command<T, T>], transaction: Bool) -> RESTBatchCommandType<T> {
414414
let commands = commands.compactMap { (command) -> API.Command<T, T>? in
415415
let path = ParseConfiguration.mountPath + command.path.urlComponent
416416
guard let body = command.body else {
@@ -452,12 +452,13 @@ extension API.Command where T: ParseObject {
452452
}
453453
}
454454

455-
let batchCommand = BatchCommand(requests: commands)
455+
let batchCommand = BatchCommand(requests: commands, transaction: transaction)
456456
return RESTBatchCommandType<T>(method: .POST, path: .batch, body: batchCommand, mapper: mapper)
457457
}
458458

459459
// MARK: Batch - Deleting
460-
static func batch(commands: [API.NonParseBodyCommand<NoBody, NoBody>]) -> RESTBatchCommandNoBodyType<NoBody> {
460+
static func batch(commands: [API.NonParseBodyCommand<NoBody, NoBody>],
461+
transaction: Bool) -> RESTBatchCommandNoBodyType<NoBody> {
461462
let commands = commands.compactMap { (command) -> API.NonParseBodyCommand<NoBody, NoBody>? in
462463
let path = ParseConfiguration.mountPath + command.path.urlComponent
463464
return API.NonParseBodyCommand<NoBody, NoBody>(
@@ -490,7 +491,7 @@ extension API.Command where T: ParseObject {
490491
}
491492
}
492493

493-
let batchCommand = BatchCommandNoBody(requests: commands)
494+
let batchCommand = BatchCommandNoBody(requests: commands, transaction: transaction)
494495
return RESTBatchCommandNoBodyType<NoBody>(method: .POST, path: .batch, body: batchCommand, mapper: mapper)
495496
}
496497
}

Sources/ParseSwift/API/API.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public struct API {
114114
/// Specify metadata.
115115
/// - note: This is typically used indirectly by `ParseFile`.
116116
case metadata([String: String])
117-
// Specify tags.
117+
/// Specify tags.
118118
/// - note: This is typically used indirectly by `ParseFile`.
119119
case tags([String: String])
120120

Sources/ParseSwift/API/BatchUtils.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ typealias RESTBatchCommandTypeEncodable<T> = API.Command<ParseObjectBatchCommand
2525
*/
2626
internal struct BatchCommand<T, U>: ParseType where T: ParseType {
2727
let requests: [API.Command<T, U>]
28+
var transaction: Bool
2829
}
2930

3031
internal struct BatchCommandNoBody<T, U>: Encodable where T: Encodable {
3132
let requests: [API.NonParseBodyCommand<T, U>]
33+
var transaction: Bool
3234
}
3335

3436
struct BatchUtils {

Sources/ParseSwift/Objects/ParseInstallation+combine.swift

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,28 +88,51 @@ public extension Sequence where Element: ParseInstallation {
8888

8989
/**
9090
Saves a collection of installations *asynchronously* and publishes when complete.
91-
91+
- parameter batchLimit: The maximum number of objects to send in each batch. If the items to be batched
92+
is greater than the `batchLimit`, the objects will be sent to the server in waves up to the `batchLimit`.
93+
Defaults to 50.
94+
- parameter transaction: Treat as an all-or-nothing operation. If some operation failure occurs that
95+
prevents the transaction from completing, then none of the objects are committed to the Parse Server database.
9296
- parameter options: A set of header options sent to the server. Defaults to an empty set.
9397
- returns: A publisher that eventually produces a single value and then finishes or fails.
9498
- important: If an object saved has the same objectId as current, it will automatically update the current.
99+
- warning: If `transaction = true`, then `batchLimit` will be automatically be set to the amount of the
100+
objects in the transaction. The developer should ensure their respective Parse Servers can handle the limit or else
101+
the transactions can fail.
95102
*/
96-
func saveAllPublisher(options: API.Options = []) -> Future<[(Result<Self.Element, ParseError>)], ParseError> {
103+
func saveAllPublisher(batchLimit limit: Int? = nil,
104+
transaction: Bool = false,
105+
options: API.Options = []) -> Future<[(Result<Self.Element, ParseError>)], ParseError> {
97106
Future { promise in
98-
self.saveAll(options: options,
107+
self.saveAll(batchLimit: limit,
108+
transaction: transaction,
109+
options: options,
99110
completion: promise)
100111
}
101112
}
102113

103114
/**
104115
Deletes a collection of installations *asynchronously* and publishes when complete.
105-
116+
- parameter batchLimit: The maximum number of objects to send in each batch. If the items to be batched
117+
is greater than the `batchLimit`, the objects will be sent to the server in waves up to the `batchLimit`.
118+
Defaults to 50.
119+
- parameter transaction: Treat as an all-or-nothing operation. If some operation failure occurs that
120+
prevents the transaction from completing, then none of the objects are committed to the Parse Server database.
106121
- parameter options: A set of header options sent to the server. Defaults to an empty set.
107122
- returns: A publisher that eventually produces a single value and then finishes or fails.
108123
- important: If an object deleted has the same objectId as current, it will automatically update the current.
124+
- warning: If `transaction = true`, then `batchLimit` will be automatically be set to the amount of the
125+
objects in the transaction. The developer should ensure their respective Parse Servers can handle the limit or else
126+
the transactions can fail.
109127
*/
110-
func deleteAllPublisher(options: API.Options = []) -> Future<[(Result<Void, ParseError>)], ParseError> {
128+
func deleteAllPublisher(batchLimit limit: Int? = nil,
129+
transaction: Bool = false,
130+
options: API.Options = []) -> Future<[(Result<Void, ParseError>)], ParseError> {
111131
Future { promise in
112-
self.deleteAll(options: options, completion: promise)
132+
self.deleteAll(batchLimit: limit,
133+
transaction: transaction,
134+
options: options,
135+
completion: promise)
113136
}
114137
}
115138
}

0 commit comments

Comments
 (0)