nano-store 0.5.2 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/{CHANGELOG → CHANGELOG.md} +7 -0
- data/README.md +5 -1
- data/Rakefile +1 -1
- data/lib/nano_store.rb +1 -1
- data/lib/nano_store/finder.rb +10 -2
- data/lib/nano_store/model.rb +7 -7
- data/lib/nano_store/version.rb +1 -1
- data/spec/association_spec.rb +6 -6
- data/spec/finder_spec.rb +2 -0
- data/spec/model_spec.rb +33 -3
- data/spec/nano_store_spec.rb +5 -0
- data/spec/spec_helper.rb +14 -0
- data/vendor/Podfile.lock +3 -3
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoBag.h +6 -1
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoEngine.h +5 -0
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoEngine_Private.h +2 -0
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoExpression.h +6 -0
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoExpression_Private.h +1 -1
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoGlobals.h +5 -1
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoGlobals_Private.h +6 -2
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoObject.h +15 -3
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoObject_Private.h +4 -0
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoPredicate.h +6 -1
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoResult.h +5 -0
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoSearch.h +16 -2
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoSortDescriptor.h +7 -1
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoStore.h +12 -0
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoStore_Private.h +3 -1
- data/vendor/Pods/BuildHeaders/NanoStore/NSFOrderedDictionary.h +33 -0
- data/vendor/Pods/BuildHeaders/NanoStore/NanoStore.h +36 -0
- data/vendor/Pods/Headers/NanoStore/NSFNanoBag.h +6 -1
- data/vendor/Pods/Headers/NanoStore/NSFNanoEngine.h +5 -0
- data/vendor/Pods/Headers/NanoStore/NSFNanoEngine_Private.h +2 -0
- data/vendor/Pods/Headers/NanoStore/NSFNanoExpression.h +6 -0
- data/vendor/Pods/Headers/NanoStore/NSFNanoExpression_Private.h +1 -1
- data/vendor/Pods/Headers/NanoStore/NSFNanoGlobals.h +5 -1
- data/vendor/Pods/Headers/NanoStore/NSFNanoGlobals_Private.h +6 -2
- data/vendor/Pods/Headers/NanoStore/NSFNanoObject.h +15 -3
- data/vendor/Pods/Headers/NanoStore/NSFNanoObject_Private.h +4 -0
- data/vendor/Pods/Headers/NanoStore/NSFNanoPredicate.h +6 -1
- data/vendor/Pods/Headers/NanoStore/NSFNanoResult.h +5 -0
- data/vendor/Pods/Headers/NanoStore/NSFNanoSearch.h +16 -2
- data/vendor/Pods/Headers/NanoStore/NSFNanoSortDescriptor.h +7 -1
- data/vendor/Pods/Headers/NanoStore/NSFNanoStore.h +12 -0
- data/vendor/Pods/Headers/NanoStore/NSFNanoStore_Private.h +3 -1
- data/vendor/Pods/Headers/NanoStore/NSFOrderedDictionary.h +33 -0
- data/vendor/Pods/Headers/NanoStore/NanoStore.h +36 -0
- data/vendor/Pods/NanoStore/Classes/Advanced/NSFNanoEngine.h +5 -0
- data/vendor/Pods/NanoStore/Classes/Advanced/NSFNanoEngine.m +142 -131
- data/vendor/Pods/NanoStore/Classes/Advanced/NSFNanoResult.h +5 -0
- data/vendor/Pods/NanoStore/Classes/Advanced/NSFNanoResult.m +148 -51
- data/vendor/Pods/NanoStore/Classes/Advanced/NSFOrderedDictionary.h +33 -0
- data/vendor/Pods/NanoStore/Classes/Advanced/NSFOrderedDictionary.m +148 -0
- data/vendor/Pods/NanoStore/Classes/Private/NSFNanoEngine_Private.h +2 -0
- data/vendor/Pods/NanoStore/Classes/Private/NSFNanoExpression_Private.h +1 -1
- data/vendor/Pods/NanoStore/Classes/Private/NSFNanoGlobals_Private.h +6 -2
- data/vendor/Pods/NanoStore/Classes/Private/NSFNanoObject_Private.h +4 -0
- data/vendor/Pods/NanoStore/Classes/Private/NSFNanoStore_Private.h +3 -1
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoBag.h +6 -1
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoBag.m +126 -117
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoExpression.h +6 -0
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoExpression.m +32 -18
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoGlobals.h +5 -1
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoGlobals.m +6 -3
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoObject.h +15 -3
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoObject.m +152 -31
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoPredicate.h +6 -1
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoPredicate.m +51 -26
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSearch.h +16 -2
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSearch.m +156 -115
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSortDescriptor.h +7 -1
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSortDescriptor.m +34 -17
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoStore.h +12 -0
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoStore.m +210 -196
- data/vendor/Pods/NanoStore/Classes/Public/NanoStore.h +36 -0
- data/vendor/Pods/NanoStore/README.md +49 -0
- data/vendor/Pods/Pods.bridgesupport +798 -685
- metadata +30 -8
@@ -30,10 +30,12 @@
|
|
30
30
|
#import "NSFNanoEngine.h"
|
31
31
|
#import "NSFNanoGlobals_Private.h"
|
32
32
|
#import "NSFNanoResult.h"
|
33
|
+
#import "NSFOrderedDictionary.h"
|
33
34
|
|
34
35
|
/** \cond */
|
35
36
|
|
36
37
|
@interface NSFNanoEngine (Private)
|
38
|
+
- (NSFOrderedDictionary *)dictionaryDescription;
|
37
39
|
+ (NSArray *)NSFP_sharedROWIDKeywords;
|
38
40
|
- (NSString *)NSFP_cacheMethodToString;
|
39
41
|
- (NSString*)NSFP_nestedDescriptionWithPrefixedSpace:(NSString *)prefixedSpace;
|
@@ -53,6 +53,10 @@
|
|
53
53
|
|
54
54
|
*/
|
55
55
|
|
56
|
+
extern NSDictionary * safeJSONDictionaryFromDictionary (NSDictionary *dictionary);
|
57
|
+
extern NSArray * safeJSONArrayFromArray (NSArray *array);
|
58
|
+
extern id safeJSONObjectFromObject (id object);
|
59
|
+
|
56
60
|
extern NSString * NSFStringFromMatchType (NSFMatchType aMatchType);
|
57
61
|
|
58
62
|
extern void _NSFLog (NSString *format, ...);
|
@@ -67,13 +71,13 @@ extern NSString * const NSFValue;
|
|
67
71
|
extern NSString * const NSFDatatype;
|
68
72
|
extern NSString * const NSFCalendarDate;
|
69
73
|
extern NSString * const NSFObjectClass;
|
70
|
-
extern NSString * const
|
74
|
+
extern NSString * const NSFKeyedArchive;
|
71
75
|
extern NSString * const NSFAttribute;
|
72
76
|
|
73
77
|
#pragma mark -
|
74
78
|
|
75
79
|
extern NSString * const NSF_Private_NSFKeys_NSFKey;
|
76
|
-
extern NSString * const
|
80
|
+
extern NSString * const NSF_Private_NSFKeys_NSFKeyedArchive;
|
77
81
|
extern NSString * const NSF_Private_NSFValues_NSFKey;
|
78
82
|
extern NSString * const NSF_Private_NSFValues_NSFAttribute;
|
79
83
|
extern NSString * const NSF_Private_NSFValues_NSFValue;
|
@@ -30,6 +30,10 @@
|
|
30
30
|
|
31
31
|
@interface NSFNanoObject (Private)
|
32
32
|
- (void)_setOriginalClassString:(NSString *)theClassString;
|
33
|
+
+ (NSString *)_NSObjectToJSONString:(id)object error:(NSError **)error;
|
34
|
+
+ (NSDictionary *)_safeDictionaryFromDictionary:(NSDictionary *)dictionary;
|
35
|
+
+ (NSArray *)_safeArrayFromArray:(NSArray *)array;
|
36
|
+
+ (id)_safeObjectFromObject:(id)object;
|
33
37
|
@end
|
34
38
|
|
35
39
|
/** \endcond */
|
@@ -25,10 +25,12 @@
|
|
25
25
|
*/
|
26
26
|
|
27
27
|
#import "NSFNanoStore.h"
|
28
|
+
#import "NSFOrderedDictionary.h"
|
28
29
|
|
29
30
|
/** \cond */
|
30
31
|
|
31
32
|
@interface NSFNanoStore (Private)
|
33
|
+
- (NSFOrderedDictionary *)dictionaryDescription;
|
32
34
|
+ (NSFNanoStore *)_createAndOpenDebugDatabase;
|
33
35
|
- (NSFNanoResult *)_executeSQL:(NSString *)theSQLStatement;
|
34
36
|
- (NSString*)_nestedDescriptionWithPrefixedSpace:(NSString *)prefixedSpace;
|
@@ -37,7 +39,7 @@
|
|
37
39
|
- (void)_setIsOurTransaction:(BOOL)value;
|
38
40
|
- (BOOL)_isOurTransaction;
|
39
41
|
- (BOOL)_setupCachingSchema;
|
40
|
-
- (BOOL)_storeDictionary:(NSDictionary *)someInfo forKey:(NSString *)aKey forClassNamed:(NSString *)classType
|
42
|
+
- (BOOL)_storeDictionary:(NSDictionary *)someInfo forKey:(NSString *)aKey forClassNamed:(NSString *)classType error:(out NSError **)outError;
|
41
43
|
- (BOOL)__storeDictionaries:(NSArray *)someObjects forKeys:(NSArray *)someKeys error:(out NSError **)outError;
|
42
44
|
- (BOOL)_bindValue:(id)aValue forAttribute:(NSString *)anAttribute parameterNumber:(NSInteger)aParamNumber usingSQLite3Statement:(sqlite3_stmt *)aStatement;
|
43
45
|
- (BOOL)_checkNanoStoreIsReadyAndReturnError:(out NSError **)outError;
|
@@ -302,11 +302,16 @@
|
|
302
302
|
|
303
303
|
/** * Returns a string representation of the bag.
|
304
304
|
* @note Check properties savedObjects, unsavedObjects and removedObjects to find out the current state of the bag.
|
305
|
-
* @see \link dictionaryRepresentation - (NSDictionary *)dictionaryRepresentation \endlink
|
306
305
|
*/
|
307
306
|
|
308
307
|
- (NSString *)description;
|
309
308
|
|
309
|
+
/** Returns a JSON representation of the bag.
|
310
|
+
* @note Check properties savedObjects, unsavedObjects and removedObjects to find out the current state of the bag.
|
311
|
+
*/
|
312
|
+
|
313
|
+
- (NSString *)JSONDescription;
|
314
|
+
|
310
315
|
//@}
|
311
316
|
|
312
317
|
@end
|
@@ -30,19 +30,18 @@
|
|
30
30
|
#import "NSFNanoGlobals_Private.h"
|
31
31
|
#import "NSFNanoStore_Private.h"
|
32
32
|
#import "NSFNanoSearch_Private.h"
|
33
|
+
#import "NSFOrderedDictionary.h"
|
34
|
+
#import "NSFNanoObject_Private.h"
|
33
35
|
|
34
36
|
@implementation NSFNanoBag
|
35
37
|
{
|
36
|
-
@protected
|
37
38
|
/** \cond */
|
38
|
-
NSMutableDictionary
|
39
|
-
NSMutableDictionary
|
40
|
-
NSMutableDictionary
|
39
|
+
NSMutableDictionary *_savedObjects;
|
40
|
+
NSMutableDictionary *_unsavedObjects;
|
41
|
+
NSMutableDictionary *_removedObjects;
|
41
42
|
/** \endcond */
|
42
43
|
}
|
43
44
|
|
44
|
-
@synthesize store, name, key, savedObjects, unsavedObjects, removedObjects, hasUnsavedChanges;
|
45
|
-
|
46
45
|
+ (NSFNanoBag*)bag
|
47
46
|
{
|
48
47
|
return [[self alloc]initBagWithName:nil andObjects:[NSArray array]];
|
@@ -67,15 +66,15 @@
|
|
67
66
|
{
|
68
67
|
if (nil == someObjects) {
|
69
68
|
[[NSException exceptionWithName:NSFUnexpectedParameterException
|
70
|
-
reason:[NSString stringWithFormat:@"*** -[%@
|
69
|
+
reason:[NSString stringWithFormat:@"*** -[%@ %@]: 'someObjects' cannot be nil.", [self class], NSStringFromSelector(_cmd)]
|
71
70
|
userInfo:nil]raise];
|
72
71
|
}
|
73
72
|
|
74
73
|
if ((self = [self init])) {
|
75
74
|
[self addObjectsFromArray:someObjects error:nil];
|
76
75
|
|
77
|
-
|
78
|
-
|
76
|
+
_name = theName;
|
77
|
+
_hasUnsavedChanges = YES;
|
79
78
|
}
|
80
79
|
|
81
80
|
return self;
|
@@ -86,12 +85,13 @@
|
|
86
85
|
- (id)init
|
87
86
|
{
|
88
87
|
if ((self = [super init])) {
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
88
|
+
_store = nil;
|
89
|
+
_key = [NSFNanoEngine stringWithUUID];
|
90
|
+
_name = nil;
|
91
|
+
_savedObjects = [NSMutableDictionary new];
|
92
|
+
_unsavedObjects = [NSMutableDictionary new];
|
93
|
+
_removedObjects = [NSMutableDictionary new];
|
94
|
+
_hasUnsavedChanges = NO;
|
95
95
|
}
|
96
96
|
|
97
97
|
return self;
|
@@ -99,7 +99,7 @@
|
|
99
99
|
|
100
100
|
- (id)copyWithZone:(NSZone *)zone
|
101
101
|
{
|
102
|
-
NSFNanoBag *copy = [[[self class]allocWithZone:zone]initNanoObjectFromDictionaryRepresentation:[self dictionaryRepresentation] forKey:[NSFNanoEngine stringWithUUID] store:
|
102
|
+
NSFNanoBag *copy = [[[self class]allocWithZone:zone]initNanoObjectFromDictionaryRepresentation:[self dictionaryRepresentation] forKey:[NSFNanoEngine stringWithUUID] store:_store];
|
103
103
|
return copy;
|
104
104
|
}
|
105
105
|
|
@@ -113,38 +113,70 @@
|
|
113
113
|
|
114
114
|
- (void)setName:(NSString *)aName
|
115
115
|
{
|
116
|
-
|
117
|
-
|
116
|
+
_name = aName;
|
117
|
+
_hasUnsavedChanges = YES;
|
118
118
|
}
|
119
119
|
|
120
120
|
/** \endcond */
|
121
121
|
|
122
|
-
- (
|
122
|
+
- (NSUInteger)count
|
123
123
|
{
|
124
|
-
return
|
124
|
+
return _savedObjects.count + _unsavedObjects.count;
|
125
125
|
}
|
126
126
|
|
127
|
-
- (
|
127
|
+
- (NSString *)description
|
128
128
|
{
|
129
|
-
return
|
129
|
+
return [self JSONDescription];
|
130
130
|
}
|
131
131
|
|
132
|
-
- (
|
132
|
+
- (NSDictionary *)dictionaryDescription
|
133
133
|
{
|
134
|
-
|
134
|
+
NSFOrderedDictionary *values = [NSFOrderedDictionary new];
|
135
|
+
|
136
|
+
values[@"NanoBag address"] = [NSString stringWithFormat:@"%p", self];
|
137
|
+
values[@"Key"] = _key;
|
138
|
+
values[@"Name"] = (nil != _name) ? _name : @"<untitled>";
|
139
|
+
values[@"Document store"] = ([_store dictionaryDescription] ? [_store dictionaryDescription] : @"<nil>");
|
140
|
+
values[@"Has unsaved changes?"] = (_hasUnsavedChanges ? @"YES" : @"NO");
|
141
|
+
values[@"Saved objects"] = @([_savedObjects count]);
|
142
|
+
values[@"Unsaved objects"] = @([_unsavedObjects count]);
|
143
|
+
values[@"Removed objects"] = @([_removedObjects count]);
|
135
144
|
|
136
|
-
|
137
|
-
|
138
|
-
[description appendString:[NSString stringWithFormat:@"Name : %@\n", (nil != name) ? name : @"<untitled>"]];
|
139
|
-
[description appendString:[NSString stringWithFormat:@"Document store : 0x%x\n", store]];
|
140
|
-
[description appendString:[NSString stringWithFormat:@"Has unsaved changes? : %@\n", (hasUnsavedChanges ? @"YES" : @"NO")]];
|
141
|
-
[description appendString:[NSString stringWithFormat:@"Saved objects : %ld key/value pairs\n", [savedObjects count]]];
|
142
|
-
[description appendString:[NSString stringWithFormat:@"Unsaved objects : %ld key/value pairs\n", [unsavedObjects count]]];
|
143
|
-
[description appendString:[NSString stringWithFormat:@"Removed objects : %ld key/value pairs\n", [removedObjects count]]];
|
145
|
+
return values;
|
146
|
+
}
|
144
147
|
|
148
|
+
- (NSString *)JSONDescription
|
149
|
+
{
|
150
|
+
NSDictionary *values = [self dictionaryDescription];
|
151
|
+
|
152
|
+
NSError *outError = nil;
|
153
|
+
NSString *description = [NSFNanoObject _NSObjectToJSONString:values error:&outError];
|
154
|
+
|
145
155
|
return description;
|
146
156
|
}
|
147
157
|
|
158
|
+
- (NSDictionary *)dictionaryRepresentation
|
159
|
+
{
|
160
|
+
// Iterate the objects collecting the object keys
|
161
|
+
NSMutableArray *objectKeys = [NSMutableArray new];
|
162
|
+
for (NSString *objectKey in _savedObjects) {
|
163
|
+
[objectKeys addObject:objectKey];
|
164
|
+
}
|
165
|
+
for (NSString *objectKey in _unsavedObjects) {
|
166
|
+
[objectKeys addObject:objectKey];
|
167
|
+
}
|
168
|
+
|
169
|
+
NSMutableDictionary *info = [NSMutableDictionary dictionary];
|
170
|
+
|
171
|
+
if (nil != _name) {
|
172
|
+
[info setObject:_name forKey:NSF_Private_NSFNanoBag_Name];
|
173
|
+
}
|
174
|
+
[info setObject:self.key forKey:NSF_Private_NSFNanoBag_NSFKey];
|
175
|
+
[info setObject:objectKeys forKey:NSF_Private_NSFNanoBag_NSFObjectKeys];
|
176
|
+
|
177
|
+
return info;
|
178
|
+
}
|
179
|
+
|
148
180
|
- (BOOL)isEqualToNanoBag:(NSFNanoBag *)otherNanoBag
|
149
181
|
{
|
150
182
|
if (self == otherNanoBag) {
|
@@ -153,17 +185,17 @@
|
|
153
185
|
|
154
186
|
BOOL success = YES;
|
155
187
|
|
156
|
-
NSArray *sortedArraySelf = [[
|
188
|
+
NSArray *sortedArraySelf = [[_savedObjects allKeys]sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
|
157
189
|
NSArray *sortedArrayOther = [[[otherNanoBag savedObjects]allKeys]sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
|
158
190
|
if (NO == [sortedArraySelf isEqualToArray:sortedArrayOther]) {
|
159
191
|
success = NO;
|
160
192
|
} else {
|
161
|
-
sortedArraySelf = [[
|
193
|
+
sortedArraySelf = [[_unsavedObjects allKeys]sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
|
162
194
|
sortedArrayOther = [[[otherNanoBag unsavedObjects]allKeys]sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
|
163
195
|
if (NO == [sortedArraySelf isEqualToArray:sortedArrayOther]) {
|
164
196
|
success = NO;
|
165
197
|
} else {
|
166
|
-
sortedArraySelf = [[
|
198
|
+
sortedArraySelf = [[_removedObjects allKeys]sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
|
167
199
|
sortedArrayOther = [[[otherNanoBag removedObjects]allKeys]sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
|
168
200
|
if (NO == [sortedArraySelf isEqualToArray:sortedArrayOther]) {
|
169
201
|
success = NO;
|
@@ -174,35 +206,13 @@
|
|
174
206
|
return success;
|
175
207
|
}
|
176
208
|
|
177
|
-
- (NSDictionary *)dictionaryRepresentation
|
178
|
-
{
|
179
|
-
// Iterate the objects collecting the object keys
|
180
|
-
NSMutableArray *objectKeys = [NSMutableArray new];
|
181
|
-
for (NSString *objectKey in self.savedObjects) {
|
182
|
-
[objectKeys addObject:objectKey];
|
183
|
-
}
|
184
|
-
for (NSString *objectKey in self.unsavedObjects) {
|
185
|
-
[objectKeys addObject:objectKey];
|
186
|
-
}
|
187
|
-
|
188
|
-
NSMutableDictionary *info = [NSMutableDictionary dictionary];
|
189
|
-
|
190
|
-
if (nil != name) {
|
191
|
-
[info setObject:name forKey:NSF_Private_NSFNanoBag_Name];
|
192
|
-
}
|
193
|
-
[info setObject:self.key forKey:NSF_Private_NSFNanoBag_NSFKey];
|
194
|
-
[info setObject:objectKeys forKey:NSF_Private_NSFNanoBag_NSFObjectKeys];
|
195
|
-
|
196
|
-
return info;
|
197
|
-
}
|
198
|
-
|
199
209
|
#pragma mark -
|
200
210
|
|
201
211
|
- (BOOL)addObject:(id <NSFNanoObjectProtocol>)object error:(out NSError **)outError
|
202
212
|
{
|
203
213
|
if (NO == [(id)object conformsToProtocol:@protocol(NSFNanoObjectProtocol)]) {
|
204
214
|
[[NSException exceptionWithName:NSFNonConformingNanoObjectProtocolException
|
205
|
-
reason:[NSString stringWithFormat:@"*** -[%@
|
215
|
+
reason:[NSString stringWithFormat:@"*** -[%@ %@]: the object does not conform to NSFNanoObjectProtocol.", [self class], NSStringFromSelector(_cmd)]
|
206
216
|
userInfo:nil]raise];
|
207
217
|
}
|
208
218
|
|
@@ -210,16 +220,16 @@
|
|
210
220
|
NSDictionary *info = [(id)object dictionaryRepresentation];
|
211
221
|
|
212
222
|
if (objectKey && info) {
|
213
|
-
[
|
214
|
-
[
|
215
|
-
[
|
216
|
-
|
223
|
+
[_savedObjects removeObjectForKey:objectKey];
|
224
|
+
[_unsavedObjects setObject:object forKey:objectKey];
|
225
|
+
[_removedObjects removeObjectForKey:objectKey];
|
226
|
+
_hasUnsavedChanges = YES;
|
217
227
|
} else {
|
218
228
|
NSString *message = nil;
|
219
229
|
if (nil == objectKey)
|
220
|
-
message = [NSString stringWithFormat:@"*** -[%@
|
230
|
+
message = [NSString stringWithFormat:@"*** -[%@ %@]: unexpected NSFNanoObject behavior. Reason: the object's key is nil.", [self class], NSStringFromSelector(_cmd)];
|
221
231
|
else
|
222
|
-
message = [NSString stringWithFormat:@"*** -[%@
|
232
|
+
message = [NSString stringWithFormat:@"*** -[%@ %@]: unexpected NSFNanoObject behavior. Reason: the object's dictionary is nil.", [self class], NSStringFromSelector(_cmd)];
|
223
233
|
|
224
234
|
[[NSException exceptionWithName:NSFNanoObjectBehaviorException reason:message userInfo:nil]raise];
|
225
235
|
}
|
@@ -233,7 +243,7 @@
|
|
233
243
|
if (nil != outError) {
|
234
244
|
*outError = [NSError errorWithDomain:NSFDomainKey
|
235
245
|
code:NSFNanoStoreErrorKey
|
236
|
-
userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@
|
246
|
+
userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %@]: the object cannot be added because the list provided is nil.", [self class], NSStringFromSelector(_cmd)]
|
237
247
|
forKey:NSLocalizedFailureReasonErrorKey]];
|
238
248
|
}
|
239
249
|
return NO;
|
@@ -254,7 +264,7 @@
|
|
254
264
|
{
|
255
265
|
if (NO == [(id)object conformsToProtocol:@protocol(NSFNanoObjectProtocol)]) {
|
256
266
|
[[NSException exceptionWithName:NSFNonConformingNanoObjectProtocolException
|
257
|
-
reason:[NSString stringWithFormat:@"*** -[%@
|
267
|
+
reason:[NSString stringWithFormat:@"*** -[%@ %@]: the object does not conform to NSFNanoObjectProtocol.", [self class], NSStringFromSelector(_cmd)]
|
258
268
|
userInfo:nil]raise];
|
259
269
|
}
|
260
270
|
|
@@ -263,21 +273,20 @@
|
|
263
273
|
|
264
274
|
- (void)removeAllObjects
|
265
275
|
{
|
266
|
-
NSMutableDictionary *objects = [[NSMutableDictionary alloc]initWithCapacity:(
|
276
|
+
NSMutableDictionary *objects = [[NSMutableDictionary alloc]initWithCapacity:(_savedObjects.count + _removedObjects.count)];
|
267
277
|
|
268
278
|
// Save the object and its key
|
269
|
-
for (id object in
|
279
|
+
for (id object in _savedObjects) {
|
270
280
|
[objects setObject:object forKey:[object performSelector:@selector(key)]];
|
271
281
|
}
|
272
282
|
|
273
283
|
// Save the previously removed objects (if any)
|
274
|
-
[objects addEntriesFromDictionary:
|
275
|
-
|
276
|
-
[savedObjects removeAllObjects];
|
277
|
-
[unsavedObjects removeAllObjects];
|
278
|
-
[removedObjects setDictionary:objects];
|
279
|
-
hasUnsavedChanges = YES;
|
284
|
+
[objects addEntriesFromDictionary:_removedObjects];
|
280
285
|
|
286
|
+
[_savedObjects removeAllObjects];
|
287
|
+
[_unsavedObjects removeAllObjects];
|
288
|
+
[_removedObjects setDictionary:objects];
|
289
|
+
_hasUnsavedChanges = YES;
|
281
290
|
}
|
282
291
|
|
283
292
|
- (void)removeObjectsInArray:(NSArray *)someObjects
|
@@ -291,27 +300,27 @@
|
|
291
300
|
{
|
292
301
|
if (nil == objectKey) {
|
293
302
|
[[NSException exceptionWithName:NSFNanoObjectBehaviorException
|
294
|
-
reason:[NSString stringWithFormat:@"*** -[%@
|
303
|
+
reason:[NSString stringWithFormat:@"*** -[%@ %@]: unexpected NSFNanoObject behavior. Reason: the object's key is nil.", [self class], NSStringFromSelector(_cmd)]
|
295
304
|
userInfo:nil]raise];
|
296
305
|
}
|
297
306
|
|
298
307
|
// Is the object an existing one?
|
299
|
-
id object = [
|
308
|
+
id object = [_savedObjects objectForKey:objectKey];
|
300
309
|
if (nil != object) {
|
301
|
-
[
|
310
|
+
[_savedObjects removeObjectForKey:objectKey];
|
302
311
|
} else {
|
303
312
|
// Is the object still unsaved?
|
304
|
-
object = [
|
313
|
+
object = [_unsavedObjects objectForKey:objectKey];
|
305
314
|
if (nil != object) {
|
306
|
-
[
|
315
|
+
[_unsavedObjects removeObjectForKey:objectKey];
|
307
316
|
}
|
308
317
|
}
|
309
318
|
|
310
319
|
if (nil == object) {
|
311
320
|
// The object doesn't exist, so there is no need to mark the bag as dirty
|
312
321
|
} else {
|
313
|
-
[
|
314
|
-
|
322
|
+
[_removedObjects setObject:object forKey:objectKey];
|
323
|
+
_hasUnsavedChanges = YES;
|
315
324
|
}
|
316
325
|
}
|
317
326
|
|
@@ -328,58 +337,58 @@
|
|
328
337
|
return YES;
|
329
338
|
}
|
330
339
|
|
331
|
-
if (nil ==
|
340
|
+
if (nil == _store) {
|
332
341
|
if (nil != outError) {
|
333
342
|
*outError = [NSError errorWithDomain:NSFDomainKey
|
334
343
|
code:NSFNanoStoreErrorKey
|
335
|
-
userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@
|
344
|
+
userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %@]: unable to save the bag. Reason: the store has not been set.", [self class], NSStringFromSelector(_cmd)]
|
336
345
|
forKey:NSLocalizedFailureReasonErrorKey]];
|
337
346
|
}
|
338
347
|
return NO;
|
339
348
|
}
|
340
349
|
|
341
|
-
return [self _saveInStore:
|
350
|
+
return [self _saveInStore:_store error:outError];
|
342
351
|
}
|
343
352
|
|
344
353
|
#pragma mark -
|
345
354
|
|
346
355
|
- (void)deflateBag
|
347
356
|
{
|
348
|
-
NSArray *savedObjectsCopy = [[NSArray alloc]initWithArray:[
|
357
|
+
NSArray *savedObjectsCopy = [[NSArray alloc]initWithArray:[_savedObjects allKeys]];
|
349
358
|
|
350
359
|
for (id saveObjectKey in savedObjectsCopy) {
|
351
|
-
[
|
360
|
+
[_savedObjects setObject:[NSNull null] forKey:saveObjectKey];
|
352
361
|
}
|
353
362
|
|
354
363
|
}
|
355
364
|
|
356
365
|
- (void)inflateBag
|
357
366
|
{
|
358
|
-
NSArray *objectKeys = [
|
367
|
+
NSArray *objectKeys = [_savedObjects allKeys];
|
359
368
|
[self _inflateObjectsWithKeys:objectKeys];
|
360
369
|
}
|
361
370
|
|
362
371
|
- (BOOL)reloadBagWithError:(out NSError **)outError
|
363
372
|
{
|
364
373
|
// If the bag is not associated to a document store, there is no need to continue
|
365
|
-
if (nil ==
|
374
|
+
if (nil == _store) {
|
366
375
|
return YES;
|
367
376
|
}
|
368
377
|
|
369
378
|
// Refresh the bag to match the contents stored on the database
|
370
|
-
[self _inflateObjectsWithKeys:[NSArray arrayWithObject:
|
371
|
-
NSFNanoBag *savedBag = [
|
379
|
+
[self _inflateObjectsWithKeys:[NSArray arrayWithObject:_key]];
|
380
|
+
NSFNanoBag *savedBag = [_savedObjects objectForKey:_key];
|
372
381
|
if (nil != savedBag) {
|
373
|
-
[
|
374
|
-
[
|
375
|
-
for (NSString *objectKey in
|
376
|
-
[
|
382
|
+
[_savedObjects removeAllObjects];
|
383
|
+
[_savedObjects addEntriesFromDictionary:savedBag.savedObjects];
|
384
|
+
for (NSString *objectKey in _unsavedObjects) {
|
385
|
+
[_savedObjects removeObjectForKey:objectKey];
|
377
386
|
}
|
378
387
|
} else {
|
379
388
|
if (nil != outError) {
|
380
389
|
*outError = [NSError errorWithDomain:NSFDomainKey
|
381
390
|
code:NSFNanoStoreErrorKey
|
382
|
-
userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@
|
391
|
+
userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %@]: the bag could not be refreshed.", [self class], NSStringFromSelector(_cmd)]
|
383
392
|
forKey:NSLocalizedFailureReasonErrorKey]];
|
384
393
|
}
|
385
394
|
return NO;
|
@@ -390,11 +399,11 @@
|
|
390
399
|
|
391
400
|
- (BOOL)undoChangesWithError:(out NSError **)outError
|
392
401
|
{
|
393
|
-
[
|
394
|
-
[
|
395
|
-
[
|
402
|
+
[_savedObjects removeAllObjects];
|
403
|
+
[_unsavedObjects removeAllObjects];
|
404
|
+
[_removedObjects removeAllObjects];
|
396
405
|
|
397
|
-
|
406
|
+
_hasUnsavedChanges = NO;
|
398
407
|
|
399
408
|
return [self reloadBagWithError:outError];
|
400
409
|
}
|
@@ -408,18 +417,18 @@
|
|
408
417
|
- (id)initNanoObjectFromDictionaryRepresentation:(NSDictionary *)dictionary forKey:(NSString *)aKey store:(NSFNanoStore *)aStore
|
409
418
|
{
|
410
419
|
if ((self = [self init])) {
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
420
|
+
_name = [dictionary objectForKey:NSF_Private_NSFNanoBag_Name];
|
421
|
+
_store = aStore;
|
422
|
+
_key = aKey;
|
423
|
+
_savedObjects = [NSMutableDictionary new];
|
424
|
+
_unsavedObjects = [NSMutableDictionary new];
|
425
|
+
_removedObjects = [NSMutableDictionary new];
|
417
426
|
|
418
427
|
NSArray *objectKeys = [dictionary objectForKey:NSF_Private_NSFNanoBag_NSFObjectKeys];
|
419
428
|
|
420
429
|
[self _inflateObjectsWithKeys:objectKeys];
|
421
430
|
|
422
|
-
|
431
|
+
_hasUnsavedChanges = NO;
|
423
432
|
}
|
424
433
|
|
425
434
|
return self;
|
@@ -432,35 +441,35 @@
|
|
432
441
|
|
433
442
|
- (NSString *)nanoObjectKey
|
434
443
|
{
|
435
|
-
return
|
444
|
+
return _key;
|
436
445
|
}
|
437
446
|
|
438
447
|
- (void)_setStore:(NSFNanoStore *)aStore
|
439
448
|
{
|
440
|
-
|
449
|
+
_store = aStore;
|
441
450
|
}
|
442
451
|
|
443
452
|
- (BOOL)_saveInStore:(NSFNanoStore *)someStore error:(out NSError **)outError
|
444
453
|
{
|
445
454
|
// Save the unsaved objects first...
|
446
|
-
NSArray *contentsToBeSaved = [
|
455
|
+
NSArray *contentsToBeSaved = [_unsavedObjects allValues];
|
447
456
|
if ([contentsToBeSaved count] > 0) {
|
448
457
|
[someStore _addObjectsFromArray:contentsToBeSaved forceSave:YES error:outError];
|
449
458
|
}
|
450
459
|
|
451
460
|
// Move the existing objects to the unsaved list, in order to save the bag
|
452
|
-
[
|
453
|
-
[
|
454
|
-
[
|
461
|
+
[_unsavedObjects addEntriesFromDictionary:_savedObjects];
|
462
|
+
[_savedObjects removeAllObjects];
|
463
|
+
[_removedObjects removeAllObjects];
|
455
464
|
|
456
465
|
// Save the unsaved bag...
|
457
466
|
BOOL success = [someStore _addObjectsFromArray:[NSArray arrayWithObject:self] forceSave:YES error:outError];
|
458
467
|
|
459
468
|
if (YES == success) {
|
460
|
-
[
|
469
|
+
[_unsavedObjects removeAllObjects];
|
461
470
|
success = [self reloadBagWithError:outError];
|
462
471
|
if (YES == success) {
|
463
|
-
|
472
|
+
_hasUnsavedChanges = NO;
|
464
473
|
}
|
465
474
|
return success;
|
466
475
|
}
|
@@ -471,14 +480,14 @@
|
|
471
480
|
- (void)_inflateObjectsWithKeys:(NSArray *)someKeys
|
472
481
|
{
|
473
482
|
if ([someKeys count] != 0) {
|
474
|
-
NSFNanoSearch *search = [NSFNanoSearch searchWithStore:
|
483
|
+
NSFNanoSearch *search = [NSFNanoSearch searchWithStore:_store];
|
475
484
|
NSString *quotedString = [NSFNanoSearch _quoteStrings:someKeys joiningWithDelimiter:@","];
|
476
|
-
NSString *theSQLStatement = [NSString stringWithFormat:@"SELECT NSFKey,
|
485
|
+
NSString *theSQLStatement = [NSString stringWithFormat:@"SELECT NSFKey, NSFKeyedArchive, NSFObjectClass FROM NSFKeys WHERE NSFKey IN (%@)", quotedString];
|
477
486
|
|
478
487
|
NSDictionary *results = [search executeSQL:theSQLStatement returnType:NSFReturnObjects error:nil];
|
479
488
|
|
480
489
|
if (nil != results) {
|
481
|
-
[
|
490
|
+
[_savedObjects addEntriesFromDictionary:results];
|
482
491
|
}
|
483
492
|
}
|
484
493
|
}
|