nano-store 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/.gitignore +3 -0
  2. data/.gitmodules +3 -0
  3. data/.rvmrc +1 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +25 -0
  6. data/README.md +193 -0
  7. data/Rakefile +1 -0
  8. data/app/app_delegate.rb +5 -0
  9. data/lib/nano-store.rb +1 -0
  10. data/lib/nano_store/bag.rb +98 -0
  11. data/lib/nano_store/model.rb +142 -0
  12. data/lib/nano_store/nano_store.rb +36 -0
  13. data/lib/nano_store/store_extension.rb +150 -0
  14. data/lib/nano_store/version.rb +3 -0
  15. data/lib/nano_store.rb +14 -0
  16. data/nano-store.gemspec +17 -0
  17. data/resources/.gitignore +0 -0
  18. data/spec/bag_spec.rb +66 -0
  19. data/spec/model_spec.rb +130 -0
  20. data/spec/nano_store_spec.rb +48 -0
  21. data/spec/store_extension_spec.rb +110 -0
  22. data/vendor/NanoStore/Classes/Advanced/NSFNanoEngine.h +542 -0
  23. data/vendor/NanoStore/Classes/Advanced/NSFNanoEngine.m +1781 -0
  24. data/vendor/NanoStore/Classes/Advanced/NSFNanoResult.h +137 -0
  25. data/vendor/NanoStore/Classes/Advanced/NSFNanoResult.m +265 -0
  26. data/vendor/NanoStore/Classes/Private/NSFNanoBag_Private.h +37 -0
  27. data/vendor/NanoStore/Classes/Private/NSFNanoEngine_Private.h +69 -0
  28. data/vendor/NanoStore/Classes/Private/NSFNanoExpression_Private.h +35 -0
  29. data/vendor/NanoStore/Classes/Private/NSFNanoGlobals_Private.h +99 -0
  30. data/vendor/NanoStore/Classes/Private/NSFNanoObject_Private.h +35 -0
  31. data/vendor/NanoStore/Classes/Private/NSFNanoPredicate_Private.h +35 -0
  32. data/vendor/NanoStore/Classes/Private/NSFNanoResult_Private.h +43 -0
  33. data/vendor/NanoStore/Classes/Private/NSFNanoSearch_Private.h +48 -0
  34. data/vendor/NanoStore/Classes/Private/NSFNanoStore_Private.h +57 -0
  35. data/vendor/NanoStore/Classes/Private/NanoStore_Private.h +37 -0
  36. data/vendor/NanoStore/Classes/Public/NSFNanoBag.h +306 -0
  37. data/vendor/NanoStore/Classes/Public/NSFNanoBag.m +485 -0
  38. data/vendor/NanoStore/Classes/Public/NSFNanoExpression.h +125 -0
  39. data/vendor/NanoStore/Classes/Public/NSFNanoExpression.m +103 -0
  40. data/vendor/NanoStore/Classes/Public/NSFNanoGlobals.h +323 -0
  41. data/vendor/NanoStore/Classes/Public/NSFNanoGlobals.m +145 -0
  42. data/vendor/NanoStore/Classes/Public/NSFNanoObject.h +298 -0
  43. data/vendor/NanoStore/Classes/Public/NSFNanoObject.m +187 -0
  44. data/vendor/NanoStore/Classes/Public/NSFNanoObjectProtocol.h +119 -0
  45. data/vendor/NanoStore/Classes/Public/NSFNanoPredicate.h +123 -0
  46. data/vendor/NanoStore/Classes/Public/NSFNanoPredicate.m +130 -0
  47. data/vendor/NanoStore/Classes/Public/NSFNanoSearch.h +381 -0
  48. data/vendor/NanoStore/Classes/Public/NSFNanoSearch.m +835 -0
  49. data/vendor/NanoStore/Classes/Public/NSFNanoSortDescriptor.h +124 -0
  50. data/vendor/NanoStore/Classes/Public/NSFNanoSortDescriptor.m +79 -0
  51. data/vendor/NanoStore/Classes/Public/NSFNanoStore.h +475 -0
  52. data/vendor/NanoStore/Classes/Public/NSFNanoStore.m +1375 -0
  53. data/vendor/NanoStore/Classes/Public/NanoStore.h +463 -0
  54. data/vendor/NanoStore/LICENSE +25 -0
  55. data/vendor/NanoStore/NanoStore.bridgesupport +1215 -0
  56. data/vendor/NanoStore/README.md +411 -0
  57. metadata +118 -0
