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.
Files changed (78) hide show
  1. data/{CHANGELOG → CHANGELOG.md} +7 -0
  2. data/README.md +5 -1
  3. data/Rakefile +1 -1
  4. data/lib/nano_store.rb +1 -1
  5. data/lib/nano_store/finder.rb +10 -2
  6. data/lib/nano_store/model.rb +7 -7
  7. data/lib/nano_store/version.rb +1 -1
  8. data/spec/association_spec.rb +6 -6
  9. data/spec/finder_spec.rb +2 -0
  10. data/spec/model_spec.rb +33 -3
  11. data/spec/nano_store_spec.rb +5 -0
  12. data/spec/spec_helper.rb +14 -0
  13. data/vendor/Podfile.lock +3 -3
  14. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoBag.h +6 -1
  15. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoEngine.h +5 -0
  16. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoEngine_Private.h +2 -0
  17. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoExpression.h +6 -0
  18. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoExpression_Private.h +1 -1
  19. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoGlobals.h +5 -1
  20. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoGlobals_Private.h +6 -2
  21. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoObject.h +15 -3
  22. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoObject_Private.h +4 -0
  23. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoPredicate.h +6 -1
  24. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoResult.h +5 -0
  25. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoSearch.h +16 -2
  26. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoSortDescriptor.h +7 -1
  27. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoStore.h +12 -0
  28. data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoStore_Private.h +3 -1
  29. data/vendor/Pods/BuildHeaders/NanoStore/NSFOrderedDictionary.h +33 -0
  30. data/vendor/Pods/BuildHeaders/NanoStore/NanoStore.h +36 -0
  31. data/vendor/Pods/Headers/NanoStore/NSFNanoBag.h +6 -1
  32. data/vendor/Pods/Headers/NanoStore/NSFNanoEngine.h +5 -0
  33. data/vendor/Pods/Headers/NanoStore/NSFNanoEngine_Private.h +2 -0
  34. data/vendor/Pods/Headers/NanoStore/NSFNanoExpression.h +6 -0
  35. data/vendor/Pods/Headers/NanoStore/NSFNanoExpression_Private.h +1 -1
  36. data/vendor/Pods/Headers/NanoStore/NSFNanoGlobals.h +5 -1
  37. data/vendor/Pods/Headers/NanoStore/NSFNanoGlobals_Private.h +6 -2
  38. data/vendor/Pods/Headers/NanoStore/NSFNanoObject.h +15 -3
  39. data/vendor/Pods/Headers/NanoStore/NSFNanoObject_Private.h +4 -0
  40. data/vendor/Pods/Headers/NanoStore/NSFNanoPredicate.h +6 -1
  41. data/vendor/Pods/Headers/NanoStore/NSFNanoResult.h +5 -0
  42. data/vendor/Pods/Headers/NanoStore/NSFNanoSearch.h +16 -2
  43. data/vendor/Pods/Headers/NanoStore/NSFNanoSortDescriptor.h +7 -1
  44. data/vendor/Pods/Headers/NanoStore/NSFNanoStore.h +12 -0
  45. data/vendor/Pods/Headers/NanoStore/NSFNanoStore_Private.h +3 -1
  46. data/vendor/Pods/Headers/NanoStore/NSFOrderedDictionary.h +33 -0
  47. data/vendor/Pods/Headers/NanoStore/NanoStore.h +36 -0
  48. data/vendor/Pods/NanoStore/Classes/Advanced/NSFNanoEngine.h +5 -0
  49. data/vendor/Pods/NanoStore/Classes/Advanced/NSFNanoEngine.m +142 -131
  50. data/vendor/Pods/NanoStore/Classes/Advanced/NSFNanoResult.h +5 -0
  51. data/vendor/Pods/NanoStore/Classes/Advanced/NSFNanoResult.m +148 -51
  52. data/vendor/Pods/NanoStore/Classes/Advanced/NSFOrderedDictionary.h +33 -0
  53. data/vendor/Pods/NanoStore/Classes/Advanced/NSFOrderedDictionary.m +148 -0
  54. data/vendor/Pods/NanoStore/Classes/Private/NSFNanoEngine_Private.h +2 -0
  55. data/vendor/Pods/NanoStore/Classes/Private/NSFNanoExpression_Private.h +1 -1
  56. data/vendor/Pods/NanoStore/Classes/Private/NSFNanoGlobals_Private.h +6 -2
  57. data/vendor/Pods/NanoStore/Classes/Private/NSFNanoObject_Private.h +4 -0
  58. data/vendor/Pods/NanoStore/Classes/Private/NSFNanoStore_Private.h +3 -1
  59. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoBag.h +6 -1
  60. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoBag.m +126 -117
  61. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoExpression.h +6 -0
  62. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoExpression.m +32 -18
  63. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoGlobals.h +5 -1
  64. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoGlobals.m +6 -3
  65. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoObject.h +15 -3
  66. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoObject.m +152 -31
  67. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoPredicate.h +6 -1
  68. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoPredicate.m +51 -26
  69. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSearch.h +16 -2
  70. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSearch.m +156 -115
  71. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSortDescriptor.h +7 -1
  72. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSortDescriptor.m +34 -17
  73. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoStore.h +12 -0
  74. data/vendor/Pods/NanoStore/Classes/Public/NSFNanoStore.m +210 -196
  75. data/vendor/Pods/NanoStore/Classes/Public/NanoStore.h +36 -0
  76. data/vendor/Pods/NanoStore/README.md +49 -0
  77. data/vendor/Pods/Pods.bridgesupport +798 -685
  78. metadata +30 -8
@@ -75,7 +75,7 @@
75
75
  @interface NSFNanoSortDescriptor : NSObject
76
76
 
77
77
  /** * The property key to use when performing a comparison */
78
- @property (nonatomic, readonly) NSString *attribute;
78
+ @property (nonatomic, copy, readonly) NSString *attribute;
79
79
  /** * The property to indicate whether the comparison should be performed in ascending mode */
80
80
  @property (nonatomic, readonly) BOOL isAscending;
81
81
 
@@ -119,6 +119,12 @@
119
119
 
120
120
  - (NSString *)description;
121
121
 
122
+ /** Returns a JSON representation of the sort.
123
+ * @note Check properties attribute and isAscending to find out the current state of the sort.
124
+ */
125
+
126
+ - (NSString *)JSONDescription;
127
+
122
128
  //@}
123
129
 
124
130
  @end
@@ -26,16 +26,19 @@
26
26
 
27
27
  #import "NSFNanoSortDescriptor.h"
28
28
  #import "NSFNanoGlobals.h"
29
+ #import "NSFOrderedDictionary.h"
30
+ #import "NSFNanoObject_Private.h"
29
31
 
30
- @implementation NSFNanoSortDescriptor
31
- {
32
- /** \cond */
33
- NSString *attribute;
34
- BOOL isAscending;
35
- /** \endcond */
36
- }
32
+ @interface NSFNanoSortDescriptor ()
33
+
34
+ /** \cond */
35
+ @property (nonatomic, copy, readwrite) NSString *attribute;
36
+ @property (nonatomic, readwrite) BOOL isAscending;
37
+ /** \endcond */
37
38
 
38
- @synthesize attribute, isAscending;
39
+ @end
40
+
41
+ @implementation NSFNanoSortDescriptor
39
42
 
40
43
  + (NSFNanoSortDescriptor *)sortDescriptorWithAttribute:(NSString *)theAttribute ascending:(BOOL)ascending
