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,123 @@
1
+ /*
2
+ NSFNanoPredicate.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 NSFNanoPredicate.h
28
+ @brief A predicate is an element of an expression used to perform complex queries.
29
+ */
30
+
31
+ /** @class NSFNanoPredicate
32
+ * A predicate is an element of an expression used to perform complex queries.
33
+ *
34
+ * @note
35
+ * A predicate must be added to a NSFNanoExpression.
36
+ *
37
+ * @details <b>Example:</b>
38
+ @code
39
+ // Instantiate a NanoStore and open it
40
+ NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
41
+
42
+ // Add some data to the document store
43
+ NSDictionary *info = ...;
44
+ NSFNanoObject *object = [NSFNanoObject nanoObjectWithDictionary:info];
45
+ [nanoStore addObject:object error:nil];
46
+
47
+ // Prepare the expression
48
+ NSFNanoPredicate *attribute = [NSFNanoPredicate predicateWithColumn:NSFAttributeColumn matching:NSFEqualTo value:@"FirstName"];
49
+ NSFNanoPredicate *value = [NSFNanoPredicate predicateWithColumn:NSFValueColumn matching:NSFEqualTo value:@"Hobbes"];
50
+ NSFNanoExpression *expression = [NSFNanoExpression expressionWithPredicate:predicateAttribute];
51
+ [expression addPredicate:predicateValue withOperator:NSFAnd];
52
+
53
+ // Setup the search with the document store and a given expression
54
+ NSFNanoSearch *search = [NSFNanoSearch searchWithStore:nanoStore];
55
+ [search setExpressions:[NSArray arrayWithObject:expression]];
56
+
57
+ // Obtain the matching objects
58
+ NSDictionary *searchResults = [search searchObjectsWithReturnType:NSFReturnObjects error:nil];
59
+
60
+ // Close the document store
61
+ [nanoStore closeWithError:nil];
62
+ @endcode
63
+ *
64
+ * @see \link NSFNanoExpression::expressionWithPredicate: + (NSFNanoExpression*)expressionWithPredicate:(NSFNanoPredicate *)thePredicate \endlink
65
+ * @see \link NSFNanoExpression::initWithPredicate: - (id)initWithPredicate:(NSFNanoPredicate *)thePredicate \endlink
66
+ * @see \link NSFNanoExpression::addPredicate:withOperator: - (void)addPredicate:(NSFNanoPredicate *)thePredicate withOperator:(NSFOperator)theOperator \endlink
67
+ */
68
+
69
+ #import <Foundation/Foundation.h>
70
+
71
+ #import "NSFNanoGlobals.h"
72
+
73
+ @interface NSFNanoPredicate : NSObject
74
+
75
+ /** * The type of column being referenced. */
76
+ @property (nonatomic, assign, readonly) NSFTableColumnType column;
77
+ /** * The comparison operator to be used. */
78
+ @property (nonatomic, assign, readonly) NSFMatchType match;
79
+ /** * The value to be used for comparison. */
80
+ @property (nonatomic, copy, readonly) NSString *value;
81
+
82
+ /** @name Creating and Initializing a Predicate
83
+ */
84
+
85
+ //@{
86
+
87
+ /** * Creates and returns a predicate.
88
+ * @param theType is the column type. Can be \link Globals::NSFKeyColumn NSFKeyColumn \endlink, \link Globals::NSFAttributeColumn NSFAttributeColumn \endlink or \link Globals::NSFValueColumn NSFValueColumn \endlink.
89
+ * @param theMatch is the match operator.
90
+ * @param theValue is the value.
91
+ * @return A predicate which can be used in an NSFNanoExpression.
92
+ * @see \link initWithColumn:matching:value: - (id)initWithColumn:(NSFTableColumnType)theType matching:(NSFMatchType)theMatch value:(NSString *)theValue \endlink
93
+ */
94
+
95
+ + (NSFNanoPredicate*)predicateWithColumn:(NSFTableColumnType)theType matching:(NSFMatchType)theMatch value:(NSString *)theValue;
96
+
97
+ /** * Initializes a newly allocated predicate.
98
+ * @param theType is the column type. Can be \link Globals::NSFKeyColumn NSFKeyColumn \endlink, \link Globals::NSFAttributeColumn NSFAttributeColumn \endlink or \link Globals::NSFValueColumn NSFValueColumn \endlink.
99
+ * @param theMatch is the match operator.
100
+ * @param theValue is the value.
101
+ * @return A predicate which can be used in an NSFNanoExpression.
102
+ * @see \link predicateWithColumn:matching:value: + (NSFNanoPredicate*)predicateWithColumn:(NSFTableColumnType)theType matching:(NSFMatchType)theMatch value:(NSString *)theValue \endlink
103
+ */
104
+
105
+ - (id)initWithColumn:(NSFTableColumnType)theType matching:(NSFMatchType)theMatch value:(NSString *)theValue;
106
+
107
+ //@}
108
+
109
+ /** @name Miscellaneous
110
+ */
111
+
112
+ //@{
113
+
114
+ /** * Returns a string representation of the predicate.
115
+ * @note Check properties column, match and value to find out the current state of the predicate.
116
+ * @see \link description - (NSString *)description \endlink
117
+ */
118
+
119
+ - (NSString *)description;
120
+
121
+ //@}
122
+
123
+ @end
@@ -0,0 +1,130 @@
1
+ /*
2
+ NSFNanoExpression.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 "NSFNanoExpression.h"
28
+ #import "NanoStore_Private.h"
29
+
30
+ @implementation NSFNanoPredicate
31
+
32
+ @synthesize column, match, value;
33
+
34
+ // ----------------------------------------------
35
+ // Initialization / Cleanup
36
+ // ----------------------------------------------
37
+
38
+ + (NSFNanoPredicate*)predicateWithColumn:(NSFTableColumnType)type matching:(NSFMatchType)matching value:(NSString *)aValue
39
+ {
40
+ if (nil == aValue)
41
+ [[NSException exceptionWithName:NSFUnexpectedParameterException
42
+ reason:[NSString stringWithFormat:@"*** -[%@ %s]: value is nil.", [self class], _cmd]
43
+ userInfo:nil]raise];
44
+
45
+ return [[self alloc]initWithColumn:type matching:matching value:aValue];
46
+ }
47
+
48
+ - (id)initWithColumn:(NSFTableColumnType)type matching:(NSFMatchType)matching value:(NSString *)aValue
49
+ {
50
+ if (nil == aValue)
51
+ [[NSException exceptionWithName:NSFUnexpectedParameterException
52
+ reason:[NSString stringWithFormat:@"*** -[%@ %s]: value is nil.", [self class], _cmd]
53
+ userInfo:nil]raise];
54
+
55
+ if ((self = [super init])) {
56
+ column = type;
57
+ match = matching;
58
+ value = aValue;
59
+ }
60
+
61
+ return self;
62
+ }
63
+
64
+ - (NSString *)description
65
+ {
66
+ NSMutableString *description = [NSMutableString string];
67
+ NSMutableString *mutatedString = nil;
68
+ NSInteger mutatedStringLength = 0;
69
+ NSString *columnValue = nil;
70
+
71
+ switch (column) {
72
+ case NSFKeyColumn:
73
+ columnValue = NSFKey;
74
+ break;
75
+ case NSFAttributeColumn:
76
+ columnValue = NSFAttribute;
77
+ break;
78
+ default:
79
+ columnValue = NSFValue;
80
+ break;
81
+ }
82
+
83
+ switch (match) {
84
+ case NSFEqualTo:
85
+ [description appendString:[NSString stringWithFormat:@"%@ = '%@'", columnValue, value]];
86
+ break;
87
+ case NSFBeginsWith:
88
+ mutatedString = [NSMutableString stringWithString:value];
89
+ mutatedStringLength = [value length];
90
+ [mutatedString replaceCharactersInRange:NSMakeRange(mutatedStringLength - 1, 1) withString:[NSString stringWithFormat:@"%c", [mutatedString characterAtIndex:mutatedStringLength - 1]+1]];
91
+ [description appendString:[NSString stringWithFormat:@"(%@ >= '%@' AND %@ < '%@')", columnValue, value, columnValue, mutatedString]];
92
+ break;
93
+ case NSFContains:
94
+ [description appendString:[NSString stringWithFormat:@"%@ GLOB '*%@*'", columnValue, value]];
95
+ break;
96
+ case NSFEndsWith:
97
+ [description appendString:[NSString stringWithFormat:@"%@ GLOB '*%@'", columnValue, value]];
98
+ break;
99
+ case NSFInsensitiveEqualTo:
100
+ [description appendString:[NSString stringWithFormat:@"upper(%@) = '%@'", columnValue, [value uppercaseString]]];
101
+ break;
102
+ case NSFInsensitiveBeginsWith:
103
+ mutatedString = [NSMutableString stringWithString:value];
104
+ mutatedStringLength = [value length];
105
+ [mutatedString replaceCharactersInRange:NSMakeRange(mutatedStringLength - 1, 1) withString:[NSString stringWithFormat:@"%c", [mutatedString characterAtIndex:mutatedStringLength - 1]+1]];
106
+ [description appendString:[NSString stringWithFormat:@"(upper(%@) >= '%@' AND upper(%@) < '%@')", columnValue, [value uppercaseString], columnValue, [mutatedString uppercaseString]]];
107
+ break;
108
+ case NSFInsensitiveContains:
109
+ [description appendString:[NSString stringWithFormat:@"%@ LIKE '%@%@%@'", columnValue, @"%", value, @"%"]];
110
+ break;
111
+ case NSFInsensitiveEndsWith:
112
+ [description appendString:[NSString stringWithFormat:@"%@ LIKE '%@%@'", columnValue, @"%", value]];
113
+ break;
114
+ case NSFGreaterThan:
115
+ [description appendString:[NSString stringWithFormat:@"%@ > '%@'", columnValue, value]];
116
+ break;
117
+ case NSFLessThan:
118
+ [description appendString:[NSString stringWithFormat:@"%@ < '%@'", columnValue, value]];
119
+ break;
120
+ }
121
+
122
+ return description;
123
+ }
124
+
125
+ /** \cond */
126
+
127
+
128
+ /** \endcond */
129
+
130
+ @end
@@ -0,0 +1,381 @@
1
+ /*
2
+ NSFNanoSearch.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 NSFNanoSearch.h
28
+ @brief A unit that provides an API to retrieve data from the document store.
29
+ */
30
+
31
+ /** @class NSFNanoSearch
32
+ * A unit that provides an API to retrieve data from the document store.
33
+ *
34
+ * The search can be conducted in two ways: programatically via setters or by providing a SQL statement. In both cases,
35
+ * it's necessary to indicate which object type should be returned. The type \link Globals::NSFReturnType NSFReturnType \endlink provides two options: \link Globals::NSFReturnObjects NSFReturnObjects \endlink and \link Globals::NSFReturnKeys NSFReturnKeys \endlink.
36
+ *
37
+ * - \link Globals::NSFReturnObjects NSFReturnObjects \endlink will return a dictionary with the key of the NanoObject (key) and the NanoObject itself (value).
38
+ * - \link Globals::NSFReturnKeys NSFReturnKeys \endlink will return an array of NanoObjects.
39
+ *
40
+ * @par <b>Some observations about retrieving data</b><br>
41
+ *
42
+ * Given the following data set:
43
+ *
44
+ * - Number of dictionaries: 3.956
45
+ * - Number of attributes: 593.862
46
+ *
47
+ * The table describing different timings to perform a simple value search (i.e. 'Barcelona') is included below, ordered from fastest to slowest:
48
+ *
49
+ *<table border="1" cellpadding="5">
50
+ *<tr>
51
+ *<th>Match type</th>
52
+ *<th>Seconds</th>
53
+ *</tr>
54
+ *<tr><td>Equal to</td><td>0.295</td></tr>
55
+ *<tr><td>Begins with</td><td>0.295</td></tr>
56
+ *<tr><td>Contains</td><td>1.295</td></tr>
57
+ *<tr><td>Contains (insensitive)</td><td>1.339</td></tr>
58
+ *<tr><td>Ends with (insensitive)</td><td>1.341</td></tr>
59
+ *<tr><td>Ends with</td><td>1.351</td></tr>
60
+ *<tr><td>Equal to (insensitive)</td><td>1.890</td></tr>
61
+ *<tr><td>Begins with (insensitive)</td><td>2.412</td></tr>
62
+ *<tr><td>Greater than</td><td>18.246</td></tr>
63
+ *<tr><td>Less than</td><td>27.677</td></tr>
64
+ *</table>
65
+
66
+ @section wherearetheobjects_sec Where are my objects?
67
+
68
+ While NSFNanoStore provides some convenience methods to obtain standard objects (such as objects of type NSFNanoBag), the bulk of the search mechanism is handled by NSFNanoSearch.
69
+ The steps involved to perform a search are quite simple:
70
+
71
+ - 1) Instantiate a search object
72
+ - 2) Configure the search via its accessors
73
+ - 3) Obtain the results specifying whether objects or keys should be returned (*)
74
+
75
+ (*) Request objects if you're interested in the data. Otherwise, you should request keys if you need to feed the result to another method, such as NSFNanoStore
76
+ \link NSFNanoStore::removeObjectsWithKeysInArray:error: -(BOOL)removeObjectsWithKeysInArray:(NSArray *)theKeys error:(out NSError **)outError \endlink method.
77
+
78
+ @details <b>Example: finding all objects with the attribute 'LastName' and value 'Doe'.</b>
79
+ @code
80
+ NSFNanoSearch *search = [NSFNanoSearch searchWithStore:nanoStore];
81
+
82
+ search.attribute = @"LastName";
83
+ search.match = NSFEqualTo;
84
+ search.value = @"Doe";
85
+
86
+ // Returns a dictionary with the UUID of the object (key) and the NanoObject (value).
87
+ NSDictionary *searchResults = [search searchObjectsWithReturnType:NSFReturnObjects error:nil];
88
+ @endcode
89
+
90
+ @details <b>Example: removing all objects with the attribute 'LastName' and value 'Doe'.</b>
91
+ @code
92
+ NSFNanoSearch *search = [NSFNanoSearch searchWithStore:nanoStore];
93
+
94
+ search.attribute = @"LastName";
95
+ search.match = NSFEqualTo;
96
+ search.value = @"Doe";
97
+
98
+ // Returns an array of matching UUIDs
99
+ NSArray *matchingKeys = [search searchObjectsWithReturnType:NSFReturnKeys error:nil];
100
+
101
+ // Remove the NanoObjects matching the selected UUIDs
102
+ NSError *outError = nil;
103
+ if (YES == [nanoStore removeObjectsWithKeysInArray:matchingKeys error:&outError]) {
104
+ NSLog(@"The matching objects have been removed.");
105
+ } else {
106
+ NSLog(@"An error has occurred while removing the matching objects. Reason: %@", [outError localizedDescription]);
107
+ }
108
+ @endcode
109
+
110
+ Another cool feature is the possibility to invoke aggregated functions (count, avg, min, max and total) on the search results. Using the search snippet above,
111
+ calculating the average salary of all people with last name equal to 'Doe' is very easy.
112
+
113
+ @details <b>Example: calculating the average salary of all objects with the attribute 'LastName' and value 'Doe'.</b>
114
+ @code
115
+ NSFNanoSearch *search = [NSFNanoSearch searchWithStore:nanoStore];
116
+
117
+ search.attribute = @"LastName";
118
+ search.match = NSFEqualTo;
119
+ search.value = @"Doe";
120
+
121
+ float averageSalary = [[search aggregateOperation:NSFAverage onAttribute:@"Salary"]floatValue];
122
+ @endcode
123
+
124
+ * @details <b>Example:</b>
125
+ @code
126
+ // Instantiate a NanoStore and open it
127
+ NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
128
+
129
+ // Generate a NanoObject with a dictionary and a key
130
+ NSString *key = @"ABC-123";
131
+ NSDictionary *info = ...;
132
+ NSFNanoObject *nanoObject = [NSFNanoObject nanoObjectWithDictionary:info];
133
+
134
+ // Add it to the document store
135
+ [nanoStore addObject:nanoObject error:nil];
136
+
137
+ // Instantiate a search and specify the attribute(s) we want to search for
138
+ NSFNanoSearch *search = [NSFNanoSearch searchWithStore:nanoStore];
139
+ search.key = key;
140
+
141
+ // Perform the search and obtain the results
142
+ NSDictionary *searchResults = [search searchObjectsWithReturnType:NSFReturnObjects error:nil];
143
+
144
+ // Close the document store
145
+ [nanoStore closeWithError:nil];
146
+ @endcode
147
+ */
148
+
149
+ #import <Foundation/Foundation.h>
150
+
151
+ #import "NSFNanoGlobals.h"
152
+
153
+ @class NSFNanoStore, NSFNanoResult;
154
+
155
+ @interface NSFNanoSearch : NSObject
156
+
157
+ /** * The document store used for searching. */
158
+ @property (nonatomic, weak, readonly) NSFNanoStore *nanoStore;
159
+ /** * The set of attributes to be returned on matching objects. */
160
+ @property (nonatomic, strong, readwrite) NSArray *attributesToBeReturned;
161
+ /** * The key used for searching. */
162
+ @property (nonatomic, copy, readwrite) NSString *key;
163
+ /** * The attribute used for searching. */
164
+ @property (nonatomic, copy, readwrite) NSString *attribute;
165
+ /** * The value used for searching. */
166
+ @property (nonatomic, copy, readwrite) id value;
167
+ /** * The comparison operator used for searching. */
168
+ @property (nonatomic, assign, readwrite) NSFMatchType match;
169
+ /** * The list of NSFNanoExpression objects used for searching. */
170
+ @property (nonatomic, strong, readwrite) NSArray *expressions;
171
+ /** * If set to YES, specifying NSFReturnKeys applies the DISTINCT function and groups the values. */
172
+ @property (nonatomic, assign, readwrite) BOOL groupValues;
173
+ /** * The SQL statement used for searching. Set when executeSQL: is invoked. */
174
+ @property (nonatomic, copy, readonly) NSString *sql;
175
+ /** * The sort holds an array of one or more sort descriptors of type \link NSFNanoSortDescriptor NSFNanoSortDescriptor \endlink. */
176
+ @property (nonatomic, strong, readwrite) NSArray *sort;
177
+
178
+ /** @name Creating and Initializing a Search
179
+ */
180
+
181
+ //@{
182
+
183
+ /** * Creates and returns a search element for a given document store.
184
+ * @param theNanoStore the document store where the search will be performed. Must not be nil.
185
+ * @return An search element upon success, nil otherwise.
186
+ * @see \link initWithStore: - (id)initWithStore:(NSFNanoStore *)theNanoStore \endlink
187
+ */
188
+
189
+ + (NSFNanoSearch *)searchWithStore:(NSFNanoStore *)theNanoStore;
190
+
191
+ /** * Initializes a newly allocated search element for a given document store.
192
+ * @param theNanoStore the document store where the search will be performed. Must not be nil.
193
+ * @return An search element upon success, nil otherwise.
194
+ * @see \link searchWithStore: + (NSFNanoSearch *)searchWithStore:(NSFNanoStore *)theNanoStore \endlink
195
+ */
196
+
197
+ - (id)initWithStore:(NSFNanoStore *)theNanoStore;
198
+
199
+ //@}
200
+
201
+ /** @name Searching
202
+ */
203
+
204
+ //@{
205
+
206
+ /** * Performs a search using the values of the properties.
207
+ * @param theReturnType the type of object to be returned. Can be \link Globals::NSFReturnObjects NSFReturnObjects \endlink or \link Globals::NSFReturnKeys NSFReturnKeys \endlink.
208
+ * @param outError is used if an error occurs. May be NULL.
209
+ * @return An array is returned if: 1) the sort has been specified or 2) the return type is \link Globals::NSFReturnKeys NSFReturnKeys \endlink. Otherwise, a dictionary is returned.
210
+ * @note The sort descriptor will be ignored when returning requesting NSFReturnKeys.
211
+ * @see \link searchObjectsAdded:date:returnType:error: - (id)searchObjectsAdded:(NSFDateMatchType)theDateMatch date:(NSDate *)theDate returnType:(NSFReturnType)theReturnType error:(out NSError **)outError \endlink
212
+ */
213
+
214
+ - (id)searchObjectsWithReturnType:(NSFReturnType)theReturnType error:(out NSError **)outError;
215
+
216
+ /** * Performs a search using the values of the properties before, on or after a given date.
217
+ * @param theDateMatch the type of date comparison. Can be \link Globals::NSFBeforeDate NSFBeforeDate \endlink, \link Globals::NSFOnDate NSFOnDate \endlink or \link Globals::NSFAfterDate NSFAfterDate \endlink.
218
+ * @param theDate the date to use as a pivot during the search.
219
+ * @param theReturnType the type of object to be returned. Can be \link Globals::NSFReturnObjects NSFReturnObjects \endlink or \link Globals::NSFReturnKeys NSFReturnKeys \endlink.
220
+ * @param outError is used if an error occurs. May be NULL.
221
+ * @return If theReturnType is \link Globals::NSFReturnObjects NSFReturnObjects \endlink, a dictionary is returned. Otherwise, an array is returned.
222
+ * @note The sort descriptor will be ignored when returning requesting NSFReturnKeys.
223
+ * @see \link searchObjectsWithReturnType:error: - (id)searchObjectsWithReturnType:(NSFReturnType)theReturnType error:(out NSError **)outError \endlink
224
+ */
225
+
226
+ - (id)searchObjectsAdded:(NSFDateMatchType)theDateMatch date:(NSDate *)theDate returnType:(NSFReturnType)theReturnType error:(out NSError **)outError;
227
+
228
+ /** * Returns the result of the aggregate function.
229
+ * @param theFunctionType is the function type to be applied.
230
+ * @param theAttribute is the attribute used in the function.
231
+ * @returns An NSNumber containing the result of the aggregate function.
232
+ * @details <b>Example:</b>
233
+ @code
234
+ * NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
235
+ *
236
+ * // Assume we have saved data to the document store
237
+ * ...
238
+ * ...
239
+ *
240
+ * // Get the average for the attribute named 'SomeNumber'
241
+ * NSFNanoSearch *search = [NSFNanoSearch searchWithStore:nanoStore];
242
+ * NSNumber *result = [search aggregateOperation:NSFAverage onAttribute:@"SomeNumber"];
243
+ @endcode
244
+ @note The sort descriptor will be ignored when executing aggregate operations.
245
+ */
246
+
247
+ - (NSNumber *)aggregateOperation:(NSFAggregateFunctionType)theFunctionType onAttribute:(NSString *)theAttribute;
248
+
249
+ /** * Performs a search with a given SQL statement.
250
+ * @param theSQLStatement is the SQL statement to be executed. Must not be nil or an empty string.
251
+ * @param theReturnType the type of object to be returned. Can be \link Globals::NSFReturnObjects NSFReturnObjects \endlink or \link Globals::NSFReturnKeys NSFReturnKeys \endlink.
252
+ * @param outError is used if an error occurs. May be NULL.
253
+ * @return If theReturnType is \link Globals::NSFReturnObjects NSFReturnObjects \endlink, a dictionary is returned. Otherwise, an array is returned.
254
+ * @note
255
+ * Use this method when performing search on NanoObjects. If you need to perform more advanced SQL statements, you may want to use
256
+ * \link executeSQL: - (NSFNanoResult *)executeSQL:(NSString *)theSQLStatement \endlink instead.
257
+ * @par
258
+ * The key difference between this method and \link executeSQL: - (NSFNanoResult *)executeSQL:(NSString *)theSQLStatement \endlink is that this method performs
259
+ * a check to make sure the columns specified match the ones required by the \link Globals::NSFReturnType NSFReturnType \endlink type selected. If the column selection is wrong,
260
+ * NanoStore rewrites the query by specifying the right set of columns while honoring the rest of the query.
261
+ * @details <b>Example:</b>
262
+ * @code
263
+ * // Prepare a document store
264
+ * NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
265
+ *
266
+ * // Prepare some data and wrap it in a NanoObject
267
+ * NSString *key = @"ABC-123";
268
+ * NSDictionary *info = ...;
269
+ * NSFNanoObject *nanoObject = [NSFNanoObject nanoObjectWithDictionary:info];
270
+ *
271
+ * // Add it to the document store
272
+ * [nanoStore addObjectsFromArray:[NSArray arrayWithObject:nanoObject] error:nil];
273
+ *
274
+ * // Instantiate a search and specify the attribute(s) we want to search for
275
+ * NSFNanoSearch *search = [NSFNanoSearch searchWithStore:nanoStore];
276
+ *
277
+ * // Perform the search
278
+ * // The query will be rewritten as @"SELECT NSFKey, NSFPlist, NSFObjectClass FROM NSFKeys"
279
+ * NSDictionary *results = [search executeSQL:@"SELECT foo, bar FROM NSFKeys" returnType:NSFReturnObjects error:nil];
280
+ * @endcode
281
+ * @note The sort descriptor will be ignored when executing custom SQL statements.
282
+ * @see \link executeSQL: - (NSFNanoResult *)executeSQL:(NSString *)theSQLStatement \endlink
283
+ */
284
+
285
+ - (id)executeSQL:(NSString *)theSQLStatement returnType:(NSFReturnType)theReturnType error:(out NSError **)outError;
286
+
287
+ /** * Performs a search with a given SQL statement.
288
+ * @param theSQLStatement is the SQL statement to be executed. Must not be nil or an empty string.
289
+ * @return Returns a NSFNanoResult.
290
+ * @note
291
+ * Use this method when you need to perform more advanced SQL statements. If you just want to query NanoObjects using your own SQL statement,
292
+ * you may want to use \link executeSQL:returnType:error: - (id)executeSQL:(NSString *)theSQLStatement returnType:(NSFReturnType)theReturnType error:(out NSError **)outError \endlink instead.
293
+ * @par
294
+ * The key difference between this method and \link executeSQL:returnType:error: - (id)executeSQL:(NSString *)theSQLStatement returnType:(NSFReturnType)theReturnType error:(out NSError **)outError \endlink
295
+ * is that this method doesn't perform any check at all. The SQL statement will be sent verbatim to SQLite.
296
+ * @details <b>Example:</b>
297
+ * @code
298
+ * // Prepare a document store
299
+ * NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
300
+ *
301
+ * // Prepare some data and wrap it in a NanoObject
302
+ * NSString *key = @"ABC-123";
303
+ * NSDictionary *info = ...;
304
+ * NSFNanoObject *nanoObject = [NSFNanoObject nanoObjectWithDictionary:info];
305
+ *
306
+ * // Add it to the document store
307
+ * [nanoStore addObjectsFromArray:[NSArray arrayWithObject:nanoObject] error:nil];
308
+ *
309
+ * // Instantiate a search and specify the attribute(s) we want to search for
310
+ * NSFNanoSearch *search = [NSFNanoSearch searchWithStore:nanoStore];
311
+ *
312
+ * // Perform the search
313
+ * NSFNanoResult *result = [search executeSQL:@"SELECT COUNT(*) FROM NSFKEYS"];
314
+ * @endcode
315
+ * @see \link executeSQL:returnType:error: - (id)executeSQL:(NSString *)theSQLStatement returnType:(NSFReturnType)theReturnType error:(out NSError **)outError \endlink
316
+ * @note The sort descriptor will be ignored when executing custom SQL statements.
317
+ */
318
+
319
+ - (NSFNanoResult *)executeSQL:(NSString *)theSQLStatement;
320
+
321
+ /** * Performs an analysis of the given SQL statement.
322
+ * @param theSQLStatement is the SQL statement to be analyzed. Must not be nil or an empty string.
323
+ * @return Returns a NSFNanoResult.
324
+ * @note
325
+ * Returns the sequence of virtual machine instructions with high-level information about what indices would have been used if the SQL statement had
326
+ * been executed.
327
+ *
328
+ * @warning
329
+ * The analysis generated by this method is intended for interactive analysis and troubleshooting only. The details of the output format
330
+ * are subject to change from one release of SQLite to the next. Applications should not use this method in production code since the exact behavior
331
+ * is undocumented, unspecified, and variable.
332
+ *
333
+ * For additional information about SQLite's Virtual Machine Opcodes, see http://www.sqlite.org/opcode.html
334
+ *
335
+ * The tutorial Virtual Database Engine of SQLite is available here: http://www.sqlite.org/vdbe.html
336
+ *
337
+ * @details <b>Example:</b>
338
+ * @code
339
+ * // Prepare a document store
340
+ * NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
341
+ *
342
+ * // Instantiate a search object
343
+ * NSFNanoSearch *search = [NSFNanoSearch searchWithStore:nanoStore];
344
+ *
345
+ * // Perform the analysis
346
+ * NSFNanoResult *results = [search explainSQL:@"SELECT * FROM NSFValues"];
347
+ * @endcode
348
+ * @see \link executeSQL: - (NSFNanoResult *)executeSQL:(NSString *)theSQLStatement \endlink
349
+ * @see \link executeSQL:returnType:error: - (id)executeSQL:(NSString *)theSQLStatement returnType:(NSFReturnType)theReturnType error:(out NSError **)outError \endlink
350
+ */
351
+
352
+ - (NSFNanoResult *)explainSQL:(NSString *)theSQLStatement;
353
+
354
+ //@}
355
+
356
+ /** @name Resetting Values
357
+ */
358
+
359
+ //@{
360
+
361
+ /** * Resets the values to a know, default state.
362
+ * - key = nil;
363
+ * - attribute = nil;
364
+ * - value = nil;
365
+ * - match = NSFContains;
366
+ * - object type = NSFReturnObjects;
367
+ * - groupValues = NO;
368
+ * - attributesReturned = nil;
369
+ * - type returned = NSFReturnObjects;
370
+ * - sql = nil;
371
+ * - sort = nil;
372
+ *
373
+ * @note
374
+ * When invoked, it sets the values of search to its initial state. Resetting and performing a search will select all records.
375
+ */
376
+
377
+ - (void)reset;
378
+
379
+ //@}
380
+
381
+ @end