@@ -0,0 +1,298 @@
1
+ /*
2
+ NSFNanoObject.h
3
+ NanoStore
4
+
5
+ Copyright (c) 2010 Webbo, L.L.C. All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without modification, are permitted
8
+ provided that the following conditions are met:
9
+
10
+ * Redistributions of source code must retain the above copyright notice, this list of conditions
11
+ and the following disclaimer.
12
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
13
+ and the following disclaimer in the documentation and/or other materials provided with the distribution.
14
+ * Neither the name of Webbo nor the names of its contributors may be used to endorse or promote
15
+ products derived from this software without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
18
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
19
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
20
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
+ SUCH DAMAGE.
25
+ */
26
+
27
+ /*! @file NSFNanoObject.h
28
+ @brief A generic class that implements all the basic behavior required of a NanoStore object.
29
+ */
30
+
31
+ /** @class NSFNanoObject
32
+ The basic unit of data in NanoStore is called NanoObject. A NanoObject is any object which conforms to the NSFNanoObjectProtocol protocol.
33
+
34
+ @section notaflatworld_sec It's not a flat World
35
+
36
+ Most database solutions force the developer to think in a two-dimensional space (rows and columns), forcing the developer to plan the schema ahead of
37
+ time. This situation is not ideal because in most cases schema refinements could be required, oftentimes impacting the code as well.
38
+
39
+ NanoStore goes beyond that allowing the developer to store objects in their natural form. These objects must conform to the NSFNanoObjectProtocol
40
+ protocol, providing NanoStore with the NSDictionary that will be stored. By using a dictionary data can be inspected very quickly, and it also allows the
41
+ structure to be defined in a hierarchical fashion as well, due to the fact that it includes support for nested collections (of type NSDictionary and NSArray.)
42
+ Each inner-object is indexed automatically, thus allowing to quickly find objects which contain a specific key and/or value.
43
+
44
+ By default, NanoStore allows objects to be stored without any sense of relationship to other objects. This simple format, while powerful, is limited because
45
+ the developer has to keep track of the relationships among objects. Some applications may need to relate objects, some of them perhaps of different nature or class
46
+ type. This is exactly what NanoBag (represented by the NSFNanoBag class) does: it allows any object conforming to the NSFNanoObjectProtocol protocol to be
47
+ added to the bag. By saving the bag with one single call, the new and/or modified are taken care of seamlessly.
48
+
49
+ The NSFNanoBag API is rich, allowing the developer to add, remove, reload and undo its changes, deflate it (thus saving memory) and inflate it whenever it's
50
+ required. In addition, it provides methods to obtain all bags, specific bags matching some keys, and bags containing a specific object
51
+ (see NSFNanoStore for more information).
52
+
53
+ <b>Structure of a NanoObject object</b>
54
+
55
+ At its core, a NanoObject is nothing more than a wrapper around two properties:
56
+
57
+ - A dictionary which contains the metadata (provided by the developer)
58
+ - A key (UUID) that identifies the object (provided by NanoStore)
59
+
60
+ The dictionary <i>must</i> be serializable, which means that only the following data types are allowed:
61
+
62
+ - NSArray
63
+ - NSDictionary
64
+ - NSString
65
+ - NSData (*)
66
+ - NSDate
67
+ - NSNumber
68
+
69
+ (*) The data type NSData is allowed, but it will be excluded from the indexing process.
70
+
71
+ To save and retrieve objects from the document store, NanoStore moves the data around by encapsulating it in NanoObjects. In order to store the objects in
72
+ NanoStore the developer has three options:
73
+
74
+ - Use the NSFNanoObject class directly
75
+ - Expand your custom classes by inheriting from NSFNanoObject
76
+ - Expand your custom classes by implementing the NSFNanoObjectProtocol protocol
77
+
78
+ Regardless of the route you decide to take, NanoStore will be able to store and retrieve objects from the document store seamlessly. The beauty of this system is that
79
+ NanoStore returns the object as it was stored, that is, instantiating an object of the class that was originally stored.
80
+
81
+ @note
82
+ If the document store is opened by another application that doesn't implement the object that was stored, NanoStore will instantiate a
83
+ NSFNanoObject instead, thus allowing the app to retrieve the data seamlessly. If the object is then updated by this application, the original
84
+ class name will be honored.
85
+
86
+ <b>Example:</b>
87
+
88
+ - App A stores an object of class <i>Car</i>.
89
+ - App B retrieves the object, but since it doesn't know anything about the class <i>Car</i>, NanoStore returns a NSFNanoObject.
90
+ - App B updates the object, perhaps adding a timestamp or additional information. NanoStore saves it as a <i>Car</i>, not as a NSFNanoObject.
91
+ - App A retrieves the updated object as a <i>Car</i> object, in exactly the same format as it was originally stored.
92
+
93
+ @section workingwithnanoobject_sec Working with a NanoObject
94
+
95
+ There are three basic operations that NanoStore can perform with a NanoObject:
96
+
97
+ - Add it to the document store
98
+ - Update an existing object in the document store
99
+ - Remove it from the document store
100
+
101
+ To add an object, instantiate a \link NSFNanoObject::nanoObject NanoObject, \endlink populate it and add it to the document store.
102
+
103
+ @details <b>Example:</b>
104
+ @code
105
+ // Instantiate a NanoStore and open it
106
+ NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
107
+
108
+ // Generate an empty NanoObject
109
+ NSFNanoObject *object = [NSFNanoObject nanoObject];
110
+
111
+ // Add some data
112
+ [object setObject:@"Doe" forKey:@"kLastName"];
113
+ [object setObject:@"John" forKey:@"kFirstName"];
114
+ [object setObject:[NSArray arrayWithObjects:@"jdoe@foo.com", @"jdoe@bar.com", nil] forKey:@"kEmails"];
115
+
116
+ // Add it to the document store
117
+ [nanoStore addObject:object error:nil];
118
+
119
+ // Close the document store
120
+ [nanoStore closeWithError:nil];
121
+ @endcode
122
+
123
+ Alternatively, you can instantiate a \link NSFNanoObject::nanoObject NanoObject \endlink providing a dictionary via \link NSFNanoObject::nanoObjectWithDictionary: + (NSFNanoObject*)nanoObjectWithDictionary:(NSDictionary *)theDictionary. \endlink
124
+ NanoStore will assign a UUID automatically when the \link NSFNanoObject::nanoObjectWithDictionary: NanoObject \endlink
125
+ is instantiated. This means that requesting the key from the \link NSFNanoObject::nanoObjectWithDictionary: NanoObject \endlink will return a valid UUID.
126
+ The same holds true for objects that inherit from NSFNanoObject. However, classes that implement the NSFNanoObjectProtocol protocol should
127
+ make sure they return a valid key via \link NSFNanoObjectProtocol::nanoObjectKey - (NSString *)nanoObjectKey \endlink
128
+
129
+ @warning
130
+ If an attempt is made to add or remove an object without a valid key, an exception of type \ref NSFGlobals::NSFNanoObjectBehaviorException
131
+ "NSFNanoObjectBehaviorException" will be raised.
132
+
133
+ To update an object, simply modify the object and add it to the document store. NanoStore will replace the existing object with the one being added.
134
+
135
+ @details <b>Example:</b>
136
+ @code
137
+ // Instantiate and open a NanoStore
138
+ NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
139
+
140
+ // Assuming the dictionary exists, instantiate a NanoObject
141
+ NSDictionary *info = ...;
142
+ NSFNanoObject *object = [NSFNanoObject nanoObjectWithDictionary:info];
143
+
144
+ // Add the NanoObject to the document store
145
+ [nanoStore addObject:object error:nil];
146
+
147
+ // Update the NanoObject with new data
148
+ [object setObject:@"foo" forKey:@"SomeKey"];
149
+
150
+ // Update the NanoObject in the document store
151
+ [nanoStore addObject:object error:nil];
152
+ @endcode
153
+
154
+ To remove an object, there are several options available. The most common methods are found in NSFNanoStore:
155
+
156
+ - \link NSFNanoStore::removeObject:error: - (BOOL)removeObject:(id <NSFNanoObjectProtocol>)theObject error:(out NSError **)outError \endlink
157
+ - \link NSFNanoStore::removeObjectsWithKeysInArray:error: - (BOOL)removeObjectsWithKeysInArray:(NSArray *)theKeys error:(out NSError **)outError \endlink
158
+ - \link NSFNanoStore::removeObjectsInArray:error: - (BOOL)removeObjectsInArray:(NSArray *)theObjects error:(out NSError **)outError \endlink
159
+
160
+ @details <b>Example:</b>
161
+ @code
162
+ // Instantiate and open a NanoStore
163
+ NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
164
+
165
+ // Assuming the dictionary exists, instantiate a NanoObject
166
+ NSDictionary *info = ...;
167
+ NSFNanoObject *object = [NSFNanoObject nanoObjectWithDictionary:info];
168
+
169
+ // Add the NanoObject to the document store
170
+ [nanoStore addObject:object error:nil];
171
+
172
+ // Remove the object
173
+ [nanoStore removeObject:object error:nil];
174
+
175
+ // ... or you could pass the key instead
176
+ [nanoStore removeObjectsWithKeysInArray:[NSArray arrayWithObjects:[object nanoObjectKey], nil] error:nil];
177
+ @endcode
178
+ */
179
+
180
+ #import "NanoStore.h"
181
+
182
+ @interface NSFNanoObject : NSObject <NSFNanoObjectProtocol, NSCopying>
183
+
184
+ /** * The UUID of the NanoObject. */
185
+ @property (nonatomic, copy, readonly) NSString *key;
186
+ /** * The user-supplied information of the NanoObject. */
187
+ @property (nonatomic, copy, readonly) NSDictionary *info;
188
+ /** * The class name used to store the NanoObject. */
189
+ @property (nonatomic, copy, readonly) NSString *originalClassString;
190
+
191
+ /** @name Creating and Initializing a NanoObject
192
+ */
193
+
194
+ //@{
195
+
196
+ /** * Creates and returns an empty NanoObject.
197
+ * @return An empty NanoObject upon success, nil otherwise.
198
+ */
199
+
200
+ + (NSFNanoObject*)nanoObject;
201
+
202
+ /** * Creates and returns a NanoObject with the given dictionary.
203
+ * @param theDictionary the information associated with the object. Must not be nil.
204
+ * @return An initialized object upon success, nil otherwise.
205
+ * @attention The dictionary must be serializable. For more information, please read the Property List Programming Guide.
206
+ * @see \link initFromDictionaryRepresentation: - (id)initFromDictionaryRepresentation:(NSDictionary *)theDictionary \endlink
207
+ */
208
+
209
+ + (NSFNanoObject*)nanoObjectWithDictionary:(NSDictionary *)theDictionary;
210
+
211
+ /** * Initializes a newly allocated NanoObject with the given dictionary.
212
+ * @param theDictionary the information associated with the object. Must not be nil.
213
+ * @return An initialized object upon success, nil otherwise.
214
+ * @attention The dictionary must be serializable. For more information, please read the Property List Programming Guide.
215
+ * @see \link nanoObjectWithDictionary: + (NSFNanoObject*)nanoObjectWithDictionary:(NSDictionary *)theDictionary \endlink
216
+ */
217
+
218
+ - (id)initFromDictionaryRepresentation:(NSDictionary *)theDictionary;
219
+
220
+ //@}
221
+
222
+ /** @name Setting and Removing Contents
223
+ */
224
+
225
+ //@{
226
+
227
+ /** * Adds a given key-value pair to the NanoObject.
228
+ * @param anObject the value for key. Must not be nil.
229
+ * @param aKey the key for value. Must not be nil.
230
+ * @note Raises an NSInvalidArgumentException if <i>aKey</i> or <i>anObject</i> is nil. If you need to represent a nil value in the dictionary, use NSNull.
231
+ * @see \link removeObjectForKey: - (void)removeObjectForKey:(NSString *)aKey \endlink
232
+ */
233
+
234
+ - (void)setObject:(id)anObject forKey:(NSString *)aKey;
235
+
236
+ /** * Returns the value associated with a given key.
237
+ * @param aKey the key for value. Must not be nil.
238
+ * @note Raises an NSInvalidArgumentException if <i>aKey</i> or <i>anObject</i> is nil. If you need to represent a nil value in the dictionary, use NSNull.
239
+ * @see \link setObject:forKey: - (void)setObject:(id)anObject forKey:(NSString *)aKey \endlink
240
+ */
241
+
242
+ - (id)objectForKey:(NSString *)aKey;
243
+
244
+ /** * Removes a given key and its associated value from the NanoObject.
245
+ * @param aKey the key to remove. Must not be nil.
246
+ * @note Does nothing if <i>aKey</i> does not exist.
247
+ * @see \link setObject:forKey: - (void)setObject:(id)anObject forKey:(NSString *)aKey \endlink
248
+ */
249
+
250
+ - (void)removeObjectForKey:(NSString *)aKey;
251
+
252
+ /** * Empties the NanoObject of its entries.
253
+ * @see \link removeObjectForKey: - (void)removeObjectForKey:(NSString *)aKey \endlink
254
+ * @see \link removeObjectsForKeys: - (void)removeObjectsForKeys:(NSArray *)keyArray \endlink
255
+ */
256
+
257
+ - (void)removeAllObjects;
258
+
259
+ /** * Removes from the NanoObject entries specified by elements in a given array.
260
+ * @param keyArray An array of objects specifying the keys to remove.
261
+ * @note If a key in <i>keyArray</i> does not exist, the entry is ignored.
262
+ * @see \link removeAllObjects - (void)removeAllObjects \endlink
263
+ * @see \link removeObjectForKey: - (void)removeObjectForKey:(NSString *)aKey \endlink
264
+ */
265
+
266
+ - (void)removeObjectsForKeys:(NSArray *)keyArray;
267
+
268
+ //@}
269
+
270
+ /** @name Miscellaneous
271
+ */
272
+
273
+ //@{
274
+
275
+ /** * Compares the receiving NanoObject to another NanoObject.
276
+ * @param otherNanoObject is a NanoObject.
277
+ * @return YES if the contents of otherNanoObject are equal to the contents of the receiving NanoObject, otherwise NO.
278
+ */
279
+
280
+ - (BOOL)isEqualToNanoObject:(NSFNanoObject *)otherNanoObject;
281
+
282
+ /** * Returns a dictionary that contains the information stored in the object.
283
+ * @note Check properties info and key to find out the current state of the object.
284
+ * @see \link description - (NSString *)description \endlink
285
+ */
286
+
287
+ - (NSDictionary *)dictionaryRepresentation;
288
+
289
+ /** * Returns a string representation of the bag.
290
+ * @note Check properties info and key to find out the current state of the object.
291
+ * @see \link dictionaryRepresentation - (NSString *)dictionaryRepresentation \endlink
292
+ */
293
+
294
+ - (NSString *)description;
295
+
296
+ //@}
297
+
298
+ @end
@@ -0,0 +1,187 @@
1
+ /*
2
+ NSFNanoObject.m
3
+ NanoStore
4
+
5
+ Copyright (c) 2010 Webbo, L.L.C. All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without modification, are permitted
8
+ provided that the following conditions are met:
9
+
10
+ * Redistributions of source code must retain the above copyright notice, this list of conditions
11
+ and the following disclaimer.
12
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
13
+ and the following disclaimer in the documentation and/or other materials provided with the distribution.
14
+ * Neither the name of Webbo nor the names of its contributors may be used to endorse or promote
15
+ products derived from this software without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
18
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
19
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
20
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
+ SUCH DAMAGE.
25
+ */
26
+
27
+ #import "NSFNanoObject.h"
28
+ #import "NSFNanoObject_Private.h"
29
+ #import "NSFNanoGlobals_Private.h"
30
+
31
+ @implementation NSFNanoObject
32
+ {
33
+ NSMutableDictionary *info;
34
+ }
35
+
36
+ @synthesize info, key, originalClassString;
37
+
38
+ + (NSFNanoObject*)nanoObject
39
+ {
40
+ NSString *theKey = [NSFNanoEngine stringWithUUID];
41
+ return [[self alloc]initNanoObjectFromDictionaryRepresentation:nil forKey:theKey store:nil];
42
+ }
43
+
44
+ + (NSFNanoObject*)nanoObjectWithDictionary:(NSDictionary *)aDictionary
45
+ {
46
+ NSString *theKey = [NSFNanoEngine stringWithUUID];
47
+ return [[self alloc]initNanoObjectFromDictionaryRepresentation:aDictionary forKey:theKey store:nil];
48
+ }
49
+
50
+ - (id)initFromDictionaryRepresentation:(NSDictionary *)aDictionary
51
+ {
52
+ NSString *theKey = [NSFNanoEngine stringWithUUID];
53
+ return [self initNanoObjectFromDictionaryRepresentation:aDictionary forKey:theKey store:nil];
54
+ }
55
+
56
+ - (NSString*)description
57
+ {
58
+ NSMutableString *description = [NSMutableString string];
59
+
60
+ [description appendString:@"\n"];
61
+ [description appendString:[NSString stringWithFormat:@"NanoObject address : 0x%x\n", self]];
62
+ [description appendString:[NSString stringWithFormat:@"Original class : %@\n", (nil != originalClassString) ? originalClassString : NSStringFromClass ([self class])]];
63
+ [description appendString:[NSString stringWithFormat:@"Key : %@\n", key]];
64
+ [description appendString:[NSString stringWithFormat:@"Info : %ld key/value pairs\n", [info count]]];
65
+
66
+ return description;
67
+ }
68
+
69
+ - (void)setObject:(id)anObject forKey:(NSString *)aKey
70
+ {
71
+ [info setObject:anObject forKey:aKey];
72
+ }
73
+
74
+ - (id)objectForKey:(NSString *)aKey
75
+ {
76
+ return [info objectForKey:aKey];
77
+ }
78
+
79
+ - (void)removeObjectForKey:(NSString *)aKey
80
+ {
81
+ [info removeObjectForKey:aKey];
82
+ }
83
+
84
+ - (void)removeAllObjects
85
+ {
86
+ [info removeAllObjects];
87
+ }
88
+
89
+ - (void)removeObjectsForKeys:(NSArray *)keyArray
90
+ {
91
+ [info removeObjectsForKeys:keyArray];
92
+ }
93
+
94
+ - (BOOL)isEqualToNanoObject:(NSFNanoObject *)otherNanoObject
95
+ {
96
+ if (self == otherNanoObject) {
97
+ return YES;
98
+ }
99
+
100
+ BOOL success = YES;
101
+
102
+ if (originalClassString != otherNanoObject.originalClassString) {
103
+ if (NO == [originalClassString isEqualToString:otherNanoObject.originalClassString]) {
104
+ success = NO;
105
+ }
106
+ }
107
+
108
+ if (YES == success) {
109
+ success = [info isEqualToDictionary:otherNanoObject.info];
110
+ }
111
+
112
+ return success;
113
+ }
114
+
115
+ - (NSDictionary *)dictionaryRepresentation
116
+ {
117
+ return self.info;
118
+ }
119
+
120
+ /** \cond */
121
+
122
+ - (id)init
123
+ {
124
+ if ((self = [super init])) {
125
+ key = nil;
126
+ info = [NSMutableDictionary new];
127
+ originalClassString = nil;
128
+ }
129
+
130
+ return self;
131
+ }
132
+
133
+ #pragma mark -
134
+
135
+ - (id)initNanoObjectFromDictionaryRepresentation:(NSDictionary *)aDictionary forKey:(NSString *)aKey store:(NSFNanoStore *)aStore
136
+ {
137
+ // We allow a nil dictionary because: 1) it's interpreted as empty and 2) reduces memory consumption on the caller if no data is being passed.
138
+
139
+ if (nil == aKey)
140
+ [[NSException exceptionWithName:NSFUnexpectedParameterException
141
+ reason:[NSString stringWithFormat:@"*** -[%@ %s]: aKey is nil.", [self class], _cmd]
142
+ userInfo:nil]raise];
143
+
144
+ if ((self = [self init])) {
145
+ [info addEntriesFromDictionary:aDictionary];
146
+ key = [aKey copy];
147
+ }
148
+
149
+ return self;
150
+ }
151
+
152
+ - (id)copyWithZone:(NSZone *)zone
153
+ {
154
+ NSFNanoObject *copy = [[[self class]allocWithZone:zone]initNanoObjectFromDictionaryRepresentation:[self dictionaryRepresentation] forKey:[NSFNanoEngine stringWithUUID] store:nil];
155
+ return copy;
156
+ }
157
+
158
+
159
+ - (NSDictionary *)nanoObjectDictionaryRepresentation
160
+ {
161
+ return [self dictionaryRepresentation];
162
+ }
163
+
164
+ - (NSString *)nanoObjectKey
165
+ {
166
+ return self.key;
167
+ }
168
+
169
+ - (id)rootObject
170
+ {
171
+ return info;
172
+ }
173
+
174
+ #pragma mark -
175
+ #pragma mark Private Methods
176
+ #pragma mark -
177
+
178
+ - (void)_setOriginalClassString:(NSString *)theClassString
179
+ {
180
+ if (originalClassString != theClassString) {
181
+ originalClassString = theClassString;
182
+ }
183
+ }
184
+
185
+ /** \endcond */
186
+
187
+ @end
@@ -0,0 +1,119 @@
1
+ /*
2
+ NSFNanoObjectProtocol.h
3
+ NanoStore
4
+
5
+ Copyright (c) 2010 Webbo, L.L.C. All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without modification, are permitted
8
+ provided that the following conditions are met:
9
+
10
+ * Redistributions of source code must retain the above copyright notice, this list of conditions
11
+ and the following disclaimer.
12
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
13
+ and the following disclaimer in the documentation and/or other materials provided with the distribution.
14
+ * Neither the name of Webbo nor the names of its contributors may be used to endorse or promote
15
+ products derived from this software without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
18
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
19
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
20
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
+ SUCH DAMAGE.
25
+ */
26
+
27
+ /*! @file NSFNanoObjectProtocol.h
28
+ @brief A protocol declaring the interface that objects interfacing with NanoStore must implement.
29
+ */
30
+
31
+ /** @protocol NSFNanoObjectProtocol
32
+ * A protocol declaring the interface that objects interfacing with NanoStore must implement.
33
+ *
34
+ * @note
35
+ * Check NSFNanoBag or NSFNanoObject to see a concrete example of how NSFNanoObjectProtocol is implemented.
36
+ */
37
+
38
+ @class NSFNanoStore;
39
+
40
+ @protocol NSFNanoObjectProtocol
41
+
42
+ @required
43
+
44
+ /** * Initializes a newly allocated object containing a given key and value associated with a document store.
45
+ * @param theDictionary the information associated with the object.
46
+ * @param aKey the key associated with the information.
47
+ * @param theStore the document store where the object is stored.
48
+ * @return An initialized object upon success, nil otherwise.
49
+ * @details <b>Example:</b>
50
+ @code
51
+ - (id)initNanoObjectFromDictionaryRepresentation:(NSDictionary *)aDictionary forKey:(NSString *)aKey store:(NSFNanoStore *)aStore
52
+ {
53
+ if (self = [self init]) {
54
+ info = [aDictionary retain];
55
+ key = [aKey copy];
56
+ }
57
+
58
+ return self;
59
+ }
60
+ @endcode
61
+ */
62
+
63
+ - (id)initNanoObjectFromDictionaryRepresentation:(NSDictionary *)theDictionary forKey:(NSString *)aKey store:(NSFNanoStore *)theStore;
64
+
65
+ /** * Returns a dictionary that contains the information stored in the object.
66
+ * @see \link nanoObjectKey - (NSString *)nanoObjectKey \endlink
67
+ */
68
+
69
+ - (NSDictionary *)nanoObjectDictionaryRepresentation;
70
+
71
+ /** * Returns the key associated with the object.
72
+ * @note
73
+ * The class NSFNanoEngine contains a convenience method for this purpose: \ref NSFNanoEngine::stringWithUUID "+(NSString*)stringWithUUID"
74
+ *
75
+ * @see \link nanoObjectDictionaryRepresentation - (NSDictionary *)nanoObjectDictionaryRepresentation \endlink
76
+ */
77
+
78
+ - (NSString *)nanoObjectKey;
79
+
80
+ /** * Returns a reference to the object holding the private data or information that will be used for sorting.
81
+ * Most custom objects will return <i>self</i>, as is the case for NSFNanoBag. Since we can sort a bag by <i>name</i>, <i>key</i> or <i>hasUnsavedChanges</i>,
82
+ * NanoStore requires a hint to find the attribute. This hint is the root object, which KVC uses to perform the sort. Taking NSFNanoBag as an example:
83
+ @code
84
+ @interface NSFNanoBag : NSObject <NSFNanoObjectProtocol, NSCopying>
85
+ {
86
+ NSFNanoStore *store;
87
+ NSString *name;
88
+ NSString *key;
89
+ BOOL hasUnsavedChanges;
90
+ }
91
+ @endcode
92
+ * The implementation of <i>rootObject</i> would look like so:
93
+ @code
94
+ - (id)rootObject
95
+ {
96
+ return self;
97
+ }
98
+ @endcode
99
+ * Other objects may point directly to the collection that holds the information. NSFNanoObject stores all its data in the <i>info</i> dictionary, so the
100
+ * implementation looks like this:
101
+ @code
102
+ - (id)rootObject
103
+ {
104
+ return info;
105
+ }
106
+ @endcode
107
+ * Assuming that <i>info</i> contains a key named <i>City</i>, we would specify a NSFNanoSortDescriptor which would sort the cities like so:
108
+ @code
109
+ NSFNanoSortDescriptor *sortedCities = [[NSFNanoSortDescriptor alloc]initWithAttribute:@"City" ascending:YES];
110
+ @endcode
111
+ * If we had returned <i>self</i> as the root object, the sort descriptor would have to be written like so:
112
+ @code
113
+ NSFNanoSortDescriptor *sortedCities = [[NSFNanoSortDescriptor alloc]initWithAttribute:@"info.City" ascending:YES];
114
+ @endcode
115
+ */
116
+
117
+ - (id)rootObject;
118
+
119
+ @end