41
44
  {
@@ -46,12 +49,12 @@
46
49
  {
47
50
  if (theAttribute.length == 0)
48
51
  [[NSException exceptionWithName:NSFUnexpectedParameterException
49
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: theAttribute is invalid.", [self class], _cmd]
52
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: theAttribute is invalid.", [self class], NSStringFromSelector(_cmd)]
50
53
  userInfo:nil]raise];
51
54
 
52
55
  if ((self = [super init])) {
53
- attribute = [theAttribute copy];
54
- isAscending = ascending;
56
+ _attribute = theAttribute;
57
+ _isAscending = ascending;
55
58
  }
56
59
 
57
60
  return self;
@@ -64,14 +67,28 @@
64
67
 
65
68
  #pragma mark -
66
69
 
67
- - (NSString*)description
70
+ - (NSString *)description
71
+ {
72
+ return [self JSONDescription];
73
+ }
74
+
75
+ - (NSFOrderedDictionary *)dictionaryDescription
76
+ {
77
+ NSFOrderedDictionary *values = [NSFOrderedDictionary new];
78
+
79
+ values[@"Sort descriptor address"] = [NSString stringWithFormat:@"%p", self];
80
+ values[@"Attribute"] = _attribute;
81
+ values[@"Is ascending?"] = (_isAscending ? @"YES" : @"NO");
82
+
83
+ return values;
84
+ }
85
+
86
+ - (NSString *)JSONDescription
68
87
  {
69
- NSMutableString *description = [NSMutableString string];
88
+ NSFOrderedDictionary *values = [self dictionaryDescription];
70
89
 
71
- [description appendString:@"\n"];
72
- [description appendString:[NSString stringWithFormat:@"Sort descriptor address : 0x%x\n", self]];
73
- [description appendString:[NSString stringWithFormat:@"Attribute : %@\n", attribute]];
74
- [description appendString:[NSString stringWithFormat:@"Is ascending? : %@\n", (isAscending ? @"YES" : @"NO")]];
90
+ NSError *outError = nil;
91
+ NSString *description = [NSFNanoObject _NSObjectToJSONString:values error:&outError];
75
92
 
76
93
  return description;
77
94
  }
@@ -297,6 +297,13 @@
297
297
 
298
298
  - (NSFNanoBag *)bagWithName:(NSString *)theName;
299
299
 
300
+ /** * Retrieves all bags associated with the specified name.
301
+ * @param theName the name of the bag.
302
+ * @returns The bags that match the specified name, an empty array otherwise.
303
+ */
304
+
305
+ - (NSArray *)bagsWithName:(NSString *)theName;
306
+
300
307
  /** * Returns a new array containing the bags found in the document store matching the specified list of keys.
301
308
  * @param theKeys the list of bag keys.
302
309
  * @returns An array with the bags that match the specified list of keys.
@@ -470,6 +477,11 @@
470
477
 
471
478
  - (NSString *)description;
472
479
 
480
+ /** Returns a JSON representation of the store.
481
+ */
482
+
483
+ - (NSString *)JSONDescription;
484
+
473
485
  //@}
474
486
 
475
487
  @end
@@ -6,7 +6,7 @@
6
6
 
7
7
  Redistribution and use in source and binary forms, with or without modification, are permitted
8
8
  provided that the following conditions are met:
9
-
9
+
10
10
  * Redistributions of source code must retain the above copyright notice, this list of conditions
11
11
  and the following disclaimer.
12
12
  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
@@ -28,23 +28,26 @@
28
28
  #import "NSFNanoObjectProtocol.h"
29
29
  #import "NanoStore_Private.h"
30
30
  #import "NSFNanoStore_Private.h"
31
+ #import "NSFNanoEngine_Private.h"
32
+ #import "NSFOrderedDictionary.h"
31
33
 
32
34
  #include <stdlib.h>
33
35
 
36
+ @interface NSFNanoStore ()
37
+
38
+ /** \cond */
39
+ @property (nonatomic, strong, readwrite) NSFNanoEngine *nanoStoreEngine;
40
+ @property (nonatomic, readwrite) BOOL hasUnsavedChanges;
41
+ @property (nonatomic) NSMutableArray *addedObjects;
42
+ @property (nonatomic) BOOL isOurTransaction;
43
+ @property (nonatomic, assign) sqlite3_stmt *insertDeleteKeysStatement;
44
+ @property (nonatomic, assign) sqlite3_stmt *storeValuesStatement;
45
+ @property (nonatomic, assign) sqlite3_stmt *storeKeysStatement;
46
+ /** \endcond */
47
+
48
+ @end
49
+
34
50
  @implementation NSFNanoStore
35
- {
36
- @protected
37
- NSFNanoEngine *nanoStoreEngine;
38
- NSFEngineProcessingMode nanoEngineProcessingMode;
39
- NSUInteger saveInterval;
40
-
41
- /** \cond */
42
- NSMutableArray *addedObjects;
43
- BOOL _isOurTransaction;
44
- sqlite3_stmt *_storeValuesStatement;
45
- sqlite3_stmt *_storeKeysStatement;
46
- /** \endcond */
47
- }
48
51
 
49
52
  @synthesize nanoStoreEngine;
50
53
  @synthesize nanoEngineProcessingMode;
@@ -82,14 +85,14 @@
82
85
 
83
86
  if (nil == thePath) {
84
87
  [[NSException exceptionWithName:NSFUnexpectedParameterException
85
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: the path cannot be nil.", [self class], _cmd]
88
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: the path cannot be nil.", [self class], NSStringFromSelector(_cmd)]
86
89
  userInfo:nil]raise];
87
90
  }
88
91
 
89
92
  if ((self = [super init])) {
90
93
  nanoStoreEngine = [[NSFNanoEngine alloc]initWithPath:[thePath stringByExpandingTildeInPath]];
91
94
  if (nil == nanoStoreEngine) {
92
- _NSFLog([NSString stringWithFormat:@"*** -[%@ %s]: [NSFNanoEngine initWithPath:] failed: %@", [self class], _cmd, thePath]);
95
+ _NSFLog([NSString stringWithFormat:@"*** -[%@ %@]: [NSFNanoEngine initWithPath:] failed: %@", [self class], NSStringFromSelector(_cmd), thePath]);
93
96
  [self closeWithError:nil];
94
97
  return nil;
95
98
  }
@@ -99,10 +102,11 @@
99
102
  _isOurTransaction = NO;
100
103
  saveInterval = 1;
101
104
 
105
+ _insertDeleteKeysStatement = NULL;
102
106
  _storeValuesStatement = NULL;
103
107
  _storeKeysStatement = NULL;
104
108
 
105
- addedObjects = [[NSMutableArray alloc]initWithCapacity:saveInterval];
109
+ _addedObjects = [[NSMutableArray alloc]initWithCapacity:saveInterval];
106
110
  }
107
111
 
108
112
  return self;
@@ -111,8 +115,6 @@
111
115
  - (void)dealloc
112
116
  {
113
117
  [self closeWithError:nil];
114
-
115
-
116
118
  }
117
119
 
118
120
  - (NSString *)filePath
@@ -126,7 +128,7 @@
126
128
  return YES;
127
129
 
128
130
  if ([nanoStoreEngine openWithCacheMethod:CacheAllData useFastMode:(NSFEngineProcessingFastMode == nanoEngineProcessingMode)] == NO) {
129
- NSString *message = [NSString stringWithFormat:@"*** -[%@ %s]: open database failed: %@", [self class], _cmd, [self filePath]];
131
+ NSString *message = [NSString stringWithFormat:@"*** -[%@ %@]: open database failed: %@", [self class], NSStringFromSelector(_cmd), [self filePath]];
130
132
  _NSFLog(message);
131
133
  if (nil != outError)
132
134
  *outError = [NSError errorWithDomain:NSFDomainKey
@@ -138,7 +140,7 @@
138
140
  }
139
141
 
140
142
  if ([self _setupCachingSchema] == NO) {
141
- NSString *message = [NSString stringWithFormat:@"*** -[%@ %s]: the schema could not be created when opening database: %@", [self class], _cmd, [self filePath]];
143
+ NSString *message = [NSString stringWithFormat:@"*** -[%@ %@]: the schema could not be created when opening database: %@", [self class], NSStringFromSelector(_cmd), [self filePath]];
142
144
  _NSFLog(message);
143
145
  if (nil != outError)
144
146
  *outError = [NSError errorWithDomain:NSFDomainKey
@@ -150,7 +152,7 @@
150
152
  }
151
153
 
152
154
  if ([self _initializePreparedStatementsWithError:outError] == NO) {
153
- NSString *message = [NSString stringWithFormat:@"*** -[%@ %s]: the SQL statements could not be prepared when opening database: %@", [self class], _cmd, [self filePath]];
155
+ NSString *message = [NSString stringWithFormat:@"*** -[%@ %@]: the SQL statements could not be prepared when opening database: %@", [self class], NSStringFromSelector(_cmd), [self filePath]];
154
156
  _NSFLog(message);
155
157
  [self closeWithError:nil];
156
158
  return NO;
@@ -173,14 +175,36 @@
173
175
  return ([nanoStoreEngine isDatabaseOpen] == NO);
174
176
  }
175
177
 
176
- - (NSString*)description
178
+ - (NSString *)description
177
179
  {
178
- return [self _nestedDescriptionWithPrefixedSpace:@""];
180
+ return [self JSONDescription];
181
+ }
182
+
183
+ - (NSFOrderedDictionary *)dictionaryDescription
184
+ {
185
+ NSFOrderedDictionary *values = [NSFOrderedDictionary new];
186
+
187
+ values[@"NanoStore address"] = [NSString stringWithFormat:@"%p", self];
188
+ values[@"Is our transaction?"] = (_isOurTransaction ? @"YES" : @"NO");
189
+ values[@"Save interval"] = (saveInterval ? @(saveInterval) : @(1));
190
+ values[@"Engine"] = [nanoStoreEngine dictionaryDescription];
191
+
192
+ return values;
193
+ }
194
+
195
+ - (NSString *)JSONDescription
196
+ {
197
+ NSFOrderedDictionary *values = [self dictionaryDescription];
198
+
199
+ NSError *outError = nil;
200
+ NSString *description = [NSFNanoObject _NSObjectToJSONString:values error:&outError];
201
+
202
+ return description;
179
203
  }
180
204
 
181
205
  - (BOOL)hasUnsavedChanges
182
206
  {
183
- return ([addedObjects count] > 0);
207
+ return ([_addedObjects count] > 0);
184
208
  }
185
209
 
186
210
  #pragma mark -
@@ -196,16 +220,17 @@
196
220
  {
197
221
  if (nil == someObjects) {
198
222
  [[NSException exceptionWithName:NSFUnexpectedParameterException
199
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: someObjects is nil.", [self class], _cmd]
223
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: someObjects is nil.", [self class], NSStringFromSelector(_cmd)]
200
224
  userInfo:nil]raise];
201
225
  }
202
226
 
203
227
  if ([someObjects count] == 0) {
204
- if (nil != outError)
228
+ if (nil != outError) {
205
229
  *outError = [NSError errorWithDomain:NSFDomainKey
206
230
  code:NSFNanoStoreErrorKey
207
- userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %s]: ([someObjects count] == 0)", [self class], _cmd]
231
+ userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %@]: ([someObjects count] == 0)", [self class], NSStringFromSelector(_cmd)]
208
232
  forKey:NSLocalizedFailureReasonErrorKey]];
233
+ }
209
234
  return NO;
210
235
  }
211
236
 
@@ -216,47 +241,32 @@
216
241
  // If it's a bag, make sure the name is unique
217
242
  if (YES == [object isKindOfClass:[NSFNanoBag class]]) {
218
243
  NSFNanoBag *bag = (NSFNanoBag *)object;
219
- NSString *bagName = bag.name;
220
- if (bagName.length > 0) {
221
- NSFNanoBag *bagWithSameName = [self bagWithName:bagName];
222
- if (nil != bagWithSameName) {
223
- if (nil != outError) {
224
- *outError = [NSError errorWithDomain:NSFDomainKey
225
- code:NSFNanoStoreErrorKey
226
- userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %s]: a bag named '%@' already exists.", [self class], _cmd, bagName]
227
- forKey:NSLocalizedFailureReasonErrorKey]];
228
-
229
- return NO;
230
- }
231
- }
232
- }
233
-
234
244
 
235
245
  // If it's a bag, process it first by gathering. If it's not dirty, there's no need to save...
236
- if (YES == [object hasUnsavedChanges]) {
246
+ if (YES == [bag hasUnsavedChanges]) {
237
247
  NSError *error = nil;
238
248
 
239
249
  // Associate the bag to this store
240
- if (nil == [object store]) {
250
+ if (nil == [bag store]) {
241
251
  [object _setStore:self];
242
252
  }
243
253
 
244
- if (NO == [object _saveInStore:self error:&error]) {
254
+ if (NO == [bag _saveInStore:self error:&error]) {
245
255
  [[NSException exceptionWithName:NSFNanoStoreUnableToManipulateStoreException
246
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: %@", [self class], _cmd, [error localizedDescription]]
256
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: %@", [self class], NSStringFromSelector(_cmd), [error localizedDescription]]
247
257
  userInfo:nil]raise];
248
258
  }
249
259
  }
250
260
  } else {
251
261
  if (NO == [(id)object conformsToProtocol:@protocol(NSFNanoObjectProtocol)]) {
252
262
  [[NSException exceptionWithName:NSFNonConformingNanoObjectProtocolException
253
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: the object does not conform to NSFNanoObjectProtocol.", [self class], _cmd]
263
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: the object does not conform to NSFNanoObjectProtocol.", [self class], NSStringFromSelector(_cmd)]
254
264
  userInfo:nil]raise];
255
265
  }
256
266
 
257
267
  if (nil == [object nanoObjectKey]) {
258
268
  [[NSException exceptionWithName:NSFNanoObjectBehaviorException
259
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: unexpected NSFNanoObject behavior. Reason: the object's key is nil.", [self class], _cmd]
269
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: unexpected NSFNanoObject behavior. Reason: the object's key is nil.", [self class], NSStringFromSelector(_cmd)]
260
270
  userInfo:nil]raise];
261
271
  }
262
272
 
@@ -284,7 +294,7 @@
284
294
 
285
295
  if (nil == someKeys)
286
296
  [[NSException exceptionWithName:NSFUnexpectedParameterException
287
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: someKeys is nil.", [self class], _cmd]
297
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: someKeys is nil.", [self class], NSStringFromSelector(_cmd)]
288
298
  userInfo:nil]raise];
289
299
 
290
300
  NSUInteger count = [someKeys count];
@@ -297,31 +307,38 @@
297
307
  NSString *theSQLStatement = [[NSString alloc]initWithFormat:@"CREATE TEMP TABLE %@(x);", NSF_Private_ToDeleteTableKey];
298
308
  [nanoStoreEngine executeSQL:theSQLStatement];
299
309
 
300
- sqlite3_stmt *statement;
301
- theSQLStatement = [[NSString alloc]initWithFormat:@"INSERT INTO %@ VALUES (?);", NSF_Private_ToDeleteTableKey];
302
- BOOL success = [self _prepareSQLite3Statement:&statement theSQLStatement:theSQLStatement];
303
-
304
- if (success) {
305
- for (NSString *key in someKeys) {
306
- int status = sqlite3_reset (statement);
307
- if (SQLITE_OK != status) {
308
- break;
309
- }
310
-
311
- // Bind and execute the statement...
312
- status = sqlite3_bind_text ( statement, 1, [key UTF8String], -1, SQLITE_STATIC);
313
-
314
- // Since we're operating with extended result code support, extract the bits
315
- // and obtain the regular result code
316
- // For more info check: http://www.sqlite.org/c3ref/c_ioerr_access.html
317
-
318
- status = [NSFNanoEngine NSFP_stripBitsFromExtendedResultCode:status];
319
-
320
- if (SQLITE_OK == status) {
321
- [self _executeSQLite3StepUsingSQLite3Statement:statement];
310
+ if (NULL == _insertDeleteKeysStatement) {
311
+ theSQLStatement = [[NSString alloc]initWithFormat:@"INSERT INTO %@ VALUES (?);", NSF_Private_ToDeleteTableKey];
312
+ BOOL success = [self _prepareSQLite3Statement:&_insertDeleteKeysStatement theSQLStatement:theSQLStatement];
313
+ if (NO == success) {
314
+ if (nil != outError) {
315
+ *outError = [NSError errorWithDomain:NSFDomainKey
316
+ code:NSFNanoStoreErrorKey
317
+ userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %@]: failed to prepare _insertDeleteKeysStatement.", [self class], NSStringFromSelector(_cmd)]
318
+ forKey:NSLocalizedFailureReasonErrorKey]];
322
319
  }
320
+ return NO;
321
+ }
322
+ }
323
+
324
+ for (NSString *key in someKeys) {
325
+ int status = sqlite3_reset (_insertDeleteKeysStatement);
326
+ if (SQLITE_OK != status) {
327
+ break;
328
+ }
329
+
330
+ // Bind and execute the statement...
331
+ status = sqlite3_bind_text ( _insertDeleteKeysStatement, 1, [key UTF8String], -1, SQLITE_STATIC);
332
+
333
+ // Since we're operating with extended result code support, extract the bits
334
+ // and obtain the regular result code
335
+ // For more info check: http://www.sqlite.org/c3ref/c_ioerr_access.html
336
+
337
+ status = [NSFNanoEngine NSFP_stripBitsFromExtendedResultCode:status];
338
+
339
+ if (SQLITE_OK == status) {
340
+ [self _executeSQLite3StepUsingSQLite3Statement:_insertDeleteKeysStatement];
323
341
  }
324
- sqlite3_finalize(statement);
325
342
  }
326
343
 
327
344
  _NSFLog(@" Before removing the keys to be stored from NSFKeys...");
@@ -351,13 +368,13 @@
351
368
  for (id object in someObjects) {
352
369
  if (NO == [(id)object conformsToProtocol:@protocol(NSFNanoObjectProtocol)]) {
353
370
  [[NSException exceptionWithName:NSFNonConformingNanoObjectProtocolException
354
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: the object does not conform to NSFNanoObjectProtocol.", [self class], _cmd]
371
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: the object does not conform to NSFNanoObjectProtocol.", [self class], NSStringFromSelector(_cmd)]
355
372
  userInfo:nil]raise];
356
373
  } else {
357
374
  NSString *objectKey = [(id)object nanoObjectKey];
358
375
  if (nil == objectKey) {
359
376
  [[NSException exceptionWithName:NSFNanoObjectBehaviorException
360
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: unexpected NSFNanoObject behavior. Reason: the object's key is nil.", [self class], _cmd]
377
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: unexpected NSFNanoObject behavior. Reason: the object's key is nil.", [self class], NSStringFromSelector(_cmd)]
361
378
  userInfo:nil]raise];
362
379
  }
363
380
  [someKeys addObject:objectKey];
@@ -374,7 +391,7 @@
374
391
  - (NSArray *)bags
375
392
  {
376
393
  NSFNanoSearch *search = [NSFNanoSearch searchWithStore:self];
377
- NSString *theSQLStatement = [NSString stringWithFormat:@"SELECT NSFKey, NSFPlist, NSFObjectClass FROM NSFKeys WHERE NSFObjectClass = \"%@\"", NSStringFromClass([NSFNanoBag class])];
394
+ NSString *theSQLStatement = [NSString stringWithFormat:@"SELECT NSFKey, NSFKeyedArchive, NSFObjectClass FROM NSFKeys WHERE NSFObjectClass = \"%@\"", NSStringFromClass([NSFNanoBag class])];
378
395
 
379
396
  return [[search executeSQL:theSQLStatement returnType:NSFReturnObjects error:nil]allValues];
380
397
 
@@ -388,10 +405,20 @@
388
405
  search.match = NSFEqualTo;
389
406
  search.value = theName;
390
407
 
391
- // Returns a dictionary with the UUID of the object (key) and the NanoObject (value).
392
408
  return [[[search searchObjectsWithReturnType:NSFReturnObjects error:nil]allObjects]lastObject];
393
409
  }
394
410
 
411
+ - (NSArray *)bagsWithName:(NSString *)theName
412
+ {
413
+ NSFNanoSearch *search = [NSFNanoSearch searchWithStore:self];
414
+
415
+ search.attribute = NSF_Private_NSFNanoBag_Name;
416
+ search.match = NSFEqualTo;
417
+ search.value = theName;
418
+
419
+ return [[search searchObjectsWithReturnType:NSFReturnObjects error:nil]allObjects];
420
+ }
421
+
395
422
  - (NSArray *)bagsWithKeysInArray:(NSArray *)someKeys
396
423
  {
397
424
  if ([someKeys count] == 0) {
@@ -400,7 +427,7 @@
400
427
 
401
428
  NSFNanoSearch *search = [NSFNanoSearch searchWithStore:self];
402
429
  NSString *quotedString = [NSFNanoSearch _quoteStrings:someKeys joiningWithDelimiter:@","];
403
- NSString *theSQLStatement = [NSString stringWithFormat:@"SELECT NSFKey, NSFPlist, NSFObjectClass FROM NSFKeys WHERE NSFKey IN (%@) AND NSFObjectClass = \"%@\"", quotedString, NSStringFromClass([NSFNanoBag class])];
430
+ NSString *theSQLStatement = [NSString stringWithFormat:@"SELECT NSFKey, NSFKeyedArchive, NSFObjectClass FROM NSFKeys WHERE NSFKey IN (%@) AND NSFObjectClass = \"%@\"", quotedString, NSStringFromClass([NSFNanoBag class])];
404
431
 
405
432
  return [[search executeSQL:theSQLStatement returnType:NSFReturnObjects error:nil]allValues];
406
433
  }
@@ -412,7 +439,7 @@
412
439
  }
413
440
 
414
441
  NSFNanoSearch *search = [NSFNanoSearch searchWithStore:self];
415
- NSString *theSQLStatement = [NSString stringWithFormat:@"SELECT NSFKey, NSFPlist, NSFObjectClass FROM NSFKeys WHERE NSFKey IN (SELECT DISTINCT (NSFKEY) FROM NSFValues WHERE NSFValue = \"%@\") AND NSFObjectClass = \"%@\"", aKey, NSStringFromClass([NSFNanoBag class])];
442
+ NSString *theSQLStatement = [NSString stringWithFormat:@"SELECT NSFKey, NSFKeyedArchive, NSFObjectClass FROM NSFKeys WHERE NSFKey IN (SELECT DISTINCT (NSFKEY) FROM NSFValues WHERE NSFValue = \"%@\") AND NSFObjectClass = \"%@\"", aKey, NSStringFromClass([NSFNanoBag class])];
416
443
 
417
444
  return [[search executeSQL:theSQLStatement returnType:NSFReturnObjects error:nil]allValues];
418
445
  }
@@ -425,7 +452,7 @@
425
452
 
426
453
  NSFNanoSearch *search = [NSFNanoSearch searchWithStore:self];
427
454
  NSString *quotedString = [NSFNanoSearch _quoteStrings:someKeys joiningWithDelimiter:@","];
428
- NSString *theSQLStatement = [NSString stringWithFormat:@"SELECT NSFKey, NSFPlist, NSFObjectClass FROM NSFKeys WHERE NSFKey IN (%@)", quotedString];
455
+ NSString *theSQLStatement = [NSString stringWithFormat:@"SELECT NSFKey, NSFKeyedArchive, NSFObjectClass FROM NSFKeys WHERE NSFKey IN (%@)", quotedString];
429
456
 
430
457
  return [[search executeSQL:theSQLStatement returnType:NSFReturnObjects error:nil]allValues];
431
458
  }
@@ -446,14 +473,14 @@
446
473
  {
447
474
  if (nil == theClassName) {
448
475
  [[NSException exceptionWithName:NSFUnexpectedParameterException
449
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: the class name cannot be nil.", [self class], _cmd]
476
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: the class name cannot be nil.", [self class], NSStringFromSelector(_cmd)]
450
477
  userInfo:nil]raise];
451
478
  }
452
479
 
453
480
  NSFNanoSearch *search = [NSFNanoSearch searchWithStore:self];
454
481
  search.sort = theSortDescriptors;
455
482
 
456
- NSString *theSQLStatement = [NSString stringWithFormat:@"SELECT NSFKey, NSFPlist, NSFObjectClass FROM NSFKeys WHERE NSFObjectClass = \"%@\"", theClassName];
483
+ NSString *theSQLStatement = [NSString stringWithFormat:@"SELECT NSFKey, NSFKeyedArchive, NSFObjectClass FROM NSFKeys WHERE NSFObjectClass = \"%@\"", theClassName];
457
484
 
458
485
  if (nil == theSortDescriptors)
459
486
  return [[search executeSQL:theSQLStatement returnType:NSFReturnObjects error:nil] allValues];
@@ -465,7 +492,7 @@
465
492
  {
466
493
  if (nil == theClassName) {
467
494
  [[NSException exceptionWithName:NSFUnexpectedParameterException
468
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: the class name cannot be nil.", [self class], _cmd]
495
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: the class name cannot be nil.", [self class], NSStringFromSelector(_cmd)]
469
496
  userInfo:nil]raise];
470
497
  }
471
498
 
@@ -532,7 +559,7 @@
532
559
  - (BOOL)saveStoreAndReturnError:(out NSError **)outError
533
560
  {
534
561
  // We are really not saving anything new, just indicating that we should commit the unsaved changes.
535
- if (NO == self.hasUnsavedChanges) {
562
+ if (NO == _hasUnsavedChanges) {
536
563
  return YES;
537
564
  }
538
565
 
@@ -541,7 +568,7 @@
541
568
 
542
569
  - (void)discardUnsavedChanges
543
570
  {
544
- [addedObjects removeAllObjects];
571
+ [_addedObjects removeAllObjects];
545
572
  }
546
573
 
547
574
  // ----------------------------------------------
@@ -633,7 +660,7 @@
633
660
  {
634
661
  if (nil == path)
635
662
  [[NSException exceptionWithName:NSFUnexpectedParameterException
636
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: path is nil.", [self class], _cmd]
663
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: path is nil.", [self class], NSStringFromSelector(_cmd)]
637
664
  userInfo:nil]raise];
638
665
 
639
666
  // Make sure we've expanded the tilde
@@ -643,11 +670,12 @@
643
670
  return NO;
644
671
 
645
672
  if ([[self nanoStoreEngine]isTransactionActive]) {
646
- if (nil != outError)
673
+ if (nil != outError) {
647
674
  *outError = [NSError errorWithDomain:NSFDomainKey
648
675
  code:NSFNanoStoreErrorKey
649
676
  userInfo:[NSDictionary dictionaryWithObject:@"Cannot backup store. A transaction is still open."
650
677
  forKey:NSLocalizedDescriptionKey]];
678
+ }
651
679
  return NO;
652
680
  }
653
681
 
@@ -667,12 +695,12 @@
667
695
 
668
696
  + (NSFNanoStore *)_createAndOpenDebugDatabase
669
697
  {
670
- NSFNanoStore *db = [NSFNanoStore createStoreWithType:NSFPersistentStoreType path:[@"~/Desktop/NanoStoreDebug.db" stringByExpandingTildeInPath]];
698
+ NSFNanoStore *db = [NSFNanoStore createStoreWithType:NSFPersistentStoreType path:[@"~/Desktop/NanoStoreDebug.sqlite" stringByExpandingTildeInPath]];
671
699
  NSError *outError = nil;
672
700
 
673
701
  if (NO == [db openWithError:&outError]) {
674
702
  [[NSException exceptionWithName:NSFNanoStoreUnableToManipulateStoreException
675
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: could not open the database. Reason: %@", [self class], _cmd, [outError localizedDescription]]
703
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: could not open the database. Reason: %@", [self class], NSStringFromSelector(_cmd), [outError localizedDescription]]
676
704
  userInfo:nil]raise];
677
705
  }
678
706
 
@@ -695,31 +723,38 @@
695
723
  NSString *theSQLStatement = [[NSString alloc]initWithFormat:@"INSERT INTO %@(%@, %@, %@, %@) VALUES (?,?,?,?);", NSFValues, NSFKey, NSFAttribute, NSFValue, NSFDatatype];
696
724
  hasInitializationSucceeded = [self _prepareSQLite3Statement:&_storeValuesStatement theSQLStatement:theSQLStatement];
697
725
 
698
- if ((nil != outError) && (NO == hasInitializationSucceeded)) {
699
- *outError = [NSError errorWithDomain:NSFDomainKey
700
- code:NSFNanoStoreErrorKey
701
- userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %s]: failed to prepare _storeValuesStatement.", [self class], _cmd]
702
- forKey:NSLocalizedFailureReasonErrorKey]];
726
+ if (NO == hasInitializationSucceeded) {
727
+ if (nil != outError) {
728
+ *outError = [NSError errorWithDomain:NSFDomainKey
729
+ code:NSFNanoStoreErrorKey
730
+ userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %@]: failed to prepare _storeValuesStatement.", [self class], NSStringFromSelector(_cmd)]
731
+ forKey:NSLocalizedFailureReasonErrorKey]];
732
+ }
733
+ return NO;
703
734
  }
704
735
  }
705
736
 
706
- if ((NULL == _storeKeysStatement) && (YES == hasInitializationSucceeded)) {
707
- NSString *theSQLStatement = [[NSString alloc]initWithFormat:@"INSERT INTO %@(%@, %@, %@, %@) VALUES (?,?,?,?);", NSFKeys, NSFKey, NSFPlist, NSFCalendarDate, NSFObjectClass];
737
+ if (NULL == _storeKeysStatement) {
738
+ NSString *theSQLStatement = [[NSString alloc]initWithFormat:@"INSERT INTO %@(%@, %@, %@, %@) VALUES (?,?,?,?);", NSFKeys, NSFKey, NSFKeyedArchive, NSFCalendarDate, NSFObjectClass];
708
739
  hasInitializationSucceeded = [self _prepareSQLite3Statement:&_storeKeysStatement theSQLStatement:theSQLStatement];
709
740
 
710
- if ((nil != outError) && (NO == hasInitializationSucceeded)) {
711
- *outError = [NSError errorWithDomain:NSFDomainKey
712
- code:NSFNanoStoreErrorKey
713
- userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %s]: failed to prepare _storeKeysStatement.", [self class], _cmd]
714
- forKey:NSLocalizedFailureReasonErrorKey]];
741
+ if (NO == hasInitializationSucceeded) {
742
+ if (nil != outError) {
743
+ *outError = [NSError errorWithDomain:NSFDomainKey
744
+ code:NSFNanoStoreErrorKey
745
+ userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %@]: failed to prepare _storeKeysStatement.", [self class], NSStringFromSelector(_cmd)]
746
+ forKey:NSLocalizedFailureReasonErrorKey]];
747
+ }
748
+ return NO;
715
749
  }
716
750
  }
717
751
 
718
- return hasInitializationSucceeded;
752
+ return YES;
719
753
  }
720
754
 
721
755
  - (void)_releasePreparedStatements
722
756
  {
757
+ if (_insertDeleteKeysStatement != NULL) { sqlite3_finalize(_insertDeleteKeysStatement);_insertDeleteKeysStatement = NULL; }
723
758
  if (_storeValuesStatement != NULL) { sqlite3_finalize(_storeValuesStatement);_storeValuesStatement = NULL; }
724
759
  if (_storeKeysStatement != NULL) { sqlite3_finalize(_storeKeysStatement);_storeKeysStatement = NULL; }
725
760
  }
@@ -736,29 +771,13 @@
736
771
  return _isOurTransaction;
737
772
  }
738
773
 
739
- - (NSString*)_nestedDescriptionWithPrefixedSpace:(NSString *)prefixedSpace
740
- {
741
- if (nil == prefixedSpace) {
742
- prefixedSpace = @"";
743
- }
744
-
745
- NSMutableString *description = [NSMutableString string];
746
- [description appendString:@"\n"];
747
- [description appendString:[NSString stringWithFormat:@"%@NanoStore address : 0x%x\n", prefixedSpace, self]];
748
- [description appendString:[NSString stringWithFormat:@"%@Is our transaction? : %@\n", prefixedSpace, (_isOurTransaction ? @"Yes" : @"No")]];
749
- [description appendString:[NSString stringWithFormat:@"%@Save interval : %ld\n", prefixedSpace, (saveInterval == 0 ? 1 : saveInterval)]];
750
- [description appendString:[NSString stringWithFormat:@"%@Engine : %@\n", prefixedSpace, [nanoStoreEngine NSFP_nestedDescriptionWithPrefixedSpace:@" "]]];
751
-
752
- return description;
753
- }
754
-
755
774
  - (BOOL)_checkNanoStoreIsReadyAndReturnError:(out NSError **)outError
756
775
  {
757
776
  if (nil == [self nanoStoreEngine]) {
758
777
  if (nil != outError)
759
778
  *outError = [NSError errorWithDomain:NSFDomainKey
760
779
  code:NSFNanoStoreErrorKey
761
- userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %s]: the NSF store has not been set.", [self class], _cmd]
780
+ userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %@]: the NSF store has not been set.", [self class], NSStringFromSelector(_cmd)]
762
781
  forKey:NSLocalizedFailureReasonErrorKey]];
763
782
  return NO;
764
783
  }
@@ -767,7 +786,7 @@
767
786
  if (nil != outError)
768
787
  *outError = [NSError errorWithDomain:NSFDomainKey
769
788
  code:NSFNanoStoreErrorKey
770
- userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %s]: the store is not open.", [self class], _cmd]
789
+ userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %@]: the store is not open.", [self class], NSStringFromSelector(_cmd)]
771
790
  forKey:NSLocalizedFailureReasonErrorKey]];
