Class: Analysand::Instance

Inherits:
Object
  • Object
show all
Includes:
Errors, Http, Rack::Utils
Defined in:
lib/analysand/instance.rb

Overview

Wraps a CouchDB instance.

This class is meant to be used for interacting with parts of CouchDB that aren’t associated with any particular database: session management, for example. If you’re looking to do database operations, Analysand::Database is where you want to be.

Instances MUST be identified by an absolute URI; instantiating this class with a relative URI will raise an exception.

Common tasks

Opening an instance


instance = Analysand::Instance(URI('http://localhost:5984'))

Pinging an instance


instance.ping  # => #<Response code=200 ...>

Establishing a session


resp, = instance.post_session('username', 'password')
cookie = resp.session_cookie

For harmony, the same credentials hash accepted by database methods is also supported:

resp = instance.post_session(:username => 'username',
                             :password => 'password')

resp.success? will be true if the session cookie is not empty, false otherwise.

Testing a session cookie for validity


resp = instance.get_session(cookie)

In CouchDB 1.2.0, the response body is a JSON object that looks like

{
    "info": {
        "authentication_db": "_users",
        "authentication_handlers": [
            "oauth",
            "cookie",
            "default"
        ]
    },
    "ok": true,
    "userCtx": {
        "name": "username",
        "roles": ["member"]
    }
}

resp.valid? will be true if userCtx is non-null, false otherwise.

Adding and removing admins


instance.put_admin('admin', 'password', credentials)
# => #<ConfigResponse code=200 ...>
instance.delete_admin('admin', credentials)
# => #<ConfigResponse code=200 ...>

Obviously, you’ll need admin credentials to manage the admin list.

There also exist bang-method variants:

instance.put_admin!('admin', 'password', bad_creds)
# => raises ConfigurationNotSaved on failure
instance.delete_admin!('admin', bad_creds)
# => raises ConfigurationNotDeleted on failure

Getting and setting instance configuration


v = instance.get_config('couchdb_httpd_auth/allow_persistent_cookies',
  credentials)
v.value # => false

instance.put_config('couchdb_httpd_auth/allow_persistent_cookies',
  '"true"', credentials)
# => #<Response code=200 ...>

v = instance.get_config('couchdb_httpd_auth/allow_persistent_cookies',
  credentials)
v.value #=> '"true"'

instance.delete_config('couchdb_httpd_auth/allow_persistent_cookies',
  credentials)

You can get configuration at any level:

v = instance.get_config('', credentials)
v.body['stats']['rate']  # => "1000", or whatever you have it set to

#get_config and #put_config both return Response-like objects. You can check for failure or success that way:

v = instance.get_config('couchdb_httpd_auth/allow_persistent_cookies')
v.code # => '403'

instance.put_config('couchdb_httpd_auth/allow_persistent_cookies', '"false"')
# => #<Response code=403 ...>

If you want to set configuration and just want to let errors bubble up the stack, you can use the bang-variants:

instance.put_config!('stats/rate', '"1000"')
# => on non-2xx response, raises ConfigurationNotSaved

instance.delete_config!('stats/rate')
# => on non-2xx response, raises ConfigurationNotDeleted

Other instance-level services


CouchDB can be extended with additional service handlers; authentication handlers are a popular example.

Instance exposes #get, #put, and #post methods to access arbitrary endpoints.

Examples:

instance.get('_log', {}, admin_credentials)
instance.post('_browserid', { 'assertion' => assertion },
  { 'Content-Type' => 'application/json' })
instance.put('_config/httpd/bind_address', '192.168.0.1', {},
  admin_credentials)

Constant Summary

Constants included from Http

Http::SSL_METHODS

Instance Attribute Summary

Attributes included from Http

#http, #uri

Instance Method Summary collapse

Methods included from Http

#_req, #close, #init_http_client, #set_credentials

Methods included from Errors

#bulk_ex, #ex

Constructor Details

