mwmitchell-rsolr 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,101 +0,0 @@
1
- #
2
- # Connection adapter decorator
3
- #
4
- class RSolr::Connection::Base
5
-
6
- attr_reader :adapter, :opts
7
-
8
- # "adapter" is instance of:
9
- # RSolr::Adapter::HTTP
10
- # RSolr::Adapter::Direct (jRuby only)
11
- def initialize(adapter, opts={})
12
- @adapter = adapter
13
- @opts = opts
14
- end
15
-
16
- # send request (no param mapping) to the select handler
17
- # params is hash with valid solr request params (:q, :fl, :qf etc..)
18
- # if params[:wt] is not set, the default is :ruby (see opts[:global_params])
19
- # if :wt is something other than :ruby, the raw response body is returned
20
- # otherwise, an instance of RSolr::Response::Query is returned
21
- # NOTE: to get raw ruby, use :wt=>'ruby'
22
- # There is NO param mapping here, what you put it is what gets sent to Solr
23
- def query(*args)
24
- params = map_params(args.extract_options!)
25
- args << params
26
- response = @adapter.query(*args)
27
- params[:wt] == :ruby ? RSolr::Response::Query::Base.new(response) : response
28
- end
29
-
30
- # Finds a document by its id
31
- def find_by_id(*args)
32
- params = map_params(args.extract_options!)
33
- params[:q] = 'id:"#{id}"'
34
- args << params
35
- self.query(*args)
36
- end
37
-
38
- #
39
- def update(*args)
40
- params = map_params(args.extract_options!)
41
- args << params
42
- response = @adapter.update(*args)
43
- params[:wt] == :ruby ? RSolr::Response::Update.new(response) : response
44
- end
45
-
46
- def index_info(*args)
47
- params = map_params(args.extract_options!)
48
- args << params
49
- response = @adapter.index_info(*args)
50
- params[:wt] == :ruby ? RSolr::Response::IndexInfo.new(response) : response
51
- end
52
-
53
- def add(*args, &block)
54
- update message.add(*args, &block)
55
- end
56
-
57
- # send </commit>
58
- def commit(*args)
59
- update message.commit, *args
60
- end
61
-
62
- # send </optimize>
63
- def optimize(*args)
64
- update message.optimize, *args
65
- end
66
-
67
- # send </rollback>
68
- # NOTE: solr 1.4 only
69
- def rollback(*args)
70
- update message.rollback, *args
71
- end
72
-
73
- # Delete one or many documents by id
74
- # solr.delete_by_id 10
75
- # solr.delete_by_id([12, 41, 199])
76
- def delete_by_id(*args)
77
- update message.delete_by_id(args.shift), *args
78
- end
79
-
80
- # delete one or many documents by query
81
- # solr.delete_by_query 'available:0'
82
- # solr.delete_by_query ['quantity:0', 'manu:"FQ"']
83
- def delete_by_query(*args)
84
- update message.delete_by_query(args.shift), *args
85
- end
86
-
87
- protected
88
-
89
- # shortcut to solr::message
90
- def message
91
- RSolr::Message
92
- end
93
-
94
- # sets default params etc.. - could be used as a mapping hook
95
- # type of request should be passed in here? -> map_params(:query, {})
96
- def map_params(params)
97
- params||={}
98
- {:wt=>:ruby}.merge(params)
99
- end
100
-
101
- end
data/lib/rsolr/query.rb DELETED
@@ -1,58 +0,0 @@
1
- module RSolr::Query
2
-
3
- module HelperMethods
4
-
5
- # returns a quoted or non-quoted string
6
- # "value" should be a string
7
- # "quote" should be true/false
8
- def prep_value(value, quote)
9
- quote ? %("#{value}") : value
10
- end
11
-
12
- # value can be a string, array, hash or symbol
13
- # symbols are treated as strings
14
- # arrays are recursed through #build_query
15
- # keys for hashes are fields for fielded queries, the values are recused through #build_query
16
- # strings/symbols are sent to #prep_value for possible quoting
17
- #
18
- # opts can have:
19
- # :quote=>bool - default false
20
- # :join=>string - default ' '
21
- def build_query(value, opts={})
22
- opts[:join]||=' '
23
- opts[:quote]||=false
24
- result = (
25
- case value
26
- when Array
27
- value.collect do |item|
28
- build_query item, opts
29
- end.flatten
30
- when String,Symbol
31
- [prep_value(value.to_s, opts[:quote])]
32
- when Hash
33
- value.collect do |(k,v)|
34
- "#{k}:#{build_query(v, opts)}"
35
- end.flatten
36
- else
37
- [prep_value(value.to_s, opts[:quote])]
38
- end
39
- )
40
- opts[:join] ? result.join(opts[:join]) : result
41
- end
42
-
43
- # start_for(2, 10)
44
- # calculates the :start value for pagination etc..
45
- def start_for(current_page, per_page)
46
- page = current_page.to_s.to_i
47
- page = page > 0 ? page : 1
48
- ((page - 1) * (per_page || 0))
49
- end
50
-
51
- end # end HelperMethods
52
-
53
- # Easy access: RSolr::Query::Helper.start_for(page=1, per_page=10)
54
- class Helper
55
- extend HelperMethods
56
- end
57
-
58
- end
@@ -1,8 +0,0 @@
1
- module RSolr::Response
2
-
3
- autoload :Base, 'rsolr/response/base'
4
- autoload :Query, 'rsolr/response/query'
5
- autoload :IndexInfo, 'rsolr/response/index_info'
6
- autoload :Update, 'rsolr/response/update'
7
-
8
- end
@@ -1,25 +0,0 @@
1
- # default/base response object
2
- # This is where the ruby "eval" happens
3
- # So far, all response classes extend this
4
- class RSolr::Response::Base
5
-
6
- # the object that contains the original :body, :params, full solr :query, post :data etc.
7
- attr_reader :input
8
-
9
- attr_reader :data, :header, :params, :status, :query_time
10
-
11
- def initialize(input)
12
- input = {:body=>input} if input.is_a?(String)
13
- @input = input
14
- @data = Kernel.eval(input[:body]).to_mash
15
- @header = @data[:responseHeader]
16
- @params = @header[:params]
17
- @status = @header[:status]
18
- @query_time = @header[:QTime]
19
- end
20
-
21
- def ok?
22
- self.status == 0
23
- end
24
-
25
- end
@@ -1,33 +0,0 @@
1
- # response for /admin/luke
2
- class RSolr::Response::IndexInfo < RSolr::Response::Base
3
-
4
- attr_reader :index, :directory, :has_deletions, :optimized, :current, :max_doc, :num_docs, :version
5
-
6
- alias :has_deletions? :has_deletions
7
- alias :optimized? :optimized
8
- alias :current? :current
9
-
10
- def initialize(data)
11
- super(data)
12
- @index = @data[:index]
13
- @directory = @data[:directory]
14
- # index fields
15
- @has_deletions = @index[:hasDeletions]
16
- @optimized = @index[:optimized]
17
- @current = @index[:current]
18
- @max_doc = @index[:maxDoc]
19
- @num_docs = @index[:numDocs]
20
- @version = @index[:version]
21
- end
22
-
23
- # Returns an array of fields from the index
24
- # An optional rule can be used for "grepping" field names:
25
- # field_list(/_facet$/)
26
- def field_list(rule=nil)
27
- @data[:fields].select do |k,v|
28
- rule ? k =~ rule : true
29
- end.collect{|k,v|k}
30
- end
31
-
32
-
33
- end
@@ -1,163 +0,0 @@
1
- # response module for queries
2
- module RSolr::Response::Query
3
-
4
- # module for adding helper methods to each Hash document
5
- module DocExt
6
-
7
- # Helper method to check if value/multi-values exist for a given key.
8
- # The value can be a string, or a RegExp
9
- # Example:
10
- # doc.has?(:location_facet)
11
- # doc.has?(:location_facet, 'Clemons')
12
- # doc.has?(:id, 'h009', /^u/i)
13
- def has?(k, *values)
14
- return if self[k].nil?
15
- return true if self.key?(k) and values.empty?
16
- target = self[k]
17
- if target.is_a?(Array)
18
- values.each do |val|
19
- return target.any?{|tv| val.is_a?(Regexp) ? (tv =~ val) : (tv==val)}
20
- end
21
- else
22
- return values.any? {|val| val.is_a?(Regexp) ? (target =~ val) : (target == val)}
23
- end
24
- end
25
-
26
- # helper
27
- # key is the name of the field
28
- # opts is a hash with the following valid keys:
29
- # - :sep - a string used for joining multivalued field values
30
- # - :default - a value to return when the key doesn't exist
31
- # if :sep is nil and the field is a multivalued field, the array is returned
32
- def get(key, opts={:sep=>', ', :default=>nil})
33
- if self.key? key
34
- val = self[key]
35
- (val.is_a?(Array) and opts[:sep]) ? val.join(opts[:sep]) : val
36
- else
37
- opts[:default]
38
- end
39
- end
40
-
41
- end
42
-
43
- # from the delsolr project -> http://github.com/avvo/delsolr/tree/master/lib/delsolr/response.rb
44
- module Facets
45
-
46
- class FacetValue
47
- attr_reader :value,:hits
48
- def initialize(value,hits)
49
- @value,@hits=value,hits
50
- end
51
- end
52
-
53
- class Facet
54
- attr_reader :field
55
- attr_accessor :values
56
- def initialize(field)
57
- @field=field
58
- @values=[]
59
- end
60
- end
61
-
62
- # @response.facet_fields.each do |facet|
63
- # facet.field
64
- # end
65
- # "caches" the result in the @facets instance var
66
- def facets
67
- @facets ||= (
68
- facet_fields.inject([]) do |acc,(facet_field_name,values_and_hits_list)|
69
- acc << facet = Facet.new(facet_field_name)
70
- # the values_and_hits_list is an array where a value is immediately followed by it's hit count
71
- # so we shift off an item (the value)
72
- while value = values_and_hits_list.shift
73
- # and then shift off the next to get the hit value
74
- facet.values << FacetValue.new(value, values_and_hits_list.shift)
75
- # repeat until there are no more pairs in the values_and_hits_list array
76
- end
77
- acc
78
- end
79
- )
80
- end
81
-
82
- # pass in a facet field name and get back a Facet instance
83
- def facet_by_field_name(name)
84
- facets.detect{|facet|facet.field.to_s == name.to_s}
85
- end
86
-
87
- def facet_counts
88
- @facets ||= data['facet_counts'] || {}
89
- end
90
-
91
- # Returns the hash of all the facet_fields (ie: {'instock_b' => ['true', 123, 'false', 20]}
92
- def facet_fields
93
- @facet_fields ||= facet_counts['facet_fields'] || {}
94
- end
95
-
96
- # Returns all of the facet queries
97
- def facet_queries
98
- @facet_queries ||= facet_counts['facet_queries'] || {}
99
- end
100
-
101
- end
102
-
103
- #
104
- #
105
- #
106
- module Pagination
107
-
108
- # alias to the Solr param, 'rows'
109
- def per_page
110
- @per_page ||= params['rows'].to_s.to_i
111
- end
112
-
113
- # Returns the current page calculated from 'rows' and 'start'
114
- # WillPaginate hook
115
- def current_page
116
- @current_page ||= (self.start / self.per_page).ceil + 1
117
- end
118
-
119
- # Calcuates the total pages from 'numFound' and 'rows'
120
- # WillPaginate hook
121
- def total_pages
122
- @total_pages ||= self.per_page > 0 ? (self.total / self.per_page.to_f).ceil : 1
123
- end
124
-
125
- # returns the previous page number or 1
126
- # WillPaginate hook
127
- def previous_page
128
- @previous_page ||= (current_page > 1) ? current_page - 1 : 1
129
- end
130
-
131
- # returns the next page number or the last
132
- # WillPaginate hook
133
- def next_page
134
- @next_page ||= (current_page < total_pages) ? current_page + 1 : total_pages
135
- end
136
-
137
- end
138
-
139
- # The base query response class
140
- # adds to the Solr::Response::Base class by defining a few more attributes,
141
- # includes the Pagination module, and extends each of the doc hashes
142
- # with Solr::Response::Query::DocExt
143
- class Base < RSolr::Response::Base
144
-
145
- include RSolr::Response::Query::Pagination
146
- include RSolr::Response::Query::Facets
147
-
148
- attr_reader :response, :docs, :num_found, :start
149
-
150
- alias :total :num_found
151
- alias :offset :start
152
-
153
- def initialize(data)
154
- super(data)
155
- @response = @data[:response]
156
- @docs = @response[:docs].collect{ |d| d=d.to_mash; d.extend(DocExt); d }
157
- @num_found = @response[:numFound]
158
- @start = @response[:start]
159
- end
160
-
161
- end
162
-
163
- end
@@ -1,4 +0,0 @@
1
- # response class for update requests - not sure if this is needed yet?
2
- class RSolr::Response::Update < RSolr::Response::Base
3
-
4
- end
@@ -1,30 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'test_helpers.rb')
2
-
3
- class RSolrQueryHelperTest < RSolrBaseTest
4
-
5
- H = RSolr::Query::Helper
6
-
7
- test 'pre_value' do
8
- value = 'the man'
9
- assert_equal 'the man', H.prep_value(value, false)
10
- assert_equal "\"the man\"", H.prep_value(value, :quote=>true)
11
- end
12
-
13
- test 'build_query' do
14
- assert_equal 'testing', H.build_query('testing')
15
- assert_equal '"testing"', H.build_query('testing', :quote=>true)
16
- assert_equal 'testing again', H.build_query(['testing', 'again'])
17
- assert_equal '"testing" "again"', H.build_query(['testing', 'again'], :quote=>true)
18
- assert_equal 'name:whatever', H.build_query({:name=>'whatever'})
19
- assert_equal 'name:"whatever"', H.build_query({:name=>'whatever'}, :quote=>true)
20
- assert_equal 'sam name:whatever i am', H.build_query(['sam', {:name=>'whatever'}, 'i', 'am'])
21
- assert_equal 'testing AND blah', H.build_query(['testing', 'blah'], :join=>' AND ')
22
- end
23
-
24
- test 'start_for' do
25
- per_page = 8
26
- current_page = 2
27
- assert_equal 8, H.start_for(current_page, per_page)
28
- end
29
-
30
- end
@@ -1,38 +0,0 @@
1
- require File.join(File.dirname(__FILE__), '..', 'test_helpers')
2
-
3
- class ResponseBaseTest < RSolrBaseTest
4
-
5
- def test_accessors
6
-
7
- adapter_response = {:body=>mock_query_response}
8
-
9
- r = RSolr::Response::Base.new(adapter_response)
10
-
11
- assert_class Mash, r.data
12
- assert_class Mash, r.params
13
- assert_class Mash, r.header
14
-
15
- # make sure the incoming adapter response is the same as the response.input
16
- assert_equal adapter_response, r.input
17
-
18
- assert_equal r.query_time, r.header[:QTime]
19
- assert_equal r.query_time, r.header['QTime']
20
-
21
- assert_equal r.params, r.header[:params]
22
- assert_equal r.params, r.header['params']
23
-
24
- assert_equal '*:*', r.params[:q]
25
- assert_equal '*:*', r.params['q']
26
-
27
- assert_equal 0, r.status
28
- assert_equal r.status, r.header[:status]
29
- assert_equal r.status, r.header['status']
30
-
31
- assert_equal r.header, r.data[:responseHeader]
32
- assert_equal r.header, r.data['responseHeader']
33
-
34
- assert r.ok?
35
-
36
- end
37
-
38
- end