This file is indexed.

/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