Skip to content
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

CBLIS query with boolean value returns 0 result #756

Closed
pasin opened this issue Jun 4, 2015 · 5 comments
Closed

CBLIS query with boolean value returns 0 result #756

pasin opened this issue Jun 4, 2015 · 5 comments

Comments

@pasin
Copy link
Contributor

pasin commented Jun 4, 2015

Reported by #751.

@pasin
Copy link
Contributor Author

pasin commented Jun 4, 2015

CBLIS stores boolean value as 0 or 1 (CoreData boolean value) instead of true or false.

Option1:
Converting the value from 0 or 1 to NSNumber with the correct boolean value. Users will then need to update their documents to have correct boolean values otherwise they would need to query by using the predicate like 'checked == YES or checked == 1'.

Option2:
Changing boolean predicate value to number value.

@snej
Copy link
Contributor

snej commented Jun 4, 2015

Storing booleans as the NSNumbers 0 and 1, instead of NO and YES, seems wrong. Is it a bug in the CBLIS code, or is this something CoreData does?

(Is this being caused by the problem of distinguishing NSNumbers 0/1 from NO/YES? I.e. CoreData tells us to store a YES value, but it's an NSNumber and we think it's a 1? If so, I know the workaround; see CBJSONEncoder.m, lines 178-185.)

@mastohhh
Copy link
Contributor

mastohhh commented Jun 5, 2015

Each of these tests fails :

fetchRequest.predicate = [NSPredicate predicateWithFormat:@"check == YES"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"check == NO"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"check == 1"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"check == 0"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"check == %@", @YES];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"check == %@", @NO];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"check == %@", @(1)];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"check == %@", @(0)];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"check == %@", @"1"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"check == %@", @"0"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"check == %c", "1"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"check == %c", "0"];

To avoid this problem, I fetch all objects and then I filter the array of NSManagedObjects.

Problems :

  • performance
  • unusable with NSFetchedResultsController, indexPaths are false.

@pasin
Copy link
Contributor Author

pasin commented Jun 8, 2015

The boolean value from the CoreData is NSNumber with char type ('1' or '0') and CBLIncrementalStore doesn't convert that to the correct JSON boolean value.

case NSBooleanAttributeType:
        result = CBLISIsNull(value) ? @(NO) : value;
        break;

@mastohhh When I change your unit test PR with below, the unit test pass but that's not what it should be anyway.

 fetchRequest.predicate = [NSPredicate predicateWithFormat:@"check == 1"];
 fetchRequest.predicate = [NSPredicate predicateWithFormat:@"check == 0"];

I plan to correct the value saved in CBL database, but currently I don't have an efficient way to correct the existing data.

pasin added a commit that referenced this issue Jun 9, 2015
- Store boolean value in CBL database as JSON boolean value instead of number boolean value

- Provide kCBLISCustomPropertyQueryBooleanWithNumber (Default is NO) to support querying the existing boolean number value.

- If setting the kCBLISCustomPropertyQueryBooleanWithNumber property value to YES, when scanning the predicate for CBLQueryBuilder, CBLIS will replcate the original boolean predicate with an OR-compound predicate of the original predicate and the improvised number boolean predicate without parameterizing. For example, if the predicate is 'checked == YES', CBLIS will replace the predicate with 'checked == YES or checked == 1.

#756
pasin added a commit that referenced this issue Jun 9, 2015
- Store boolean value in CBL database as JSON boolean value instead of number boolean value

- Provide kCBLISCustomPropertyQueryBooleanWithNumber (Default is NO) to support querying the existing boolean number value.

- If setting the kCBLISCustomPropertyQueryBooleanWithNumber property value to YES, when scanning the predicate for CBLQueryBuilder, CBLIS will replcate the original boolean predicate with an OR-compound predicate of the original predicate and the improvised number boolean predicate without parameterizing. For example, if the predicate is 'checked == YES', CBLIS will replace the predicate with 'checked == YES or checked == 1.

#756
@snej snej closed this as completed in 9d9f799 Jun 9, 2015
@pasin
Copy link
Contributor Author

pasin commented Jun 10, 2015

@mastohhh I have fixed the issue in the master branch. The boolean value is now stored as the JSON boolean value instead of number value from now on.

I would be ideal if you could reset your data, otherwise please set customProperty kCBLISCustomPropertyQueryBooleanWithNumber with value = YES to the CBLIS store as below:

[store setCustomProperties:@{kCBLISCustomPropertyQueryBooleanWithNumber: @(YES)}];

Let me know if you have any questions.

@pasin pasin added this to the 1.1.1 milestone Jul 28, 2015
@pasin pasin added the bug label Jul 28, 2015
pasin added a commit that referenced this issue Jul 30, 2015
- Store boolean value in CBL database as JSON boolean value instead of number boolean value

- Provide kCBLISCustomPropertyQueryBooleanWithNumber (Default is NO) to support querying the existing boolean number value.

- If setting the kCBLISCustomPropertyQueryBooleanWithNumber property value to YES, when scanning the predicate for CBLQueryBuilder, CBLIS will replcate the original boolean predicate with an OR-compound predicate of the original predicate and the improvised number boolean predicate without parameterizing. For example, if the predicate is 'checked == YES', CBLIS will replace the predicate with 'checked == YES or checked == 1.

#756

# Conflicts:
#	Unit-Tests/IncrementalStore_Tests.m
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants