# 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'

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


Retrieving Documents:

    doc = CouchPillow::Document.get('123')
    doc.stuff # 'hello'
  

Overriding `CouchPillow::Document`:

    class User < CouchPillow::Document
      type :user
    end

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

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

Using built-in validation methods:

    class User < CouchPillow::Document
      type              :user
      validate_presence :email
      validate_type     :first_name, String
    end

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

Using custom validation blocks:

    class User < CouchPillow::Document
      type :user
      validate :phone, 'is not a number', lambda { |v| v.is_a? Numeric }
    end

    CouchPillow.db = Couchbase.connect( bucket: 'default', host: 'localhost' )
    doc = User.new
    doc.phone = '123'
    doc.save! # raises ValidationError('phone is not a number')
    doc.phone = 123
    doc.save! # Success!

Using `rename` to rename keys. Useful to maintain document integrity.

    class User < CouchPillow::Document
      rename :username, :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.value, v.id)
      end