Class: Makura::Server

Inherits:
Object
  • Object
show all
Includes:
HTTPMethods
Defined in:
lib/makura/server.rb

Constant Summary collapse

COUCHDB_URI =
'http://localhost:5984'
CACHE_TTL =
5
CACHE_TRIES =
2

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from HTTPMethods

#delete, #get, #post, #put

Constructor Details

#initialize(uri = COUCHDB_URI, cache_ttl = CACHE_TTL, cache_tries = CACHE_TRIES) ⇒ Server

Usage:

server = Makura::Server.new
#<URI::HTTP:0xb778ce38 URL:http://localhost:5984>
server.info
{"couchdb"=>"Welcome", "version"=>"0.9.0a718650-incubating"}


15
16
17
18
19
20
# File 'lib/makura/server.rb', line 15

def initialize(uri = COUCHDB_URI, cache_ttl = CACHE_TTL, cache_tries = CACHE_TRIES)
  @uri = URI(uri.to_s)
  @cache_ttl = cache_ttl
  @cache_tries = cache_tries
  @uuids = UUIDCache.new(self)
end

Instance Attribute Details

#cache_triesObject

Returns the value of attribute cache_tries.



4
5
6
# File 'lib/makura/server.rb', line 4

def cache_tries
  @cache_tries
end

#cache_ttlObject

Returns the value of attribute cache_ttl.



4
5
6
# File 'lib/makura/server.rb', line 4

def cache_ttl
  @cache_ttl
end

#uri(path = '/', params = {}) ⇒ Object

Returns the value of attribute uri.



4
5
6
# File 'lib/makura/server.rb', line 4

def uri
  @uri
end

Instance Method Details

#active_tasksObject

Returns an array with the active tasks on the server.

Reference:

http://wiki.apache.org/couchdb/HttpGetActiveTasks

Usage:

server.active_tasks
# [{"type" => "Replication",
#   "task" => "e22ef0: http://fox:5984/example/ -> example",
#   "status" => "W Processed source update #2130297",
#   "pid" => "<0.8704.97>"}]


87
88
89
# File 'lib/makura/server.rb', line 87

def active_tasks
  get('/_active_tasks')
end

#all_dbsObject Also known as: databases

Array of names of databases on the server

Usage:

server.databases
# ["another", "blog", "makura-spec"]


144
145
146
# File 'lib/makura/server.rb', line 144

def all_dbs
  get('/_all_dbs')
end

#appropriate_error(exception) ⇒ Object



244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/makura/server.rb', line 244

def appropriate_error(exception)
  body = exception.response.body if exception.respond_to?(:response)
  backtrace = exception.backtrace

  raise(Error::RequestFailed, exception.message, backtrace) unless body
  raise(Error::RequestFailed, exception.message, backtrace) if body.empty?

  json = JSON.parse(body)
  error, reason = json['error'], json['reason']

  case error
  when 'bad_request'
    raise(Error::BadRequest, reason, backtrace)
  when 'authorization'
    raise(Error::Authorization, reason, backtrace)
  when 'not_found'
    raise(Error::NotFound, reason, backtrace)
  when 'file_exists'
    raise(Error::FileExists, reason, backtrace)
  when 'missing_rev'
    raise(Error::MissingRevision, reason, backtrace)
  when 'conflict'
    raise(Error::Conflict, reason, backtrace)
  else
    raise(Error::RequestFailed, json.inspect, backtrace)
  end
end

#cached(request, ttl = cache_ttl, tries = cache_tries) ⇒ Object



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/makura/server.rb', line 178

def cached(request, ttl = cache_ttl, tries = cache_tries)
  key = request[:url]

  unless response = @cache.get(key)
    response = execute(request)
    @cache.add(key, response, ttl)
  end

  return response
rescue MemCache::MemCacheError => error
  servers = @cache.servers.map{|s| "#{s.host}:#{s.port}"}
  start_cache(@cache.namespace, *servers)
  tries -= 1
  retry if tries > 0
  warn "[makura caching disabled] #{error.message}"
  @cache = nil
  execute(request)
end

#configObject

Answers with configuration info.

Usage:

server.config


47
48
49
# File 'lib/makura/server.rb', line 47

def config
  get('/_config')
end

#database(name) ⇒ Object

Return new database instance using this server instance.

Usage:

foo = server.database('foo')
# #<Makura::Database 'http://localhost:5984/foo'>
server.databases
# ["another", "blog", "foo", "makura-spec"]


156
157
158
# File 'lib/makura/server.rb', line 156

def database(name)
  Database.new(self, name)
end

