rsolr 1.0.10 → 1.0.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/CHANGES.txt +14 -0
- data/Gemfile +1 -11
- data/README.rdoc +18 -15
- data/Rakefile +1 -10
- data/lib/rsolr/char.rb +3 -0
- data/lib/rsolr/client.rb +9 -12
- data/lib/rsolr/error.rb +2 -2
- data/lib/rsolr/response.rb +45 -15
- data/lib/rsolr/uri.rb +44 -27
- data/lib/rsolr/version.rb +1 -1
- data/lib/rsolr.rb +15 -8
- data/rsolr.gemspec +6 -4
- data/spec/api/char_spec.rb +8 -3
- data/spec/api/client_spec.rb +37 -38
- data/spec/api/connection_spec.rb +32 -30
- data/spec/api/error_spec.rb +6 -6
- data/spec/api/pagination_spec.rb +5 -5
- data/spec/api/rsolr_spec.rb +28 -8
- data/spec/api/uri_spec.rb +108 -50
- data/spec/api/xml_spec.rb +33 -34
- data/spec/spec_helper.rb +6 -1
- data/tasks/spec.rake +1 -38
- metadata +13 -13
- data/tasks/rcov.rake +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d605bb65e2fdbd7e99f9bd1890549408f304016e
|
4
|
+
data.tar.gz: 02b7f7e889860627575f10e55b6fe73c9c73663c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 656df9328215c9dba8d747baa7faff8b47a7b6a0fb5a8a46cb0246a7967ea7ecee78f5f59076396ddd463fd4413f8d54a7efc914df59c64c614a13fe396f1763
|
7
|
+
data.tar.gz: 8efa618685448b35cc7da82c6ec0576b17838bddc4924fb70ac07529afc2075754f9231697b221c42f0fe418010332ddce050236a4d16d1bf0b994d7855975cb
|
data/CHANGES.txt
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
1.0.11
|
2
|
+
- add RSolr.solr_escape method and add deprecation messages to RSolr.escape (ndushay)
|
3
|
+
- use stdlib URI.escape methods instead of homegrown in RSolr::URI (ndushay)
|
4
|
+
- fix bug with Rsolr::Uri.create adding trailing slash if query params (ndushay)
|
5
|
+
- update rake tasks (cbeer)
|
6
|
+
- add Ruby 2.2.0 to travis ci build (ndushay)
|
7
|
+
- Housekeeping (badges to README, license in gemspec, correct url in gemspec ...) (ndushay)
|
8
|
+
- Improve rdoc styling (udaykadaboina)
|
9
|
+
- Support setting default_wt per connection via its options. (jcoleman)
|
10
|
+
- eliminates the usage of per-instance `extend` (jcoleman)
|
11
|
+
- Upgrade to RSpec 3 (blackwinter, adamjonas, cbeer)
|
12
|
+
- Fixed RSolr::Error to_s (PofMagicfingers)
|
13
|
+
1.0.10 xxx
|
14
|
+
|
1
15
|
1.0.8
|
2
16
|
- Fix connection refused errors in specs + add basic auth support (Denis Goeury)
|
3
17
|
- Ability to set :retry_503, the number of retry attempts for a 503 response
|
data/Gemfile
CHANGED
@@ -4,16 +4,6 @@ gemspec
|
|
4
4
|
|
5
5
|
gem "builder", ">= 2.1.2"
|
6
6
|
|
7
|
-
group :development do
|
8
|
-
gem "rake", ">= 0.9.2"
|
9
|
-
gem "rdoc", ">= 3.9"
|
10
|
-
end
|
11
|
-
|
12
|
-
group :test do
|
13
|
-
gem "rake", ">= 0.9.2"
|
14
|
-
gem "rspec", "~> 2.6"
|
15
|
-
end
|
16
|
-
|
17
7
|
if defined? RUBY_VERSION and RUBY_VERSION < "1.9"
|
18
8
|
gem 'nokogiri', "< 1.6"
|
19
|
-
end
|
9
|
+
end
|
data/README.rdoc
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
=RSolr
|
2
|
+
{<img src="https://travis-ci.org/rsolr/rsolr.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/rsolr/rsolr] {<img src="https://badge.fury.io/rb/rsolr.svg" alt="Gem Version" />}[http://badge.fury.io/rb/rsolr]
|
3
|
+
|
2
4
|
|
3
5
|
A simple, extensible Ruby client for Apache Solr.
|
4
6
|
|
5
7
|
==Documentation
|
6
|
-
The code docs
|
8
|
+
The code docs http://www.rubydoc.info/gems/rsolr
|
7
9
|
|
8
10
|
== Installation:
|
9
|
-
|
11
|
+
gem install rsolr
|
10
12
|
|
11
13
|
== Example:
|
12
14
|
require 'rubygems'
|
@@ -24,22 +26,22 @@ The code docs for the last *release* can be viewed here: http://rubydoc.info/gem
|
|
24
26
|
# send a request to /catalog
|
25
27
|
response = solr.get 'catalog', :params => {:q => '*:*'}
|
26
28
|
|
27
|
-
When the Solr
|
29
|
+
When the Solr +:wt+ is +:ruby+, then the response will be a Hash. This Hash is the same object returned by Solr, but evaluated as Ruby. If the +:wt+ is not +:ruby+, then the response will be a String.
|
28
30
|
|
29
|
-
The response also exposes 2 attribute readers (for any
|
31
|
+
The response also exposes 2 attribute readers (for any +:wt+ value), +:request+ and +:response+. Both are Hash objects with symbolized keys.
|
30
32
|
|
31
|
-
The
|
33
|
+
The +:request+ attribute contains the original request context. You can use this for debugging or logging. Some of the keys this object contains are +:uri+, +:query+, +:method+ etc..
|
32
34
|
|
33
|
-
The
|
35
|
+
The +:response+ attribute contains the original response. This object contains the +:status+, +:body+ and +:headers+ keys.
|
34
36
|
|
35
37
|
== Timeouts
|
36
38
|
The read and connect timeout settings can be set when creating a new instance of RSolr:
|
37
39
|
solr = RSolr.connect(:read_timeout => 120, :open_timeout => 120)
|
38
40
|
|
39
41
|
== Retry 503s
|
40
|
-
A 503 is usually a temporary error which RSolr may retry if requested. You may specify the number of retry attempts with the
|
42
|
+
A 503 is usually a temporary error which RSolr may retry if requested. You may specify the number of retry attempts with the +:retry_503+ option.
|
41
43
|
|
42
|
-
Only requests which specify a Retry-After header will be retried, after waiting the indicated retry interval, otherwise RSolr will treat the request as a 500. You may specify a maximum Retry-After interval to wait with the
|
44
|
+
Only requests which specify a Retry-After header will be retried, after waiting the indicated retry interval, otherwise RSolr will treat the request as a 500. You may specify a maximum Retry-After interval to wait with the +:retry_after_limit+ option (default: one second).
|
43
45
|
solr = RSolr.connect(:retry_503 => 1, :retry_after_limit => 1)
|
44
46
|
|
45
47
|
|
@@ -52,7 +54,7 @@ Use the #get / #post method to send search requests to the /select handler:
|
|
52
54
|
}
|
53
55
|
response["response"]["docs"].each{|doc| puts doc["id"] }
|
54
56
|
|
55
|
-
The
|
57
|
+
The +:params+ sent into the method are sent to Solr as-is, which is to say they are converted to Solr url style, but no special mapping is used.
|
56
58
|
When an array is used, multiple parameters *with the same name* are generated for the Solr query. Example:
|
57
59
|
|
58
60
|
solr.get 'select', :params => {:q=>'roses', :fq=>['red', 'violet']}
|
@@ -71,7 +73,7 @@ The paginate method returns WillPaginate ready "docs" objects, so for example in
|
|
71
73
|
<%= will_paginate @solr_response["response"]["docs"] %>
|
72
74
|
|
73
75
|
===Method Missing
|
74
|
-
The RSolr::Client class also uses method_missing for setting the request handler/path:
|
76
|
+
The +RSolr::Client+ class also uses +method_missing+ for setting the request handler/path:
|
75
77
|
|
76
78
|
solr.paintings :params => {:q=>'roses', :fq=>['red', 'violet']}
|
77
79
|
|
@@ -86,7 +88,7 @@ This works with pagination as well:
|
|
86
88
|
There may be cases where the query string is too long for a GET request. RSolr solves this issue by converting hash objects into form-encoded strings:
|
87
89
|
response = solr.music :data => {:q => "*:*"}
|
88
90
|
|
89
|
-
The
|
91
|
+
The +:data+ hash is serialized as a form-encoded query string, and the correct content-type headers are sent along to Solr.
|
90
92
|
|
91
93
|
===Sending HEAD Requests
|
92
94
|
There may be cases where you'd like to send a HEAD request to Solr:
|
@@ -94,11 +96,11 @@ There may be cases where you'd like to send a HEAD request to Solr:
|
|
94
96
|
|
95
97
|
==Sending HTTP Headers
|
96
98
|
Solr responds to the request headers listed here: http://wiki.apache.org/solr/SolrAndHTTPCaches
|
97
|
-
To send header information to Solr using RSolr, just use the
|
99
|
+
To send header information to Solr using RSolr, just use the +:headers+ option:
|
98
100
|
response = solr.head "admin/ping", :headers => {"Cache-Control" => "If-None-Match"}
|
99
101
|
|
100
102
|
===Building a Request
|
101
|
-
RSolr::Client provides a method for building a request context, which can be useful for debugging or logging etc.:
|
103
|
+
+RSolr::Client+ provides a method for building a request context, which can be useful for debugging or logging etc.:
|
102
104
|
request_context = solr.build_request "select", :data => {:q => "*:*"}, :method => :post, :headers => {}
|
103
105
|
|
104
106
|
To build a paginated request use build_paginated_request:
|
@@ -114,7 +116,7 @@ Multiple documents via #add
|
|
114
116
|
documents = [{:id=>1, :price=>1.00}, {:id=>2, :price=>10.50}]
|
115
117
|
solr.add documents
|
116
118
|
|
117
|
-
The optional
|
119
|
+
The optional +:add_attributes+ hash can also be used to set Solr "add" document attributes:
|
118
120
|
solr.add documents, :add_attributes => {:commitWithin => 10}
|
119
121
|
|
120
122
|
Raw XML via #update
|
@@ -151,7 +153,7 @@ Delete by array of queries
|
|
151
153
|
solr.optimize, :optimize_attributes => {}
|
152
154
|
|
153
155
|
== Response Formats
|
154
|
-
The default response format is Ruby. When the
|
156
|
+
The default response format is Ruby. When the +:wt+ param is set to +:ruby+, the response is eval'd resulting in a Hash. You can get a raw response by setting the +:wt+ to +"ruby"+ - notice, the string -- not a symbol. RSolr will eval the Ruby string ONLY if the :wt value is :ruby. All other response formats are available as expected, +:wt=>'xml'+ etc..
|
155
157
|
|
156
158
|
===Evaluated Ruby (default)
|
157
159
|
solr.get 'select', :params => {:wt => :ruby} # notice :ruby is a Symbol
|
@@ -197,6 +199,7 @@ The default response format is Ruby. When the :wt param is set to :ruby, the res
|
|
197
199
|
* Lucas Souza
|
198
200
|
* Dmitry Lihachev
|
199
201
|
* Antoine Latter
|
202
|
+
* Naomi Dushay
|
200
203
|
|
201
204
|
==Author
|
202
205
|
|
data/Rakefile
CHANGED
@@ -1,15 +1,6 @@
|
|
1
1
|
require 'rake'
|
2
|
-
require 'rake/testtask'
|
3
2
|
require 'bundler/gem_tasks'
|
4
3
|
|
5
|
-
require 'rubygems/package_task'
|
6
|
-
|
7
|
-
ENV['RUBYOPT'] = '-W1'
|
8
|
-
|
9
|
-
task :environment do
|
10
|
-
require File.dirname(__FILE__) + '/lib/rsolr'
|
11
|
-
end
|
12
|
-
|
13
4
|
Dir['tasks/**/*.rake'].each { |t| load t }
|
14
5
|
|
15
|
-
task :default => ['spec
|
6
|
+
task :default => ['spec']
|
data/lib/rsolr/char.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
# A module that contains (1) string related methods
|
2
|
+
# @deprecated remove this module when we remove the method (duh)
|
2
3
|
module RSolr::Char
|
3
4
|
|
4
5
|
# backslash everything
|
5
6
|
# that isn't a word character
|
7
|
+
# @deprecated - this is incorrect Solr escaping
|
6
8
|
def escape value
|
9
|
+
warn "[DEPRECATION] `RSolr.escape` is deprecated (and incorrect). Use `Rsolr.solr_escape` instead."
|
7
10
|
value.gsub(/(\W)/, '\\\\\1')
|
8
11
|
end
|
9
12
|
|
data/lib/rsolr/client.rb
CHANGED
@@ -261,12 +261,7 @@ class RSolr::Client
|
|
261
261
|
opts[:params]["rows"] = per_page
|
262
262
|
build_request path, opts
|
263
263
|
end
|
264
|
-
|
265
|
-
# A mixin for used by #adapt_response
|
266
|
-
module Context
|
267
|
-
attr_accessor :request, :response
|
268
|
-
end
|
269
|
-
|
264
|
+
|
270
265
|
# This method will evaluate the :body value
|
271
266
|
# if the params[:uri].params[:wt] == :ruby
|
272
267
|
# ... otherwise, the body is returned as is.
|
@@ -288,13 +283,15 @@ class RSolr::Client
|
|
288
283
|
response[:body]
|
289
284
|
end
|
290
285
|
|
291
|
-
result.
|
292
|
-
|
293
|
-
|
286
|
+
if result.is_a?(Hash)
|
287
|
+
result = RSolr::HashWithResponse.new(request, response, result)
|
288
|
+
end
|
289
|
+
|
290
|
+
result
|
294
291
|
end
|
295
|
-
|
292
|
+
|
296
293
|
protected
|
297
|
-
|
294
|
+
|
298
295
|
# converts the method name for the solr request handler path.
|
299
296
|
def method_missing name, *args
|
300
297
|
if name.to_s =~ /^paginated?_(.+)$/
|
@@ -330,6 +327,6 @@ class RSolr::Client
|
|
330
327
|
end
|
331
328
|
|
332
329
|
def default_wt
|
333
|
-
self.class.default_wt
|
330
|
+
self.options[:default_wt] || self.class.default_wt
|
334
331
|
end
|
335
332
|
end
|
data/lib/rsolr/error.rb
CHANGED
@@ -12,8 +12,8 @@ module RSolr::Error
|
|
12
12
|
m << "\nError: #{details}\n" if details
|
13
13
|
end
|
14
14
|
p = "\nURI: #{request[:uri].to_s}"
|
15
|
-
p
|
16
|
-
p
|
15
|
+
p << "\nRequest Headers: #{request[:headers].inspect}" if request[:headers]
|
16
|
+
p << "\nRequest Data: #{request[:data].inspect}" if request[:data]
|
17
17
|
p << "\n"
|
18
18
|
p << "\nBacktrace: " + self.backtrace[0..10].join("\n")
|
19
19
|
m << p
|
data/lib/rsolr/response.rb
CHANGED
@@ -1,26 +1,47 @@
|
|
1
1
|
module RSolr::Response
|
2
|
-
|
3
|
-
def self.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
unless base < Hash
|
5
|
+
raise ArgumentError, "RSolr::Response expects to included only in (sub)classes of Hash; got included in '#{base}' instead."
|
6
|
+
end
|
7
|
+
base.send(:attr_reader, :request, :response)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize_rsolr_response(request, response, result)
|
11
|
+
@request = request
|
12
|
+
@response = response
|
13
|
+
self.merge!(result)
|
14
|
+
if self["response"] && self["response"]["docs"].is_a?(Array)
|
15
|
+
docs = PaginatedDocSet.new(self["response"]["docs"])
|
16
|
+
docs.per_page = request[:params]["rows"]
|
17
|
+
docs.page_start = request[:params]["start"]
|
18
|
+
docs.page_total = self["response"]["numFound"].to_s.to_i
|
19
|
+
self["response"]["docs"] = docs
|
11
20
|
end
|
12
21
|
end
|
13
|
-
|
22
|
+
|
14
23
|
def with_indifferent_access
|
15
|
-
if
|
16
|
-
|
24
|
+
if defined?(::RSolr::HashWithIndifferentAccessWithResponse)
|
25
|
+
::RSolr::HashWithIndifferentAccessWithResponse.new(request, response, self)
|
17
26
|
else
|
18
|
-
|
27
|
+
if defined?(ActiveSupport::HashWithIndifferentAccess)
|
28
|
+
RSolr.const_set("HashWithIndifferentAccessWithResponse", Class.new(ActiveSupport::HashWithIndifferentAccess))
|
29
|
+
RSolr::HashWithIndifferentAccessWithResponse.class_eval <<-eos
|
30
|
+
include RSolr::Response
|
31
|
+
def initialize(request, response, result)
|
32
|
+
super()
|
33
|
+
initialize_rsolr_response(request, response, result)
|
34
|
+
end
|
35
|
+
eos
|
36
|
+
::RSolr::HashWithIndifferentAccessWithResponse.new(request, response, self)
|
37
|
+
else
|
38
|
+
raise RuntimeError, "HashWithIndifferentAccess is not currently defined"
|
39
|
+
end
|
19
40
|
end
|
20
41
|
end
|
21
42
|
|
22
43
|
# A response module which gets mixed into the solr ["response"]["docs"] array.
|
23
|
-
|
44
|
+
class PaginatedDocSet < Array
|
24
45
|
|
25
46
|
attr_accessor :page_start, :per_page, :page_total
|
26
47
|
if not (Object.const_defined?("RUBY_ENGINE") and Object::RUBY_ENGINE=='rbx')
|
@@ -61,5 +82,14 @@ module RSolr::Response
|
|
61
82
|
end
|
62
83
|
|
63
84
|
end
|
64
|
-
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
class RSolr::HashWithResponse < Hash
|
89
|
+
include RSolr::Response
|
90
|
+
|
91
|
+
def initialize(request, response, result)
|
92
|
+
super()
|
93
|
+
initialize_rsolr_response(request, response, result)
|
94
|
+
end
|
65
95
|
end
|
data/lib/rsolr/uri.rb
CHANGED
@@ -3,56 +3,73 @@ require 'uri'
|
|
3
3
|
module RSolr::Uri
|
4
4
|
|
5
5
|
def create url
|
6
|
-
::URI.parse url[-1] ==
|
6
|
+
::URI.parse (url[-1] == '/' || URI.parse(url).query) ? url : "#{url}/"
|
7
7
|
end
|
8
8
|
|
9
|
-
# Returns a query string param pair as a string.
|
10
|
-
# Both key and value are escaped.
|
11
|
-
def build_param(k,v, escape = true)
|
12
|
-
escape ?
|
13
|
-
"#{escape_query_value(k)}=#{escape_query_value(v)}" :
|
14
|
-
"#{k}=#{v}"
|
15
|
-
end
|
16
|
-
|
17
|
-
# Return the bytesize of String; uses String#size under Ruby 1.8 and
|
18
|
-
# String#bytesize under 1.9.
|
19
|
-
if ''.respond_to?(:bytesize)
|
20
|
-
def bytesize(string)
|
21
|
-
string.bytesize
|
22
|
-
end
|
23
|
-
else
|
24
|
-
def bytesize(string)
|
25
|
-
string.size
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
9
|
# Creates a Solr based query string.
|
30
10
|
# Keys that have arrays values are set multiple times:
|
31
11
|
# params_to_solr(:q => 'query', :fq => ['a', 'b'])
|
32
12
|
# is converted to:
|
33
13
|
# ?q=query&fq=a&fq=b
|
14
|
+
# @param [boolean] escape false if no URI escaping is to be performed. Default true.
|
15
|
+
# @return [String] Solr query params as a String, suitable for use in a url
|
34
16
|
def params_to_solr(params, escape = true)
|
17
|
+
return URI.encode_www_form(params.reject{|k,v| k.to_s.empty? || v.to_s.empty?}) if escape
|
18
|
+
|
19
|
+
# escape = false if we are here
|
35
20
|
mapped = params.map do |k, v|
|
36
21
|
next if v.to_s.empty?
|
37
22
|
if v.class == Array
|
38
|
-
params_to_solr(v.map { |x| [k, x] },
|
23
|
+
params_to_solr(v.map { |x| [k, x] }, false)
|
39
24
|
else
|
40
|
-
|
25
|
+
"#{k}=#{v}"
|
41
26
|
end
|
42
27
|
end
|
43
28
|
mapped.compact.join("&")
|
44
29
|
end
|
45
30
|
|
31
|
+
# Returns a query string param pair as a string.
|
32
|
+
# Both key and value are URI escaped, unless third param is false
|
33
|
+
# @param [boolean] escape false if no URI escaping is to be performed. Default true.
|
34
|
+
# @deprecated - used to be called from params_to_solr before 2015-02-25
|
35
|
+
def build_param(k, v, escape = true)
|
36
|
+
warn "[DEPRECATION] `RSolr::Uri.build_param` is deprecated. Use `URI.encode_www_form_component` or k=v instead."
|
37
|
+
escape ?
|
38
|
+
"#{URI.encode_www_form_component(k)}=#{URI.encode_www_form_component(v)}" :
|
39
|
+
"#{k}=#{v}"
|
40
|
+
end
|
41
|
+
|
42
|
+
# 2015-02 Deprecated: use URI.encode_www_form_component(s)
|
43
|
+
#
|
46
44
|
# Performs URI escaping so that you can construct proper
|
47
45
|
# query strings faster. Use this rather than the cgi.rb
|
48
46
|
# version since it's faster.
|
49
47
|
# (Stolen from Rack).
|
48
|
+
# http://www.rubydoc.info/github/rack/rack/URI.encode_www_form_component
|
49
|
+
# @deprecated
|
50
50
|
def escape_query_value(s)
|
51
|
-
|
52
|
-
|
53
|
-
|
51
|
+
warn "[DEPRECATION] `RSolr::Uri.escape_query_value` is deprecated. Use `URI.encode_www_form_component` instead."
|
52
|
+
URI.encode_www_form_component(s)
|
53
|
+
# s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/u) {
|
54
|
+
# '%'+$1.unpack('H2'*bytesize($1)).join('%').upcase
|
55
|
+
# }.tr(' ', '+')
|
54
56
|
end
|
55
|
-
|
57
|
+
|
58
|
+
# Return the bytesize of String; uses String#size under Ruby 1.8 and
|
59
|
+
# String#bytesize under 1.9.
|
60
|
+
# @deprecated as bytesize was only used by escape_query_value which is itself deprecated
|
61
|
+
if ''.respond_to?(:bytesize)
|
62
|
+
def bytesize(string)
|
63
|
+
warn "[DEPRECATION] `RSolr::Uri.bytesize` is deprecated. Use String.bytesize"
|
64
|
+
string.bytesize
|
65
|
+
end
|
66
|
+
else
|
67
|
+
def bytesize(string)
|
68
|
+
warn "[DEPRECATION] `RSolr::Uri.bytesize` is deprecated. Use String.size"
|
69
|
+
string.size
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
56
73
|
extend self
|
57
74
|
|
58
75
|
end
|
data/lib/rsolr/version.rb
CHANGED
data/lib/rsolr.rb
CHANGED
@@ -1,11 +1,6 @@
|
|
1
|
-
$: << "#{File.dirname(__FILE__)}" unless $:.include? File.dirname(__FILE__)
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'rsolr/version'
|
5
|
-
|
6
1
|
module RSolr
|
7
2
|
|
8
|
-
|
3
|
+
Dir.glob(File.expand_path("../rsolr/*.rb", __FILE__)).each{|rb_file| require(rb_file)}
|
9
4
|
|
10
5
|
def self.connect *args
|
11
6
|
driver = Class === args[0] ? args[0] : RSolr::Connection
|
@@ -13,7 +8,19 @@ module RSolr
|
|
13
8
|
Client.new driver.new, opts
|
14
9
|
end
|
15
10
|
|
16
|
-
# RSolr.escape
|
11
|
+
# RSolr.escape, which is deprecated as of 2015-02
|
17
12
|
extend Char
|
18
13
|
|
19
|
-
|
14
|
+
# backslash escape characters that have special meaning to Solr query parser
|
15
|
+
# per http://lucene.apache.org/core/4_0_0/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#Escaping_Special_Characters
|
16
|
+
# + - & | ! ( ) { } [ ] ^ " ~ * ? : \ /
|
17
|
+
# see also http://svn.apache.org/repos/asf/lucene/dev/tags/lucene_solr_4_9_1/solr/solrj/src/java/org/apache/solr/client/solrj/util/ClientUtils.java
|
18
|
+
# escapeQueryChars method
|
19
|
+
# @return [String] str with special chars preceded by a backslash
|
20
|
+
def self.solr_escape(str)
|
21
|
+
# note that the gsub will parse the escaped backslashes, as will the ruby code sending the query to Solr
|
22
|
+
# so the result sent to Solr is ultimately a single backslash in front of the particular character
|
23
|
+
str.gsub(/([+\-&|!\(\)\{\}\[\]\^"~\*\?:\\\/])/, '\\\\\1')
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/rsolr.gemspec
CHANGED
@@ -18,9 +18,11 @@ Gem::Specification.new do |s|
|
|
18
18
|
"Mat Brown", "Shairon Toledo",
|
19
19
|
"Matthew Rudy", "Fouad Mardini",
|
20
20
|
"Jeremy Hinegardner", "Nathan Witmer",
|
21
|
+
"Naomi Dushay",
|
21
22
|
"\"shima\""]
|
22
23
|
s.email = ["goodieboy@gmail.com"]
|
23
|
-
s.
|
24
|
+
s.license = 'Apache-2.0'
|
25
|
+
s.homepage = "https://github.com/rsolr/rsolr"
|
24
26
|
s.rubyforge_project = "rsolr"
|
25
27
|
s.files = `git ls-files`.split("\n")
|
26
28
|
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
@@ -30,7 +32,7 @@ Gem::Specification.new do |s|
|
|
30
32
|
s.add_dependency 'builder', '>= 2.1.2'
|
31
33
|
s.add_development_dependency 'activesupport'
|
32
34
|
s.add_development_dependency 'nokogiri', '>= 1.4.0'
|
33
|
-
s.add_development_dependency 'rake', '~> 0
|
34
|
-
s.add_development_dependency 'rdoc', '~>
|
35
|
-
s.add_development_dependency 'rspec', '~>
|
35
|
+
s.add_development_dependency 'rake', '~> 10.0'
|
36
|
+
s.add_development_dependency 'rdoc', '~> 4.0'
|
37
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
36
38
|
end
|
data/spec/api/char_spec.rb
CHANGED
@@ -1,18 +1,23 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
# @deprecated remove this module's specs when we remove the method (duh)
|
2
3
|
describe "RSolr::Char" do
|
3
4
|
|
4
5
|
let(:char){Object.new.extend RSolr::Char}
|
5
6
|
|
7
|
+
# deprecated as of 2015-02, as it is incorrect Solr escaping.
|
8
|
+
# instead, use RSolr.solr_escape
|
9
|
+
# commented out as it gives a mess of deprecation warnings
|
10
|
+
=begin
|
6
11
|
it 'should escape everything that is not a word with \\' do
|
7
12
|
(0..255).each do |ascii|
|
8
13
|
chr = ascii.chr
|
9
14
|
esc = char.escape(chr)
|
10
15
|
if chr =~ /\W/
|
11
|
-
esc.to_s.
|
16
|
+
expect(esc.to_s).to eq("\\#{chr}")
|
12
17
|
else
|
13
|
-
esc.to_s.
|
18
|
+
expect(esc.to_s).to eq(chr)
|
14
19
|
end
|
15
20
|
end
|
16
21
|
end
|
17
|
-
|
22
|
+
=end
|
18
23
|
end
|