solr4r 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ChangeLog +30 -0
- data/README +1 -1
- data/lib/solr4r/builder.rb +31 -21
- data/lib/solr4r/client/admin.rb +83 -0
- data/lib/solr4r/client/query.rb +93 -0
- data/lib/solr4r/client/update.rb +123 -0
- data/lib/solr4r/client.rb +113 -149
- data/lib/solr4r/document.rb +14 -14
- data/lib/solr4r/endpoints.rb +86 -0
- data/lib/solr4r/logging.rb +5 -3
- data/lib/solr4r/request.rb +10 -38
- data/lib/solr4r/response.rb +19 -8
- data/lib/solr4r/result.rb +2 -2
- data/lib/solr4r/uri_extension.rb +5 -4
- data/lib/solr4r/version.rb +1 -1
- data/lib/solr4r.rb +3 -2
- data/spec/solr4r/builder_spec.rb +50 -30
- data/spec/solr4r/client_spec.rb +93 -0
- data/spec/spec_helper.rb +0 -4
- metadata +37 -12
- data/lib/solr4r/request_extension.rb +0 -44
    
        data/lib/solr4r/client.rb
    CHANGED
    
    | @@ -7,7 +7,7 @@ | |
| 7 7 | 
             
            #                                                                             #
         | 
| 8 8 | 
             
            # Copyright (C) 2014-2015 Jens Wille                                          #
         | 
| 9 9 | 
             
            #                                                                             #
         | 
| 10 | 
            -
            #  | 
| 10 | 
            +
            # solr4r is free software: you can redistribute it and/or modify it under the #
         | 
| 11 11 | 
             
            # terms of the GNU Affero General Public License as published by the Free     #
         | 
| 12 12 | 
             
            # Software Foundation, either version 3 of the License, or (at your option)   #
         | 
| 13 13 | 
             
            # any later version.                                                          #
         | 
| @@ -30,178 +30,143 @@ module Solr4R | |
| 30 30 | 
             
                include Logging
         | 
| 31 31 |  | 
| 32 32 | 
             
                DEFAULT_HOST = 'localhost'
         | 
| 33 | 
            -
                DEFAULT_PATH = 'solr'
         | 
| 34 33 | 
             
                DEFAULT_PORT = 8983
         | 
| 34 | 
            +
                DEFAULT_PATH = 'solr'
         | 
| 35 | 
            +
                DEFAULT_CORE = 'collection1'
         | 
| 35 36 |  | 
| 36 | 
            -
                DEFAULT_PARAMS = {
         | 
| 37 | 
            -
                  wt: :json
         | 
| 38 | 
            -
                }
         | 
| 39 | 
            -
             | 
| 40 | 
            -
                DEFAULT_BATCH_SIZE = 1000
         | 
| 41 | 
            -
             | 
| 42 | 
            -
                DEFAULT_ENDPOINTS = %w[select query spell suggest terms] <<
         | 
| 43 | 
            -
                  ['ping', path: 'admin/ping', method: :head] <<
         | 
| 44 | 
            -
                  ['dump', path: 'debug/dump']
         | 
| 45 | 
            -
             | 
| 46 | 
            -
                DEFAULT_SELECT_PATH = 'select'
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                DEFAULT_UPDATE_PATH = 'update'
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                DEFAULT_MLT_PATH = 'mlt'
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                SYSTEM_INFO_PATH = 'admin/info/system'
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                MATCH_ALL_QUERY = '*:*'
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                def initialize(options = {})
         | 
| 57 | 
            -
                  uri, options = options, {} unless options.is_a?(Hash)
         | 
| 58 | 
            -
             | 
| 59 | 
            -
                  self.options = options
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                  uri ||= options.fetch(:uri, default_uri)
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                  self.logger = options.fetch(:logger, default_logger)
         | 
| 37 | 
            +
                DEFAULT_PARAMS = { wt: :json }
         | 
| 64 38 |  | 
| 65 | 
            -
             | 
| 66 | 
            -
                    forward_logger(Builder.new) }
         | 
| 39 | 
            +
                class << self
         | 
| 67 40 |  | 
| 68 | 
            -
                   | 
| 69 | 
            -
                     | 
| 41 | 
            +
                  def default_uri(options = {})
         | 
| 42 | 
            +
                    'http://%s:%d/%s/%s' % [
         | 
| 43 | 
            +
                      options.fetch(:host, DEFAULT_HOST),
         | 
| 44 | 
            +
                      options.fetch(:port, DEFAULT_PORT),
         | 
| 45 | 
            +
                      options.fetch(:path, DEFAULT_PATH),
         | 
| 46 | 
            +
                      options.fetch(:core, DEFAULT_CORE)
         | 
| 47 | 
            +
                    ]
         | 
| 48 | 
            +
                  end
         | 
| 70 49 |  | 
| 71 | 
            -
                   | 
| 50 | 
            +
                  def query_string(query, escape = true)
         | 
| 51 | 
            +
                    case query
         | 
| 52 | 
            +
                      when nil
         | 
| 53 | 
            +
                        # ignore
         | 
| 54 | 
            +
                      when String
         | 
| 55 | 
            +
                        escape(query, escape) unless query.empty?
         | 
| 56 | 
            +
                      when Array
         | 
| 57 | 
            +
                        if query.last.is_a?(Hash)
         | 
| 58 | 
            +
                          lp, qs = query_from_hash((query = query.dup).pop, escape)
         | 
| 59 | 
            +
                          query << qs if qs
         | 
| 60 | 
            +
                        end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                        query_with_params(lp, query_string(query.join(' '), escape))
         | 
| 63 | 
            +
                      when Hash
         | 
| 64 | 
            +
                        query_with_params(*query_from_hash(query, escape))
         | 
| 65 | 
            +
                      else
         | 
| 66 | 
            +
                        type_error(query)
         | 
| 67 | 
            +
                    end
         | 
| 68 | 
            +
                  end
         | 
| 72 69 |  | 
| 73 | 
            -
                   | 
| 74 | 
            -
             | 
| 70 | 
            +
                  def local_params_string(local_params, hash = {}, escape = true)
         | 
| 71 | 
            +
                    case local_params = expand_local_params(local_params, hash)
         | 
| 72 | 
            +
                      when nil
         | 
| 73 | 
            +
                        # ignore
         | 
| 74 | 
            +
                      when String
         | 
| 75 | 
            +
                        escape("{!#{local_params}}", escape) unless local_params.empty?
         | 
| 76 | 
            +
                      when Array
         | 
| 77 | 
            +
                        local_params_string(local_params.join(' '), {}, escape)
         | 
| 78 | 
            +
                      when Hash
         | 
