Skip to content

Commit c86b77f

Browse files
authored
Improve query hint (#119)
* Improve query hint * Hint can take any encodable type * findAll use regular findCommand
1 parent db0fdea commit c86b77f

File tree

9 files changed

+59
-65
lines changed

9 files changed

+59
-65
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
# Parse-Swift Changelog
22

33
### main
4-
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.3.1...main)
4+
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.4.0...main)
55
* _Contributing to this repo? Add info about your change here to be included in the next release_
66

7+
### 1.4.0
8+
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.3.1...1.4.0)
9+
10+
__Improvements__
11+
- (Breaking Change) A query hint can now be set using a method and its return type is automatically inferred. In addition, a hint can now be any Encodable type instead of just a String ([#119](https://github.com/parse-community/Parse-Swift/pull/119)), thanks to [Corey Baker](https://github.com/cbaker6).
12+
713
### 1.3.1
814
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.3.0...1.3.1)
915

ParseSwift.playground/Pages/7 - GeoPoint.xcplaygroundpage/Contents.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,13 +184,9 @@ query8.findAll { result in
184184
}
185185
}
186186

187-
//: Explain the previous query.
188-
let explain: AnyDecodable = try query2.first(explain: true)
189-
print(explain)
190-
191187
//: Hint of the previous query (asynchronous)
192-
query2.find(explain: false,
193-
hint: "_id_") { (result: Result<[GameScore], ParseError>) in
188+
query2 = query2.hint("_id_")
189+
query2.find { result in
194190
switch result {
195191
case .success(let scores):
196192
print(scores)
@@ -199,5 +195,9 @@ query2.find(explain: false,
199195
}
200196
}
201197

198+
//: Explain the previous query.
199+
let explain: AnyDecodable = try query2.first(explain: true)
200+
print(explain)
201+
202202
PlaygroundPage.current.finishExecution()
203203
//: [Next](@next)

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.3.1"
3+
s.version = "1.4.0"
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
@@ -2329,7 +2329,7 @@
23292329
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
23302330
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
23312331
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2332-
MARKETING_VERSION = 1.3.1;
2332+
MARKETING_VERSION = 1.4.0;
23332333
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
23342334
PRODUCT_NAME = ParseSwift;
23352335
SKIP_INSTALL = YES;
@@ -2353,7 +2353,7 @@
23532353
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
23542354
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
23552355
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2356-
MARKETING_VERSION = 1.3.1;
2356+
MARKETING_VERSION = 1.4.0;
23572357
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
23582358
PRODUCT_NAME = ParseSwift;
23592359
SKIP_INSTALL = YES;
@@ -2419,7 +2419,7 @@
24192419
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
24202420
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
24212421
MACOSX_DEPLOYMENT_TARGET = 10.13;
2422-
MARKETING_VERSION = 1.3.1;
2422+
MARKETING_VERSION = 1.4.0;
24232423
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
24242424
PRODUCT_NAME = ParseSwift;
24252425
SDKROOT = macosx;
@@ -2445,7 +2445,7 @@
24452445
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
24462446
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
24472447
MACOSX_DEPLOYMENT_TARGET = 10.13;
2448-
MARKETING_VERSION = 1.3.1;
2448+
MARKETING_VERSION = 1.4.0;
24492449
PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwift;
24502450
PRODUCT_NAME = ParseSwift;
24512451
SDKROOT = macosx;
@@ -2592,7 +2592,7 @@
25922592
INFOPLIST_FILE = "ParseSwift-watchOS/Info.plist";
25932593
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
25942594
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2595-
MARKETING_VERSION = 1.3.1;
2595+
MARKETING_VERSION = 1.4.0;
25962596
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
25972597
MTL_FAST_MATH = YES;
25982598
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-watchOS";
@@ -2621,7 +2621,7 @@
26212621
INFOPLIST_FILE = "ParseSwift-watchOS/Info.plist";
26222622
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
26232623
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2624-
MARKETING_VERSION = 1.3.1;
2624+
MARKETING_VERSION = 1.4.0;
26252625
MTL_FAST_MATH = YES;
26262626
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-watchOS";
26272627
PRODUCT_NAME = ParseSwift;
@@ -2648,7 +2648,7 @@
26482648
INFOPLIST_FILE = "ParseSwift-tvOS/Info.plist";
26492649
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
26502650
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2651-
MARKETING_VERSION = 1.3.1;
2651+
MARKETING_VERSION = 1.4.0;
26522652
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
26532653
MTL_FAST_MATH = YES;
26542654
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-tvOS";
@@ -2676,7 +2676,7 @@
26762676
INFOPLIST_FILE = "ParseSwift-tvOS/Info.plist";
26772677
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
26782678
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
2679-
MARKETING_VERSION = 1.3.1;
2679+
MARKETING_VERSION = 1.4.0;
26802680
MTL_FAST_MATH = YES;
26812681
PRODUCT_BUNDLE_IDENTIFIER = "com.parse.ParseSwift-tvOS";
26822682
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.3.1 \
8+
--module-version 1.4.0 \
99
--theme fullwidth \
1010
--skip-undocumented \
1111
--output ./docs/api \

Sources/ParseSwift/ParseConstants.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import Foundation
1010

1111
enum ParseConstants {
12-
static let parseVersion = "1.3.1"
12+
static let parseVersion = "1.4.0"
1313
static let hashingKey = "parseSwift"
1414
static let fileManagementDirectory = "parse/"
1515
static let fileManagementPrivateDocumentsDirectory = "Private Documents/"

Sources/ParseSwift/Types/Query+combine.swift

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ public extension Query {
4040
options: API.Options = []) -> Future<[U], ParseError> {
4141
Future { promise in
4242
self.find(explain: explain,
43-
hint: hint,
4443
options: options,
4544
completion: promise)
4645
}
@@ -49,19 +48,16 @@ public extension Query {
4948
/**
5049
Retrieves *asynchronously* a complete list of `ParseObject`'s that satisfy this query
5150
and publishes when complete.
52-
- parameter hint: String or Object of index that should be used when executing query.
5351
- parameter batchLimit: The maximum number of objects to send in each batch. If the items to be batched.
5452
- parameter options: A set of header options sent to the server. Defaults to an empty set.
5553
- returns: A publisher that eventually produces a single value and then finishes or fails.
5654
- warning: The items are processed in an unspecified order. The query may not have any sort
5755
order, and may not use limit or skip.
5856
*/
59-
func findAllPublisher(hint: String? = nil,
60-
batchLimit: Int? = nil,
57+
func findAllPublisher(batchLimit: Int? = nil,
6158
options: API.Options = []) -> Future<[ResultType], ParseError> {
6259
Future { promise in
63-
self.findAll(hint: hint,
64-
batchLimit: batchLimit,
60+
self.findAll(batchLimit: batchLimit,
6561
options: options,
6662
completion: promise)
6763
}
@@ -91,7 +87,6 @@ public extension Query {
9187
options: API.Options = []) -> Future<U, ParseError> {
9288
Future { promise in
9389
self.first(explain: explain,
94-
hint: hint,
9590
options: options,
9691
completion: promise)
9792
}
@@ -121,7 +116,6 @@ public extension Query {
121116
options: API.Options = []) -> Future<U, ParseError> {
122117
Future { promise in
123118
self.count(explain: explain,
124-
hint: hint,
125119
options: options,
126120
completion: promise)
127121
}

Sources/ParseSwift/Types/Query.swift

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ public struct Query<T>: Encodable, Equatable where T: ParseObject {
552552
internal var order: [Order]?
553553
internal var isCount: Bool?
554554
internal var explain: Bool?
555-
internal var hint: String?
555+
internal var hint: AnyEncodable?
556556
internal var `where` = QueryWhere()
557557
internal var excludeKeys: [String]?
558558
internal var readPreference: String?
@@ -650,6 +650,16 @@ public struct Query<T>: Encodable, Equatable where T: ParseObject {
650650
return mutableQuery
651651
}
652652

653+
/**
654+
Adds a hint to force index selection.
655+
- parameter value: String or Object of index that should be used when executing query.
656+
*/
657+
public func hint<U: Encodable>(_ value: U) -> Query<T> {
658+
var mutableQuery = self
659+
mutableQuery.hint = AnyEncodable(value)
660+
return mutableQuery
661+
}
662+
653663
/**
654664
Changes the read preference that the backend will use when performing the query to the database.
655665
- parameter readPreference: The read preference for the main query.
@@ -855,16 +865,14 @@ extension Query: Queryable {
855865
Finds objects *synchronously* based on the constructed query and sets an error if there was one.
856866

857867
- parameter explain: Used to toggle the information on the query plan.
858-
- parameter hint: String or Object of index that should be used when executing query.
859868
- parameter options: A set of header options sent to the server. Defaults to an empty set.
860869
- throws: An error of type `ParseError`.
861870

862871
- returns: Returns a response of `Decodable` type.
863872
*/
864873
public func find<U: Decodable>(explain: Bool,
865-
hint: String? = nil,
866874
options: API.Options = []) throws -> [U] {
867-
try findCommand(explain: explain, hint: hint).execute(options: options)
875+
try findCommand(explain: explain).execute(options: options)
868876
}
869877

870878
/**
@@ -889,18 +897,16 @@ extension Query: Queryable {
889897
Finds objects *asynchronously* and calls the given block with the results.
890898

891899
- parameter explain: Used to toggle the information on the query plan.
892-
- parameter hint: String or Object of index that should be used when executing query.
893900
- parameter options: A set of header options sent to the server. Defaults to an empty set.
894901
- parameter callbackQueue: The queue to return to after completion. Default value of .main.
895902
- parameter completion: The block to execute.
896903
It should have the following argument signature: `(Result<[Decodable], ParseError>)`.
897904
*/
898905
public func find<U: Decodable>(explain: Bool,
899-
hint: String? = nil,
900906
options: API.Options = [],
901907
callbackQueue: DispatchQueue = .main,
902908
completion: @escaping (Result<[U], ParseError>) -> Void) {
903-
findCommand(explain: explain, hint: hint).executeAsync(options: options) { result in
909+
findCommand(explain: explain).executeAsync(options: options) { result in
904910
callbackQueue.async {
905911
completion(result)
906912
}
@@ -910,7 +916,6 @@ extension Query: Queryable {
910916
/**
911917
Retrieves *asynchronously* a complete list of `ParseObject`'s that satisfy this query.
912918

913-
- parameter hint: String or Object of index that should be used when executing query.
914919
- parameter batchLimit: The maximum number of objects to send in each batch. If the items to be batched.
915920
is greater than the `batchLimit`, the objects will be sent to the server in waves up to the `batchLimit`.
916921
Defaults to 50.
@@ -921,8 +926,7 @@ extension Query: Queryable {
921926
- warning: The items are processed in an unspecified order. The query may not have any sort
922927
order, and may not use limit or skip.
923928
*/
924-
public func findAll(hint: String? = nil,
925-
batchLimit limit: Int? = nil,
929+
public func findAll(batchLimit limit: Int? = nil,
926930
options: API.Options = [],
927931
callbackQueue: DispatchQueue = .main,
928932
completion: @escaping (Result<[ResultType], ParseError>) -> Void) {
@@ -948,8 +952,7 @@ extension Query: Queryable {
948952

949953
while !finished {
950954
do {
951-
let currentResults: [ResultType] = try query.findCommand(explain: false,
952-
hint: hint).execute(options: options)
955+
let currentResults = try query.findCommand().execute(options: options)
953956
results.append(contentsOf: currentResults)
954957
if currentResults.count >= query.limit {
955958
guard let lastObjectId = results[results.count - 1].objectId else {
@@ -996,16 +999,14 @@ extension Query: Queryable {
996999

9971000
- warning: This method mutates the query. It will reset the limit to `1`.
9981001
- parameter explain: Used to toggle the information on the query plan.
999-
- parameter hint: String or Object of index that should be used when executing query.
10001002
- parameter options: A set of header options sent to the server. Defaults to an empty set.
10011003
- throws: An error of type `ParseError`.
10021004

10031005
- returns: Returns a response of `Decodable` type.
10041006
*/
10051007
public func first<U: Decodable>(explain: Bool,
1006-
hint: String? = nil,
10071008
options: API.Options = []) throws -> U {
1008-
try firstCommand(explain: explain, hint: hint).execute(options: options)
1009+
try firstCommand(explain: explain).execute(options: options)
10091010
}
10101011

10111012
/**
@@ -1032,17 +1033,16 @@ extension Query: Queryable {
10321033

10331034
- warning: This method mutates the query. It will reset the limit to `1`.
10341035
- parameter explain: Used to toggle the information on the query plan.
1035-
- parameter hint: String or Object of index that should be used when executing query.
10361036
- parameter options: A set of header options sent to the server. Defaults to an empty set.
10371037
- parameter callbackQueue: The queue to return to after completion. Default value of `.main`.
10381038
- parameter completion: The block to execute.
10391039
It should have the following argument signature: `(Result<Decodable, ParseError>)`.
10401040
*/
1041-
public func first<U: Decodable>(explain: Bool, hint: String? = nil,
1041+
public func first<U: Decodable>(explain: Bool,
10421042
options: API.Options = [],
10431043
callbackQueue: DispatchQueue = .main,
10441044
completion: @escaping (Result<U, ParseError>) -> Void) {
1045-
firstCommand(explain: explain, hint: hint).executeAsync(options: options) { result in
1045+
firstCommand(explain: explain).executeAsync(options: options) { result in
10461046
callbackQueue.async {
10471047
completion(result)
10481048
}
@@ -1065,16 +1065,14 @@ extension Query: Queryable {
10651065
Counts objects *synchronously* based on the constructed query and sets an error if there was one.
10661066

10671067
- parameter explain: Used to toggle the information on the query plan.
1068-
- parameter hint: String or Object of index that should be used when executing query.
10691068
- parameter options: A set of header options sent to the server. Defaults to an empty set.
10701069
- throws: An error of type `ParseError`.
10711070

10721071
- returns: Returns a response of `Decodable` type.
10731072
*/
10741073
public func count<U: Decodable>(explain: Bool,
1075-
hint: String? = nil,
10761074
options: API.Options = []) throws -> U {
1077-
try countCommand(explain: explain, hint: hint).execute(options: options)
1075+
try countCommand(explain: explain).execute(options: options)
10781076
}
10791077

10801078
/**
@@ -1097,18 +1095,16 @@ extension Query: Queryable {
10971095
/**
10981096
Counts objects *asynchronously* and calls the given block with the counts.
10991097
- parameter explain: Used to toggle the information on the query plan.
1100-
- parameter hint: String or Object of index that should be used when executing query.
11011098
- parameter options: A set of header options sent to the server. Defaults to an empty set.
11021099
- parameter callbackQueue: The queue to return to after completion. Default value of `.main`.
11031100
- parameter completion: The block to execute.
11041101
It should have the following argument signature: `(Result<Decodable, ParseError>)`.
11051102
*/
11061103
public func count<U: Decodable>(explain: Bool,
1107-
hint: String? = nil,
11081104
options: API.Options = [],
11091105
callbackQueue: DispatchQueue = .main,
11101106
completion: @escaping (Result<U, ParseError>) -> Void) {
1111-
countCommand(explain: explain, hint: hint).executeAsync(options: options) { result in
1107+
countCommand(explain: explain).executeAsync(options: options) { result in
11121108
callbackQueue.async {
11131109
completion(result)
11141110
}
@@ -1216,22 +1212,18 @@ extension Query {
12161212
}
12171213
}
12181214

1219-
func findCommand<U: Decodable>(explain: Bool,
1220-
hint: String?) -> API.NonParseBodyCommand<Query<ResultType>, [U]> {
1215+
func findCommand<U: Decodable>(explain: Bool) -> API.NonParseBodyCommand<Query<ResultType>, [U]> {
12211216
var query = self
12221217
query.explain = explain
1223-
query.hint = hint
12241218
return API.NonParseBodyCommand(method: .POST, path: query.endpoint, body: query) {
12251219
try ParseCoding.jsonDecoder().decode(AnyResultsResponse.self, from: $0).results
12261220
}
12271221
}
12281222

1229-
func firstCommand<U: Decodable>(explain: Bool,
1230-
hint: String?) -> API.NonParseBodyCommand<Query<ResultType>, U> {
1223+
func firstCommand<U: Decodable>(explain: Bool) -> API.NonParseBodyCommand<Query<ResultType>, U> {
12311224
var query = self
12321225
query.limit = 1
12331226
query.explain = explain
1234-
query.hint = hint
12351227
return API.NonParseBodyCommand(method: .POST, path: query.endpoint, body: query) {
12361228
if let decoded: U = try ParseCoding.jsonDecoder().decode(AnyResultsResponse.self, from: $0).results.first {
12371229
return decoded
@@ -1241,13 +1233,11 @@ extension Query {
12411233
}
12421234
}
12431235

1244-
func countCommand<U: Decodable>(explain: Bool,
1245-
hint: String?) -> API.NonParseBodyCommand<Query<ResultType>, U> {
1236+
func countCommand<U: Decodable>(explain: Bool) -> API.NonParseBodyCommand<Query<ResultType>, U> {
12461237
var query = self
12471238
query.limit = 1
12481239
query.isCount = true
12491240
query.explain = explain
1250-
query.hint = hint
12511241
return API.NonParseBodyCommand(method: .POST, path: query.endpoint, body: query) {
12521242
if let decoded: U = try ParseCoding.jsonDecoder().decode(AnyResultsResponse.self, from: $0).results.first {
12531243
return decoded

0 commit comments

Comments
 (0)