772
791
  return NO;
773
792
  }
@@ -800,14 +819,15 @@
800
819
 
801
820
  // Setup the Plist table
802
821
  if ([tables containsObject:NSFKeys] == NO) {
803
- theSQLStatement = [NSString stringWithFormat:@"CREATE TABLE %@(ROWID INTEGER PRIMARY KEY, %@ TEXT, %@ TEXT, %@ TEXT, %@ TEXT);", NSFKeys, NSFKey, NSFPlist, NSFCalendarDate, NSFObjectClass];
822
+ theSQLStatement = [NSString stringWithFormat:@"CREATE TABLE %@(ROWID INTEGER PRIMARY KEY, %@ TEXT, %@ BLOB, %@ TEXT, %@ TEXT);", NSFKeys, NSFKey, NSFKeyedArchive, NSFCalendarDate, NSFObjectClass];
823
+
804
824
  success = (nil == [[[self nanoStoreEngine]executeSQL:theSQLStatement]error]);
805
825
  if (NO == success)
806
826
  return NO;
807
827
 
808
828
  [[self nanoStoreEngine]NSFP_insertStringValues:[NSArray arrayWithObjects:NSFKeys, NSFRowIDColumnName, rowUIDDatatype, nil] forColumns:[NSArray arrayWithObjects:NSFP_TableIdentifier, NSFP_ColumnIdentifier, NSFP_DatatypeIdentifier, nil]table:NSFP_SchemaTable];
809
829
  [[self nanoStoreEngine]NSFP_insertStringValues:[NSArray arrayWithObjects:NSFKeys, NSFKey, stringDatatype, nil] forColumns:[NSArray arrayWithObjects:NSFP_TableIdentifier, NSFP_ColumnIdentifier, NSFP_DatatypeIdentifier, nil]table:NSFP_SchemaTable];
810
- [[self nanoStoreEngine]NSFP_insertStringValues:[NSArray arrayWithObjects:NSFKeys, NSFPlist, stringDatatype, nil] forColumns:[NSArray arrayWithObjects:NSFP_TableIdentifier, NSFP_ColumnIdentifier, NSFP_DatatypeIdentifier, nil]table:NSFP_SchemaTable];
830
+ [[self nanoStoreEngine]NSFP_insertStringValues:[NSArray arrayWithObjects:NSFKeys, NSFKeyedArchive, stringDatatype, nil] forColumns:[NSArray arrayWithObjects:NSFP_TableIdentifier, NSFP_ColumnIdentifier, NSFP_DatatypeIdentifier, nil]table:NSFP_SchemaTable];
811
831
  [[self nanoStoreEngine]NSFP_insertStringValues:[NSArray arrayWithObjects:NSFKeys, dateDatatype, dateDatatype, nil] forColumns:[NSArray arrayWithObjects:NSFP_TableIdentifier, NSFP_ColumnIdentifier, NSFP_DatatypeIdentifier, nil]table:NSFP_SchemaTable];
812
832
  [[self nanoStoreEngine]NSFP_insertStringValues:[NSArray arrayWithObjects:NSFKeys, NSFObjectClass, stringDatatype, nil] forColumns:[NSArray arrayWithObjects:NSFP_TableIdentifier, NSFP_ColumnIdentifier, NSFP_DatatypeIdentifier, nil]table:NSFP_SchemaTable];
813
833
  }