| 79 | 
            +
                        local_params_string(local_params.map { |key, value|
         | 
| 80 | 
            +
                          "#{key}=#{value =~ /\s/ ? %Q{"#{value}"} : value}" }, {}, escape)
         | 
| 81 | 
            +
                      else
         | 
| 82 | 
            +
                        type_error(local_params)
         | 
| 83 | 
            +
                    end
         | 
| 84 | 
            +
                  end
         | 
| 75 85 |  | 
| 76 | 
            -
             | 
| 86 | 
            +
                  def escape(string, escape = true)
         | 
| 87 | 
            +
                    escape ? string.gsub('&', '%26') : string
         | 
| 88 | 
            +
                  end
         | 
| 77 89 |  | 
| 78 | 
            -
             | 
| 79 | 
            -
                  endpoints.each { |args| register_endpoint(*args) } if endpoints
         | 
| 80 | 
            -
                  self
         | 
| 81 | 
            -
                end
         | 
| 90 | 
            +
                  private
         | 
| 82 91 |  | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 92 | 
            +
                  def query_from_hash(query, escape)
         | 
| 93 | 
            +
                    local_params = query.key?(lp = :_) &&
         | 
| 94 | 
            +
                      local_params_string((query = query.dup).delete(lp), {}, escape)
         | 
| 85 95 |  | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
                  else
         | 
| 89 | 
            -
                    define_singleton_method(name) { |_params = {}, _options = {}, &block|
         | 
| 90 | 
            -
                      send_request(path, options.merge(_options.merge(
         | 
| 91 | 
            -
                        params: options.fetch(:params, {}).merge(_params))), &block)
         | 
| 92 | 
            -
                    }
         | 
| 96 | 
            +
                    [local_params, query_string(query.flat_map { |key, values|
         | 
| 97 | 
            +
                      Array(values).map { |value| "#{key}:#{value}" } }, escape)]
         | 
| 93 98 | 
             
                  end
         | 
| 94 99 |  | 
| 95 | 
            -
                   | 
| 96 | 
            -
             | 
| 97 | 
            -
             | 
| 98 | 
            -
                def json(path, params = {}, options = {}, &block)
         | 
| 99 | 
            -
                  get(path, params.merge(wt: :json), options, &block).result
         | 
| 100 | 
            -
                end
         | 
| 101 | 
            -
             | 
| 102 | 
            -
                def get(path, params = {}, options = {}, &block)
         | 
| 103 | 
            -
                  send_request(path, options.merge(method: :get, params: params), &block)
         | 
| 104 | 
            -
                end
         | 
| 100 | 
            +
                  def query_with_params(local_params, query_string)
         | 
| 101 | 
            +
                    local_params ? local_params + query_string : query_string
         | 
| 102 | 
            +
                  end
         | 
| 105 103 |  | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 104 | 
            +
                  def expand_local_params(local_params, hash)
         | 
| 105 | 
            +
                    case type = hash[:type]
         | 
| 106 | 
            +
                      when nil
         | 
| 107 | 
            +
                        local_params
         | 
| 108 | 
            +
                      when String, Symbol
         | 
| 109 | 
            +
                        type_error(local_params, :Array) unless local_params.is_a?(Array)
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                        local_params.each { |param| hash[param] = "$#{type}.#{param}" }
         | 
| 112 | 
            +
                        hash
         | 
| 113 | 
            +
                      else
         | 
| 114 | 
            +
                        type_error(type, %w[String Symbol])
         | 
| 115 | 
            +
                    end
         | 
| 116 | 
            +
                  end
         | 
| 109 117 |  | 
| 110 | 
            -
             | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 118 | 
            +
                  def type_error(obj, types = %w[String Array Hash])
         | 
| 119 | 
            +
                    types = Array(types).join(' or ')
         | 
| 120 | 
            +
                    raise TypeError, "#{types} expected, got #{obj.class}", caller(1)
         | 
| 121 | 
            +
                  end
         | 
| 113 122 |  | 
| 114 | 
            -
                def update(data, options = {}, path = DEFAULT_UPDATE_PATH, &block)
         | 
| 115 | 
            -
                  options = amend_options(options, :headers, 'Content-Type' => 'text/xml')
         | 
| 116 | 
            -
                  post(path, data, options, &block)
         | 
| 117 123 | 
             
                end
         | 
| 118 124 |  | 
| 119 | 
            -
                 | 
| 120 | 
            -
             | 
| 121 | 
            -
                  update(builder.add(doc, attributes), options, &block)
         | 
| 122 | 
            -
                end
         | 
| 125 | 
            +
                def initialize(options = {})
         | 
| 126 | 
            +
                  uri, options = options, {} unless options.is_a?(Hash)
         | 
| 123 127 |  | 
| 124 | 
            -
             | 
| 125 | 
            -
             | 
| 128 | 
            +
                  self.options, self.default_params =
         | 
| 129 | 
            +
                    options, options.fetch(:default_params, DEFAULT_PARAMS)
         | 
| 126 130 |  | 
| 127 | 
            -
                   | 
| 128 | 
            -
                    unless add(batch, attributes, options, &block).success?
         | 
| 129 | 
            -
                      failed.concat(batch_size == 1 ? batch : add_batch(
         | 
| 130 | 
            -
                        batch, attributes, options, batch_size / 10, &block))
         | 
| 131 | 
            -
                    end
         | 
| 132 | 
            -
                  }
         | 
| 131 | 
            +
                  self.logger  = options.fetch(:logger)  { default_logger }
         | 
| 133 132 |  | 
| 134 | 
            -
                   | 
| 135 | 
            -
                end
         | 
| 133 | 
            +
                  self.builder = options.fetch(:builder) { forward_logger(Builder.new) }
         | 
| 136 134 |  | 
| 137 | 
            -
             | 
| 138 | 
            -
             | 
| 139 | 
            -
                  update(builder.commit(attributes), options, &block)
         | 
| 140 | 
            -
                end
         | 
| 135 | 
            +
                  self.request = options.fetch(:request) { forward_logger(Request.new(
         | 
| 136 | 
            +
                    self, uri || options.fetch(:uri) { default_uri })) }
         | 
| 141 137 |  | 
| 142 | 
            -
             | 
| 143 | 
            -
                def optimize(attributes = {}, options = {}, &block)
         | 
| 144 | 
            -
                  update(builder.optimize(attributes), options, &block)
         | 
| 138 | 
            +
                  self.endpoints = forward_logger(Endpoints.new(self))
         | 
| 145 139 | 
             
                end
         | 
| 146 140 |  | 
| 147 | 
            -
                 | 
| 148 | 
            -
                def rollback(options = {}, &block)
         | 
| 149 | 
            -
                  update(builder.rollback, options, &block)
         | 
| 150 | 
            -
                end
         | 
| 141 | 
            +
                attr_accessor :options, :builder, :request, :default_params, :endpoints
         | 
| 151 142 |  | 
| 152 | 
            -
                 | 
| 153 | 
            -
                def delete(hash, options = {}, &block)
         | 
| 154 | 
            -
                  update(builder.delete(hash), options, &block)
         | 
| 155 | 
            -
                end
         | 
| 143 | 
            +
                alias_method :ep, :endpoints
         | 
| 156 144 |  | 
| 157 | 
            -
                 | 
| 158 | 
            -
             | 
| 159 | 
            -
                  delete({ id: id }, options, &block)
         | 
| 160 | 
            -
                end
         | 
| 145 | 
            +
                def json(path,
         | 
| 146 | 
            +
                    params = {}, options = {}, &block)
         | 
| 161 147 |  | 
| 162 | 
            -
             | 
| 163 | 
            -
                def delete_by_query(query, options = {}, &block)
         | 
| 164 | 
            -
                  delete({ query: query }, options, &block)
         | 
| 148 | 
            +
                  get(path, params.merge(wt: :json), options, &block).result
         | 
| 165 149 | 
             
                end
         | 
| 166 150 |  | 
| 167 | 
            -
                 | 
| 168 | 
            -
             | 
| 169 | 
            -
                  delete_by_query(MATCH_ALL_QUERY, options, &block)
         | 
| 170 | 
            -
                end
         | 
| 151 | 
            +
                def get(path,
         | 
| 152 | 
            +
                    params = {}, options = {}, &block)
         | 
| 171 153 |  | 
| 172 | 
            -
             | 
| 173 | 
            -
             | 
| 174 | 
            -
                  params[:q] ||= MATCH_ALL_QUERY
         | 
| 175 | 
            -
                  get(path, params, options, &block)
         | 
| 154 | 
            +
                  send_request(path, options.merge(
         | 
| 155 | 
            +
                    method: :get, params: params), &block)
         | 
| 176 156 | 
             
                end
         | 
| 177 157 |  | 
| 178 | 
            -
                def  | 
| 179 | 
            -
             | 
| 180 | 
            -
                end
         | 
| 158 | 
            +
                def post(path, data = nil,
         | 
| 159 | 
            +
                    params = {}, options = {}, &block)
         | 
| 181 160 |  | 
| 182 | 
            -
             | 
| 183 | 
            -
             | 
| 161 | 
            +
                  send_request(path, options.merge(
         | 
| 162 | 
            +
                    method: :post, params: params, data: data), &block)
         | 
| 184 163 | 
             
                end
         | 
| 185 164 |  | 
| 186 | 
            -
                def  | 
| 187 | 
            -
             | 
| 188 | 
            -
                    when nil
         | 
| 189 | 
            -
                      # ignore
         | 
| 190 | 
            -
                    when String
         | 
| 191 | 
            -
                      query.gsub('&', '%26')
         | 
| 192 | 
            -
                    when Array, Hash
         | 
| 193 | 
            -
                      query.flat_map { |key, values|
         | 
| 194 | 
            -
                        Array(values).map { |value|
         | 
| 195 | 
            -
                          query_string("#{key}:#{value}")
         | 
| 196 | 
            -
                        }
         | 
| 197 | 
            -
                      }.join(' ')
         | 
| 198 | 
            -
                    else
         | 
| 199 | 
            -
                      query_string(query.to_s)
         | 
| 200 | 
            -
                  end
         | 
| 201 | 
            -
                end
         | 
| 165 | 
            +
                def head(path,
         | 
| 166 | 
            +
                    params = {}, options = {}, &block)
         | 
| 202 167 |  | 
| 203 | 
            -
             | 
| 204 | 
            -
             | 
| 168 | 
            +
                  send_request(path, options.merge(
         | 
| 169 | 
            +
                    method: :head, params: params), &block)
         | 
| 205 170 | 
             
                end
         | 
| 206 171 |  | 
| 207 172 | 
             
                def inspect
         | 
| @@ -213,27 +178,26 @@ module Solr4R | |
| 213 178 | 
             
                private
         | 
| 214 179 |  | 
| 215 180 | 
             
                def default_uri
         | 
| 216 | 
            -
                   | 
| 217 | 
            -
                    options.fetch(:host, DEFAULT_HOST),
         | 
| 218 | 
            -
                    options.fetch(:port, DEFAULT_PORT),
         | 
| 219 | 
            -
                    options.fetch(:path, DEFAULT_PATH)
         | 
| 220 | 
            -
                  ]
         | 