#execute(request) ⇒ Object



240
241
242
# File 'lib/makura/server.rb', line 240

def execute(request)
  RestClient::Request.execute(request)
end

#infoObject

Answers with general couchdb info, looks like:

Usage:

server.info
# {'couchdb' => 'Welcome', 'version' => '0.9.0a718650-incubating'}


33
34
35
# File 'lib/makura/server.rb', line 33

def info
  get('/')
end

#inspectObject



22
23
24
# File 'lib/makura/server.rb', line 22

def inspect
  @uri.inspect
end

#logObject



131
132
133
# File 'lib/makura/server.rb', line 131

def log
  get('/_log')
end

#membershipObject

BigCouch query



38
39
40
# File 'lib/makura/server.rb', line 38

def membership
  get('/_membership')
end

#next_uuidObject

Answers with an uuid from the UUIDCache.

Usage:

server.next_uuid
# "55fdca746fa5a5b56f5270875477a2cc"


165
166
167
# File 'lib/makura/server.rb', line 165

def next_uuid
  @uuids.next
end

#replicate(args) ⇒ Object

The replication is an incremental one way process involving two databases (a source and a destination).

The aim of the replication is that at the end of the process, all active documents on the source database are also in the destination database and all documents that were deleted in the source databases are also deleted (if exists) on the destination database.

The replication process only copies the last revision of a document, so all previous revisions that were only on the source database are not copied to the destination database.

Reference:

http://wiki.apache.org/couchdb/Replication

Usage:

server.replicate(source: "foodb", target: "http://example.org/foodb")

Optional Arguments:

# Start continuous replication
continuous: (default is false)

# Create the target database
create_target: (default is false)

# Cancel existing replication
cancel: (default is false)

# Use a filter function
filter: (default is none)

# Pass query parameters to filter function
query_params: {key: value} (default is none)

Please note that when you want to cancel a replication, you have to pass the exact same arguments that it was created with plus the :cancel argument.



127
128
129
# File 'lib/makura/server.rb', line 127

def replicate(args)
  post('/_replicate', :payload => args)
end

#request(method, path, params = {}) ⇒ Object

Helpers



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/makura/server.rb', line 199

def request(method, path, params = {})
  keep_raw = params.delete(:raw)
  payload = params.delete(:payload)
  payload = payload.to_json if payload and not keep_raw
  headers = {}

  if content_type = params.delete('Content-Type')
    headers['Content-Type'] = content_type
  elsif method == :post
    headers['Content-Type'] = 'application/json'
  end

  params.delete_if{|k,v| v.nil? }
  uri = uri(path, params).to_s

  request = {
    :method => method,
    :url => uri,
    :payload => payload,
    :headers => headers}

  if @cache and request[:method] == :get
    raw = cached(request)
  else
    raw = execute(request)
  end

  return raw if keep_raw
  json = JSON.parse(raw)
rescue JSON::ParserError
  return raw
rescue RestClient::RequestFailed => ex
  raise appropriate_error(ex)
rescue RestClient::ServerBrokeConnection => ex
  raise Error::ServerBrokeConnection, request[:url], ex.backtrace
rescue RestClient::ResourceNotFound => ex
  raise Error::ResourceNotFound, request[:url], ex.backtrace
rescue Errno::ECONNREFUSED
  raise Error::ConnectionRefused, "Is CouchDB running at #{@uri}?"
end

#restartObject

Issue restart of the CouchDB daemon. This will ensure that everything was committed before restarting, if you want to restart immediately, use the #restart! method.

Usage:

server.restart
# {'ok' => true}


58
59
60
61
62
63
64
65
# File 'lib/makura/server.rb', line 58

def restart
  databases.each do |name|
    db = Database.new(self, name, auto_create = false)
    db.ensure_full_commit
  end

  restart!
end

#restart!Object

Issue restart of the CouchDB daemon.

Usage:

server.restart
# {'ok' => true}


72
73
74
# File 'lib/makura/server.rb', line 72

def restart!
  post('/_restart')
end

#start_cache(namespace = 'makura', *servers) ⇒ Object



169
170
171
172
# File 'lib/makura/server.rb', line 169

def start_cache(namespace = 'makura', *servers)
  servers << 'localhost:11211' if servers.empty?
  @cache = MemCache.new(servers, :namespace => namespace, :multithread => true)
end

#statsObject



135
136
137
# File 'lib/makura/server.rb', line 135

def stats
  get('/_stats')
end

#stop_cacheObject



174
175
176
# File 'lib/makura/server.rb', line 174

def stop_cache
  @cache = nil
end