nano-store 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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