| 181 | 
            +
                  self.class.default_uri(options)
         | 
| 221 182 | 
             
                end
         | 
| 222 183 |  | 
| 223 | 
            -
                def  | 
| 184 | 
            +
                def amend_options_hash(options, key, value)
         | 
| 224 185 | 
             
                  options.merge(key => value.merge(options.fetch(key, {})))
         | 
| 225 186 | 
             
                end
         | 
| 226 187 |  | 
| 227 | 
            -
                def  | 
| 228 | 
            -
                   | 
| 229 | 
            -
                    amend_options(options, :params, default_params), &block)
         | 
| 188 | 
            +
                def amend_options_array(options, key, *value)
         | 
| 189 | 
            +
                  options.merge(key => Array(options[key]).dup.concat(value))
         | 
| 230 190 | 
             
                end
         | 
| 231 191 |  | 
| 232 | 
            -
                def  | 
| 233 | 
            -
                   | 
| 234 | 
            -
                     | 
| 192 | 
            +
                def send_request(path, options, &block)
         | 
| 193 | 
            +
                  request.execute(path, amend_options_hash(
         | 
| 194 | 
            +
                    options, :params, default_params), &block)
         | 
| 235 195 | 
             
                end
         | 
| 236 196 |  | 
| 237 197 | 
             
              end
         | 
| 238 198 |  | 
| 239 199 | 
             
            end
         | 
| 200 | 
            +
             | 
