# CouchPillow

Light and comfortable Document integrity tool for Couchbase Server.


## Why CouchPillow?

CouchPillow is an integrity tool for Couchbase Documents to make sure that all
current and existing documents can work nicely with the current code.

CouchPillow separates itself from the database drivers, making it light and
independent from the implementation.  Although it is initially designed to work
with Couchbase Server, one can easily extend this to other NoSQL drivers as
long as they `respond_to?` the `set`, `delete`, `replace`, and `get` methods.


## Features

- Automatic id generation.
- Automatic timestamp.
- Built-in and custom data validations.


## Installation

    gem install couchpillow


## How To Use

    require 'couchpillow'

    class MyDocument < CouchPillow::Document
      type :my_document
      attribute(:stuff)
    end

    CouchPillow.db = Couchbase.connect( bucket: 'default', host: 'localhost' )
    doc = CouchPillow::Document.new( { :stuff => 'hello' } )
    doc.save!
    
    # {
    #   '_id': 'my_document_fb579b265cc005c47ff420a5c2a15d2b',
    #   '_type': 'my_document',
    #   'stuff': 'hello',
    #   '_created_at': '2014-07-04 00:00:00 UTC'
    #   '_updated_at': '2014-07-04 00:00:00 UTC'
    # }


Retrieving Documents:

    doc = MyDocument.get('123')
    doc.stuff # 'hello'

Specifying custom id:

    class User < CouchPillow::Document
      type :user
      attribute(:email)
    end

    CouchPillow.db = Couchbase.connect( bucket: 'default', host: 'localhost' )
    doc = User.new( { :email => 'john@email.com' }, '123' )
    doc.email # 'john@email.com'
    doc.save!

    # {
    #   '_id': '123',
    #   '_type': 'user',
    #   'email': 'john@email.com',
    #   'created_at': '2014-07-04 00:00:00 UTC'
    #   'updated_at': '2014-07-04 00:00:00 UTC'
    # }

### Attributes

Using Attribute Directives:

    class User < CouchPillow::Document
      type              :user
      attribute(:email)
        .required

      attribute(:first_name)
        .type(String)
    end

    CouchPillow.db = Couchbase.connect( bucket: 'default', host: 'localhost' )
    doc = User.new( { :first_name => 'John' } )
    doc.save! # raises ValidationError "Attribute 'email' is missing"
    doc.email = 'john@email.com'
    doc.save! # Success!

List of Attribute Directives:

* `required`

  Sets this attribute as required. Will raise an error if attribute is missing
  upon `save!` or `update!`

* `type(T)`

   Sets the type of this attribute. Will perform type check if specified.

* `auto_convert`

   Enables auto-conversion to the specified type. This gets ignored if `type`
   directive is not specified.

* `default(&block)`

   Runs the block to set the default value for this attribute, if it's missing
   or nil.

* `content(&block)`

   Custom validation method to check the value of the attribute. This is useful
   in cases where you only want certain values to be stored (e.g a number between
   1-10 only)


### Migration

Using `rename` to rename keys. Useful to maintain document integrity
from a migration.

    class User < CouchPillow::Document
      rename :username, :nickname
      attribute(:nickname)
    end
    u = User.new( { :username => 'jdoe' } )
    u.nickname # 'jdoe'



## Design Docs and Views

What about Design Docs and Views? They are outside the scope of CouchPillow.
However, given a design doc named `my_design_doc` and a View named `by_email`,
that returns documents as values, you can easily use it like this:

    CouchPillow.db.design_docs['my_design_doc'].
      by_email(:body => { :key => 'john@email.com' }).map do |v|
        new User(v.doc, v.id)
      end