#initialize(uri) ⇒ Instance

Returns a new instance of Instance.



163
164
165
# File 'lib/analysand/instance.rb', line 163

def initialize(uri)
  init_http_client(uri)
end

Instance Method Details

#delete(path, headers = {}, credentials = nil) ⇒ Object



179
180
181
# File 'lib/analysand/instance.rb', line 179

def delete(path, headers = {}, credentials = nil)
  _delete(path, credentials, {}, headers)
end

#delete_admin(username, credentials = nil) ⇒ Object



191
192
193
# File 'lib/analysand/instance.rb', line 191

def delete_admin(username, credentials = nil)
  delete_config("admins/#{username}", credentials)
end

#delete_admin!(username, credentials = nil) ⇒ Object



195
196
197
# File 'lib/analysand/instance.rb', line 195

def delete_admin!(username, credentials = nil)
  raise_delete_error { delete_admin(username, credentials) }
end

#delete_config(key, credentials = nil) ⇒ Object



231
232
233
# File 'lib/analysand/instance.rb', line 231

def delete_config(key, credentials = nil)
  ConfigResponse.new delete("_config/#{key}", {}, credentials)
end

#delete_config!(key, credentials = nil) ⇒ Object



235
236
237
# File 'lib/analysand/instance.rb', line 235

def delete_config!(key, credentials = nil)
  raise_delete_error { delete_config(key, credentials) }
end

#get(path, headers = {}, credentials = nil) ⇒ Object



167
168
169
# File 'lib/analysand/instance.rb', line 167

def get(path, headers = {}, credentials = nil)
  _get(path, credentials, {}, headers)
end

#get_config(key, credentials = nil) ⇒ Object



219
220
221
# File 'lib/analysand/instance.rb', line 219

def get_config(key, credentials = nil)
  ConfigResponse.new get("_config/#{key}", {}, credentials)
end

#get_session(cookie) ⇒ Object



213
214
215
216
217
# File 'lib/analysand/instance.rb', line 213

def get_session(cookie)
  headers = { 'Cookie' => cookie }

  SessionResponse.new get('_session', headers)
end

#post(path, body = nil, headers = {}, credentials = nil) ⇒ Object



171
172
173
# File 'lib/analysand/instance.rb', line 171

def post(path, body = nil, headers = {}, credentials = nil)
  _post(path, credentials, {}, headers, body)
end

#post_session(*args) ⇒ Object



199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/analysand/instance.rb', line 199

def post_session(*args)
  username, password = if args.length == 2
                         args
                       else
                         h = args.first
                         [h[:username], h[:password]]
                       end

  headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
  body = build_query('name' => username, 'password' => password)

  Response.new post('_session', body, headers)
end

#put(path, body = nil, headers = {}, credentials = nil) ⇒ Object



175
176
177
# File 'lib/analysand/instance.rb', line 175

def put(path, body = nil, headers = {}, credentials = nil)
  _put(path, credentials, {}, headers, body)
end

#put_admin(username, password, credentials = nil) ⇒ Object



183
184
185
# File 'lib/analysand/instance.rb', line 183

def put_admin(username, password, credentials = nil)
  put_config("admins/#{username}", %Q{"#{password}"}, credentials)
end

#put_admin!(username, password, credentials = nil) ⇒ Object



187
188
189
# File 'lib/analysand/instance.rb', line 187

def put_admin!(username, password, credentials = nil)
  raise_put_error { put_admin(username, password, credentials) }
end

#put_config(key, value, credentials = nil) ⇒ Object



223
224
225
# File 'lib/analysand/instance.rb', line 223

def put_config(key, value, credentials = nil)
  ConfigResponse.new put("_config/#{key}", value, {}, credentials)
end

#put_config!(key, value, credentials = nil) ⇒ Object



227
228
229
# File 'lib/analysand/instance.rb', line 227

def put_config!(key, value, credentials = nil)
  raise_put_error { put_config(key, value, credentials) }
end