| 201 | 
            +
            require_relative 'client/update'
         | 
| 202 | 
            +
            require_relative 'client/query'
         | 
| 203 | 
            +
            require_relative 'client/admin'
         | 
    
        data/lib/solr4r/document.rb
    CHANGED
    
    | @@ -7,7 +7,7 @@ | |
| 7 7 | 
             
            #                                                                             #
         | 
| 8 8 | 
             
            # Copyright (C) 2014-2015 Jens Wille                                          #
         | 
| 9 9 | 
             
            #                                                                             #
         | 
| 10 | 
            -
            #  | 
| 10 | 
            +
            # solr4r is free software: you can redistribute it and/or modify it under the #
         | 
| 11 11 | 
             
            # terms of the GNU Affero General Public License as published by the Free     #
         | 
| 12 12 | 
             
            # Software Foundation, either version 3 of the License, or (at your option)   #
         | 
| 13 13 | 
             
            # any later version.                                                          #
         | 
| @@ -31,12 +31,6 @@ module Solr4R | |
| 31 31 |  | 
| 32 32 | 
             
                extend Forwardable
         | 
| 33 33 |  | 
| 34 | 
            -
                UNIQUE_KEY = 'id'
         | 
| 35 | 
            -
             | 
| 36 | 
            -
                MLT_DEFAULT_FL = '*,score'
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                MLT_DEFAULT_ROWS = 5
         | 
| 39 | 
            -
             | 
| 40 34 | 
             
                def initialize(result, hash)
         | 
| 41 35 | 
             
                  @result, @hash = result, hash
         | 
| 42 36 | 
             
                end
         | 
| @@ -45,20 +39,26 @@ module Solr4R | |
| 45 39 |  | 
| 46 40 | 
             
                def_delegators :result, :client
         | 
| 47 41 |  | 
| 48 | 
            -
                def_delegators :to_hash, :[], :each, :to_json
         | 
| 42 | 
            +
                def_delegators :to_hash, :[], :each, :fetch, :to_json
         | 
| 49 43 |  | 
| 50 44 | 
             
                def to_hash
         | 
| 51 45 | 
             
                  @hash
         | 
| 52 46 | 
             
                end
         | 
| 53 47 |  | 
| 54 | 
            -
                def  | 
| 55 | 
            -
                   | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 48 | 
            +
                def id
         | 
| 49 | 
            +
                  fetch('id')
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def more_like_this_h(*args, &block)
         | 
| 53 | 
            +
                  client.more_like_this_h(id, *args, &block)
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def more_like_this_q(*args, &block)
         | 
| 57 | 
            +
                  client.more_like_this_q(id, *args, &block)
         | 
| 60 58 | 
             
                end
         | 
| 61 59 |  | 
| 60 | 
            +
                alias_method :more_like_this, :more_like_this_q
         | 
| 61 | 
            +
             | 
| 62 62 | 
             
              end
         | 
| 63 63 |  | 
| 64 64 | 
             
            end
         | 
| @@ -0,0 +1,86 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            #--
         | 
| 4 | 
            +
            ###############################################################################
         | 
| 5 | 
            +
            #                                                                             #
         | 
| 6 | 
            +
            # solr4r -- A Ruby client for Apache Solr                                     #
         | 
| 7 | 
            +
            #                                                                             #
         | 
| 8 | 
            +
            # Copyright (C) 2014-2015 Jens Wille                                          #
         | 
| 9 | 
            +
            #                                                                             #
         | 
| 10 | 
            +
            # solr4r is free software: you can redistribute it and/or modify it under the #
         | 
| 11 | 
            +
            # terms of the GNU Affero General Public License as published by the Free     #
         | 
| 12 | 
            +
            # Software Foundation, either version 3 of the License, or (at your option)   #
         | 
| 13 | 
            +
            # any later version.                                                          #
         | 
| 14 | 
            +
            #                                                                             #
         | 
| 15 | 
            +
            # solr4r is distributed in the hope that it will be useful, but WITHOUT ANY   #
         | 
| 16 | 
            +
            # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS   #
         | 
| 17 | 
            +
            # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for     #
         | 
| 18 | 
            +
            # more details.                                                               #
         | 
| 19 | 
            +
            #                                                                             #
         | 
| 20 | 
            +
            # You should have received a copy of the GNU Affero General Public License    #
         | 
| 21 | 
            +
            # along with solr4r. If not, see <http://www.gnu.org/licenses/>.              #
         | 
| 22 | 
            +
            #                                                                             #
         | 
| 23 | 
            +
            ###############################################################################
         | 
| 24 | 
            +
            #++
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            module Solr4R
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              class Endpoints
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                include Logging
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                DEFAULT_ENDPOINTS = %w[select query export spell suggest terms debug/dump]
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def initialize(client)
         | 
| 35 | 
            +
                  @client, @endpoints = client, []
         | 