@@ -815,27 +835,27 @@
815
835
  return YES;
816
836
  }
817
837
 
818
- - (BOOL)_storeDictionary:(NSDictionary *)someInfo forKey:(NSString *)aKey forClassNamed:(NSString *)className usingSQLite3Statement:(sqlite3_stmt *)storeValuesStatement error:(out NSError **)outError
838
+ - (BOOL)_storeDictionary:(NSDictionary *)someInfo forKey:(NSString *)aKey forClassNamed:(NSString *)classType error:(out NSError **)outError
819
839
  {
820
840
  if (nil == someInfo)
821
841
  [[NSException exceptionWithName:NSFUnexpectedParameterException
822
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: someInfo is nil.", [self class], _cmd]
842
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: someInfo is nil.", [self class], NSStringFromSelector(_cmd)]
823
843
  userInfo:nil]raise];
824
844
 
825
845
  if (nil == aKey)
826
846
  [[NSException exceptionWithName:NSFUnexpectedParameterException
827
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: aKey is nil.", [self class], _cmd]
847
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: aKey is nil.", [self class], NSStringFromSelector(_cmd)]
828
848
  userInfo:nil]raise];
829
849
 
830
- if (nil == storeValuesStatement)
850
+ if (NULL == _storeValuesStatement)
831
851
  [[NSException exceptionWithName:NSFUnexpectedParameterException
832
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: aStatement is NULL.", [self class], _cmd]
852
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: aStatement is NULL.", [self class], NSStringFromSelector(_cmd)]
833
853
  userInfo:nil]raise];
834
854
 
835
855
  NSRange range = [aKey rangeOfString:@"."];
836
856
  if (NSNotFound != range.location)
837
857
  [[NSException exceptionWithName:NSFUnexpectedParameterException
838
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: aKey cannot contain a period ('.')", [self class], _cmd]
858
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: aKey cannot contain a period ('.')", [self class], NSStringFromSelector(_cmd)]
839
859
  userInfo:nil]raise];
840
860
 
841
861
  NSArray *keys = [someInfo allKeys];
@@ -843,7 +863,7 @@
843
863
  range = [key rangeOfString:@"."];
844
864
  if (NSNotFound != range.location)
845
865
  [[NSException exceptionWithName:NSFUnexpectedParameterException
846
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: the keys of the dictionary cannot contain a period ('.')", [self class], _cmd]
866
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: the keys of the dictionary cannot contain a period ('.')", [self class], NSStringFromSelector(_cmd)]
847
867
  userInfo:nil]raise];
848
868
  }
