nano-store 0.6.2 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +8 -4
- data/Rakefile +1 -1
- data/lib/nano_store.rb +2 -4
- data/lib/nano_store/version.rb +1 -1
- data/spec/model_spec.rb +14 -0
- data/spec/spec_helper.rb +4 -0
- data/vendor/Podfile.lock +4 -4
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoGlobals.h +3 -1
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoPredicate.h +5 -5
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoSearch.h +5 -3
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoSortDescriptor.h +1 -1
- data/vendor/Pods/BuildHeaders/NanoStore/NanoStore.h +36 -0
- data/vendor/Pods/Documentation/NanoStore/docset-installed.txt +2 -2
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Info.plist +3 -3
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoBag.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoEngine.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoExpression.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoObject.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoPredicate.html +7 -7
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoResult.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoSearch.html +66 -5
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoSortDescriptor.html +3 -3
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoStore.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFOrderedDictionary.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Protocols/NSFNanoObjectProtocol.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/css/styles.css +0 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/hierarchy.html +5 -5
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/index.html +5 -5
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Nodes.xml +1 -1
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Tokens5.xml +6 -6
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Tokens7.xml +24 -2
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Tokens8.xml +2 -2
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/docSet.dsidx +0 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/docSet.skidx +0 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/docSet.toc +0 -0
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoBag.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoEngine.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoExpression.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoObject.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoPredicate.html +7 -7
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoResult.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoSearch.html +66 -5
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoSortDescriptor.html +3 -3
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoStore.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFOrderedDictionary.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/html/Protocols/NSFNanoObjectProtocol.html +2 -2
- data/vendor/Pods/Documentation/NanoStore/html/css/styles.css +0 -0
- data/vendor/Pods/Documentation/NanoStore/html/hierarchy.html +5 -5
- data/vendor/Pods/Documentation/NanoStore/html/index.html +5 -5
- data/vendor/Pods/Headers/NanoStore/NSFNanoGlobals.h +3 -1
- data/vendor/Pods/Headers/NanoStore/NSFNanoPredicate.h +5 -5
- data/vendor/Pods/Headers/NanoStore/NSFNanoSearch.h +5 -3
- data/vendor/Pods/Headers/NanoStore/NSFNanoSortDescriptor.h +1 -1
- data/vendor/Pods/Headers/NanoStore/NanoStore.h +36 -0
- data/vendor/Pods/NanoStore/Classes/Advanced/NSFNanoEngine.m +40 -49
- data/vendor/Pods/NanoStore/Classes/Advanced/NSFNanoResult.m +42 -53
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoBag.m +80 -89
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoExpression.m +11 -13
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoGlobals.h +3 -1
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoGlobals.m +1 -0
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoObject.m +34 -29
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoPredicate.h +5 -5
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoPredicate.m +43 -34
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSearch.h +5 -3
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSearch.m +171 -97
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSortDescriptor.h +1 -1
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSortDescriptor.m +13 -12
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoStore.m +92 -86
- data/vendor/Pods/NanoStore/Classes/Public/NanoStore.h +36 -0
- data/vendor/Pods/Pods-resources.sh +8 -4
- data/vendor/Pods/Pods.bridgesupport +109 -101
- metadata +5 -5
@@ -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
|
|
@@ -29,15 +29,16 @@
|
|
29
29
|
#import "NSFOrderedDictionary.h"
|
30
30
|
#import "NSFNanoObject_Private.h"
|
31
31
|
|
32
|
-
@
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
}
|
32
|
+
@interface NSFNanoSortDescriptor ()
|
33
|
+
|
34
|
+
/** \cond */
|
35
|
+
@property (nonatomic, copy, readwrite) NSString *attribute;
|
36
|
+
@property (nonatomic, readwrite) BOOL isAscending;
|
37
|
+
/** \endcond */
|
39
38
|
|
40
|
-
@
|
39
|
+
@end
|
40
|
+
|
41
|
+
@implementation NSFNanoSortDescriptor
|
41
42
|
|
42
43
|
+ (NSFNanoSortDescriptor *)sortDescriptorWithAttribute:(NSString *)theAttribute ascending:(BOOL)ascending
|
43
44
|
{
|
@@ -52,8 +53,8 @@
|
|
52
53
|
userInfo:nil]raise];
|
53
54
|
|
54
55
|
if ((self = [super init])) {
|
55
|
-
|
56
|
-
|
56
|
+
_attribute = theAttribute;
|
57
|
+
_isAscending = ascending;
|
57
58
|
}
|
58
59
|
|
59
60
|
return self;
|
@@ -76,8 +77,8 @@
|
|
76
77
|
NSFOrderedDictionary *values = [NSFOrderedDictionary new];
|
77
78
|
|
78
79
|
values[@"Sort descriptor address"] = [NSString stringWithFormat:@"%p", self];
|
79
|
-
values[@"Attribute"] =
|
80
|
-
values[@"Is ascending?"] = (
|
80
|
+
values[@"Attribute"] = _attribute;
|
81
|
+
values[@"Is ascending?"] = (_isAscending ? @"YES" : @"NO");
|
81
82
|
|
82
83
|
return values;
|
83
84
|
}
|
@@ -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
|
@@ -33,20 +33,21 @@
|
|
33
33
|
|
34
34
|
#include <stdlib.h>
|
35
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
|
+
|
36
50
|
@implementation NSFNanoStore
|
37
|
-
{
|
38
|
-
@protected
|
39
|
-
NSFNanoEngine *nanoStoreEngine;
|
40
|
-
NSFEngineProcessingMode nanoEngineProcessingMode;
|
41
|
-
NSUInteger saveInterval;
|
42
|
-
|
43
|
-
/** \cond */
|
44
|
-
NSMutableArray *addedObjects;
|
45
|
-
BOOL _isOurTransaction;
|
46
|
-
sqlite3_stmt *_storeValuesStatement;
|
47
|
-
sqlite3_stmt *_storeKeysStatement;
|
48
|
-
/** \endcond */
|
49
|
-
}
|
50
51
|
|
51
52
|
@synthesize nanoStoreEngine;
|
52
53
|
@synthesize nanoEngineProcessingMode;
|
@@ -101,10 +102,11 @@
|
|
101
102
|
_isOurTransaction = NO;
|
102
103
|
saveInterval = 1;
|
103
104
|
|
105
|
+
_insertDeleteKeysStatement = NULL;
|
104
106
|
_storeValuesStatement = NULL;
|
105
107
|
_storeKeysStatement = NULL;
|
106
108
|
|
107
|
-
|
109
|
+
_addedObjects = [[NSMutableArray alloc]initWithCapacity:saveInterval];
|
108
110
|
}
|
109
111
|
|
110
112
|
return self;
|
@@ -113,8 +115,6 @@
|
|
113
115
|
- (void)dealloc
|
114
116
|
{
|
115
117
|
[self closeWithError:nil];
|
116
|
-
|
117
|
-
|
118
118
|
}
|
119
119
|
|
120
120
|
- (NSString *)filePath
|
@@ -204,7 +204,7 @@
|
|
204
204
|
|
205
205
|
- (BOOL)hasUnsavedChanges
|
206
206
|
{
|
207
|
-
return ([
|
207
|
+
return ([_addedObjects count] > 0);
|
208
208
|
}
|
209
209
|
|
210
210
|
#pragma mark -
|
@@ -225,11 +225,12 @@
|
|
225
225
|
}
|
226
226
|
|
227
227
|
if ([someObjects count] == 0) {
|
228
|
-
if (nil != outError)
|
228
|
+
if (nil != outError) {
|
229
229
|
*outError = [NSError errorWithDomain:NSFDomainKey
|
230
230
|
code:NSFNanoStoreErrorKey
|
231
231
|
userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %@]: ([someObjects count] == 0)", [self class], NSStringFromSelector(_cmd)]
|
232
232
|
forKey:NSLocalizedFailureReasonErrorKey]];
|
233
|
+
}
|
233
234
|
return NO;
|
234
235
|
}
|
235
236
|
|
@@ -240,32 +241,17 @@
|
|
240
241
|
// If it's a bag, make sure the name is unique
|
241
242
|
if (YES == [object isKindOfClass:[NSFNanoBag class]]) {
|
242
243
|
NSFNanoBag *bag = (NSFNanoBag *)object;
|
243
|
-
NSString *bagName = bag.name;
|
244
|
-
if (bagName.length > 0) {
|
245
|
-
NSFNanoBag *bagWithSameName = [self bagWithName:bagName];
|
246
|
-
if (nil != bagWithSameName) {
|
247
|
-
if (nil != outError) {
|
248
|
-
*outError = [NSError errorWithDomain:NSFDomainKey
|
249
|
-
code:NSFNanoStoreErrorKey
|
250
|
-
userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %@]: a bag named '%@' already exists.", [self class], NSStringFromSelector(_cmd), bagName]
|
251
|
-
forKey:NSLocalizedFailureReasonErrorKey]];
|
252
|
-
|
253
|
-
return NO;
|
254
|
-
}
|
255
|
-
}
|
256
|
-
}
|
257
|
-
|
258
244
|
|
259
245
|
// If it's a bag, process it first by gathering. If it's not dirty, there's no need to save...
|
260
|
-
if (YES == [
|
246
|
+
if (YES == [bag hasUnsavedChanges]) {
|
261
247
|
NSError *error = nil;
|
262
248
|
|
263
249
|
// Associate the bag to this store
|
264
|
-
if (nil == [
|
250
|
+
if (nil == [bag store]) {
|
265
251
|
[object _setStore:self];
|
266
252
|
}
|
267
253
|
|
268
|
-
if (NO == [
|
254
|
+
if (NO == [bag _saveInStore:self error:&error]) {
|
269
255
|
[[NSException exceptionWithName:NSFNanoStoreUnableToManipulateStoreException
|
270
256
|
reason:[NSString stringWithFormat:@"*** -[%@ %@]: %@", [self class], NSStringFromSelector(_cmd), [error localizedDescription]]
|
271
257
|
userInfo:nil]raise];
|
@@ -290,7 +276,6 @@
|
|
290
276
|
|
291
277
|
BOOL success = [self _addObjectsFromArray:nonBagObjects forceSave:NO error:outError];
|
292
278
|
|
293
|
-
|
294
279
|
return success;
|
295
280
|
}
|
296
281
|
|
@@ -321,31 +306,38 @@
|
|
321
306
|
NSString *theSQLStatement = [[NSString alloc]initWithFormat:@"CREATE TEMP TABLE %@(x);", NSF_Private_ToDeleteTableKey];
|
322
307
|
[nanoStoreEngine executeSQL:theSQLStatement];
|
323
308
|
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
}
|
334
|
-
|
335
|
-
// Bind and execute the statement...
|
336
|
-
status = sqlite3_bind_text ( statement, 1, [key UTF8String], -1, SQLITE_STATIC);
|
337
|
-
|
338
|
-
// Since we're operating with extended result code support, extract the bits
|
339
|
-
// and obtain the regular result code
|
340
|
-
// For more info check: http://www.sqlite.org/c3ref/c_ioerr_access.html
|
341
|
-
|
342
|
-
status = [NSFNanoEngine NSFP_stripBitsFromExtendedResultCode:status];
|
343
|
-
|
344
|
-
if (SQLITE_OK == status) {
|
345
|
-
[self _executeSQLite3StepUsingSQLite3Statement:statement];
|
309
|
+
if (NULL == _insertDeleteKeysStatement) {
|
310
|
+
theSQLStatement = [[NSString alloc]initWithFormat:@"INSERT INTO %@ VALUES (?);", NSF_Private_ToDeleteTableKey];
|
311
|
+
BOOL success = [self _prepareSQLite3Statement:&_insertDeleteKeysStatement theSQLStatement:theSQLStatement];
|
312
|
+
if (NO == success) {
|
313
|
+
if (nil != outError) {
|
314
|
+
*outError = [NSError errorWithDomain:NSFDomainKey
|
315
|
+
code:NSFNanoStoreErrorKey
|
316
|
+
userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %@]: failed to prepare _insertDeleteKeysStatement.", [self class], NSStringFromSelector(_cmd)]
|
317
|
+
forKey:NSLocalizedFailureReasonErrorKey]];
|
346
318
|
}
|
319
|
+
return NO;
|
320
|
+
}
|
321
|
+
}
|
322
|
+
|
323
|
+
for (NSString *key in someKeys) {
|
324
|
+
int status = sqlite3_reset (_insertDeleteKeysStatement);
|
325
|
+
if (SQLITE_OK != status) {
|
326
|
+
break;
|
327
|
+
}
|
328
|
+
|
329
|
+
// Bind and execute the statement...
|
330
|
+
status = sqlite3_bind_text ( _insertDeleteKeysStatement, 1, [key UTF8String], -1, SQLITE_STATIC);
|
331
|
+
|
332
|
+
// Since we're operating with extended result code support, extract the bits
|
333
|
+
// and obtain the regular result code
|
334
|
+
// For more info check: http://www.sqlite.org/c3ref/c_ioerr_access.html
|
335
|
+
|
336
|
+
status = [NSFNanoEngine NSFP_stripBitsFromExtendedResultCode:status];
|
337
|
+
|
338
|
+
if (SQLITE_OK == status) {
|
339
|
+
[self _executeSQLite3StepUsingSQLite3Statement:_insertDeleteKeysStatement];
|
347
340
|
}
|
348
|
-
sqlite3_finalize(statement);
|
349
341
|
}
|
350
342
|
|
351
343
|
_NSFLog(@" Before removing the keys to be stored from NSFKeys...");
|
@@ -575,7 +567,7 @@
|
|
575
567
|
|
576
568
|
- (void)discardUnsavedChanges
|
577
569
|
{
|
578
|
-
[
|
570
|
+
[_addedObjects removeAllObjects];
|
579
571
|
}
|
580
572
|
|
581
573
|
// ----------------------------------------------
|
@@ -677,11 +669,12 @@
|
|
677
669
|
return NO;
|
678
670
|
|
679
671
|
if ([[self nanoStoreEngine]isTransactionActive]) {
|
680
|
-
if (nil != outError)
|
672
|
+
if (nil != outError) {
|
681
673
|
*outError = [NSError errorWithDomain:NSFDomainKey
|
682
674
|
code:NSFNanoStoreErrorKey
|
683
675
|
userInfo:[NSDictionary dictionaryWithObject:@"Cannot backup store. A transaction is still open."
|
684
676
|
forKey:NSLocalizedDescriptionKey]];
|
677
|
+
}
|
685
678
|
return NO;
|
686
679
|
}
|
687
680
|
|
@@ -729,31 +722,38 @@
|
|
729
722
|
NSString *theSQLStatement = [[NSString alloc]initWithFormat:@"INSERT INTO %@(%@, %@, %@, %@) VALUES (?,?,?,?);", NSFValues, NSFKey, NSFAttribute, NSFValue, NSFDatatype];
|
730
723
|
hasInitializationSucceeded = [self _prepareSQLite3Statement:&_storeValuesStatement theSQLStatement:theSQLStatement];
|
731
724
|
|
732
|
-
if (
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
725
|
+
if (NO == hasInitializationSucceeded) {
|
726
|
+
if (nil != outError) {
|
727
|
+
*outError = [NSError errorWithDomain:NSFDomainKey
|
728
|
+
code:NSFNanoStoreErrorKey
|
729
|
+
userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %@]: failed to prepare _storeValuesStatement.", [self class], NSStringFromSelector(_cmd)]
|
730
|
+
forKey:NSLocalizedFailureReasonErrorKey]];
|
731
|
+
}
|
732
|
+
return NO;
|
737
733
|
}
|
738
734
|
}
|
739
735
|
|
740
|
-
if (
|
736
|
+
if (NULL == _storeKeysStatement) {
|
741
737
|
NSString *theSQLStatement = [[NSString alloc]initWithFormat:@"INSERT INTO %@(%@, %@, %@, %@) VALUES (?,?,?,?);", NSFKeys, NSFKey, NSFKeyedArchive, NSFCalendarDate, NSFObjectClass];
|
742
738
|
hasInitializationSucceeded = [self _prepareSQLite3Statement:&_storeKeysStatement theSQLStatement:theSQLStatement];
|
743
739
|
|
744
|
-
if (
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
740
|
+
if (NO == hasInitializationSucceeded) {
|
741
|
+
if (nil != outError) {
|
742
|
+
*outError = [NSError errorWithDomain:NSFDomainKey
|
743
|
+
code:NSFNanoStoreErrorKey
|
744
|
+
userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"*** -[%@ %@]: failed to prepare _storeKeysStatement.", [self class], NSStringFromSelector(_cmd)]
|
745
|
+
forKey:NSLocalizedFailureReasonErrorKey]];
|
746
|
+
}
|
747
|
+
return NO;
|
749
748
|
}
|
750
749
|
}
|
751
750
|
|
752
|
-
return
|
751
|
+
return YES;
|
753
752
|
}
|
754
753
|
|
755
754
|
- (void)_releasePreparedStatements
|
756
755
|
{
|
756
|
+
if (_insertDeleteKeysStatement != NULL) { sqlite3_finalize(_insertDeleteKeysStatement);_insertDeleteKeysStatement = NULL; }
|
757
757
|
if (_storeValuesStatement != NULL) { sqlite3_finalize(_storeValuesStatement);_storeValuesStatement = NULL; }
|
758
758
|
if (_storeKeysStatement != NULL) { sqlite3_finalize(_storeKeysStatement);_storeKeysStatement = NULL; }
|
759
759
|
}
|
@@ -1120,10 +1120,10 @@
|
|
1120
1120
|
- (BOOL)_addObjectsFromArray:(NSArray *)someObjects forceSave:(BOOL)forceSave error:(out NSError **)outError
|
1121
1121
|
{
|
1122
1122
|
// Collect the objects
|
1123
|
-
[
|
1123
|
+
[_addedObjects addObjectsFromArray:someObjects];
|
1124
1124
|
|
1125
1125
|
// No need to continue if there's nothing to be saved
|
1126
|
-
NSUInteger unsavedObjectsCount = [
|
1126
|
+
NSUInteger unsavedObjectsCount = [_addedObjects count];
|
1127
1127
|
if (0 == unsavedObjectsCount) {
|
1128
1128
|
return YES;
|
1129
1129
|
}
|
@@ -1138,9 +1138,9 @@
|
|
1138
1138
|
|
1139
1139
|
// Remove all objects non conforming with the NSFNanoObjectProtocol
|
1140
1140
|
while ( i-- ) {
|
1141
|
-
id object = [
|
1141
|
+
id object = [_addedObjects objectAtIndex:i];
|
1142
1142
|
if (NO == [object conformsToProtocol:@protocol(NSFNanoObjectProtocol)]) {
|
1143
|
-
[
|
1143
|
+
[_addedObjects removeObjectAtIndex:i];
|
1144
1144
|
i--;
|
1145
1145
|
continue;
|
1146
1146
|
}
|
@@ -1155,7 +1155,7 @@
|
|
1155
1155
|
}
|
1156
1156
|
|
1157
1157
|
// Recalculate how many elements we have left
|
1158
|
-
unsavedObjectsCount = [
|
1158
|
+
unsavedObjectsCount = [_addedObjects count];
|
1159
1159
|
|
1160
1160
|
if (unsavedObjectsCount > 0) {
|
1161
1161
|
NSError *localOutError = nil;
|
@@ -1179,7 +1179,9 @@
|
|
1179
1179
|
self.saveInterval = 1;
|
1180
1180
|
}
|
1181
1181
|
|
1182
|
-
|
1182
|
+
NSString *errorMessage = @"<error reason unknown>";
|
1183
|
+
|
1184
|
+
for (id object in _addedObjects) {
|
1183
1185
|
@autoreleasepool {
|
1184
1186
|
// 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.
|
1185
1187
|
NSString *className = nil;
|
@@ -1193,8 +1195,9 @@
|
|
1193
1195
|
}
|
1194
1196
|
|
1195
1197
|
if (NO == [self _storeDictionary:[object nanoObjectDictionaryRepresentation] forKey:[(id)object nanoObjectKey] forClassNamed:className error:outError]) {
|
1198
|
+
if (nil != outError) errorMessage = [*outError localizedDescription];
|
1196
1199
|
[[NSException exceptionWithName:NSFNanoStoreUnableToManipulateStoreException
|
1197
|
-
reason:[NSString stringWithFormat:@"*** -[%@ %@]: %@", [self class], NSStringFromSelector(_cmd),
|
1200
|
+
reason:[NSString stringWithFormat:@"*** -[%@ %@]: %@", [self class], NSStringFromSelector(_cmd), errorMessage]
|
1198
1201
|
userInfo:nil]raise];
|
1199
1202
|
} else {
|
1200
1203
|
SEL setStoreSelector = @selector(setStore:);
|
@@ -1211,16 +1214,18 @@
|
|
1211
1214
|
// Commit every 'saveInterval' interations...
|
1212
1215
|
if ((0 == i % self.saveInterval) && transactionStartedHere) {
|
1213
1216
|
if (NO == [self commitTransactionAndReturnError:outError]) {
|
1217
|
+
if (nil != outError) errorMessage = [*outError localizedDescription];
|
1214
1218
|
[[NSException exceptionWithName:NSFNanoStoreUnableToManipulateStoreException
|
1215
|
-
reason:[NSString stringWithFormat:@"*** -[%@ %@]: %@", [self class], NSStringFromSelector(_cmd),
|
1219
|
+
reason:[NSString stringWithFormat:@"*** -[%@ %@]: %@", [self class], NSStringFromSelector(_cmd), errorMessage]
|
1216
1220
|
userInfo:nil]raise];
|
1217
1221
|
}
|
1218
1222
|
|
1219
1223
|
if (YES == transactionStartedHere) {
|
1220
1224
|
transactionStartedHere = [self beginTransactionAndReturnError:outError];
|
1221
1225
|
if (NO == transactionStartedHere) {
|
1226
|
+
if (nil != outError) errorMessage = [*outError localizedDescription];
|
1222
1227
|
[[NSException exceptionWithName:NSFNanoStoreUnableToManipulateStoreException
|
1223
|
-
reason:[NSString stringWithFormat:@"*** -[%@ %@]: %@", [self class], NSStringFromSelector(_cmd),
|
1228
|
+
reason:[NSString stringWithFormat:@"*** -[%@ %@]: %@", [self class], NSStringFromSelector(_cmd), errorMessage]
|
1224
1229
|
userInfo:nil]raise];
|
1225
1230
|
}
|
1226
1231
|
}
|
@@ -1231,8 +1236,9 @@
|
|
1231
1236
|
// Commit the changes
|
1232
1237
|
if (transactionStartedHere) {
|
1233
1238
|
if (NO == [self commitTransactionAndReturnError:outError]) {
|
1239
|
+
if (nil != outError) errorMessage = [*outError localizedDescription];
|
1234
1240
|
[[NSException exceptionWithName:NSFNanoStoreUnableToManipulateStoreException
|
1235
|
-
reason:[NSString stringWithFormat:@"*** -[%@ %@]: %@", [self class], NSStringFromSelector(_cmd),
|
1241
|
+
reason:[NSString stringWithFormat:@"*** -[%@ %@]: %@", [self class], NSStringFromSelector(_cmd), errorMessage]
|
1236
1242
|
userInfo:nil]raise];
|
1237
1243
|
}
|
1238
1244
|
}
|
@@ -1241,7 +1247,7 @@
|
|
1241
1247
|
double ratio = unsavedObjectsCount/secondsStoring;
|
1242
1248
|
_NSFLog(@" Done. Storing the objects took %.3f seconds (%.0f keys/sec.)", secondsStoring, ratio);
|
1243
1249
|
|
1244
|
-
[
|
1250
|
+
[_addedObjects removeAllObjects];
|
1245
1251
|
}
|
1246
1252
|
|
1247
1253
|
return YES;
|
@@ -64,6 +64,13 @@
|
|
64
64
|
- iOS library runs on the device and simulator
|
65
65
|
- ARC compliant
|
66
66
|
|
67
|
+
@section latest_changes Latest changes
|
68
|
+
v2.5 - January 1, 2013
|
69
|
+
|
70
|
+
Starting with v2.5, the plist mechanism has been replaced with NSKeyedArchiver. There are several reasons for it: it's more compact, faster and uses less memory. Perhaps the most important reason is that it opens the possibility to store other data types.
|
71
|
+
|
72
|
+
NSNull is now supported. Big thanks to Wanny (https://github.com/mrwanny) for taking the time to improve this section of NanoStore.
|
73
|
+
|
67
74
|
@section installation_sec Installation
|
68
75
|
|
69
76
|
Building NanoStore is very easy. Just follow these steps:
|
@@ -423,6 +430,35 @@
|
|
423
430
|
[sortByLastName release];
|
424
431
|
@endcode
|
425
432
|
|
433
|
+
@section paging_limit_sec Paging using Limit and Offset
|
434
|
+
SQLite provides a really cool feature called OFFSET that is usually used with a LIMIT clause.
|
435
|
+
|
436
|
+
The LIMIT clause is used to limit the number of results returned in a SQL statement. So if you have 1000 rows in table, but only want to return the first 10, you would do something like this:
|
437
|
+
@code
|
438
|
+
SELECT column FROM table LIMIT 10
|
439
|
+
@endcode
|
440
|
+
Now suppose you wanted to show results 11-20. With the OFFSET keyword it's just as easy. The following query will do:
|
441
|
+
@code
|
442
|
+
SELECT column FROM table LIMIT 10 OFFSET 10
|
443
|
+
@endcode
|
444
|
+
Using pagination is also quite easy with NanoStore. This example based on one of the unit tests provided with the NanoStore distro:
|
445
|
+
@code
|
446
|
+
NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
|
447
|
+
|
448
|
+
// Assume we have added objects to the store
|
449
|
+
|
450
|
+
NSFNanoSearch *search = [NSFNanoSearch searchWithStore:nanoStore];
|
451
|
+
search.value = @"Barcelona";
|
452
|
+
search.match = NSFEqualTo;
|
453
|
+
search.limit = 5;
|
454
|
+
search.offset = 3;
|
455
|
+
|
456
|
+
NSDictionary *searchResults = [search searchObjectsWithReturnType:NSFReturnObjects error:nil];
|
457
|
+
|
458
|
+
// Assuming the query matches some results, NanoStore should have retrieved
|
459
|
+
// the first 5 records right after the 3rd one from the result set.
|
460
|
+
@endcode
|
461
|
+
|
426
462
|
@section performancetips_sec Performance Tips
|
427
463
|
|
428
464
|
NanoStore by defaults saves every object to disk one by one. To speed up inserts and edited objects, increase NSFNanoStore's \link NSFNanoStore::saveInterval saveInterval \endlink property.
|