| 36 | 
            +
                  register(client.options.fetch(:endpoints, DEFAULT_ENDPOINTS))
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                attr_reader :client
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def register(path, options = {})
         | 
| 42 | 
            +
                  case path
         | 
| 43 | 
            +
                    when nil
         | 
| 44 | 
            +
                      # ignore
         | 
| 45 | 
            +
                    when String
         | 
| 46 | 
            +
                      name, path = File.basename(path), options.fetch(:path, path).to_s
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                      error = invalid_endpoint?(name) and
         | 
| 49 | 
            +
                        raise ArgumentError, "invalid endpoint: #{name} (#{error})"
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                      @endpoints << [name, path]
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                      define_singleton_method(name) { |_params = {}, _options = {}, &block|
         | 
| 54 | 
            +
                        client.send(:send_request, path, options.merge(_options.merge(
         | 
| 55 | 
            +
                          params: options.fetch(:params, {}).merge(_params))), &block)
         | 
| 56 | 
            +
                      }
         | 
| 57 | 
            +
                    when Symbol
         | 
| 58 | 
            +
                      register(path.to_s, options)
         | 
| 59 | 
            +
                    when Array
         | 
| 60 | 
            +
                      path.each { |args| register(*args) }
         | 
| 61 | 
            +
                    when Hash
         | 
| 62 | 
            +
                      path.each { |name, opts| register(name,
         | 
| 63 | 
            +
                        opts.is_a?(Hash) ? opts : { path: opts }) }
         | 
| 64 | 
            +
                    else
         | 
| 65 | 
            +
                      Client.send(:type_error, path, %w[String Symbol Array Hash])
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                  self
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                def inspect
         | 
| 72 | 
            +
                  '#<%s:0x%x [%s]>' % [self.class, object_id, @endpoints.map { |name, path|
         | 
| 73 | 
            +
                    name == path ? name : "#{name}=#{path}" }.join(', ')]
         | 
| 74 | 
            +
                end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                private
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                def invalid_endpoint?(name)
         | 
| 79 | 
            +
                  'method already defined' if respond_to?(name) || (
         | 
| 80 | 
            +
                    respond_to?(name, true) &&
         | 
| 81 | 
            +
                      DEFAULT_ENDPOINTS.all? { |ep,| ep.to_s != name })
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
              end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
            end
         | 
    
        data/lib/solr4r/logging.rb
    CHANGED
    
    | @@ -5,9 +5,9 @@ | |
| 5 5 | 
             
            #                                                                             #
         | 
| 6 6 | 
             
            # solr4r -- A Ruby client for Apache Solr                                     #
         | 
| 7 7 | 
             
            #                                                                             #
         | 
| 8 | 
            -
            # Copyright (C) 2014 Jens Wille | 
| 8 | 
            +
            # Copyright (C) 2014-2015 Jens Wille                                          #
         | 
| 9 9 | 
             
            #                                                                             #
         | 
| 10 | 
            -
            #  | 
| 10 | 
            +
            # solr4r is free software: you can redistribute it and/or modify it under the #
         | 
| 11 11 | 
             
            # terms of the GNU Affero General Public License as published by the Free     #
         | 
| 12 12 | 
             
            # Software Foundation, either version 3 of the License, or (at your option)   #
         | 
| 13 13 | 
             
            # any later version.                                                          #
         | 
| @@ -24,12 +24,14 @@ | |
| 24 24 | 
             
            #++
         | 
| 25 25 |  | 
| 26 26 | 
             
            require 'logger'
         | 
| 27 | 
            -
            require 'nuggets/module/ | 
| 27 | 
            +
            require 'nuggets/module/lazy_attr_mixin'
         | 
| 28 28 |  | 
| 29 29 | 
             
            module Solr4R
         | 
| 30 30 |  | 
| 31 31 | 
             
              module Logging
         | 
| 32 32 |  | 
| 33 | 
            +
                extend Nuggets::Module::LazyAttrMixin
         | 
| 34 | 
            +
             | 
| 33 35 | 
             
                DEFAULT_LOG_DEVICE = $stderr
         | 
| 34 36 | 
             
                DEFAULT_LOG_LEVEL  = Logger::WARN
         | 
| 35 37 | 
             
                DEFAULT_LOG_NAME   = "Solr4R/#{VERSION}"
         | 
    
        data/lib/solr4r/request.rb
    CHANGED
    
    | @@ -7,7 +7,7 @@ | |
| 7 7 | 
             
            #                                                                             #
         | 
| 8 8 | 
             
            # Copyright (C) 2014-2015 Jens Wille                                          #
         | 
| 9 9 | 
             
            #                                                                             #
         | 
| 10 | 
            -
            #  | 
| 10 | 
            +
            # solr4r is free software: you can redistribute it and/or modify it under the #
         | 
| 11 11 | 
             
            # terms of the GNU Affero General Public License as published by the Free     #
         | 