849
869
 
@@ -867,7 +887,7 @@
867
887
  id value = [flattenedValues objectAtIndex:i];
868
888
 
869
889
  // Reset, as required by SQLite...
870
- int status = sqlite3_reset (storeValuesStatement);
890
+ int status = sqlite3_reset (_storeValuesStatement);
871
891
 
872
892
  // Since we're operating with extended result code support, extract the bits
873
893
  // and obtain the regular result code
@@ -878,8 +898,8 @@
878
898
  if (SQLITE_OK == status) {
879
899
 
880
900
  // Bind and execute the statement...
881
- BOOL resultBindKey = (sqlite3_bind_text (storeValuesStatement, 1, aKeyUTF8, -1, SQLITE_STATIC) == SQLITE_OK);
882
- BOOL resultBindAttribute = (sqlite3_bind_text (storeValuesStatement, 2, [attribute UTF8String], -1, SQLITE_STATIC) == SQLITE_OK);
901
+ BOOL resultBindKey = (sqlite3_bind_text (_storeValuesStatement, 1, aKeyUTF8, -1, SQLITE_STATIC) == SQLITE_OK);
902
+ BOOL resultBindAttribute = (sqlite3_bind_text (_storeValuesStatement, 2, [attribute UTF8String], -1, SQLITE_STATIC) == SQLITE_OK);
883
903
 
884
904
  // Take advantage of manifest typing
885
905
  // Branch the type of bind based on the type to be stored: NSString, NSData, NSDate or NSNumber
@@ -888,30 +908,36 @@
888
908
 
889
909
  switch (valueDataType) {
890
910
  case NSFNanoTypeData:
891
- resultBindValue = (sqlite3_bind_blob(storeValuesStatement, 3, [value bytes], [value length], NULL) == SQLITE_OK);
911
+ resultBindValue = (sqlite3_bind_blob(_storeValuesStatement, 3, [value bytes], (int)[value length], NULL) == SQLITE_OK);
892
912
  break;
893
913
  case NSFNanoTypeString:
894
914
  case NSFNanoTypeDate:
895
- resultBindValue = (sqlite3_bind_text (storeValuesStatement, 3, [[self _stringFromValue:value]UTF8String], -1, SQLITE_STATIC) == SQLITE_OK);
915
+ resultBindValue = (sqlite3_bind_text (_storeValuesStatement, 3, [[self _stringFromValue:value]UTF8String], -1, SQLITE_STATIC) == SQLITE_OK);
896
916
  break;
897
917
  break;
898
918
  case NSFNanoTypeNumber:
899
- resultBindValue = (sqlite3_bind_double (storeValuesStatement, 3, [value doubleValue]) == SQLITE_OK);
919
+ resultBindValue = (sqlite3_bind_double (_storeValuesStatement, 3, [value doubleValue]) == SQLITE_OK);
920
+ break;
921
+ case NSFNanoTypeNULL:
922
+ resultBindValue = (sqlite3_bind_null(_storeValuesStatement, 3) == SQLITE_OK);
923
+ break;
924
+ case NSFNanoTypeURL:
925
+ resultBindValue = (sqlite3_bind_text (_storeValuesStatement, 3, [[self _stringFromValue:value]UTF8String], -1, SQLITE_STATIC) == SQLITE_OK);
900
926
  break;
901
927
  default:
902
928
  [[NSException exceptionWithName:NSFUnexpectedParameterException
903
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: datatype %@ cannot be stored because its class type is unknown.", [self class], _cmd, [value class]]
929
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: datatype %@ cannot be stored because its class type is unknown.", [self class], NSStringFromSelector(_cmd), [value class]]
904
930
  userInfo:nil]raise];
905
931
  break;
906
932
  }
907
933
 
908
934
  // Store the element's datatype so we can recreate it later on when we read it back from the store...
909
935
  NSString *valueDatatypeString = NSFStringFromNanoDataType(valueDataType);
910
- BOOL resultBindDatatype = (sqlite3_bind_text (storeValuesStatement, 4, [valueDatatypeString UTF8String], -1, SQLITE_STATIC) == SQLITE_OK);
936
+ BOOL resultBindDatatype = (sqlite3_bind_text (_storeValuesStatement, 4, [valueDatatypeString UTF8String], -1, SQLITE_STATIC) == SQLITE_OK);
911
937
 
912
938
  success = (resultBindKey && resultBindAttribute && resultBindValue && resultBindDatatype);
913
939
  if (success) {
914
- [self _executeSQLite3StepUsingSQLite3Statement:storeValuesStatement];
940
+ [self _executeSQLite3StepUsingSQLite3Statement:_storeValuesStatement];
915
941
  }
916
942
  }
