Skip to content
🌥 A ruby interface to Cloudant's API.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
bin
lib
spec
.gitignore
.rspec
.travis.yml
Gemfile
LICENSE.txt
README.md
Rakefile
cloudant.gemspec

README.md

Cloudant

License Build Status Coverage Status

Ruby Cloudant is a simple Ruby interface for IBM Cloudant's API. Cloudant is a NoSQL database built on CouchDB.

This gem is still in development and is a work in progress.

Installation

Add this line to your application's Gemfile:

gem 'cloudant'

And then execute:

$ bundle

Or install it yourself as:

$ gem install cloudant

Usage

Create a Cloudant account and find your credentials.

Creating a new client

If valid credentials are provided a POST request will be made to /_session and the user will be logged in via cookie authentication

credentials = {
  :username => ENV['username'],
  :password => ENV['password'],
  :database => ENV['database'] # Can leave blank.
}

client = Cloudant::Client.new(credentials)

Ending a session

client.close

Setting and changing databases

If this is your first time accessing a new Cloudant instance, or don't have a database existing, create one:

client.all_dbs # See existing databases
client.create_db(database_name)

Or delete an existing database:

client.delete_db(database_name)

You can then set (or change, if one is already set) a new database:

client.database = database_name
client.db_info # See database information, including name and size

Basic Usage

# Create a single document
doc = {'_id'=>'1', 'field_one'=>'your content'}
response = client.create(doc)
# => {'ok'=>true, 'id'=>'1', 'rev'=>'1-be74a68c2105f3d9d0245eb8736ca9f1'}

# Find a single document by id
doc_id = response['id']
client.doc(doc_id)
# Options can also be passed along with the id (View Cloudant docs for a full list)
client.doc(doc_id, :revs => true))
    
# Update a single document (requires an existing doc's id and current rev)
new_doc = {'id'=>'1', 'rev'=>'1-bf74a68c2105f3d9d0245fc836ca9f3', 'field_two'=>'more content'}
client.update(new_doc)

# Delete a single doc
client.delete_doc(doc_id)

Multiple Documents

# Creating multiple documents
docs = [
  {'_id'=>'1', 'field_one' => 'your content'}, 
  {'_id'=>'2', 'field_two' => 'more content'},
  {'_id'=>'3', 'field_three' => 'new content'}
]

client.create_docs(docs)

# Updating multiple docs
# Note: updating and creating multiple documents are equivalent
client.update_docs(docs)

# Deleting multiple docs
client.delete_docs(docs)

:delete_docs is a convenience method; this performs an update, adding ['_deleted'] to each document. Bulk operations

Indices, Design Docs

# Create a new index
client.create_index({index: {}, type: 'text', name: 'test_index'})

# See all indices
client.get_indices # Or client.get_indexes

# Create a new design doc named 'test'
ddoc = {'language' => 'javascript', 'views' => {} }
client.create_design_doc('test',ddoc)

Querying a database

# Perform a single query
q = {'selector': {'test_field': {'$exists': true}},'fields': ['_id', '_rev'],'limit': 1,'skip': 0}
client.query(q)

# Performing a paginated query using a bookmark
q = {"selector": {"test_field": {"$exists": true}},"fields": ["_id", "_rev"],"limit": 1,"skip": 0}
client.bookmark_query(q) do |docs| 
  # Do something with the returned documents
end

Views (MapReduce)

# Creating a view
client.create_view('test',{"current"=>{"reduce"=>"_count","map"=>"function (doc) {\n  if (doc.field_type === \"name\") {\n    emit(doc._id,1);\n  }\n}"}})

# Querying an existing view
database = 'test'
view_name = 'current'

client.view(database,view_name) # If a reduce function is given will return a 'rows' array with a single record, the value of the reduce
# => {"rows"=>[{"key"=>nil, "value"=>2}]} 

client.view(database,view_name, :reduce => false, :include_docs => true)
# => {"total_rows"=>2, "offset"=>0, "rows"=>[{"id"=>"5d8e6c99198dfdde8accd8e019ba052", "key"=>"5d8e6c99198dfdde8accd8e019ba052", "value"=>1, "doc"=>{"_id"=>"5d8e6c99198dfdde8accd8e019ba052", "_rev"=>"1-7ebdb5b82e1cc4eaf2e27a711e9857c6", "a"=>10, "b"=>92, "c"=>31}}, {"id"=>"5d8e6c99898dcdd08accd8e019badab", "key"=>"5d8e6c99898dcdd0daccd8e019badab", "value"=>1, "doc"=>{"_id"=>"5d8e6c99898dcdd8daccd8e019badab", "_rev"=>"1-d36298f4391da575df61e170af2efa34", "b"=>12, "c"=>33}}]}

Database Security and Authorization

# View permissions for the current user
client.permissions

# View all users and their permissions for a given database
client.roles

# Create a new set of API keys
client.create_api_keys

# Create a new user and assign it one or more permissions
# Will return the credentials of the newly created user as well
client.new_user(["reader", "writer"]) 
# => {"password" => "str", "key" => "str", "ok" => true, "roles": ["_reader","_writer"]}

# Delete an existing user
username = "test_user"
client.delete_user(username)

Database Replication and Sync

# View Active tasks (including replications)
client.active_tasks

# Replicate a database
# The default options are {:create_target => true, :continuous => false}, meaning that
# the first argument provided will be the name of the target database, and it will be
# newly created. If the database already exists, set :create_target => false
client.replicate_db("test_2")

# More options can be passed, for example: 
client.replicate_db("test_2", {:continuous => true, :user_ctx => {"name" => "test_user", "roles" => ["admin"]}})

# Replication defualts to the datbase initially set; a different source can be used by calling :replicate_dbs
client.replicate_dbs("test_2", "test_3", {:continuous => true, :user_ctx => {"name" => "test_user", "roles" => ["admin"]}})

# Sync a database (replicate a database with :continuous => true)
client.sync("test_2")

# To stop a replication, delete the replication doc as you would any other document
client.delete_doc(doc_id)

Attachments

# Type refers to the MIME type of the attachment.
args = {
  :id   => "test_doc",
  :name => "test_attachment",
  :type => "text/html",
  :rev  => "1-f53050cbc4e66a4dcf6db59a9e0bc6b",
  :path => "./test.html"
}

# Create an attachment on an existing document. If no rev is given, a call will be made to get the document and extract the rev.
client.create_attachment(args)
client.update_attachment(args) # Alias of :create_attachment

# Get the attachments associated with a document. The :name field is the name of the attachment to be retrieved.
client.read_attachment(:id => "test_doc", :name => "test_attachment")

# Delete an attachment. The current rev is required.
client.delete_attachment(:id => "test_doc", :name => "test_attachment", :rev => "2-b52037c9456d75e05f718c1286d63bf6")

To Do

  • Add more robust options handling for various queries (expanding the QueryBuilder module, as used in view querying)
    • Currently, options have to be added to a query string by the user.
  • Expand the Replication module.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

License

Copyright (c) 2016 Alex Yanai. Released under the MIT License.

You can’t perform that action at this time.