nano-store 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +5 -0
- data/README.md +3 -1
- data/Rakefile +1 -1
- data/lib/nano_store.rb +1 -1
- data/lib/nano_store/model.rb +11 -7
- data/lib/nano_store/version.rb +1 -1
- data/spec/model_spec.rb +2 -5
- data/vendor/Podfile.lock +4 -4
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoGlobals.h +3 -1
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoPredicate.h +5 -5
- data/vendor/Pods/BuildHeaders/NanoStore/NSFNanoSearch.h +4 -2
- data/vendor/Pods/Documentation/NanoStore/docset-installed.txt +4 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Info.plist +33 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoBag.html +2266 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoEngine.html +4708 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoExpression.html +818 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoObject.html +1781 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoPredicate.html +800 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoResult.html +1054 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoSearch.html +2544 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoSortDescriptor.html +713 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFNanoStore.html +3723 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Classes/NSFOrderedDictionary.html +312 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/Protocols/NSFNanoObjectProtocol.html +651 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/css/styles.css +584 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/css/stylesPrint.css +22 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/hierarchy.html +106 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/img/button_bar_background.png +0 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/img/disclosure.png +0 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/img/disclosure_open.png +0 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/img/library_background.png +0 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/img/title_background.png +0 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Documents/index.html +654 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Nodes.xml +92 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Tokens1.xml +596 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Tokens10.xml +48 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Tokens11.xml +118 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Tokens2.xml +1209 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Tokens3.xml +158 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Tokens4.xml +455 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Tokens5.xml +166 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Tokens6.xml +246 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Tokens7.xml +821 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Tokens8.xml +125 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/Tokens9.xml +1082 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/docSet.dsidx +0 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/docSet.mom +0 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/docSet.skidx +0 -0
- data/vendor/Pods/Documentation/NanoStore/docset/Contents/Resources/docSet.toc +0 -0
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoBag.html +2266 -0
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoEngine.html +4708 -0
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoExpression.html +818 -0
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoObject.html +1781 -0
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoPredicate.html +800 -0
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoResult.html +1054 -0
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoSearch.html +2544 -0
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoSortDescriptor.html +713 -0
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFNanoStore.html +3723 -0
- data/vendor/Pods/Documentation/NanoStore/html/Classes/NSFOrderedDictionary.html +312 -0
- data/vendor/Pods/Documentation/NanoStore/html/Protocols/NSFNanoObjectProtocol.html +651 -0
- data/vendor/Pods/Documentation/NanoStore/html/css/styles.css +584 -0
- data/vendor/Pods/Documentation/NanoStore/html/css/stylesPrint.css +22 -0
- data/vendor/Pods/Documentation/NanoStore/html/hierarchy.html +106 -0
- data/vendor/Pods/Documentation/NanoStore/html/img/button_bar_background.png +0 -0
- data/vendor/Pods/Documentation/NanoStore/html/img/disclosure.png +0 -0
- data/vendor/Pods/Documentation/NanoStore/html/img/disclosure_open.png +0 -0
- data/vendor/Pods/Documentation/NanoStore/html/img/library_background.png +0 -0
- data/vendor/Pods/Documentation/NanoStore/html/img/title_background.png +0 -0
- data/vendor/Pods/Documentation/NanoStore/html/index.html +654 -0
- data/vendor/Pods/Headers/NanoStore/NSFNanoGlobals.h +3 -1
- data/vendor/Pods/Headers/NanoStore/NSFNanoPredicate.h +5 -5
- data/vendor/Pods/Headers/NanoStore/NSFNanoSearch.h +4 -2
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoGlobals.h +3 -1
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoGlobals.m +1 -0
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoPredicate.h +5 -5
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoPredicate.m +15 -14
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSearch.h +4 -2
- data/vendor/Pods/NanoStore/Classes/Public/NSFNanoSearch.m +95 -20
- data/vendor/Pods/Pods.bridgesupport +708 -700
- data/vendor/Pods/Pods.xcconfig +3 -3
- metadata +62 -4
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
header {
|
3
|
+
display: none;
|
4
|
+
}
|
5
|
+
|
6
|
+
div.main-navigation, div.navigation-top {
|
7
|
+
display: none;
|
8
|
+
}
|
9
|
+
|
10
|
+
div#overview_contents, div#contents.isShowingTOC, div#contents {
|
11
|
+
overflow: visible;
|
12
|
+
position: relative;
|
13
|
+
top: 0px;
|
14
|
+
border: none;
|
15
|
+
left: 0;
|
16
|
+
}
|
17
|
+
#tocContainer.isShowingTOC {
|
18
|
+
display: none;
|
19
|
+
}
|
20
|
+
nav {
|
21
|
+
display: none;
|
22
|
+
}
|
@@ -0,0 +1,106 @@
|
|
1
|
+
<!DOCTYPE HTML>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
5
|
+
<title>NanoStore 2.5.7 Hierarchy</title>
|
6
|
+
<link rel="stylesheet" type="text/css" href="css/styles.css" media="all" />
|
7
|
+
<link rel="stylesheet" type="text/css" media="print" href="css/stylesPrint.css" />
|
8
|
+
<meta name="generator" content="appledoc 2.0.5 (build 789)" />
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<header id="top_header">
|
12
|
+
<div id="library" class="hideInXcode">
|
13
|
+
<h1><a id="libraryTitle" href="index.html">NanoStore 2.5.7 </a></h1>
|
14
|
+
<a id="developerHome" href="index.html">Tito Ciuro</a>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<div id="title" role="banner">
|
18
|
+
<h1 class="hideInXcode">NanoStore 2.5.7 Hierarchy</h1>
|
19
|
+
</div>
|
20
|
+
<ul id="headerButtons" role="toolbar"></ul>
|
21
|
+
</header>
|
22
|
+
<article>
|
23
|
+
<div id="overview_contents" role="main">
|
24
|
+
<div class="main-navigation navigation-top">
|
25
|
+
<a href="index.html">Previous</a>
|
26
|
+
</div>
|
27
|
+
<div id="header">
|
28
|
+
<div class="section-header">
|
29
|
+
<h1 class="title title-header">NanoStore 2.5.7 Hierarchy</h1>
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
<div id="container">
|
33
|
+
|
34
|
+
<div class="index-column hierarchy-column">
|
35
|
+
<h2 class="index-title">Class Hierarchy</h2>
|
36
|
+
|
37
|
+
<ul>
|
38
|
+
|
39
|
+
<li>NSMutableDictionary
|
40
|
+
<ul>
|
41
|
+
|
42
|
+
<li><a href="Classes/NSFOrderedDictionary.html">NSFOrderedDictionary</a></li>
|
43
|
+
|
44
|
+
</ul>
|
45
|
+
</li>
|
46
|
+
|
47
|
+
<li>NSObject
|
48
|
+
<ul>
|
49
|
+
|
50
|
+
<li><a href="Classes/NSFNanoBag.html">NSFNanoBag</a></li>
|
51
|
+
|
52
|
+
<li><a href="Classes/NSFNanoEngine.html">NSFNanoEngine</a></li>
|
53
|
+
|
54
|
+
<li><a href="Classes/NSFNanoExpression.html">NSFNanoExpression</a></li>
|
55
|
+
|
56
|
+
<li><a href="Classes/NSFNanoObject.html">NSFNanoObject</a></li>
|
57
|
+
|
58
|
+
<li><a href="Classes/NSFNanoPredicate.html">NSFNanoPredicate</a></li>
|
59
|
+
|
60
|
+
<li><a href="Classes/NSFNanoResult.html">NSFNanoResult</a></li>
|
61
|
+
|
62
|
+
<li><a href="Classes/NSFNanoSearch.html">NSFNanoSearch</a></li>
|
63
|
+
|
64
|
+
<li><a href="Classes/NSFNanoSortDescriptor.html">NSFNanoSortDescriptor</a></li>
|
65
|
+
|
66
|
+
<li><a href="Classes/NSFNanoStore.html">NSFNanoStore</a></li>
|
67
|
+
|
68
|
+
</ul>
|
69
|
+
</li>
|
70
|
+
|
71
|
+
</ul>
|
72
|
+
|
73
|
+
</div>
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
<div class="index-column">
|
78
|
+
|
79
|
+
<h2 class="index-title">Protocol References</h2>
|
80
|
+
<ul>
|
81
|
+
|
82
|
+
<li><a href="Protocols/NSFNanoObjectProtocol.html">NSFNanoObjectProtocol</a></li>
|
83
|
+
|
84
|
+
</ul>
|
85
|
+
|
86
|
+
|
87
|
+
</div>
|
88
|
+
|
89
|
+
</div>
|
90
|
+
<div class="main-navigation navigation-bottom">
|
91
|
+
<a href="index.html">Previous</a>
|
92
|
+
</div>
|
93
|
+
<div id="footer">
|
94
|
+
<hr />
|
95
|
+
<div class="footer-copyright">
|
96
|
+
<p><span class="copyright">© 2013 Tito Ciuro. All rights reserved. (Last updated: 2013-01-22)</span><br />
|
97
|
+
|
98
|
+
<span class="generator">Generated by <a href="http://appledoc.gentlebytes.com">appledoc 2.0.5 (build 789)</a>.</span></p>
|
99
|
+
|
100
|
+
|
101
|
+
</div>
|
102
|
+
</div>
|
103
|
+
</div>
|
104
|
+
</article>
|
105
|
+
</body>
|
106
|
+
</html>
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,654 @@
|
|
1
|
+
<!DOCTYPE HTML>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
5
|
+
<title>NanoStore 2.5.7 Reference</title>
|
6
|
+
<link rel="stylesheet" type="text/css" href="css/styles.css" media="all" />
|
7
|
+
<link rel="stylesheet" type="text/css" media="print" href="css/stylesPrint.css" />
|
8
|
+
<meta name="generator" content="appledoc 2.0.5 (build 789)" />
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<header id="top_header">
|
12
|
+
<div id="library" class="hideInXcode">
|
13
|
+
<h1><a id="libraryTitle" href="index.html">NanoStore 2.5.7 </a></h1>
|
14
|
+
<a id="developerHome" href="index.html">Tito Ciuro</a>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<div id="title" role="banner">
|
18
|
+
<h1 class="hideInXcode">NanoStore 2.5.7 Reference</h1>
|
19
|
+
</div>
|
20
|
+
<ul id="headerButtons" role="toolbar"></ul>
|
21
|
+
</header>
|
22
|
+
<article>
|
23
|
+
<div id="overview_contents" role="main">
|
24
|
+
<div class="main-navigation navigation-top">
|
25
|
+
<a href="hierarchy.html">Next</a>
|
26
|
+
</div>
|
27
|
+
<div id="header">
|
28
|
+
<div class="section-header">
|
29
|
+
<h1 class="title title-header">NanoStore 2.5.7 Reference</h1>
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
<div id="container">
|
33
|
+
|
34
|
+
<div class="section section-overview index-overview">
|
35
|
+
|
36
|
+
|
37
|
+
<h1>Welcome To NanoStore</h1>
|
38
|
+
|
39
|
+
<p>–</p>
|
40
|
+
|
41
|
+
<p><strong>What is NanoStore?</strong></p>
|
42
|
+
|
43
|
+
<p>NanoStore is an open source, lightweight schema-less local key-value document store written in Objective-C for Mac OS X and iOS.</p>
|
44
|
+
|
45
|
+
<p>Relational databases tend to have a rich understanding of the structure of your data, but requires some planing beforehand and some level of maintenance as well. NanoStore provides the flexibility that comes with key-value document stores, but still understands something about your data. Because the data is key-value based, it can be accessed quickly and can grow as much as needed… all without ever worrying about the schema.</p>
|
46
|
+
|
47
|
+
<p><strong>Main advantages</strong></p>
|
48
|
+
|
49
|
+
<ul>
|
50
|
+
<li>No SQL knowledge required</li>
|
51
|
+
<li>Schema-less</li>
|
52
|
+
<li>Key-value based storage</li>
|
53
|
+
<li>Store your own custom objects</li>
|
54
|
+
<li>Bags, a free-form relational system</li>
|
55
|
+
<li>Fast, direct object manipulation</li>
|
56
|
+
<li>Dynamic queries</li>
|
57
|
+
<li>Full index support, inner-objects, embedded arrays and dictionaries</li>
|
58
|
+
<li>Convenience methods to access, manipulate and maintain SQLite databases</li>
|
59
|
+
<li>Full SQLite access available</li>
|
60
|
+
<li>Mac OS X Lion 10.7 and iOS 5 ready</li>
|
61
|
+
<li>iOS library runs on the device and simulator</li>
|
62
|
+
<li>ARC compliant</li>
|
63
|
+
</ul>
|
64
|
+
|
65
|
+
|
66
|
+
<h1>Latest changes</h1>
|
67
|
+
|
68
|
+
<p>–
|
69
|
+
v2.5 – January 1, 2013</p>
|
70
|
+
|
71
|
+
<ul>
|
72
|
+
<li><p>Starting with v2.5, the plist mechanism has been replaced with NSKeyedArchiver. There are several reasons for it: it’s more compact, faster and uses less memory. Perhaps the most important reason is that it opens the possibility to store other data types.</p></li>
|
73
|
+
<li><p>NSNull is now supported. Big thanks to Wanny (<a href="https://github.com/mrwanny">https://github.com/mrwanny)</a>) for taking the time to improve this section of NanoStore.</p></li>
|
74
|
+
</ul>
|
75
|
+
|
76
|
+
|
77
|
+
<h1>Installation</h1>
|
78
|
+
|
79
|
+
<p>–</p>
|
80
|
+
|
81
|
+
<p>Building NanoStore is very easy. Just follow these steps:</p>
|
82
|
+
|
83
|
+
<pre><code>1) Download NanoStore
|
84
|
+
2) Open the NanoStore.xcodeproj file
|
85
|
+
3) Select Universal > My Mac 64-bit or 32-bit from the Scheme popup
|
86
|
+
4) Build (Command-B)
|
87
|
+
</code></pre>
|
88
|
+
|
89
|
+
<p>Now you should have a new <strong><em>Distribution</em></strong> directory within the NanoStore project directory which contains the Universal static library (armv6/armv7/i386) as well as the header files. To add it in your project, do the following:</p>
|
90
|
+
|
91
|
+
<pre><code>1) Drag the Distribution directory to the Project Navigator panel
|
92
|
+
2) Include #import "NanoStore.h" in your code
|
93
|
+
</code></pre>
|
94
|
+
|
95
|
+
<p>You will also have to activate LLVM’s “Instrument Program Flow” setting:</p>
|
96
|
+
|
97
|
+
<p>!<a href="http://cloud.github.com/downloads/tciuro/NanoStore/profile_settings.png">Alt text</a></p>
|
98
|
+
|
99
|
+
<p>Usage example:</p>
|
100
|
+
|
101
|
+
<pre><code>#import "NanoStore.h"
|
102
|
+
|
103
|
+
@implementation MyDemoAppDelegate
|
104
|
+
|
105
|
+
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
106
|
+
{
|
107
|
+
// Override point for customization after application launch.
|
108
|
+
// Instantiate a NanoStore and open it
|
109
|
+
|
110
|
+
NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
|
111
|
+
...
|
112
|
+
</code></pre>
|
113
|
+
|
114
|
+
<h3>Note</h3>
|
115
|
+
|
116
|
+
<pre><code>If you want to add a dependency between your project and NanoStore so that it gets automatically rebuilt when
|
117
|
+
you update NanoStore, do the following (we'll assume your app is called "MyDemoApp"):
|
118
|
+
|
119
|
+
1) Select the MyDemoApp project in the Project Navigator
|
120
|
+
2) Select the MyDemoApp target
|
121
|
+
3) Expand the Target Dependencies box
|
122
|
+
4) Click "+" and add NanoStore
|
123
|
+
</code></pre>
|
124
|
+
|
125
|
+
<h1>How does NanoStore work?</h1>
|
126
|
+
|
127
|
+
<p>–</p>
|
128
|
+
|
129
|
+
<p>The basic unit of data in NanoStore is called NanoObject. A NanoObject is any object which conforms to the <a href="Protocols/NSFNanoObjectProtocol.html"><code>NSFNanoObjectProtocol</code></a> protocol.</p>
|
130
|
+
|
131
|
+
<p>At its core, a NanoObject is nothing more than a wrapper around two properties:</p>
|
132
|
+
|
133
|
+
<ul>
|
134
|
+
<li>A dictionary which contains the metadata (provided by the developer)</li>
|
135
|
+
<li>A key (UUID) that identifies the object (provided by NanoStore)</li>
|
136
|
+
</ul>
|
137
|
+
|
138
|
+
|
139
|
+
<p>The dictionary must be serializable, which means that only the following data types are allowed:</p>
|
140
|
+
|
141
|
+
<ul>
|
142
|
+
<li>NSArray</li>
|
143
|
+
<li>NSDictionary</li>
|
144
|
+
<li>NSString</li>
|
145
|
+
<li>NSData (*)</li>
|
146
|
+
<li>NSDate</li>
|
147
|
+
<li>NSNumber</li>
|
148
|
+
</ul>
|
149
|
+
|
150
|
+
|
151
|
+
<h3>Note</h3>
|
152
|
+
|
153
|
+
<pre><code>(*) The data type NSData is allowed, but it will be excluded from the indexing process.
|
154
|
+
</code></pre>
|
155
|
+
|
156
|
+
<p>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 NanoStore the developer has three options:</p>
|
157
|
+
|
158
|
+
<ul>
|
159
|
+
<li>Use the <code>NSFNanoObject</code> class directly</li>
|
160
|
+
<li>Expand your custom classes by inheriting from <a href="Classes/NSFNanoObject.html"><code>NSFNanoObject</code></a></li>
|
161
|
+
<li>Expand your custom classes by implementing the <code>NSFNanoObjectProtocol</code> protocol</li>
|
162
|
+
</ul>
|
163
|
+
|
164
|
+
|
165
|
+
<p>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 NanoStore returns the object as it was stored, that is, instantiating an object of the class that was originally stored.</p>
|
166
|
+
|
167
|
+
<h3>Note</h3>
|
168
|
+
|
169
|
+
<pre><code>If the document store is opened by another application that doesn't implement the object that was stored, NanoStore
|
170
|
+
will instantiate a NSFNanoObject instead, thus allowing the app to retrieve the data seamlessly. If the object is then
|
171
|
+
updated by this application, the original class name will be honored.
|
172
|
+
</code></pre>
|
173
|
+
|
174
|
+
<h3>Example</h3>
|
175
|
+
|
176
|
+
<pre><code>App A stores an object of class Car.
|
177
|
+
App B retrieves the object, but since it doesn't know anything about the class Car, NanoStore returns a NSFNanoObject.
|
178
|
+
App B updates the object, with additional information. NanoStore saves it as a Car, not as a NSFNanoObject.
|
179
|
+
App A retrieves the updated object as a Car object, in exactly the same format as it was originally stored.
|
180
|
+
</code></pre>
|
181
|
+
|
182
|
+
<h1>Types of Document Stores</h1>
|
183
|
+
|
184
|
+
<p>–</p>
|
185
|
+
|
186
|
+
<p>There are three types of document stores available in NanoStore: in-memory, temporary and file-based. These document stores are defined by the <code>NSFNanoStoreType</code> type:</p>
|
187
|
+
|
188
|
+
<p><code>NSFMemoryStoreType</code></p>
|
189
|
+
|
190
|
+
<pre><code>Create the transient backing store in RAM. Its contents are lost when the process exits. Fastest, uses more RAM (*).
|
191
|
+
</code></pre>
|
192
|
+
|
193
|
+
<p><code>NSFTemporaryStoreType</code></p>
|
194
|
+
|
195
|
+
<pre><code>Create a transient temporary backing store on disk. Its contents are lost when the process exits. Slower, uses less
|
196
|
+
RAM than NSFMemoryStoreType.
|
197
|
+
</code></pre>
|
198
|
+
|
199
|
+
<p><code>NSFPersistentStoreType</code></p>
|
200
|
+
|
201
|
+
<pre><code>Create a persistent backing store on disk. Slower, uses less RAM than NSFMemoryStoreType (*).
|
202
|
+
</code></pre>
|
203
|
+
|
204
|
+
<h3>Note</h3>
|
205
|
+
|
206
|
+
<pre><code>Until the limit set by NSFNanoEngine's - (NSUInteger)cacheSize has been reached, memory usage would be the same for
|
207
|
+
in-memory and on-disk stores. When the size of the store grows beyond - (NSUInteger)cacheSize in-memory stores start to
|
208
|
+
consume more memory than on-disk ones, because it has nowhere to push pages out of the cache.
|
209
|
+
|
210
|
+
Typically, most developers may want to create and open the document store. To do that, use the following method:
|
211
|
+
|
212
|
+
+ (NSFNanoStore *)createAndOpenStoreWithType:(NSFNanoStoreType)aType path:(NSString *)aPath error:(out NSError **)outError
|
213
|
+
</code></pre>
|
214
|
+
|
215
|
+
<h3>Example</h3>
|
216
|
+
|
217
|
+
<pre><code>// Instantiate an in-memory document store and open it. The path parameter is unused.
|
218
|
+
NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
|
219
|
+
|
220
|
+
// Instantiate a temporary document store and open it. The path parameter is unused.
|
221
|
+
NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFTemporaryStoreType path:nil error:nil];
|
222
|
+
|
223
|
+
// Instantiate a file-based document store and open it. The path parameter must be specified.
|
224
|
+
NSString *thePath = @"~/Desktop/myDatabase.database";
|
225
|
+
NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFPersistentStoreType path:thePath error:nil];
|
226
|
+
</code></pre>
|
227
|
+
|
228
|
+
<h3>Note</h3>
|
229
|
+
|
230
|
+
<pre><code>In the case of file-based document stores, the file gets created automatically if it doesn't exist and then opened. If
|
231
|
+
it already exists, it gets opened and made available for use right away. There are instances where you may want to
|
232
|
+
fine-tune the engine. Tuning the engine has to be performed before the document store is opened. Another method is
|
233
|
+
available in NSFNanoStore for this purpose:
|
234
|
+
|
235
|
+
+ (NSFNanoStore *)createStoreWithType:(NSFNanoStoreType)theType path:(NSString *)thePath.
|
236
|
+
</code></pre>
|
237
|
+
|
238
|
+
<h3>Example</h3>
|
239
|
+
|
240
|
+
<pre><code>// Instantiate a file-based document store but don't open it right away. The path parameter must be specified.
|
241
|
+
NSString *thePath = @"~/Desktop/myDatabase.database";
|
242
|
+
NSFNanoStore *nanoStore = [NSFNanoStore createStoreWithType:NSFPersistentStoreType path:thePath error:nil];
|
243
|
+
|
244
|
+
// Obtain the engine
|
245
|
+
NSFNanoEngine *nanoStoreEngine = [nanoStore nanoStoreEngine];
|
246
|
+
|
247
|
+
// Set the synchronous mode setting
|
248
|
+
[nanoStoreEngine setSynchronousMode:SynchronousModeOff];
|
249
|
+
[nanoStoreEngine setEncodingType:NSFEncodingUTF16];
|
250
|
+
|
251
|
+
// Open the document store
|
252
|
+
[nanoStore openWithError:nil];
|
253
|
+
</code></pre>
|
254
|
+
|
255
|
+
<h3>Note</h3>
|
256
|
+
|
257
|
+
<pre><code>Check the section Performance Tips below for important information about how to get the most out of NanoStore.
|
258
|
+
</code></pre>
|
259
|
+
|
260
|
+
<h1>Working with a NanoObject</h1>
|
261
|
+
|
262
|
+
<p>–</p>
|
263
|
+
|
264
|
+
<p>There are three basic operations that NanoStore can perform with a NanoObject:</p>
|
265
|
+
|
266
|
+
<ul>
|
267
|
+
<li>Add it to the document store</li>
|
268
|
+
<li>Update an existing object in the document store</li>
|
269
|
+
<li>Remove it from the document store</li>
|
270
|
+
</ul>
|
271
|
+
|
272
|
+
|
273
|
+
<p>To add an object, instantiate a <code>NSFNanoObject</code>, populate it and add it to the document store.</p>
|
274
|
+
|
275
|
+
<h3>Example</h3>
|
276
|
+
|
277
|
+
<pre><code>// Instantiate a NanoStore and open it
|
278
|
+
NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
|
279
|
+
|
280
|
+
// Generate an empty NanoObject
|
281
|
+
NSFNanoObject *object = [NSFNanoObject nanoObject];
|
282
|
+
|
283
|
+
// Add some data
|
284
|
+
[object setObject:@"Doe" forKey:@"kLastName"];
|
285
|
+
[object setObject:@"John" forKey:@"kFirstName"];
|
286
|
+
[object setObject:[NSArray arrayWithObjects:@"jdoe@foo.com", @"jdoe@bar.com", nil] forKey:@"kEmails"];
|
287
|
+
|
288
|
+
// Add it to the document store
|
289
|
+
[nanoStore addObject:object error:nil];
|
290
|
+
|
291
|
+
// Close the document store
|
292
|
+
[nanoStore closeWithError:nil];
|
293
|
+
</code></pre>
|
294
|
+
|
295
|
+
<p>Alternatively, you can instantiate a NanoObject providing a dictionary via:</p>
|
296
|
+
|
297
|
+
<pre><code>+ (NSFNanoObject*)nanoObjectWithDictionary:(NSDictionary *)theDictionary
|
298
|
+
</code></pre>
|
299
|
+
|
300
|
+
<p>NanoStore will assign a UUID automatically when the NanoObject is instantiated. This means that requesting the key from the NanoObject will return a valid UUID. The same holds true for objects that inherit from <code>NSFNanoObject</code>. However, classes that implement the <code>NSFNanoObjectProtocol</code> protocol should make sure they return a valid key via:</p>
|
301
|
+
|
302
|
+
<pre><code>- (NSString *)nanoObjectKey
|
303
|
+
</code></pre>
|
304
|
+
|
305
|
+
<h3>Warning</h3>
|
306
|
+
|
307
|
+
<pre><code>If an attempt is made to add or remove an object without a valid key, an exception of type NSFNanoObjectBehaviorException
|
308
|
+
will be raised. To update an object, simply modify the object and add it to the document store. NanoStore will replace
|
309
|
+
the existing object with the one being added.
|
310
|
+
</code></pre>
|
311
|
+
|
312
|
+
<h3>Example</h3>
|
313
|
+
|
314
|
+
<pre><code>// Instantiate and open a NanoStore
|
315
|
+
NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
|
316
|
+
|
317
|
+
// Assuming the dictionary exists, instantiate a NanoObject
|
318
|
+
NSDictionary *info = ...;
|
319
|
+
NSFNanoObject *object = [NSFNanoObject nanoObjectWithDictionary:info];
|
320
|
+
|
321
|
+
// Add the NanoObject to the document store
|
322
|
+
[nanoStore addObject:object error:nil];
|
323
|
+
|
324
|
+
// Update the NanoObject with new data
|
325
|
+
[object setObject:@"foo" forKey:@"SomeKey"];
|
326
|
+
|
327
|
+
// Update the NanoObject in the document store
|
328
|
+
[nanoStore addObject:object error:nil];
|
329
|
+
</code></pre>
|
330
|
+
|
331
|
+
<p>To remove an object, there are several options available. The most common methods are found in <a href="Classes/NSFNanoStore.html">NSFNanoStore</a>:</p>
|
332
|
+
|
333
|
+
<pre><code>- (BOOL)removeObject:(id NSFNanoObjectProtocol)theObject error:(out NSError **)outError
|
334
|
+
- (BOOL)removeObjectsWithKeysInArray:(NSArray *)theKeys error:(out NSError **)outError
|
335
|
+
- (BOOL)removeObjectsInArray:(NSArray *)theObjects error:(out NSError **)outError
|
336
|
+
</code></pre>
|
337
|
+
|
338
|
+
<h3>Example</h3>
|
339
|
+
|
340
|
+
<pre><code>// Instantiate and open a NanoStore
|
341
|
+
NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
|
342
|
+
|
343
|
+
// Assuming the dictionary exists, instantiate a NanoObject
|
344
|
+
NSDictionary *info = ...;
|
345
|
+
NSFNanoObject *object = [NSFNanoObject nanoObjectWithDictionary:info];
|
346
|
+
|
347
|
+
// Add the NanoObject to the document store
|
348
|
+
[nanoStore addObject:object error:nil];
|
349
|
+
|
350
|
+
// Remove the object
|
351
|
+
[nanoStore removeObject:object error:nil];
|
352
|
+
|
353
|
+
// ... or you could pass the key instead
|
354
|
+
[nanoStore removeObjectsWithKeysInArray:[NSArray arrayWithObject:[object nanoObjectKey]] error:nil];
|
355
|
+
</code></pre>
|
356
|
+
|
357
|
+
<h1>It’s not a flat World</h1>
|
358
|
+
|
359
|
+
<p>–</p>
|
360
|
+
|
361
|
+
<p>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 time. This situation is not ideal because in most cases schema refinements could be required, oftentimes impacting the code as well.</p>
|
362
|
+
|
363
|
+
<p>NanoStore goes beyond that allowing the developer to store objects in their natural form. These objects must conform to the <code>NSFNanoObjectProtocol</code> 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 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.) Each inner-object is indexed automatically, thus allowing to quickly find objects which contain a specific key and/or value.</p>
|
364
|
+
|
365
|
+
<p>By default, NanoStore allows objects to be stored without any sense of relationship to other objects. This simple format, while powerful, is limited because 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 type. This is exactly what NanoBag (represented by the <code>NSFNanoBag</code> class) does: it allows any object conforming to the <code>NSFNanoObjectProtocol</code> protocol to be added to the bag. By saving the bag with one single call, the new and/or modified NanoObjects are taken care of seamlessly.</p>
|
366
|
+
|
367
|
+
<p>The <code>NSFNanoBag</code> 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 required. In addition, it provides methods to obtain all bags, specific bags matching some keys, and bags containing a specific object (see <code>NSFNanoStore</code> for more information).</p>
|
368
|
+
|
369
|
+
<h1>Where are my objects?</h1>
|
370
|
+
|
371
|
+
<p>–</p>
|
372
|
+
|
373
|
+
<p>While <code>NSFNanoStore</code> provides some convenience methods to obtain standard objects such as bags, the bulk of the search mechanism is handled by <code>NSFNanoSearch</code>. The steps involved to perform a search are quite simple:</p>
|
374
|
+
|
375
|
+
<pre><code>1) Instantiate a search object
|
376
|
+
2) Configure the search via its accessors
|
377
|
+
3) Obtain the results specifying whether objects or keys should be returned (*)
|
378
|
+
</code></pre>
|
379
|
+
|
380
|
+
<h3>Note</h3>
|
381
|
+
|
382
|
+
<pre><code>(*) If introspecting the data is needed, request objects. You should request keys if you need to feed the result to
|
383
|
+
another method, such as the following method in NSFNanoStore:
|
384
|
+
|
385
|
+
-(BOOL)removeObjectsWithKeysInArray:(NSArray *)theKeys error:(out NSError **)outError
|
386
|
+
</code></pre>
|
387
|
+
|
388
|
+
<h3>Example: finding all objects with the attribute ‘LastName’ and value ‘Doe’</h3>
|
389
|
+
|
390
|
+
<pre><code>NSFNanoSearch *search = [NSFNanoSearch searchWithStore:nanoStore];
|
391
|
+
|
392
|
+
search.attribute = @"LastName";
|
393
|
+
search.match = NSFEqualTo;
|
394
|
+
search.value = @"Doe";
|
395
|
+
|
396
|
+
// Returns a dictionary with the UUID of the object (key) and the NanoObject (value).
|
397
|
+
NSDictionary *searchResults = [search searchObjectsWithReturnType:NSFReturnObjects error:nil];
|
398
|
+
</code></pre>
|
399
|
+
|
400
|
+
<h3>Example: removing all objects with the attribute ‘LastName’ and value ‘Doe’</h3>
|
401
|
+
|
402
|
+
<pre><code>NSFNanoSearch *search = [NSFNanoSearch searchWithStore:nanoStore];
|
403
|
+
|
404
|
+
search.attribute = @"LastName";
|
405
|
+
search.match = NSFEqualTo;
|
406
|
+
search.value = @"Doe";
|
407
|
+
|
408
|
+
// Returns an array of matching UUIDs
|
409
|
+
NSArray *matchingKeys = [search searchObjectsWithReturnType:NSFReturnKeys error:nil];
|
410
|
+
|
411
|
+
// Remove the NanoObjects matching the selected UUIDs
|
412
|
+
NSError *outError = nil;
|
413
|
+
if (YES == [nanoStore removeObjectsWithKeysInArray:matchingKeys error:&outError]) {
|
414
|
+
NSLog(@"The matching objects have been removed.");
|
415
|
+
} else {
|
416
|
+
NSLog(@"An error has occurred while removing the matching objects. Reason: %@", [outError localizedDescription]);
|
417
|
+
}
|
418
|
+
</code></pre>
|
419
|
+
|
420
|
+
<h3>Example: calculating the average salary of all objects with the attribute ‘LastName’ and value ‘Doe’</h3>
|
421
|
+
|
422
|
+
<p>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, calculating the average salary of all people with last name equal to ‘Doe’ is very easy.</p>
|
423
|
+
|
424
|
+
<pre><code>NSFNanoSearch *search = [NSFNanoSearch searchWithStore:nanoStore];
|
425
|
+
|
426
|
+
search.attribute = @"LastName";
|
427
|
+
search.match = NSFEqualTo;
|
428
|
+
search.value = @"Doe";
|
429
|
+
|
430
|
+
float averageSalary = [[search aggregateOperation:NSFAverage onAttribute:@"Salary"]floatValue];
|
431
|
+
</code></pre>
|
432
|
+
|
433
|
+
<h1>Sorting</h1>
|
434
|
+
|
435
|
+
<p>–</p>
|
436
|
+
|
437
|
+
<p>Combining search and sort is an extremely easy operation. There are two simple parts:</p>
|
438
|
+
|
439
|
+
<pre><code>1) Preparing your classes for sorting
|
440
|
+
2) Setup a search operation and set its sort descriptors
|
441
|
+
</code></pre>
|
442
|
+
|
443
|
+
<h3>Preparing your classes for sorting</h3>
|
444
|
+
|
445
|
+
<p>Since NanoStore relies on KVC to perform the sorts, a hint of the location where the data lives within the object is required. Since KVC uses a key path to reach the element being sorted, we need a way to “point” to it. Most custom classes will return <em>self</em>, as is the case for NSFNanoBag:</p>
|
446
|
+
|
447
|
+
<pre><code>- (id)rootObject
|
448
|
+
{
|
449
|
+
return self;
|
450
|
+
}
|
451
|
+
</code></pre>
|
452
|
+
|
453
|
+
<p><em>Self</em> in this case represents the top level, the location where the variables <em>name</em>, <em>key</em> and <em>hasUnsavedChanges</em> are located:</p>
|
454
|
+
|
455
|
+
<pre><code>@interface NSFNanoBag : NSObject <NSFNanoObjectProtocol, NSCopying>
|
456
|
+
{
|
457
|
+
NSFNanoStore *store;
|
458
|
+
NSString *name;
|
459
|
+
NSString *key;
|
460
|
+
BOOL hasUnsavedChanges;
|
461
|
+
}
|
462
|
+
</code></pre>
|
463
|
+
|
464
|
+
<p>Assume we have an object that represents a person and its root object is set to <i>self</i>, just as demonstrated above:</p>
|
465
|
+
|
466
|
+
<pre><code>@interface Person : NSFNanoObject
|
467
|
+
{
|
468
|
+
NSString *firstName;
|
469
|
+
NSString *lastName;
|
470
|
+
NSString *email;
|
471
|
+
}
|
472
|
+
</code></pre>
|
473
|
+
|
474
|
+
<p>If we wanted to retrieve all the existing people with <i>firstName</i> equal to <i>John</i> sorted by <i>lastName</i> we would do the following:</p>
|
475
|
+
|
476
|
+
<pre><code>// Assume NanoStore has been opened elsewhere
|
477
|
+
NSFNanoStore *nanoStore = ...;
|
478
|
+
|
479
|
+
// Prepare the search
|
480
|
+
NSFNanoSearch *search = [NSFNanoSearch searchWithStore:nanoStore];
|
481
|
+
search.attribute = @"firstName";
|
482
|
+
search.match = NSFEqualTo;
|
483
|
+
search.value = @"John";
|
484
|
+
|
485
|
+
// Prepare and set the sort descriptor
|
486
|
+
NSFNanoSortDescriptor *sortByLastName = [[NSFNanoSortDescriptor alloc]initWithAttribute:@"lastName" ascending:YES];
|
487
|
+
search.sort = [NSArray arrayWithObject:sortByLastName];
|
488
|
+
|
489
|
+
// Perform the search
|
490
|
+
NSArray *searchResults = [search searchObjectsWithReturnType:NSFReturnObjects error:nil];
|
491
|
+
|
492
|
+
// Cleanup
|
493
|
+
[sortByLastName release];
|
494
|
+
</code></pre>
|
495
|
+
|
496
|
+
<h1>Paging using Limit and Offset</h1>
|
497
|
+
|
498
|
+
<p>–</p>
|
499
|
+
|
500
|
+
<p>SQLite provides a really cool feature called OFFSET that is usually used with a LIMIT clause.</p>
|
501
|
+
|
502
|
+
<p>The LIMIT clause is used to limit the number of results returned in a SQL statement. So if you have 1000 rows in a table, but only want to return the first 10, you would do something like this:</p>
|
503
|
+
|
504
|
+
<pre><code>SELECT column FROM table LIMIT 10
|
505
|
+
</code></pre>
|
506
|
+
|
507
|
+
<p>Now suppose you wanted to show results 11-20. With the OFFSET keyword it’s just as easy. The following query will do:</p>
|
508
|
+
|
509
|
+
<pre><code>SELECT column FROM table LIMIT 10 OFFSET 10
|
510
|
+
</code></pre>
|
511
|
+
|
512
|
+
<p>Using pagination is also quite easy with NanoStore. This example based on one of the unit tests provided with the NanoStore distro:</p>
|
513
|
+
|
514
|
+
<pre><code>NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
|
515
|
+
|
516
|
+
// Assume we have added objects to the store
|
517
|
+
|
518
|
+
NSFNanoSearch *search = [NSFNanoSearch searchWithStore:nanoStore];
|
519
|
+
search.value = @"Barcelona";
|
520
|
+
search.match = NSFEqualTo;
|
521
|
+
search.limit = 5;
|
522
|
+
search.offset = 3;
|
523
|
+
|
524
|
+
NSDictionary *searchResults = [search searchObjectsWithReturnType:NSFReturnObjects error:nil];
|
525
|
+
|
526
|
+
// Assuming the query matches some results, NanoStore should have retrieved
|
527
|
+
// the first 5 records right after the 3rd one from the result set.
|
528
|
+
</code></pre>
|
529
|
+
|
530
|
+
<h1>Performance Tips</h1>
|
531
|
+
|
532
|
+
<p>–</p>
|
533
|
+
|
534
|
+
<p>NanoStore by defaults saves every object to disk one by one. To speed up inserts and edited objects, increase NSFNanoStore’s <code>saveInterval</code> property.</p>
|
535
|
+
|
536
|
+
<h3>Example</h3>
|
537
|
+
|
538
|
+
<pre><code>// Instantiate and open a NanoStore
|
539
|
+
NSFNanoStore *nanoStore = [NSFNanoStore createAndOpenStoreWithType:NSFMemoryStoreType path:nil error:nil];
|
540
|
+
|
541
|
+
// Increase the save interval
|
542
|
+
[nanoStore setSaveInterval:1000];
|
543
|
+
|
544
|
+
// Do a bunch of inserts and/or edits
|
545
|
+
|
546
|
+
// Don't forget that some objects could be lingering in memory. Force a save.
|
547
|
+
[nanoStore saveStoreAndReturnError:nil];
|
548
|
+
</code></pre>
|
549
|
+
|
550
|
+
<h3>Note</h3>
|
551
|
+
|
552
|
+
<pre><code>If you set the saveInterval value to anything other one, keep in mind that some objects may still be left unsaved after
|
553
|
+
being added or modified. To make sure they're saved properly, call:
|
554
|
+
|
555
|
+
- (BOOL)saveStoreAndReturnError:(out NSError **)outError .
|
556
|
+
|
557
|
+
Choosing a good saveInterval value is more art than science. While testing NanoStore using a medium-sized dictionary
|
558
|
+
(iTunes MP3 dictionary) setting saveInterval to 1000 resulted in the best performance. You may want to test with
|
559
|
+
different numbers and fine-tune it for your data set.
|
560
|
+
</code></pre>
|
561
|
+
|
562
|
+
<h3>Warning</h3>
|
563
|
+
|
564
|
+
<pre><code>Setting saveInterval to a large number could result in decreased performance because SQLite's would have to spend more
|
565
|
+
time reading the journal file and writing the changes to the store.
|
566
|
+
</code></pre>
|
567
|
+
|
568
|
+
<h1>Need more help?</h1>
|
569
|
+
|
570
|
+
<p>–</p>
|
571
|
+
|
572
|
+
<p>There are two quick ways to find answers: reading the documentation and browsing the Unit tests.</p>
|
573
|
+
|
574
|
+
<p>While several attempts have been made to make the documentation easy to read and understand, it’s far from perfect. If you find that the documentation is incomplete, incorrect or needs some clarification, please file a bug. I’ll appreciate it and correct it as soon as possible:</p>
|
575
|
+
|
576
|
+
<ul>
|
577
|
+
<li>NanoStore Documentation: <a href="http://dl.dropbox.com/u/2601212/NanoStore%202.0/html/index.html">http://dl.dropbox.com/u/2601212/NanoStore%202.0/html/index.html</a></li>
|
578
|
+
<li>NanoStore Bug Tracker: <a href="https://github.com/tciuro/NanoStore/issues">https://github.com/tciuro/NanoStore/issues</a></li>
|
579
|
+
<li>Twitter: <a href="http://twitter.com/nanostoredev">http://twitter.com/nanostoredev</a></li>
|
580
|
+
</ul>
|
581
|
+
|
582
|
+
|
583
|
+
<h1>Official Source Repository</h1>
|
584
|
+
|
585
|
+
<p>–</p>
|
586
|
+
|
587
|
+
<p>The official repository for NanoStore is hosted on GitHub: <a href="https://github.com/tciuro/NanoStore">https://github.com/tciuro/NanoStore</a></p>
|
588
|
+
|
589
|
+
|
590
|
+
</div>
|
591
|
+
|
592
|
+
|
593
|
+
|
594
|
+
|
595
|
+
|
596
|
+
<div class="index-column">
|
597
|
+
<h2 class="index-title">Class References</h2>
|
598
|
+
<ul>
|
599
|
+
|
600
|
+
<li><a href="Classes/NSFNanoBag.html">NSFNanoBag</a></li>
|
601
|
+
|
602
|
+
<li><a href="Classes/NSFNanoEngine.html">NSFNanoEngine</a></li>
|
603
|
+
|
604
|
+
<li><a href="Classes/NSFNanoExpression.html">NSFNanoExpression</a></li>
|
605
|
+
|
606
|
+
<li><a href="Classes/NSFNanoObject.html">NSFNanoObject</a></li>
|
607
|
+
|
608
|
+
<li><a href="Classes/NSFNanoPredicate.html">NSFNanoPredicate</a></li>
|
609
|
+
|
610
|
+
<li><a href="Classes/NSFNanoResult.html">NSFNanoResult</a></li>
|
611
|
+
|
612
|
+
<li><a href="Classes/NSFNanoSearch.html">NSFNanoSearch</a></li>
|
613
|
+
|
614
|
+
<li><a href="Classes/NSFNanoSortDescriptor.html">NSFNanoSortDescriptor</a></li>
|
615
|
+
|
616
|
+
<li><a href="Classes/NSFNanoStore.html">NSFNanoStore</a></li>
|
617
|
+
|
618
|
+
<li><a href="Classes/NSFOrderedDictionary.html">NSFOrderedDictionary</a></li>
|
619
|
+
|
620
|
+
</ul>
|
621
|
+
</div>
|
622
|
+
|
623
|
+
|
624
|
+
|
625
|
+
<div class="index-column">
|
626
|
+
|
627
|
+
<h2 class="index-title">Protocol References</h2>
|
628
|
+
<ul>
|
629
|
+
|
630
|
+
<li><a href="Protocols/NSFNanoObjectProtocol.html">NSFNanoObjectProtocol</a></li>
|
631
|
+
|
632
|
+
</ul>
|
633
|
+
|
634
|
+
|
635
|
+
</div>
|
636
|
+
|
637
|
+
</div>
|
638
|
+
<div class="main-navigation navigation-bottom">
|
639
|
+
<a href="hierarchy.html">Next</a>
|
640
|
+
</div>
|
641
|
+
<div id="footer">
|
642
|
+
<hr />
|
643
|
+
<div class="footer-copyright">
|
644
|
+
<p><span class="copyright">© 2013 Tito Ciuro. All rights reserved. (Last updated: 2013-01-22)</span><br />
|
645
|
+
|
646
|
+
<span class="generator">Generated by <a href="http://appledoc.gentlebytes.com">appledoc 2.0.5 (build 789)</a>.</span></p>
|
647
|
+
|
648
|
+
|
649
|
+
</div>
|
650
|
+
</div>
|
651
|
+
</div>
|
652
|
+
</article>
|
653
|
+
</body>
|
654
|
+
</html>
|