h1. Stone: Dead-Simple Data Persistence
h1. → 'stone'
!images/stone.png!
h2. Sections
"What":#what
"Installing":#installing
"Getting Up and Running":#running
* "Rails":#rails
* "Merb":#merb
* "Everywhere Else":#everywhere
"Usage":#usage
* "Models":#models
* "Get, Post, Put, and Delete":#gppd
"A Word About Finding Stuff":#word
"License":#license
"Contributing":#contrib
"Contact":#contact
<br /><br />
h2(#what). What
For small applications, a database can be overkill for storing your data in a consistent and
organized manner. Therefore, Stone was built to provide plug-and-play data persistence for
any application or framework. It is fast, and it is easy... therefore it is good.
You can check out an application that uses Merb+Stone "here.":http://theprestigio.us
The source for that blog is "here.":http://github.com/ndemonner/written_in_stone/tree/master
h2(#installing). Installing
<pre>sudo gem install stone</pre>
h2(#running). Up and Running
h3(#rails). Rails
* Create a new file in <code>config/initializers</code> called <code>stone.rb</code>
* Add the following code to your new file:
<pre syntax="ruby">
require 'stone'
Stone.start(Dir.pwd, Dir.glob(File.join(Dir.pwd,"app/models/*")), :rails)
</pre>
* Open your <code>environment.rb</code> file and look for the following lines:
<pre syntax="ruby">
# Skip frameworks you're not going to use (only works if using vendor/rails).
# To use Rails without a database, you must remove the Active Record framework
# config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
</pre>
** Uncomment the last of those lines, and leave only active_record,
so that it looks like this:
<pre syntax="ruby">
# Skip frameworks you're not going to use (only works if using vendor/rails).
# To use Rails without a database, you must remove the Active Record framework
config.frameworks -= [ :active_record ]
</pre>
* Create some models! We'll use an Author as an example:
<pre syntax="none">
stone-gen model Author name:string
</pre>
h3(#merb). Merb
* Add the following code to your <code>init.rb</code> file:
<pre syntax="ruby">
dependency 'stone'
# add this in the Merb::BootLoader.after_app_loads block
# at the bottom of init.rb
Stone.start(Dir.pwd, Dir.glob(File.join(Dir.pwd,"app/models/*")), :merb)
</pre>
* Create some models! We'll use an Author as an example:
<pre syntax="none">
stone-gen model Author name:string
</pre>
h3(#everywhere). Everywhere Else
Stone was designed to provide easy data storage management for <strong>any</strong>
app, not just web ones.
* Wherever you load your app, add the following:
<pre syntax="ruby">
require 'stone'
# replace path/to/models/ with wherever your models/resources may be
Stone.start(Dir.pwd, Dir.glob(File.join(Dir.pwd,"path/to/models/*")))
</pre>
* Create some models! See "Models":#models.
That's it! Remember, there are no databases to install with Stone. Instead,
your data gets persisted to files within <code>myapp/datastore/</code>.
h2(#usage). Usage
h3(#models). Model Files
Models are really easy to create. Here is an example:
<pre syntax="ruby">
class Person
include Stone::Resource # gives you access to persistence methods
# defines an attribute called "name" of type String
field :name, String
# defines an attribute called "email" of type String.
# Since :unique => true is set, "email" must be unique.
field :email, String, :unique => true
# Notifies Stone of a relationship between People and Jewels.
# This allows for @person.jewels retrieval.
has_many :jewels
# both name and email must be present or errors will be added
validates_presence_of :name, :email
end
</pre>
For more validation methods, see "here":http://validatable.rubyforge.org/classes/Validatable/Macros.html.
h3(#gppd). Get, Post, Put, and Delete
* Getting
<pre syntax="ruby">
Author.get(some_id) # gets Author with some_id
Author[some_id] # same as get()
# brings back first author whose name is "Nick DeMonner"
Author.first(:name => "Nick DeMonner")
# brings back first author whose name contains "Nick"
Author.first(:name.includes => 'Nick')
# brings back all authors whose email contains "gmail.com", and who
# were created before today
Author.all(:email.includes => "gmail.com", :created_at.lt => DateTime.now)
# brings back all Authors created before today, and orders them descending
# from most recent to least
Author.all(:created_at.lt => DateTime.now, :order => {:created_at => :desc})
</pre>
* Posting
<pre syntax="ruby">
author = Author.new
author.name = "Nick DeMonner"
author.save # calls Author.post after validations
</pre>
* Putting
<pre syntax="ruby">
author = Author[some_id] # gets Author with id of some_id
# updates name and calls Resource.save (which in turn calls Resource.put
# because this resource is being updated, not created)
author.update_attributes(:name => "Bob Bobberson")
</pre>
* Deleting
<pre syntax="ruby">
Author.delete(some_id) # deletes Author at some_id
</pre>
h3(#word). A Word About Finding Stuff
Stone uses a series of unique methods (à la DataMapper) to finding objects.
You may use the following methods when searching:
* Matches all objects whose <code>field</code> is greater
than <code>thing</code>
<pre syntax="ruby">
:field.gt => thing
</pre>
* Matches all objects whose <code>field</code> is greater than
or equal to <code>thing</code>
<pre syntax="ruby">
:field.gte => thing
</pre>
* Matches all objects whose <code>field</code> is less than <code>thing</code>
<pre syntax="ruby">
:field.lt => thing
</pre>
* Matches all objects whose <code>field</code> is less than or
equal to <code>thing</code>
<pre syntax="ruby">
:field.lte => thing
</pre>
* Matches all objects whose <code>field</code> includes <code>thing</code>
<pre syntax="ruby">
:field.includes => thing
</pre>
* Matches all objects whose <code>field</code> is equal to <code>thing</code>
<pre syntax="ruby">
:field.equals => thing
</pre>
* Matches all objects whose <code>field</code> Regexp matches <code>thing</code>
<pre syntax="ruby">
:field.matches => regexp
</pre>
* Matches all objects whose <code>field</code> does not equal <code>thing</code>
<pre syntax="ruby">
:field.not => thing
</pre>
h2(#license). License
This code is free to use under the terms of the MIT license.
h2(#contrib). Contributing
PLEASE. Stone is extremely immature at this point -- "stable" is
the watchword for the moment.
* You can grab the source using Git:
<pre syntax="none">
git clone git://github.com/ndemonner/stone.git
</pre>
The code is pretty well specced out, so make sure you don't break anything
by running <code>rake ok</code> every once in a while.
Please add specs for any new functionality you might add, and hit me up to
commit. =D
h2(#contact). Contact
Comments are welcome. Join me in the IRC channel #stone on freenode.