| 12 12 | 
             
            # Software Foundation, either version 3 of the License, or (at your option)   #
         | 
| 13 13 | 
             
            # any later version.                                                          #
         | 
| @@ -25,7 +25,6 @@ | |
| 25 25 |  | 
| 26 26 | 
             
            require 'net/https'
         | 
| 27 27 |  | 
| 28 | 
            -
            require_relative 'request_extension'
         | 
| 29 28 | 
             
            require_relative 'uri_extension'
         | 
| 30 29 |  | 
| 31 30 | 
             
            module Solr4R
         | 
| @@ -45,6 +44,8 @@ module Solr4R | |
| 45 44 |  | 
| 46 45 | 
             
                attr_reader :client
         | 
| 47 46 |  | 
| 47 | 
            +
                attr_accessor :base_uri, :http_options, :http, :last_response
         | 
| 48 | 
            +
             | 
| 48 49 | 
             
                def start
         | 
| 49 50 | 
             
                  self.http = Net::HTTP.start(base_uri.hostname, base_uri.port,
         | 
| 50 51 | 
             
                    { use_ssl: base_uri.scheme == 'https' }.merge(http_options))
         | 
| @@ -69,18 +70,7 @@ module Solr4R | |
| 69 70 | 
             
                  req = prepare_request(path, options, &block)
         | 
| 70 71 | 
             
                  res = http.request(req)
         | 
| 71 72 |  | 
| 72 | 
            -
                  self.last_response = Response.new(self,
         | 
| 73 | 
            -
                    request_body:     req.body,
         | 
| 74 | 
            -
                    request_headers:  req.to_hash,
         | 
| 75 | 
            -
                    request_method:   req.method.downcase.to_sym,
         | 
| 76 | 
            -
                    request_params:   req.params,
         | 
| 77 | 
            -
                    request_url:      req.uri.to_s,
         | 
| 78 | 
            -
             | 
| 79 | 
            -
                    response_body:    res.body,
         | 
| 80 | 
            -
                    response_charset: res.type_params['charset'],
         | 
| 81 | 
            -
                    response_code:    res.code.to_i,
         | 
| 82 | 
            -
                    response_headers: res.to_hash
         | 
| 83 | 
            -
                  )
         | 
| 73 | 
            +
                  self.last_response = Response.new(self, req, res)
         | 
| 84 74 | 
             
                end
         | 
| 85 75 |  | 
| 86 76 | 
             
                def request_line
         | 
| @@ -93,15 +83,11 @@ module Solr4R | |
| 93 83 |  | 
| 94 84 | 
             
                private
         | 
| 95 85 |  | 
| 96 | 
            -
                attr_accessor :base_uri, :http_options, :http, :last_response
         | 
| 97 | 
            -
             | 
| 98 86 | 
             
                def prepare_request(path, options)
         | 
| 99 87 | 
             
                  uri = make_uri(path, options.fetch(:params, {}))
         | 
| 88 | 
            +
                  req = make_request(uri, options.fetch(:method, DEFAULT_METHOD))
         | 
| 100 89 |  | 
| 101 | 
            -
                  req  | 
| 102 | 
            -
                    options.fetch(:method, DEFAULT_METHOD),
         | 
| 103 | 
            -
                    options.fetch(:data, {}))
         | 
| 104 | 
            -
             | 
| 90 | 
            +
                  set_data(req, options.fetch(:data, {})) if req.request_body_permitted?
         | 
| 105 91 | 
             
                  set_headers(req, options.fetch(:headers, {}))
         | 
| 106 92 |  | 
| 107 93 | 
             
                  yield req if block_given?
         | 
| @@ -113,31 +99,17 @@ module Solr4R | |
| 113 99 | 
             
                  base_uri.merge(path).extend(RequestUriExtension).with_params(params)
         | 
| 114 100 | 
             
                end
         | 
| 115 101 |  | 
| 116 | 
            -
                def make_request(uri, method | 
| 117 | 
            -
                   | 
| 118 | 
            -
             | 
| 119 | 
            -
                      req = request_for(method, uri)
         | 
| 120 | 
            -
                    when :post
         | 
| 121 | 
            -
                      req = request_for(method, uri)
         | 
| 122 | 
            -
                      set_data(req, data)
         | 
| 123 | 
            -
                    else
         | 
| 124 | 
            -
                      raise ArgumentError, "method not supported: #{method}"
         | 
| 125 | 
            -
                  end
         | 
| 126 | 
            -
             | 
| 102 | 
            +
                def make_request(uri, method)
         | 
| 103 | 
            +
                  req = Net::HTTP.const_get(method.to_s.capitalize).new(uri)
         | 
| 104 | 
            +
                  req.uri.extend(RequestUriExtension).params = uri.params
         | 
| 127 105 | 
             
                  req
         | 
| 128 106 | 
             
                end
         | 
| 129 107 |  | 
| 130 | 
            -
                def request_for(method, uri)
         | 
| 131 | 
            -
                  Net::HTTP.const_get(method.to_s.capitalize)
         | 
| 132 | 
            -
                    .extend(HTTPRequestExtension).from_uri(uri)
         | 
| 133 | 
            -
                end
         | 
| 134 | 
            -
             | 
| 135 108 | 
             
                def set_headers(req, headers)
         | 
| 136 109 | 
             
                  req['User-Agent'] = DEFAULT_USER_AGENT
         | 
| 137 110 |  | 
| 138 111 | 
             
                  headers.each { |key, value|
         | 
| 139 | 
            -
                    Array(value).each { |val| req.add_field(key, val) }
         | 
| 140 | 
            -
                  }
         | 
| 112 | 
            +
                    Array(value).each { |val| req.add_field(key, val) } }
         | 
