nano-store 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.gitmodules +3 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/LICENSE +25 -0
- data/README.md +193 -0
- data/Rakefile +1 -0
- data/app/app_delegate.rb +5 -0
- data/lib/nano-store.rb +1 -0
- data/lib/nano_store/bag.rb +98 -0
- data/lib/nano_store/model.rb +142 -0
- data/lib/nano_store/nano_store.rb +36 -0
- data/lib/nano_store/store_extension.rb +150 -0
- data/lib/nano_store/version.rb +3 -0
- data/lib/nano_store.rb +14 -0
- data/nano-store.gemspec +17 -0
- data/resources/.gitignore +0 -0
- data/spec/bag_spec.rb +66 -0
- data/spec/model_spec.rb +130 -0
- data/spec/nano_store_spec.rb +48 -0
- data/spec/store_extension_spec.rb +110 -0
- data/vendor/NanoStore/Classes/Advanced/NSFNanoEngine.h +542 -0
- data/vendor/NanoStore/Classes/Advanced/NSFNanoEngine.m +1781 -0
- data/vendor/NanoStore/Classes/Advanced/NSFNanoResult.h +137 -0
- data/vendor/NanoStore/Classes/Advanced/NSFNanoResult.m +265 -0
- data/vendor/NanoStore/Classes/Private/NSFNanoBag_Private.h +37 -0
- data/vendor/NanoStore/Classes/Private/NSFNanoEngine_Private.h +69 -0
- data/vendor/NanoStore/Classes/Private/NSFNanoExpression_Private.h +35 -0
- data/vendor/NanoStore/Classes/Private/NSFNanoGlobals_Private.h +99 -0
- data/vendor/NanoStore/Classes/Private/NSFNanoObject_Private.h +35 -0
- data/vendor/NanoStore/Classes/Private/NSFNanoPredicate_Private.h +35 -0
- data/vendor/NanoStore/Classes/Private/NSFNanoResult_Private.h +43 -0
- data/vendor/NanoStore/Classes/Private/NSFNanoSearch_Private.h +48 -0
- data/vendor/NanoStore/Classes/Private/NSFNanoStore_Private.h +57 -0
- data/vendor/NanoStore/Classes/Private/NanoStore_Private.h +37 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoBag.h +306 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoBag.m +485 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoExpression.h +125 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoExpression.m +103 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoGlobals.h +323 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoGlobals.m +145 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoObject.h +298 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoObject.m +187 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoObjectProtocol.h +119 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoPredicate.h +123 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoPredicate.m +130 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoSearch.h +381 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoSearch.m +835 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoSortDescriptor.h +124 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoSortDescriptor.m +79 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoStore.h +475 -0
- data/vendor/NanoStore/Classes/Public/NSFNanoStore.m +1375 -0
- data/vendor/NanoStore/Classes/Public/NanoStore.h +463 -0
- data/vendor/NanoStore/LICENSE +25 -0
- data/vendor/NanoStore/NanoStore.bridgesupport +1215 -0
- data/vendor/NanoStore/README.md +411 -0
- metadata +118 -0
data/.gitignore
ADDED
data/.gitmodules
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm ruby-1.9.3-p194@motion
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
Copyright (c) 2012, Francis Chong, All rights reserved.
|
2
|
+
Redistribution and use in source and binary forms, with or without
|
3
|
+
modification, are permitted provided that the following conditions are met:
|
4
|
+
|
5
|
+
* Redistributions of source code must retain the above copyright notice, this
|
6
|
+
list of conditions and the following disclaimer.
|
7
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
8
|
+
this list of conditions and the following disclaimer in the documentation
|
9
|
+
and/or other materials provided with the distribution.
|
10
|
+
* Neither the name of Tito Ciuro, Webbo, L.L.C. nor the names of its
|
11
|
+
contributors may be used to endorse or promote products derived from this
|
12
|
+
software without specific prior written permission.
|
13
|
+
|
14
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
15
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
16
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
18
|
+
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
19
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
20
|
+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
21
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
22
|
+
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
23
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
24
|
+
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
25
|
+
DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
# NanoStore for RubyMotion
|
2
|
+
|
3
|
+
Wrapper for NanoStore, a lightweight schema-less key-value document database based on sqlite, in RubyMotion.
|
4
|
+
|
5
|
+
Status: Work in progress. API subject to change.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Install the CocoaPods dependency manager if you haven't it already:
|
10
|
+
|
11
|
+
gem install motion-cocoapods
|
12
|
+
pod setup
|
13
|
+
|
14
|
+
Install nano-store gem
|
15
|
+
|
16
|
+
gem install nano-store
|
17
|
+
|
18
|
+
Require nano-store to your project 'Rakefile'
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
$:.unshift("/Library/RubyMotion/lib")
|
22
|
+
require 'motion/project'
|
23
|
+
require 'motion-cocoapods'
|
24
|
+
require 'nano-store'
|
25
|
+
|
26
|
+
Motion::Project::App.setup do |app|
|
27
|
+
app.name = 'myapp'
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
Now, you can use NanoStore in your app.
|
32
|
+
|
33
|
+
## Basic Usage
|
34
|
+
|
35
|
+
### Set default storage type
|
36
|
+
|
37
|
+
````ruby
|
38
|
+
NanoStore.shared_store = NanoStore.store(:memory) # memory only db
|
39
|
+
NanoStore.shared_store = NanoStore.store(:file, documents_path + "/nano.db") # persist the data
|
40
|
+
````
|
41
|
+
|
42
|
+
### Define Model
|
43
|
+
|
44
|
+
````ruby
|
45
|
+
class User < NanoStore::Model
|
46
|
+
attribute :name
|
47
|
+
attribute :age
|
48
|
+
attribute :created_at
|
49
|
+
end
|
50
|
+
````
|
51
|
+
|
52
|
+
A key (UUID) that identifies the object will be added automatically.
|
53
|
+
|
54
|
+
Attributes must be serializable, which means that only the following data types are allowed:
|
55
|
+
|
56
|
+
- NSArray
|
57
|
+
- NSDictionary
|
58
|
+
- NSString
|
59
|
+
- NSData (*)
|
60
|
+
- NSDate
|
61
|
+
- NSNumber
|
62
|
+
|
63
|
+
#### Note
|
64
|
+
|
65
|
+
(*) The data type NSData is allowed, but it will be excluded from the indexing process.
|
66
|
+
|
67
|
+
### Create
|
68
|
+
|
69
|
+
````ruby
|
70
|
+
# Initialize a new object and save it
|
71
|
+
user = User.new(:name => "Bob", :age => 16, :created_at => Time.now)
|
72
|
+
user.save
|
73
|
+
user.key # => "550e8400-e29b-41d4-a716-446655440000" (automatically generated UUID)
|
74
|
+
|
75
|
+
# Create a new object directly
|
76
|
+
user = User.create(:name => "Bob", :age => 16, :created_at => Time.now)
|
77
|
+
````
|
78
|
+
|
79
|
+
### Retrieve
|
80
|
+
|
81
|
+
````ruby
|
82
|
+
# find all models
|
83
|
+
User.all # => [<User#1>, <User#2>]
|
84
|
+
|
85
|
+
# find model by criteria
|
86
|
+
users = User.find(:name, NSFEqualTo, "Bob")
|
87
|
+
````
|
88
|
+
|
89
|
+
### Update
|
90
|
+
|
91
|
+
````ruby
|
92
|
+
user = User.find(:name, NSFEqualTo, "Bob").first
|
93
|
+
user.name = "Dom"
|
94
|
+
user.save
|
95
|
+
````
|
96
|
+
|
97
|
+
### Delete
|
98
|
+
|
99
|
+
````ruby
|
100
|
+
user = User.find(:name, NSFEqualTo, "Bob").first
|
101
|
+
user.delete
|
102
|
+
````
|
103
|
+
|
104
|
+
## Using Transaction
|
105
|
+
|
106
|
+
Use transaction is easy, just wrap your database code in a transaction block.
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
store = NanoStore.shared_store = NanoStore.store
|
110
|
+
|
111
|
+
begin
|
112
|
+
store.transaction do |the_store|
|
113
|
+
Animal.count # => 0
|
114
|
+
obj1 = Animal.new
|
115
|
+
obj1.name = "Cat"
|
116
|
+
obj1.save
|
117
|
+
|
118
|
+
obj2 = Animal.new
|
119
|
+
obj2.name = "Dog"
|
120
|
+
obj2.save
|
121
|
+
Animal.count # => 2
|
122
|
+
raise "error" # => an error happened!
|
123
|
+
end
|
124
|
+
rescue
|
125
|
+
# error handling
|
126
|
+
end
|
127
|
+
|
128
|
+
Animal.count # => 0
|
129
|
+
```
|
130
|
+
|
131
|
+
## Using Bags
|
132
|
+
|
133
|
+
A bag is a loose collection of objects stored in a document store.
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
store = NanoStore.store
|
137
|
+
bag = Bag.bag
|
138
|
+
store << bag
|
139
|
+
|
140
|
+
# add subclass of NanoStore::Model object to bag
|
141
|
+
page = Page.new
|
142
|
+
page.text = "Hello"
|
143
|
+
page.index = 1
|
144
|
+
bag << page
|
145
|
+
|
146
|
+
# save the bag
|
147
|
+
bag.save
|
148
|
+
|
149
|
+
# obtain the bags from document store
|
150
|
+
bags = store.bags
|
151
|
+
```
|
152
|
+
|
153
|
+
## Performance Tips
|
154
|
+
|
155
|
+
NanoStore by defaults saves every object to disk one by one. To speed up inserts and edited objects, increase NSFNanoStore's ```saveInterval``` property.
|
156
|
+
|
157
|
+
### Example
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
# Create a store
|
161
|
+
store = NanoStore.shared_store = NanoStore.store
|
162
|
+
|
163
|
+
# Increase the save interval
|
164
|
+
store.save_interval = 1000
|
165
|
+
|
166
|
+
# Do a bunch of inserts and/or edits
|
167
|
+
obj1 = Animal.new
|
168
|
+
obj1.name = "Cat"
|
169
|
+
store << obj1
|
170
|
+
|
171
|
+
obj2 = Animal.new
|
172
|
+
obj2.name = "Dog"
|
173
|
+
store << obj2
|
174
|
+
|
175
|
+
# Don't forget that some objects could be lingering in memory. Force a save.
|
176
|
+
store.save
|
177
|
+
```
|
178
|
+
|
179
|
+
Note: If you set the saveInterval value to anything other one, keep in mind that some objects may still be left unsaved after being added or modified. To make sure they're saved properly, call:
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
store.save
|
183
|
+
```
|
184
|
+
|
185
|
+
Choosing a good saveInterval value is more art than science. While testing NanoStore using a medium-sized dictionary (iTunes MP3 dictionary) setting saveInterval to 1000 resulted in the best performance. You may want to test with different numbers and fine-tune it for your data set.
|
186
|
+
|
187
|
+
## Credit
|
188
|
+
|
189
|
+
- Based on [NanoStore](https://github.com/tciuro/NanoStore) from Tito Ciuro, Webbo, L.L.C.
|
190
|
+
|
191
|
+
## License
|
192
|
+
|
193
|
+
BSD License
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/app/app_delegate.rb
ADDED
data/lib/nano-store.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "nano_store"
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module NanoStore
|
2
|
+
class Bag < NSFNanoBag
|
3
|
+
## Accessors
|
4
|
+
alias_method :saved, :savedObjects
|
5
|
+
alias_method :unsaved, :unsavedObjects
|
6
|
+
alias_method :removed, :removedObjects
|
7
|
+
|
8
|
+
def changed?
|
9
|
+
self.hasUnsavedChanges
|
10
|
+
end
|
11
|
+
|
12
|
+
## Adding and Removing Objects
|
13
|
+
|
14
|
+
# Add an object to bag
|
15
|
+
# @return self
|
16
|
+
def <<(object)
|
17
|
+
error_ptr = Pointer.new(:id)
|
18
|
+
self.addObject(object, error:error_ptr)
|
19
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
# Clear the bag - remove all objects
|
24
|
+
alias_method :clear, :removeAllObjects
|
25
|
+
|
26
|
+
# Add an object or array of objects to bag
|
27
|
+
# Return the bag
|
28
|
+
def +(object_or_array)
|
29
|
+
error_ptr = Pointer.new(:id)
|
30
|
+
if object_or_array.is_a?(Array)
|
31
|
+
self.addObjectsFromArray(object_or_array, error:error_ptr)
|
32
|
+
else
|
33
|
+
self.addObject(object_or_array, error:error_ptr)
|
34
|
+
end
|
35
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
# Remove object from bag
|
40
|
+
def delete(object)
|
41
|
+
self.removeObject(object)
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
# Remove object from bag with key
|
46
|
+
# params:
|
47
|
+
# key - a key or array of keys
|
48
|
+
def delete_key(key)
|
49
|
+
if key.is_a?(Array)
|
50
|
+
self.removeObjectsWithKeysInArray(key)
|
51
|
+
else
|
52
|
+
self.removeObjectWithKey(key)
|
53
|
+
end
|
54
|
+
self
|
55
|
+
end
|
56
|
+
|
57
|
+
# Add an object or array of objects to bag
|
58
|
+
# Return the bag
|
59
|
+
def -(object_or_array)
|
60
|
+
error_ptr = Pointer.new(:id)
|
61
|
+
if object_or_array.is_a?(Array)
|
62
|
+
self.removeObjectsInArray(object_or_array, error:error_ptr)
|
63
|
+
else
|
64
|
+
self.removeObject(object, error_ptr)
|
65
|
+
end
|
66
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
## Saving, Reloading and Undoing
|
71
|
+
|
72
|
+
def save
|
73
|
+
error_ptr = Pointer.new(:id)
|
74
|
+
result = self.saveAndReturnError(error_ptr)
|
75
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
76
|
+
result
|
77
|
+
end
|
78
|
+
|
79
|
+
def reload
|
80
|
+
error_ptr = Pointer.new(:id)
|
81
|
+
result = self.reloadBagWithError(error_ptr)
|
82
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
83
|
+
result
|
84
|
+
end
|
85
|
+
|
86
|
+
def undo
|
87
|
+
error_ptr = Pointer.new(:id)
|
88
|
+
result = self.undoChangesWithError(error_ptr)
|
89
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
90
|
+
result
|
91
|
+
end
|
92
|
+
|
93
|
+
## Inflating and Deflating
|
94
|
+
|
95
|
+
alias_method :inflate, :inflateBag
|
96
|
+
alias_method :deflate, :deflateBag
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
module NanoStore
|
2
|
+
module ModelInstanceMethods
|
3
|
+
def save
|
4
|
+
raise NanoStoreError, 'No store provided' unless self.class.store
|
5
|
+
|
6
|
+
error_ptr = Pointer.new(:id)
|
7
|
+
self.class.store.addObject(self, error:error_ptr)
|
8
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def delete
|
13
|
+
raise NanoStoreError, 'No store provided' unless self.class.store
|
14
|
+
|
15
|
+
error_ptr = Pointer.new(:id)
|
16
|
+
self.class.store.removeObject(self, error: error_ptr)
|
17
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def method_missing(method, *args)
|
22
|
+
matched = method.to_s.match(/^([^=]+)(=)?$/)
|
23
|
+
name = matched[1]
|
24
|
+
modifier = matched[2]
|
25
|
+
|
26
|
+
if self.class.attributes.include?(name.to_sym) || name == "_id"
|
27
|
+
if modifier == "="
|
28
|
+
if args[0].nil?
|
29
|
+
self.info.delete(name.to_sym)
|
30
|
+
else
|
31
|
+
self.info[name.to_sym] = args[0]
|
32
|
+
end
|
33
|
+
else
|
34
|
+
self.info[name.to_sym]
|
35
|
+
end
|
36
|
+
else
|
37
|
+
super
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module ModelClassMethods
|
43
|
+
# initialize a new object
|
44
|
+
def new(data={})
|
45
|
+
extra_keys = (data.keys - self.attributes)
|
46
|
+
if extra_keys.size > 0
|
47
|
+
raise NanoStoreError, "fields #{extra_keys.join(', ')} is not a defined fields"
|
48
|
+
end
|
49
|
+
|
50
|
+
object = self.nanoObjectWithDictionary(data)
|
51
|
+
object
|
52
|
+
end
|
53
|
+
|
54
|
+
# initialize a new object and save it
|
55
|
+
def create(data={})
|
56
|
+
object = self.new(data)
|
57
|
+
object.save
|
58
|
+
end
|
59
|
+
|
60
|
+
def attribute(name)
|
61
|
+
@attributes << name
|
62
|
+
end
|
63
|
+
|
64
|
+
def attributes
|
65
|
+
@attributes
|
66
|
+
end
|
67
|
+
|
68
|
+
def store
|
69
|
+
if @store.nil?
|
70
|
+
return NanoStore.shared_store
|
71
|
+
end
|
72
|
+
@store
|
73
|
+
end
|
74
|
+
|
75
|
+
def store=(store)
|
76
|
+
@store = store
|
77
|
+
end
|
78
|
+
|
79
|
+
def count
|
80
|
+
self.store.count(self)
|
81
|
+
end
|
82
|
+
|
83
|
+
def all
|
84
|
+
search = NSFNanoSearch.searchWithStore(self.store)
|
85
|
+
error_ptr = Pointer.new(:id)
|
86
|
+
searchResults = search.searchObjectsWithReturnType(NSFReturnObjects, error:error_ptr)
|
87
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
88
|
+
searchResults.values
|
89
|
+
end
|
90
|
+
|
91
|
+
# find model by criteria
|
92
|
+
#
|
93
|
+
# Return array of models
|
94
|
+
#
|
95
|
+
# Example:
|
96
|
+
#
|
97
|
+
# User.find(:name, NSFEqualTo, "Bob") => [<User#1>]
|
98
|
+
#
|
99
|
+
def find(attribute, match, value)
|
100
|
+
search = search_with_store(self.store, attribute, match, value)
|
101
|
+
error_ptr = Pointer.new(:id)
|
102
|
+
searchResults = search.searchObjectsWithReturnType(NSFReturnObjects, error:error_ptr)
|
103
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
104
|
+
searchResults.values
|
105
|
+
end
|
106
|
+
|
107
|
+
# find model keys by criteria
|
108
|
+
#
|
109
|
+
# Return array of model keys
|
110
|
+
#
|
111
|
+
# Example:
|
112
|
+
#
|
113
|
+
# User.find(:name, NSFEqualTo, "Bob") => [<User#1>]
|
114
|
+
#
|
115
|
+
def find_keys(attribute, match, value)
|
116
|
+
search = search_with_store(self.store, attribute, match, value)
|
117
|
+
error_ptr = Pointer.new(:id)
|
118
|
+
searchResults = search.searchObjectsWithReturnType(NSFReturnKeys, error:error_ptr)
|
119
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
120
|
+
searchResults
|
121
|
+
end
|
122
|
+
|
123
|
+
def inherited(subclass)
|
124
|
+
subclass.instance_variable_set(:@attributes, [])
|
125
|
+
subclass.instance_variable_set(:@store, nil)
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
def search_with_store(store, attribute, match, value)
|
130
|
+
search = NSFNanoSearch.searchWithStore(self.store)
|
131
|
+
search.attribute = attribute.to_s
|
132
|
+
search.match = match
|
133
|
+
search.value = value
|
134
|
+
search
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class Model < NSFNanoObject
|
139
|
+
include ModelInstanceMethods
|
140
|
+
extend ModelClassMethods
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module NanoStore
|
2
|
+
class NanoStoreError < StandardError; end
|
3
|
+
|
4
|
+
def self.store(type=:memory, path=nil)
|
5
|
+
error_ptr = Pointer.new(:id)
|
6
|
+
|
7
|
+
case type
|
8
|
+
when :memory
|
9
|
+
store = NSFNanoStore.createAndOpenStoreWithType(NSFMemoryStoreType, path:nil, error: error_ptr)
|
10
|
+
when :temporary, :temp
|
11
|
+
store = NSFNanoStore.createAndOpenStoreWithType(NSFTemporaryStoreType, path:nil, error: error_ptr)
|
12
|
+
when :persistent, :file
|
13
|
+
store = NSFNanoStore.createAndOpenStoreWithType(NSFPersistentStoreType, path:path, error: error_ptr)
|
14
|
+
else
|
15
|
+
raise NanoStoreError.new("unexpected store type (#{type}), must be one of: :memory, :temporary or :persistent")
|
16
|
+
end
|
17
|
+
|
18
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
19
|
+
store
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.shared_store
|
23
|
+
@shared_store
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.shared_store=(store)
|
27
|
+
@shared_store = store
|
28
|
+
end
|
29
|
+
|
30
|
+
# set debug mode
|
31
|
+
# if YES, debug mode is on; otherwise debug mode is disabled.
|
32
|
+
def self.debug=(debug)
|
33
|
+
NSFSetIsDebugOn(debug)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
class NSFNanoStore
|
2
|
+
def engine
|
3
|
+
self.nanoStoreEngine
|
4
|
+
end
|
5
|
+
|
6
|
+
def changed?
|
7
|
+
self.hasUnsavedChanges
|
8
|
+
end
|
9
|
+
|
10
|
+
def save_interval=(interval)
|
11
|
+
self.setSaveInterval(interval)
|
12
|
+
end
|
13
|
+
|
14
|
+
## Open and Close store
|
15
|
+
|
16
|
+
def close
|
17
|
+
error_ptr = Pointer.new(:id)
|
18
|
+
closed = self.closeWithError(error_ptr)
|
19
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
20
|
+
closed
|
21
|
+
end
|
22
|
+
|
23
|
+
def open
|
24
|
+
error_ptr = Pointer.new(:id)
|
25
|
+
opened = self.openWithError(error_ptr)
|
26
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
27
|
+
opened
|
28
|
+
end
|
29
|
+
|
30
|
+
def closed?
|
31
|
+
self.isClosed
|
32
|
+
end
|
33
|
+
|
34
|
+
## Adding and Removing Objects
|
35
|
+
|
36
|
+
def <<(objects)
|
37
|
+
error_ptr = Pointer.new(:id)
|
38
|
+
if objects.is_a?(Array)
|
39
|
+
self.addObjectsFromArray(objects, error:error_ptr)
|
40
|
+
else
|
41
|
+
self.addObject(objects, error:error_ptr)
|
42
|
+
end
|
43
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def +(object)
|
48
|
+
error_ptr = Pointer.new(:id)
|
49
|
+
self.addObject(object, error:error_ptr)
|
50
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
# delete a object or array of objects from the array
|
55
|
+
def delete(objects)
|
56
|
+
error_ptr = Pointer.new(:id)
|
57
|
+
if objects.is_a?(Array)
|
58
|
+
result = self.removeObjectsInArray(objects, error:error_ptr)
|
59
|
+
else
|
60
|
+
result = self.removeObject(objects, error:error_ptr)
|
61
|
+
end
|
62
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
63
|
+
result
|
64
|
+
end
|
65
|
+
|
66
|
+
# delete all objects from store
|
67
|
+
def clear
|
68
|
+
error_ptr = Pointer.new(:id)
|
69
|
+
result = self.removeAllObjectsFromStoreAndReturnError(error_ptr)
|
70
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
71
|
+
result
|
72
|
+
end
|
73
|
+
|
74
|
+
# delete object with keys
|
75
|
+
# param: keys - array of key
|
76
|
+
def delete_keys(keys)
|
77
|
+
error_ptr = Pointer.new(:id)
|
78
|
+
result = self.removeObjectsWithKeysInArray(keys, error:error_ptr)
|
79
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
80
|
+
result
|
81
|
+
end
|
82
|
+
|
83
|
+
## Save and Maintenance
|
84
|
+
|
85
|
+
# Saves the uncommitted changes to the document store.
|
86
|
+
def save
|
87
|
+
error_ptr = Pointer.new(:id)
|
88
|
+
result = saveStoreAndReturnError(error_ptr)
|
89
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
90
|
+
result
|
91
|
+
end
|
92
|
+
|
93
|
+
# Discards the uncommitted changes that were added to the document store.
|
94
|
+
alias_method :discard, :discardUnsavedChanges
|
95
|
+
|
96
|
+
# Compact the database file size.
|
97
|
+
def compact
|
98
|
+
error_ptr = Pointer.new(:id)
|
99
|
+
result = self.compactStoreAndReturnError(error_ptr)
|
100
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
101
|
+
result
|
102
|
+
end
|
103
|
+
|
104
|
+
# Remove all indexes from the document store.
|
105
|
+
def clear_index
|
106
|
+
error_ptr = Pointer.new(:id)
|
107
|
+
result = self.clearIndexesAndReturnError(error_ptr)
|
108
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
109
|
+
result
|
110
|
+
end
|
111
|
+
|
112
|
+
# Recreate all indexes from the document store.
|
113
|
+
def rebuild_index
|
114
|
+
error_ptr = Pointer.new(:id)
|
115
|
+
result = self.rebuildIndexesAndReturnError(error_ptr)
|
116
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
117
|
+
result
|
118
|
+
end
|
119
|
+
|
120
|
+
# Makes a copy of the document store to a different location and optionally compacts it to its minimum size.
|
121
|
+
def save_store(path, compact=true)
|
122
|
+
error_ptr = Pointer.new(:id)
|
123
|
+
result = self.saveStoreToDirectoryAtPath(path, compactDatabase:compact, error:error_ptr)
|
124
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
125
|
+
result
|
126
|
+
end
|
127
|
+
|
128
|
+
# Count number of this class objects in store
|
129
|
+
def count(clazz)
|
130
|
+
self.countOfObjectsOfClassNamed(clazz.to_s)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Create a transaction
|
134
|
+
def transaction
|
135
|
+
error_ptr = Pointer.new(:id)
|
136
|
+
beginTransactionAndReturnError(error_ptr)
|
137
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
138
|
+
|
139
|
+
begin
|
140
|
+
yield self
|
141
|
+
rescue StandardError => e
|
142
|
+
rollbackTransactionAndReturnError(error_ptr)
|
143
|
+
raise e
|
144
|
+
end
|
145
|
+
success = commitTransactionAndReturnError(error_ptr)
|
146
|
+
raise NanoStoreError, error_ptr[0].description if error_ptr[0]
|
147
|
+
success
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
data/lib/nano_store.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "nano_store/version"
|
2
|
+
|
3
|
+
unless defined?(Motion::Project::Config)
|
4
|
+
raise "This file must be required within a RubyMotion project Rakefile."
|
5
|
+
end
|
6
|
+
|
7
|
+
Motion::Project::App.setup do |app|
|
8
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'nano_store/*.rb')).each do |file|
|
9
|
+
app.files.unshift(file)
|
10
|
+
end
|
11
|
+
|
12
|
+
app.pods ||= Motion::Project::CocoaPods.new(app)
|
13
|
+
app.pods.dependency 'NanoStore', '~> 2.0.1'
|
14
|
+
end
|