-
Notifications
You must be signed in to change notification settings - Fork 227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix smart-folder lookup/selection #1868
base: master
Are you sure you want to change the base?
Conversation
Vienna/Sources/Database/Database.m
Outdated
[self.smartfoldersDict enumerateKeysAndObjectsUsingBlock:^(NSNumber *folderID, CriteriaTree *criteriaTree, BOOL *stop) { | ||
// Two predicates may have the same format string, but be of different | ||
// predicate types that cannot be compared with -isEqual:. | ||
if ([criteriaTree.predicate.predicateFormat isEqualToString:predicate.predicateFormat]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you checked whether the format string is always in the same order for two given NSPredicates that are equivalent? Because, for example, "and" and "or" are both commutative, and to make sure all NSPredicates that express the same logical condition are recognized here, you'd have to create a normal form representation of them first... I think this problem shouldn't be solved here, but a note about the notion that this implementation has about predicates being equal would be good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I limited my test to the result that Criteria and CriteriaTree with a single Criteria returned. The format string will be the same for the comparison predicate and the compound predicate which has a single comparison predicate, but no and
/or
predicate. In both cases the format string will be read == No
, regardless whether the CriteriaTree is created as an all
or any
CriteriaTree.
let criteria = Criteria(
field: MA_Field_Read,
operatorType: .equalTo,
value: "No"
)
let criteriaTree = CriteriaTree(subtree: [], condition: .all)
criteriaTree.criteriaTree.append(criteria)
XCTAssert(criteria.predicate is NSComparisonPredicate)
XCTAssertEqual(criteria.predicate.predicateFormat, "\"Read\" == \"No\"")
XCTAssert(criteriaTree.predicate is NSCompoundPredicate)
XCTAssertEqual(criteriaTree.predicate.predicateFormat, "\"Read\" == \"No\"")
criteriaTree.condition = .any
XCTAssertEqual(criteriaTree.predicate.predicateFormat, "\"Read\" == \"No\"")
criteriaTree.condition = .none
XCTAssertNotEqual(criteriaTree.predicate.predicateFormat, "\"Read\" == \"No\"")
I decided against putting in the effort for a more generic solution to compare predicates, because it presently has only a single use case that is not even itself ideal. After all, the user might add more Criteria to this smart folder, e.g. to add a date predicate. However, for its intended use case, namely selecting the "Unread Articles" smart folder, it will work.
However, I am inclined to narrow the scope of this new method or change its name to reflect this very specific case that it's used for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, if you change the name so it indicates to only search one-term predicates (or single-condition predicates?) its limitations will be clear enough.
The name-based lookup is fragile; the folder name is set when Vienna is first launched, whereas the default name depends on the user's current localisation (which may have changed) and/or on the user keeping that default name. This approach uses the underlying predicate format string instead.
0e6a8f7
to
4cd12b9
Compare
The current implementation uses the localised default name "Unread Articles" to look up the smart folder. However, this breaks if the user changes the name afterwards or switches to a different localisation (which is what I did). My proposed solution uses the underlying predicate format string to look for the smart folder.