| 141 113 | 
             
                end
         | 
| 142 114 |  | 
| 143 115 | 
             
                def set_data(req, data)
         | 
    
        data/lib/solr4r/response.rb
    CHANGED
    
    | @@ -7,7 +7,7 @@ | |
| 7 7 | 
             
            #                                                                             #
         | 
| 8 8 | 
             
            # Copyright (C) 2014-2015 Jens Wille                                          #
         | 
| 9 9 | 
             
            #                                                                             #
         | 
| 10 | 
            -
            #  | 
| 10 | 
            +
            # solr4r is free software: you can redistribute it and/or modify it under the #
         | 
| 11 11 | 
             
            # terms of the GNU Affero General Public License as published by the Free     #
         | 
| 12 12 | 
             
            # Software Foundation, either version 3 of the License, or (at your option)   #
         | 
| 13 13 | 
             
            # any later version.                                                          #
         | 
| @@ -34,18 +34,29 @@ module Solr4R | |
| 34 34 |  | 
| 35 35 | 
             
                DEFAULT_CHARSET = 'UTF-8'
         | 
| 36 36 |  | 
| 37 | 
            -
                 | 
| 37 | 
            +
                def initialize(request, req = nil, res = nil)
         | 
| 38 | 
            +
                  @request, @evaluate = request, req.response_body_permitted?
         | 
| 38 39 |  | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 40 | 
            +
                  if req
         | 
| 41 | 
            +
                    self.request_body    = req.body
         | 
| 42 | 
            +
                    self.request_headers = req.to_hash
         | 
| 43 | 
            +
                    self.request_method  = req.method.downcase.to_sym
         | 
| 44 | 
            +
                    self.request_params  = req.uri.params
         | 
| 45 | 
            +
                    self.request_url     = req.uri.to_s
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  if res
         | 
| 49 | 
            +
                    self.response_body    = res.body
         | 
| 50 | 
            +
                    self.response_headers = res.to_hash
         | 
| 51 | 
            +
                    self.response_charset = res.type_params['charset']
         | 
| 52 | 
            +
                    self.response_code    = res.code.to_i
         | 
| 53 | 
            +
                  end
         | 
| 43 54 | 
             
                end
         | 
| 44 55 |  | 
| 45 56 | 
             
                attr_reader :request
         | 
| 46 57 |  | 
| 47 | 
            -
                attr_accessor :response_body, : | 
| 48 | 
            -
                  :request_body, :request_method, :request_params, :request_url | 
| 58 | 
            +
                attr_accessor :response_body, :response_headers, :response_charset, :response_code,
         | 
| 59 | 
            +
                  :request_body, :request_headers, :request_method, :request_params, :request_url
         | 
| 49 60 |  | 
| 50 61 | 
             
                def_delegators :request, :client
         | 
| 51 62 |  | 
    
        data/lib/solr4r/result.rb
    CHANGED
    
    | @@ -7,7 +7,7 @@ | |
| 7 7 | 
             
            #                                                                             #
         | 
| 8 8 | 
             
            # Copyright (C) 2014-2015 Jens Wille                                          #
         | 
| 9 9 | 
             
            #                                                                             #
         | 
| 10 | 
            -
            #  | 
| 10 | 
            +
            # solr4r is free software: you can redistribute it and/or modify it under the #
         | 
| 11 11 | 
             
            # terms of the GNU Affero General Public License as published by the Free     #
         | 
| 12 12 | 
             
            # Software Foundation, either version 3 of the License, or (at your option)   #
         | 
| 13 13 | 
             
            # any later version.                                                          #
         | 
| @@ -55,7 +55,7 @@ module Solr4R | |
| 55 55 |  | 
| 56 56 | 
             
                def_delegators :response, :client
         | 
| 57 57 |  | 
| 58 | 
            -
                def_delegators :to_hash,  | 
| 58 | 
            +
                def_delegators :to_hash, :%, :deep_fetch, :fetch
         | 
| 59 59 |  | 
| 60 60 | 
             
                def to_hash
         | 
| 61 61 | 
             
                  @hash
         |