marcoarment / FCModel

An alternative to Core Data for people who like having direct SQL access.
MIT License
1.65k stars 178 forks source link

Query return the same instance whose NSNumber value is the one being set before without saving. #122

Closed roman-yu closed 9 years ago

roman-yu commented 9 years ago
FCApple : FCModal
@property (nonatomic, assign) NSNumber appleID;
@property (nonatomic, strong) NSNumber *deleted; //default: NO

FCApple *apple = [FCApple firstInstanceWhere:@"appleID = 1"];
apple.deleted = YES; // no save

FCApple *apple1 = [FCApple firstInstanceWhere:@"appleID = 1 AND (deleted = 0 OR deleted IS NULL)"];

turn out: apple == apple1 and apple.deleted == apple1.deleted == YES

I do not know it is a problem or the correct behavior, just write it here.

Thanks.

marcoarment commented 9 years ago

That's correct behavior if appleID is the primary key for the FCApple table, although your queries need to be against the FCApple class, not "FCModel", e.g.:

// wrong:
FCApple *apple = [FCModel firstInstanceWhere:@"appleID = 1"];

// correct:
FCApple *apple = [FCApple firstInstanceWhere:@"appleID = 1"];

// better, use the instanceWithPrimaryKey method:
FCApple *apple = [FCApple instanceWithPrimaryKey:@1];

// even better, your application's model subclasses shouldn't use the "FC" prefix:
RYApple *apple = [RYApple instanceWithPrimaryKey:@1];

Uniqueness in memory is by primary-key value, so as long as the version in the database of apple with ID 1 has deleted set to 0 at the time of your second query, this is correct. Database queries with WHERE clauses won't see the updates performed on properties of in-memory models until you save them.

And this is one of the reasons why, in the unique2 branch, I've modified the structure and convention of save to put all writes into a block in the database queue, never leaving changes "unsaved", e.g.:

[apple save:^{
    apple.deleted = YES;
}];
roman-yu commented 9 years ago

Thanks for your respond, it should be FCApple not FCModel by mistake.

So once the apple with ID 1 has deleted(0 in database) set to YES without saving, thedeleted properties of in-memory model changed to YES, and the deleted property of result of any queries which are identical to [FCApple instanceWithPrimaryKey:@1] will always be YES even its value in database is 0. Am I right?

marcoarment commented 9 years ago

That's right. Because instances in memory are unique by primary key, so your subsequent calls to [FCApple instanceWithPrimaryKey:@1] will keep returning the same instance that was already in memory and that you set .deleted = YES on.

roman-yu commented 9 years ago

Great, got it!