Skip to content

AlexYanai/cloudant

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

64 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

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.

About

πŸŒ₯ A ruby interface to Cloudant's API.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages