NanoStore for RubyMotion
Wrapper for NanoStore, a lightweight schema-less key-value document database based on sqlite, in RubyMotion.
Status: Work in progress. API subject to change.
Find a sample application using NanoStore here
How to use Blog here
Installation
Install the CocoaPods dependency manager if you haven't it already:
gem install motion-cocoapods
pod setup
Install nano-store gem
gem install nano-store
Require nano-store to your project 'Rakefile'
$:.unshift("/Library/RubyMotion/lib")
require 'motion/project'
require 'rubygems'
require 'motion-cocoapods'
require 'nano-store'
Motion::Project::App.setup do |app|
app.name = 'myapp'
app.pods do
pod 'NanoStore', '~> 2.6.0'
end
end
Now, you can use NanoStore in your app.
Upgrade Notes
If you are upgrading from an older version of nano-store gem, make sure you run rake clean and remove vendor/Pods/build* folders before building your project. Otherwise you may still using the old binaries!
Basic Usage
Set default storage type
NanoStore.shared_store = NanoStore.store(:memory)
documents_path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true)[0]
NanoStore.shared_store = NanoStore.store(:file, documents_path + "/nano.db")
Define Model
class User < NanoStore::Model
attribute :name
attribute :age
attribute :created_at
end
A key (UUID) that identifies the object will be added automatically.
Attributes must be serializable, which means that only the following data types are allowed:
- NSArray
- NSDictionary
- NSString
- NSData (*)
- NSDate
- NSNumber
- NSNull
- NSURL
Note
(*) The data type NSData is allowed, but it will be excluded from the indexing process.
Create
user = User.new(:name => "Bob", :age => 16, :created_at => Time.now)
user.save
user.key
user = User.create(:name => "Bob", :age => 16, :created_at => Time.now)
Retrieve
User.all
users = User.find(:name, NSFEqualTo, "Bob")
users = User.find(:name => "Bob")
users = User.find(:name => { NSFEqualTo => "Ronald" })
users = User.find(:name => { NSFEqualTo => "Ronald" }, :age => { NSFGreaterThan => 50 })
users = User.find(:name => ["Bob", "Ronald", "Ken"])
users = User.find({:age => { NSFGreaterThan => 10 }}, {:sort => {:age => :desc}})
Update
user = User.find(:name, NSFEqualTo, "Bob").first
user.name = "Dom"
user.save
Delete
user = User.find(:name, NSFEqualTo, "Bob").first
user.delete
User.delete(:age => {NSFGreaterThan => 20})
Using Transaction
Use transaction is easy, just wrap your database code in a transaction block.
store = NanoStore.shared_store = NanoStore.store
begin
store.transaction do |the_store|
Animal.count
obj1 = Animal.new
obj1.name = "Cat"
obj1.save
obj2 = Animal.new
obj2.name = "Dog"
obj2.save
Animal.count
raise "error"
end
rescue
end
Animal.count
Using Bags
A bag is a loose collection of objects stored in a document store.
store = NanoStore.store
bag = Bag.bag
store << bag
page = Page.new
page.text = "Hello"
page.index = 1
bag << page
bag.save
bags = store.bags
Association
Use bag
to declare a Bag that associated with a Model.
class User < NanoStore::Model
attribute :name
attribute :age
attribute :created_at
bag :cars
end
class Car < NanoStore::Model
attribute :name
attribute :age
end
user = User.new(:name => "Peter", :age => 20, :created_at => Time.now)
user.cars << Car.new(:name => "Mini", :age => 0)
user.save
user.cars
Performance Tips
NanoStore by defaults saves every object to disk one by one. To speed up inserts and edited objects, increase NSFNanoStore's saveInterval
property.
Example
store = NanoStore.shared_store = NanoStore.store
store.save_interval = 1000
obj1 = Animal.new
obj1.name = "Cat"
store << obj1
obj2 = Animal.new
obj2.name = "Dog"
store << obj2
store.save
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:
store.save
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.
Credit
- Based on NanoStore from Tito Ciuro, Webbo, L.L.C.
License
BSD License