mwmitchell-rsolr 0.7.1 → 0.8.0

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