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
JSON_PARAMS =
%w[key startkey endkey]

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"}


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

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

#appropriate_error(exception) ⇒ Object



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/makura/server.rb', line 158

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



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/makura/server.rb', line 96

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


43
44
45
# File 'lib/makura/server.rb', line 43

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"]


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

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

#databasesObject

Array of names of databases on the server

Usage:

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


61
62
63
# File 'lib/makura/server.rb', line 61

def databases
  get('/_all_dbs')
end

#execute(request) ⇒ Object



154
155
156
# File 'lib/makura/server.rb', line 154

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


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

def info
  get('/')
end

#inspectObject



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

def inspect
  @uri.inspect
end

#next_uuidObject

Answers with an uuid from the UUIDCache.

Usage:

server.next_uuid
# "55fdca746fa5a5b56f5270875477a2cc"


83
84
85
# File 'lib/makura/server.rb', line 83

def next_uuid
  @uuids.next
end

#paramify(hash) ⇒ Object



188
189
190
191
192
193
194
# File 'lib/makura/server.rb', line 188

def paramify(hash)
  hash.map{|k,v|
    k = k.to_s
    v = v.to_json if JSON_PARAMS.include?(k)
    "#{Makura.escape(k)}=#{Makura.escape(v)}"
  }.join('&')
end

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

Helpers



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/makura/server.rb', line 117

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
  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::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.

Usage:

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


52
53
54
# File 'lib/makura/server.rb', line 52

def restart
  post('/_restart')
end

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



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

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

#stop_cacheObject



92
93
94
# File 'lib/makura/server.rb', line 92

def stop_cache
  @cache = nil
end