/usr/lib/ruby/vendor_ruby/moneta/adapters/couch.rb is in ruby-moneta 0.7.20-2.2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | require 'faraday'
require 'multi_json'
module Moneta
module Adapters
# CouchDB backend
#
# You can store hashes directly using this adapter.
#
# @example Store hashes
# db = Moneta::Adapters::Mongo.new
# db['key'] = {a: 1, b: 2}
#
# @api public
class Couch
include Defaults
attr_reader :backend
supports :create
# @param [Hash] options
# @option options [String] :host ('127.0.0.1') Couch host
# @option options [String] :port (5984) Couch port
# @option options [String] :db ('moneta') Couch database
# @option options [String] :value_field ('value') Document field to store value
# @option options [String] :type_field ('type') Document field to store value type
# @option options [Faraday connection] :backend Use existing backend instance
def initialize(options = {})
@value_field = options[:value_field] || 'value'
@type_field = options[:type_field] || 'type'
url = "http://#{options[:host] || '127.0.0.1'}:#{options[:port] || 5984}/#{options[:db] || 'moneta'}"
@backend = options[:backend] || ::Faraday.new(:url => url)
create_db
end
# (see Proxy#key?)
def key?(key, options = {})
@backend.head(key).status == 200
end
# (see Proxy#load)
def load(key, options = {})
response = @backend.get(key)
response.status == 200 ? body_to_value(response.body) : nil
end
# (see Proxy#store)
def store(key, value, options = {})
response = @backend.head(key)
body = value_to_body(value, response.status == 200 && response['etag'][1..-2])
response = @backend.put(key, body, 'Content-Type' => 'application/json')
raise "HTTP error #{response.status}" unless response.status == 201
value
rescue
tries ||= 0
(tries += 1) < 10 ? retry : raise
end
# (see Proxy#delete)
def delete(key, options = {})
response = @backend.get(key)
if response.status == 200
value = body_to_value(response.body)
response = @backend.delete("#{key}?rev=#{response['etag'][1..-2]}")
raise "HTTP error #{response.status}" unless response.status == 200
value
end
rescue
tries ||= 0
(tries += 1) < 10 ? retry : raise
end
# (see Proxy#clear)
def clear(options = {})
@backend.delete ''
create_db
self
end
# (see Proxy#create)
def create(key, value, options = {})
body = value_to_body(value, nil)
response = @backend.put(key, body, 'Content-Type' => 'application/json')
case response.status
when 201
true
when 409
false
else
raise "HTTP error #{response.status}"
end
rescue
tries ||= 0
(tries += 1) < 10 ? retry : raise
end
private
def body_to_value(body)
doc = MultiJson.load(body)
case doc[@type_field]
when 'Hash'
doc = doc.dup
doc.delete('_id')
doc.delete('_rev')
doc.delete(@type_field)
doc
else
doc[@value_field]
end
end
def value_to_body(value, rev)
case value
when Hash
doc = value.merge(@type_field => 'Hash')
when String
doc = { @value_field => value, @type_field => 'String' }
when Float, Fixnum
doc = { @value_field => value, @type_field => 'Number' }
else
raise ArgumentError, "Invalid value type: #{value.class}"
end
doc['_rev'] = rev if rev
MultiJson.dump(doc)
end
def create_db
response = @backend.put '', ''
raise "HTTP error #{response.status}" unless response.status == 201 || response.status == 412
end
end
end
end
|