917
943
  }
@@ -920,51 +946,27 @@
920
946
  }
921
947
 
922
948
  if (YES == success) {
923
- // Save the Key and its Plist (if it applies)
924
- NSString *dictXML = nil;
925
- NSString *errorString = nil;
926
-
927
- NSData *dictData = [NSPropertyListSerialization dataFromPropertyList:someInfo format:NSPropertyListXMLFormat_v1_0 errorDescription:&errorString];
928
- if (nil != errorString) {
929
- NSLog(@" Dictionary: %@", someInfo);
930
- NSLog(@"*** -[%@ %@]: [NSPropertyListSerialization dataFromPropertyList] failure. %@", [self class], NSStringFromSelector(_cmd), errorString);
931
- NSLog(@" Dictionary info: %@", someInfo);
932
- success = NO;
933
- } else {
934
- if ([dictData length] > 0)
935
- dictXML = [[NSString alloc]initWithBytes:[dictData bytes]length:[dictData length]encoding:NSUTF8StringEncoding];
936
- else
937
- dictXML = @"";
949
+ NSData *dictBinData = [NSKeyedArchiver archivedDataWithRootObject:someInfo];
950
+ {
951
+ int status = sqlite3_reset (_storeKeysStatement);
938
952
 
939
- if (nil == dictXML) {
940
- if (nil != outError)
941
- *outError = [NSError errorWithDomain:NSFDomainKey
942
- code:NSF_Private_InvalidParameterDataCodeKey
943
- userInfo:[NSDictionary dictionaryWithObject:@"Couldn't serialize the object: %@"
944
- forKey:NSLocalizedDescriptionKey]];
945
- success = NO;
946
- } else {
947
- // Reset, as required by SQLite...
948
- int status = sqlite3_reset (_storeKeysStatement);
949
-
950
- // Since we're operating with extended result code support, extract the bits
951
- // and obtain the regular result code
952
- // For more info check: http://www.sqlite.org/c3ref/c_ioerr_access.html
953
+ // Since we're operating with extended result code support, extract the bits
954
+ // and obtain the regular result code
955
+ // For more info check: http://www.sqlite.org/c3ref/c_ioerr_access.html
956
+
957
+ status = [NSFNanoEngine NSFP_stripBitsFromExtendedResultCode:status];
958
+
959
+ // Bind and execute the statement...
960
+ if (SQLITE_OK == status) {
953
961
 
954
- status = [NSFNanoEngine NSFP_stripBitsFromExtendedResultCode:status];
962
+ BOOL resultBindKey = (sqlite3_bind_text (_storeKeysStatement, 1, aKeyUTF8, -1, SQLITE_STATIC) == SQLITE_OK);
963
+ BOOL resultBindData = (sqlite3_bind_blob(_storeKeysStatement, 2, [dictBinData bytes], (int)[dictBinData length], SQLITE_STATIC) == SQLITE_OK);
964
+ BOOL resultBindCalendarDate = (sqlite3_bind_text (_storeKeysStatement, 3, [[NSFNanoStore _calendarDateToString:[NSDate date]]UTF8String], -1, SQLITE_STATIC) == SQLITE_OK);
965
+ BOOL resultBindClass = (sqlite3_bind_text (_storeKeysStatement, 4, [classType UTF8String], -1, SQLITE_STATIC) == SQLITE_OK);
955
966
 
956
- // Bind and execute the statement...
957
- if (SQLITE_OK == status) {
958
-
959
- BOOL resultBindKey = (sqlite3_bind_text (_storeKeysStatement, 1, aKeyUTF8, -1, SQLITE_STATIC) == SQLITE_OK);
960
- BOOL resultBindPlist = (sqlite3_bind_text (_storeKeysStatement, 2, [dictXML UTF8String], -1, SQLITE_STATIC) == SQLITE_OK);
961
- BOOL resultBindCalendarDate = (sqlite3_bind_text (_storeKeysStatement, 3, [[NSFNanoStore _calendarDateToString:[NSDate date]]UTF8String], -1, SQLITE_STATIC) == SQLITE_OK);
962
- BOOL resultBindClass = (sqlite3_bind_text (_storeKeysStatement, 4, [className UTF8String], -1, SQLITE_STATIC) == SQLITE_OK);
963
-
964
- success = (resultBindKey && resultBindPlist && resultBindCalendarDate && resultBindClass);
965
- if (success) {
966
- [self _executeSQLite3StepUsingSQLite3Statement:_storeKeysStatement];
967
- }
967
+ success = (resultBindKey && resultBindData && resultBindCalendarDate && resultBindClass);
968
+ if (success) {
969
+ [self _executeSQLite3StepUsingSQLite3Statement:_storeKeysStatement];
968
970
  }
969
971
  }
970
972
  }
@@ -985,6 +987,10 @@
985
987
  return NSFNanoTypeDate;
986
988
  else if ([value isKindOfClass:[NSData class]])
987
989
  return NSFNanoTypeData;
990
+ else if ([value isKindOfClass:[NSNull class]])
991
+ return NSFNanoTypeNULL;
992
+ else if ([value isKindOfClass:[NSURL class]])
993
+ return NSFNanoTypeURL;
988
994
 
989
995
  return type;
990
996
  }
@@ -1002,7 +1008,7 @@
1002
1008
  return [aValue description];
1003
1009
  } else {
1004
1010
  [[NSException exceptionWithName:NSFUnexpectedParameterException
1005
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: datatype %@ doesn't respond to selector 'stringValue' or 'description'.", [self class], _cmd, [aValue class]]
1011
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: datatype %@ doesn't respond to selector 'stringValue' or 'description'.", [self class], NSStringFromSelector(_cmd), [aValue class]]
1006
1012
  userInfo:nil]raise];
1007
1013
  }
1008
1014
  }
@@ -1022,7 +1028,7 @@
1022
1028
 
1023
1029
  if (nil == aDate)
1024
1030
  [[NSException exceptionWithName:NSFUnexpectedParameterException
1025
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: aDate is nil.", [self class], _cmd]
1031
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: aDate is nil.", [self class], NSStringFromSelector(_cmd)]
1026
1032
  userInfo:nil]raise];
1027
1033
 
1028
1034
  return [__sNSFNanoStoreDateFormatter stringFromDate:aDate];
@@ -1115,10 +1121,10 @@
1115
1121
  - (BOOL)_addObjectsFromArray:(NSArray *)someObjects forceSave:(BOOL)forceSave error:(out NSError **)outError
1116
1122
  {
1117
1123
  // Collect the objects
1118
- [addedObjects addObjectsFromArray:someObjects];
1124
+ [_addedObjects addObjectsFromArray:someObjects];
1119
1125
 
1120
1126
  // No need to continue if there's nothing to be saved
1121
- NSUInteger unsavedObjectsCount = [addedObjects count];
1127
+ NSUInteger unsavedObjectsCount = [_addedObjects count];
1122
1128
  if (0 == unsavedObjectsCount) {
1123
1129
  return YES;
1124
1130
  }
@@ -1133,9 +1139,9 @@
1133
1139
 
1134
1140
  // Remove all objects non conforming with the NSFNanoObjectProtocol
1135
1141
  while ( i-- ) {
1136
- id object = [addedObjects objectAtIndex:i];
1142
+ id object = [_addedObjects objectAtIndex:i];
1137
1143
  if (NO == [object conformsToProtocol:@protocol(NSFNanoObjectProtocol)]) {
1138
- [addedObjects removeObjectAtIndex:i];
1144
+ [_addedObjects removeObjectAtIndex:i];
1139
1145
  i--;
1140
1146
  continue;
1141
1147
  }
@@ -1143,20 +1149,20 @@
1143
1149
  NSString *objectKey = [(id)object nanoObjectKey];
1144
1150
  if (nil == objectKey) {
1145
1151
  [[NSException exceptionWithName:NSFNanoObjectBehaviorException
1146
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: unexpected NSFNanoObject behavior. Reason: the object's key is nil.", [self class], _cmd]
1152
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: unexpected NSFNanoObject behavior. Reason: the object's key is nil.", [self class], NSStringFromSelector(_cmd)]
1147
1153
  userInfo:nil]raise];
1148
1154
  }
1149
1155
  [keys addObject:objectKey];
1150
1156
  }
1151
1157
 
1152
1158
  // Recalculate how many elements we have left
1153
- unsavedObjectsCount = [addedObjects count];
1159
+ unsavedObjectsCount = [_addedObjects count];
1154
1160
 
1155
1161
  if (unsavedObjectsCount > 0) {
1156
1162
  NSError *localOutError = nil;
1157
1163
  if (NO == [self removeObjectsWithKeysInArray:[keys allObjects] error:&localOutError]) {
1158
1164
  [[NSException exceptionWithName:NSFNanoStoreUnableToManipulateStoreException
1159
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: %@", [self class], _cmd, [localOutError localizedDescription]]
1165
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: %@", [self class], NSStringFromSelector(_cmd), [localOutError localizedDescription]]
1160
1166
  userInfo:nil]raise];
1161
1167
  }
1162
1168
  }
@@ -1174,7 +1180,7 @@
1174
1180
  self.saveInterval = 1;
1175
1181
  }
1176
1182
 
1177
- for (id object in addedObjects) {
1183
+ for (id object in _addedObjects) {
1178
1184
  @autoreleasepool {
1179
1185
  // If the object was originally created by storing a class not recognized by this process, honor it and store it with the right class string.
1180
1186
  NSString *className = nil;
@@ -1187,10 +1193,18 @@
1187
1193
  className = NSStringFromClass([object class]);
1188
1194
  }
1189
1195
 
1190
- if (NO == [self _storeDictionary:[object nanoObjectDictionaryRepresentation] forKey:[(id)object nanoObjectKey] forClassNamed:className usingSQLite3Statement:_storeValuesStatement error:outError]) {
1196
+ if (NO == [self _storeDictionary:[object nanoObjectDictionaryRepresentation] forKey:[(id)object nanoObjectKey] forClassNamed:className error:outError]) {
1191
1197
  [[NSException exceptionWithName:NSFNanoStoreUnableToManipulateStoreException
1192
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: %@", [self class], _cmd, [*outError localizedDescription]]
1198
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: %@", [self class], NSStringFromSelector(_cmd), [*outError localizedDescription]]
1193
1199
  userInfo:nil]raise];
1200
+ } else {
1201
+ SEL setStoreSelector = @selector(setStore:);
1202
+ if (YES == [object respondsToSelector:setStoreSelector]) {
1203
+ #pragma clang diagnostic push
1204
+ #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
1205
+ [object performSelector:setStoreSelector withObject:self];
1206
+ #pragma clang diagnostic pop
1207
+ }
1194
1208
  }
1195
1209
 
1196
1210
  i++;
@@ -1199,7 +1213,7 @@
1199
1213
  if ((0 == i % self.saveInterval) && transactionStartedHere) {
1200
1214
  if (NO == [self commitTransactionAndReturnError:outError]) {
1201
1215
  [[NSException exceptionWithName:NSFNanoStoreUnableToManipulateStoreException
1202
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: %@", [self class], _cmd, [*outError localizedDescription]]
1216
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: %@", [self class], NSStringFromSelector(_cmd), [*outError localizedDescription]]
1203
1217
  userInfo:nil]raise];
1204
1218
  }
1205
1219
 
@@ -1207,7 +1221,7 @@
1207
1221
  transactionStartedHere = [self beginTransactionAndReturnError:outError];
1208
1222
  if (NO == transactionStartedHere) {
1209
1223
  [[NSException exceptionWithName:NSFNanoStoreUnableToManipulateStoreException
1210
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: %@", [self class], _cmd, [*outError localizedDescription]]
1224
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: %@", [self class], NSStringFromSelector(_cmd), [*outError localizedDescription]]
1211
1225
  userInfo:nil]raise];
1212
1226
  }
1213
1227
  }
@@ -1219,7 +1233,7 @@
1219
1233
  if (transactionStartedHere) {
1220
1234
  if (NO == [self commitTransactionAndReturnError:outError]) {
1221
1235
  [[NSException exceptionWithName:NSFNanoStoreUnableToManipulateStoreException
1222
- reason:[NSString stringWithFormat:@"*** -[%@ %s]: %@", [self class], _cmd, [*outError localizedDescription]]
1236
+ reason:[NSString stringWithFormat:@"*** -[%@ %@]: %@", [self class], NSStringFromSelector(_cmd), [*outError localizedDescription]]
1223
1237
  userInfo:nil]raise];
1224
1238
  }
1225
1239
  }
@@ -1228,7 +1242,7 @@
1228
1242
  double ratio = unsavedObjectsCount/secondsStoring;
1229
1243
  _NSFLog(@" Done. Storing the objects took %.3f seconds (%.0f keys/sec.)", secondsStoring, ratio);
1230
1244
 
1231
- [addedObjects removeAllObjects];
1245
+ [_addedObjects removeAllObjects];
1232
1246
  }
1233
1247
 
1234
1248
  return YES;