rsolr 2.1.0 → 2.6.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.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +29 -0
- data/CHANGES.txt +38 -0
- data/Gemfile +8 -0
- data/README.rdoc +17 -17
- data/lib/rsolr/client.rb +49 -9
- data/lib/rsolr/document.rb +10 -0
- data/lib/rsolr/error.rb +49 -3
- data/lib/rsolr/version.rb +1 -1
- data/rsolr.gemspec +3 -4
- data/spec/api/client_spec.rb +89 -3
- data/spec/api/error_spec.rb +112 -1
- data/spec/api/json_spec.rb +59 -0
- data/spec/integration/solr5_spec.rb +4 -0
- data/spec/lib/rsolr/client_spec.rb +19 -0
- metadata +22 -10
- data/.travis.yml +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2b7e170dd7fcd0bfd504562297b93a6fb504da5e95df0d356cd0d1c70a7515c8
|
4
|
+
data.tar.gz: b4d04a24455588c421f72d29b8e9e7ab255fb4bfde9457bc6ab5f64bb64c76a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd27dcd3369b5d1e4cd99604426927bf83a3a4c3ef7d8a06fb3cfc45676b33c920ce256ecb7fc577dedbbe910b6d50a45fdaa7dd0324516529c5705df8698385
|
7
|
+
data.tar.gz: 5a488c3aa5e5ca93e8fe2647baf313d8b5a94229e99d6a49820a3bf80b65fe9c19fd8ab05678ee402d3674d7a043ded6110acdf4ada5a2a1752b96f4080ceec1
|
@@ -0,0 +1,29 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
tests:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
strategy:
|
13
|
+
matrix:
|
14
|
+
ruby: [jruby-9.3.3.0, '3.0', '3.1', '3.2', '3.3']
|
15
|
+
faraday: ['~> 0.17', '~> 1', '~>2']
|
16
|
+
steps:
|
17
|
+
- uses: actions/checkout@v2
|
18
|
+
- name: Set up Ruby
|
19
|
+
uses: ruby/setup-ruby@v1
|
20
|
+
with:
|
21
|
+
ruby-version: ${{ matrix.ruby }}
|
22
|
+
- name: Install dependencies
|
23
|
+
run: bundle install
|
24
|
+
env:
|
25
|
+
FARADAY_VERSION: ${{ matrix.faraday}}
|
26
|
+
- name: Run tests
|
27
|
+
run: bundle exec rake
|
28
|
+
env:
|
29
|
+
FARADAY_VERSION: ${{ matrix.faraday}}
|
data/CHANGES.txt
CHANGED
@@ -1,3 +1,41 @@
|
|
1
|
+
2.6.0
|
2
|
+
|
3
|
+
- Stop testing on Ruby 2. https://github.com/rsolr/rsolr/pull/237
|
4
|
+
- Set solr version to 8.11.3. https://github.com/rsolr/rsolr/pull/238
|
5
|
+
- Add newer rubies to the test matrix. https://github.com/rsolr/rsolr/pull/239
|
6
|
+
- Sanitizing URIs displayed in error messages. https://github.com/rsolr/rsolr/pull/236
|
7
|
+
|
8
|
+
2.5.0
|
9
|
+
|
10
|
+
- Sorry, not human-edited: https://github.com/rsolr/rsolr/compare/v2.4.0...v2.5.0
|
11
|
+
|
12
|
+
|
13
|
+
2.4.0
|
14
|
+
|
15
|
+
- Raise specific timeout error for solr timeouts. https://github.com/rsolr/rsolr/pull/214
|
16
|
+
- Pass `timeout` RSolr configuration through to Faraday, deprecate `read_timeout` Rsolr configuration. https://github.com/rsolr/rsolr/pull/215
|
17
|
+
- Better visibility of Solr error message in `RSolr::Error`. https://github.com/rsolr/rsolr/pull/222
|
18
|
+
- Add soft-commit function https://github.com/rsolr/rsolr/pull/210 (thanks @giteshnandre)
|
19
|
+
- Avoid encoding exception in error message display https://github.com/rsolr/rsolr/pull/208 (thanks @expajp)
|
20
|
+
- Fix JSON generator for atomic updates of array fields https://github.com/rsolr/rsolr/pull/201 (thanks @serggl)
|
21
|
+
|
22
|
+
|
23
|
+
2.3.0
|
24
|
+
|
25
|
+
- Sorry, not human-edited: https://github.com/rsolr/rsolr/compare/v2.2.0...v2.3.0
|
26
|
+
|
27
|
+
2.2.0
|
28
|
+
|
29
|
+
- Sorry, not human-edited: https://github.com/rsolr/rsolr/compare/v2.1.0...v2.2.0
|
30
|
+
|
31
|
+
2.1.0
|
32
|
+
|
33
|
+
- Sorry, not human-edited: https://github.com/rsolr/rsolr/compare/v2.0.0...v2.1.0
|
34
|
+
|
35
|
+
2.0.0
|
36
|
+
|
37
|
+
- Sorry, not human-edited: https://github.com/rsolr/rsolr/compare/v2.0.0.pre1...v2.0.0
|
38
|
+
|
1
39
|
2.0.0.pre1
|
2
40
|
|
3
41
|
In this release, we've added many new features, including:
|
data/Gemfile
CHANGED
@@ -3,3 +3,11 @@ source "https://rubygems.org"
|
|
3
3
|
gemspec
|
4
4
|
|
5
5
|
gem "builder", ">= 2.1.2"
|
6
|
+
|
7
|
+
if defined? JRUBY_VERSION
|
8
|
+
# HTTP.rb (used by solr_wrapper to download solr for integration testing) fails
|
9
|
+
# to download the full contents of files (under jruby)?
|
10
|
+
gem "http", '< 5', platforms: :jruby
|
11
|
+
end
|
12
|
+
|
13
|
+
gem 'faraday', ENV['FARADAY_VERSION'] if ENV['FARADAY_VERSION']
|
data/README.rdoc
CHANGED
@@ -1,6 +1,4 @@
|
|
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
|
-
|
4
2
|
|
5
3
|
A simple, extensible Ruby client for Apache Solr.
|
6
4
|
|
@@ -12,26 +10,26 @@ The code docs http://www.rubydoc.info/gems/rsolr
|
|
12
10
|
|
13
11
|
== Example:
|
14
12
|
require 'rsolr'
|
15
|
-
|
13
|
+
|
16
14
|
# Direct connection
|
17
15
|
solr = RSolr.connect :url => 'http://solrserver.com'
|
18
|
-
|
16
|
+
|
19
17
|
# Connecting over a proxy server
|
20
18
|
solr = RSolr.connect :url => 'http://solrserver.com', :proxy=>'http://user:pass@proxy.example.com:8080'
|
21
19
|
|
22
20
|
# Using an alternate Faraday adapter
|
23
21
|
solr = RSolr.connect :url => 'http://solrserver.com', :adapter => :em_http
|
24
|
-
|
22
|
+
|
25
23
|
# Using a custom Faraday connection
|
26
24
|
conn = Faraday.new do |faraday|
|
27
25
|
faraday.response :logger # log requests to STDOUT
|
28
26
|
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
|
29
27
|
end
|
30
28
|
solr = RSolr.connect conn, :url => 'http://solrserver.com'
|
31
|
-
|
29
|
+
|
32
30
|
# send a request to /select
|
33
31
|
response = solr.get 'select', :params => {:q => '*:*'}
|
34
|
-
|
32
|
+
|
35
33
|
# send a request to /catalog
|
36
34
|
response = solr.get 'catalog', :params => {:q => '*:*'}
|
37
35
|
|
@@ -52,8 +50,10 @@ By default, RSolr uses the Solr JSON command format for all requests.
|
|
52
50
|
RSolr.connect :url => 'http://solrserver.com', update_format: :xml
|
53
51
|
|
54
52
|
== Timeouts
|
55
|
-
The read and connect timeout settings can be set when creating a new instance of RSolr
|
56
|
-
|
53
|
+
The read and connect timeout settings can be set when creating a new instance of RSolr, and will
|
54
|
+
be passed on to underlying Faraday instance:
|
55
|
+
|
56
|
+
solr = RSolr.connect(:timeout => 120, :open_timeout => 120)
|
57
57
|
|
58
58
|
== Retry 503s
|
59
59
|
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.
|
@@ -74,11 +74,11 @@ Use the #get / #post method to send search requests to the /select handler:
|
|
74
74
|
|
75
75
|
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.
|
76
76
|
When an array is used, multiple parameters *with the same name* are generated for the Solr query. Example:
|
77
|
-
|
77
|
+
|
78
78
|
solr.get 'select', :params => {:q=>'roses', :fq=>['red', 'violet']}
|
79
79
|
|
80
80
|
The above statement generates this Solr query:
|
81
|
-
|
81
|
+
|
82
82
|
select?q=roses&fq=red&fq=violet
|
83
83
|
|
84
84
|
===Pagination
|
@@ -92,14 +92,14 @@ The paginate method returns WillPaginate ready "docs" objects, so for example in
|
|
92
92
|
|
93
93
|
===Method Missing
|
94
94
|
The +RSolr::Client+ class also uses +method_missing+ for setting the request handler/path:
|
95
|
-
|
95
|
+
|
96
96
|
solr.paintings :params => {:q=>'roses', :fq=>['red', 'violet']}
|
97
|
-
|
97
|
+
|
98
98
|
This is sent to Solr as:
|
99
99
|
paintings?q=roses&fq=red&fq=violet
|
100
100
|
|
101
101
|
This works with pagination as well:
|
102
|
-
|
102
|
+
|
103
103
|
solr.paginate_paintings 1, 10, {:q=>'roses', :fq=>['red', 'violet']}
|
104
104
|
|
105
105
|
===Using POST for Search Queries
|
@@ -120,10 +120,10 @@ To send header information to Solr using RSolr, just use the +:headers+ option:
|
|
120
120
|
===Building a Request
|
121
121
|
+RSolr::Client+ provides a method for building a request context, which can be useful for debugging or logging etc.:
|
122
122
|
request_context = solr.build_request "select", :data => {:q => "*:*"}, :method => :post, :headers => {}
|
123
|
-
|
123
|
+
|
124
124
|
To build a paginated request use build_paginated_request:
|
125
125
|
request_context = solr.build_paginated_request 1, 10, "select", ...
|
126
|
-
|
126
|
+
|
127
127
|
== Updating Solr
|
128
128
|
Updating is done using native Ruby objects. Hashes are used for single documents and arrays are used for a collection of documents (hashes). These objects get turned into simple XML "messages". Raw XML strings can also be used.
|
129
129
|
|
@@ -142,7 +142,7 @@ Raw commands via #update
|
|
142
142
|
solr.update data: { optimize: true }.to_json, headers: { 'Content-Type' => 'application/json' }
|
143
143
|
|
144
144
|
When adding, you can also supply "add" xml element attributes and/or a block for manipulating other "add" related elements (docs and fields) by calling the +xml+ method directly:
|
145
|
-
|
145
|
+
|
146
146
|
doc = {:id=>1, :price=>1.00}
|
147
147
|
add_attributes = {:allowDups=>false, :commitWithin=>10}
|
148
148
|
add_xml = solr.xml.add(doc, add_attributes) do |doc|
|
data/lib/rsolr/client.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'json'
|
2
4
|
require 'faraday'
|
3
5
|
require 'uri'
|
4
6
|
|
5
7
|
class RSolr::Client
|
8
|
+
DEFAULT_URL = 'http://127.0.0.1:8983/solr/'
|
6
9
|
|
7
10
|
class << self
|
8
11
|
def default_wt
|
@@ -20,9 +23,7 @@ class RSolr::Client
|
|
20
23
|
@proxy = @uri = nil
|
21
24
|
@connection = connection
|
22
25
|
unless false === options[:url]
|
23
|
-
|
24
|
-
url << "/" unless url[-1] == ?/
|
25
|
-
@uri = ::URI.parse(url)
|
26
|
+
@uri = extract_url_from_options(options)
|
26
27
|
if options[:proxy]
|
27
28
|
proxy_url = options[:proxy].dup
|
28
29
|
proxy_url << "/" unless proxy_url.nil? or proxy_url[-1] == ?/
|
@@ -34,6 +35,19 @@ class RSolr::Client
|
|
34
35
|
@update_format = options.delete(:update_format) || RSolr::JSON::Generator
|
35
36
|
@update_path = options.fetch(:update_path, 'update')
|
36
37
|
@options = options
|
38
|
+
|
39
|
+
if options[:read_timeout]
|
40
|
+
warn "DEPRECATION: Rsolr.new/connect option `read_timeout` is deprecated and will be removed in Rsolr 3. `timeout` is currently a synonym, use that instead."
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def extract_url_from_options(options)
|
45
|
+
url = options[:url] ? options[:url].dup : DEFAULT_URL
|
46
|
+
url << "/" unless url[-1] == ?/
|
47
|
+
uri = ::URI.parse(url)
|
48
|
+
# URI::HTTPS is a subclass of URI::HTTP, so this check accepts HTTP(S)
|
49
|
+
raise ArgumentError, "You must provide an HTTP(S) url." unless uri.kind_of?(URI::HTTP)
|
50
|
+
uri
|
37
51
|
end
|
38
52
|
|
39
53
|
# returns the request uri object.
|
@@ -112,6 +126,14 @@ class RSolr::Client
|
|
112
126
|
update opts.merge(:data => builder.commit( commit_attrs ))
|
113
127
|
end
|
114
128
|
|
129
|
+
# soft commit
|
130
|
+
#
|
131
|
+
# https://lucene.apache.org/solr/guide/updatehandlers-in-solrconfig.html#commit-and-softcommit
|
132
|
+
#
|
133
|
+
def soft_commit opts = {}
|
134
|
+
commit(opts.merge params: { softCommit: true })
|
135
|
+
end
|
136
|
+
|
115
137
|
# send "optimize" xml with opts.
|
116
138
|
#
|
117
139
|
# http://wiki.apache.org/solr/UpdateXmlMessages#A.22commit.22_and_.22optimize.22
|
@@ -190,8 +212,10 @@ class RSolr::Client
|
|
190
212
|
end
|
191
213
|
|
192
214
|
{ status: response.status.to_i, headers: response.headers, body: response.body.force_encoding('utf-8') }
|
193
|
-
rescue
|
194
|
-
raise RSolr::Error::
|
215
|
+
rescue Faraday::TimeoutError => e
|
216
|
+
raise RSolr::Error::Timeout.new(request_context, e.response)
|
217
|
+
rescue Errno::ECONNREFUSED, defined?(Faraday::ConnectionFailed) ? Faraday::ConnectionFailed : Faraday::Error::ConnectionFailed
|
218
|
+
raise RSolr::Error::ConnectionRefused.new(request_context)
|
195
219
|
rescue Faraday::Error => e
|
196
220
|
raise RSolr::Error::Http.new(request_context, e.response)
|
197
221
|
end
|
@@ -273,23 +297,39 @@ class RSolr::Client
|
|
273
297
|
|
274
298
|
result
|
275
299
|
end
|
276
|
-
|
300
|
+
|
277
301
|
def connection
|
278
302
|
@connection ||= begin
|
279
303
|
conn_opts = { request: {} }
|
280
304
|
conn_opts[:url] = uri.to_s
|
281
305
|
conn_opts[:proxy] = proxy if proxy
|
282
306
|
conn_opts[:request][:open_timeout] = options[:open_timeout] if options[:open_timeout]
|
283
|
-
|
307
|
+
|
308
|
+
if options[:read_timeout] || options[:timeout]
|
309
|
+
# read_timeout was being passed to faraday as timeout since Rsolr 2.0,
|
310
|
+
# it's now deprecated, just use `timeout` directly.
|
311
|
+
conn_opts[:request][:timeout] = options[:timeout] || options[:read_timeout]
|
312
|
+
end
|
313
|
+
|
284
314
|
conn_opts[:request][:params_encoder] = Faraday::FlatParamsEncoder
|
285
315
|
|
286
316
|
Faraday.new(conn_opts) do |conn|
|
287
|
-
|
317
|
+
if uri.user && uri.password
|
318
|
+
case Faraday::VERSION
|
319
|
+
when /^0/
|
320
|
+
conn.basic_auth uri.user, uri.password
|
321
|
+
when /^1/
|
322
|
+
conn.request :basic_auth, uri.user, uri.password
|
323
|
+
else
|
324
|
+
conn.request :authorization, :basic_auth, uri.user, uri.password
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
288
328
|
conn.response :raise_error
|
289
329
|
conn.request :retry, max: options[:retry_after_limit], interval: 0.05,
|
290
330
|
interval_randomness: 0.5, backoff_factor: 2,
|
291
331
|
exceptions: ['Faraday::Error', 'Timeout::Error'] if options[:retry_503]
|
292
|
-
conn.adapter options[:adapter] || Faraday.default_adapter
|
332
|
+
conn.adapter options[:adapter] || Faraday.default_adapter || :net_http
|
293
333
|
end
|
294
334
|
end
|
295
335
|
end
|
data/lib/rsolr/document.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module RSolr
|
2
2
|
class Document
|
3
3
|
CHILD_DOCUMENT_KEY = '_childDocuments_'.freeze
|
4
|
+
ATOMIC_MULTI_VALUE_OPERATIONS = %i[set add add-distinct remove]
|
4
5
|
|
5
6
|
# "attrs" is a hash for setting the "doc" xml attributes
|
6
7
|
# "fields" is an array of Field objects
|
@@ -48,6 +49,15 @@ module RSolr
|
|
48
49
|
def as_json
|
49
50
|
@fields.group_by(&:name).each_with_object({}) do |(field, values), result|
|
50
51
|
v = values.map(&:as_json)
|
52
|
+
if v.length > 1 && v.first.is_a?(Hash)
|
53
|
+
if v.first.key?(:value)
|
54
|
+
v = v.first.merge(value: v.map { |single| single[:value] })
|
55
|
+
else
|
56
|
+
(v.first.keys & ATOMIC_MULTI_VALUE_OPERATIONS).each do |op|
|
57
|
+
v = [{ op => v.map { |single| single[op] } }]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
51
61
|
v = v.first if v.length == 1 && field.to_s != CHILD_DOCUMENT_KEY
|
52
62
|
result[field] = v
|
53
63
|
end
|
data/lib/rsolr/error.rb
CHANGED
@@ -1,6 +1,19 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
1
3
|
module RSolr::Error
|
2
4
|
|
5
|
+
module URICleanup
|
6
|
+
# Removes username and password from URI object.
|
7
|
+
def clean_uri(uri)
|
8
|
+
uri = uri.dup
|
9
|
+
uri.password = "REDACTED" if uri.password
|
10
|
+
uri.user = "REDACTED" if uri.user
|
11
|
+
uri
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
3
15
|
module SolrContext
|
16
|
+
include URICleanup
|
4
17
|
|
5
18
|
attr_accessor :request, :response
|
6
19
|
|
@@ -11,7 +24,7 @@ module RSolr::Error
|
|
11
24
|
details = parse_solr_error_response response[:body]
|
12
25
|
m << "\nError: #{details}\n" if details
|
13
26
|
end
|
14
|
-
p = "\nURI: #{request[:uri].to_s}"
|
27
|
+
p = "\nURI: #{clean_uri(request[:uri]).to_s}"
|
15
28
|
p << "\nRequest Headers: #{request[:headers].inspect}" if request[:headers]
|
16
29
|
p << "\nRequest Data: #{request[:data].inspect}" if request[:data]
|
17
30
|
p << "\n"
|
@@ -24,6 +37,18 @@ module RSolr::Error
|
|
24
37
|
|
25
38
|
def parse_solr_error_response body
|
26
39
|
begin
|
40
|
+
# Default JSON response, try to parse and retrieve error message
|
41
|
+
if response[:headers] && response[:headers]["content-type"].start_with?("application/json")
|
42
|
+
begin
|
43
|
+
parsed_body = JSON.parse(body)
|
44
|
+
info = parsed_body && parsed_body["error"] && parsed_body["error"]["msg"]
|
45
|
+
rescue JSON::ParserError
|
46
|
+
end
|
47
|
+
end
|
48
|
+
return info if info
|
49
|
+
|
50
|
+
# legacy analysis, I think trying to handle wt=ruby responses without
|
51
|
+
# a full parse?
|
27
52
|
if body =~ /<pre>/
|
28
53
|
info = body.scan(/<pre>(.*)<\/pre>/mi)[0]
|
29
54
|
elsif body =~ /'msg'=>/
|
@@ -38,11 +63,16 @@ module RSolr::Error
|
|
38
63
|
nil
|
39
64
|
end
|
40
65
|
end
|
41
|
-
|
42
|
-
|
43
66
|
end
|
44
67
|
|
45
68
|
class ConnectionRefused < ::Errno::ECONNREFUSED
|
69
|
+
include URICleanup
|
70
|
+
|
71
|
+
def initialize(request)
|
72
|
+
request[:uri] = clean_uri(request[:uri])
|
73
|
+
|
74
|
+
super(request.inspect)
|
75
|
+
end
|
46
76
|
end
|
47
77
|
|
48
78
|
class Http < RuntimeError
|
@@ -110,9 +140,16 @@ module RSolr::Error
|
|
110
140
|
}
|
111
141
|
|
112
142
|
def initialize request, response
|
143
|
+
response = response_with_force_encoded_body(response)
|
113
144
|
@request, @response = request, response
|
114
145
|
end
|
115
146
|
|
147
|
+
private
|
148
|
+
|
149
|
+
def response_with_force_encoded_body(response)
|
150
|
+
response[:body] = response[:body].force_encoding('UTF-8') if response
|
151
|
+
response
|
152
|
+
end
|
116
153
|
end
|
117
154
|
|
118
155
|
# Thrown if the :wt is :ruby
|
@@ -121,6 +158,15 @@ module RSolr::Error
|
|
121
158
|
|
122
159
|
end
|
123
160
|
|
161
|
+
# Subclasses Rsolr::Error::Http for legacy backwards compatibility
|
162
|
+
# purposes, because earlier RSolr 2 didn't distinguish these
|
163
|
+
# from Http errors.
|
164
|
+
#
|
165
|
+
# In RSolr 3, it could make sense to `< Timeout::Error` instead,
|
166
|
+
# analagous to ConnectionRefused above
|
167
|
+
class Timeout < Http
|
168
|
+
end
|
169
|
+
|
124
170
|
# Thrown if the :wt is :ruby
|
125
171
|
# but the body wasn't succesfully parsed/evaluated
|
126
172
|
class InvalidJsonResponse < InvalidResponse
|
data/lib/rsolr/version.rb
CHANGED
data/rsolr.gemspec
CHANGED
@@ -23,18 +23,17 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.email = ["goodieboy@gmail.com"]
|
24
24
|
s.license = 'Apache-2.0'
|
25
25
|
s.homepage = "https://github.com/rsolr/rsolr"
|
26
|
-
s.rubyforge_project = "rsolr"
|
27
26
|
s.files = `git ls-files`.split("\n")
|
28
27
|
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
29
28
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
30
29
|
s.require_paths = ["lib"]
|
31
|
-
|
30
|
+
|
32
31
|
s.required_ruby_version = '>= 1.9.3'
|
33
|
-
|
32
|
+
|
34
33
|
s.requirements << 'Apache Solr'
|
35
34
|
|
36
35
|
s.add_dependency 'builder', '>= 2.1.2'
|
37
|
-
s.add_dependency 'faraday', '>= 0.9.0'
|
36
|
+
s.add_dependency 'faraday', '>= 0.9', '!= 2.0.0', '< 3'
|
38
37
|
|
39
38
|
s.add_development_dependency 'activesupport'
|
40
39
|
s.add_development_dependency 'nokogiri', '>= 1.4.0'
|
data/spec/api/client_spec.rb
CHANGED
@@ -2,7 +2,8 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
RSpec.describe RSolr::Client do
|
4
4
|
let(:connection) { nil }
|
5
|
-
let(:
|
5
|
+
let(:url) { "http://localhost:9999/solr" }
|
6
|
+
let(:connection_options) { { url: url, update_format: :xml } }
|
6
7
|
|
7
8
|
let(:client) do
|
8
9
|
RSolr::Client.new connection, connection_options
|
@@ -41,6 +42,23 @@ RSpec.describe RSolr::Client do
|
|
41
42
|
client = RSolr::Client.new(:whatevs, { proxy: false })
|
42
43
|
expect(client.proxy).to eq(false)
|
43
44
|
end
|
45
|
+
|
46
|
+
context "with an non-HTTP url" do
|
47
|
+
let(:url) { "fake://localhost:9999/solr" }
|
48
|
+
|
49
|
+
it "raises an argument error" do
|
50
|
+
expect { client }.to raise_error ArgumentError, "You must provide an HTTP(S) url."
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "with an HTTPS url" do
|
55
|
+
let(:url) { "https://localhost:9999/solr" }
|
56
|
+
|
57
|
+
it "creates a connection" do
|
58
|
+
expect(client.uri).to be_kind_of URI::HTTPS
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
44
62
|
end
|
45
63
|
|
46
64
|
context "send_and_receive" do
|
@@ -53,6 +71,32 @@ RSpec.describe RSolr::Client do
|
|
53
71
|
end
|
54
72
|
end
|
55
73
|
|
74
|
+
context "execute" do
|
75
|
+
it "maps Faraday::TimeoutError to an RSolr::Error::Timeout" do
|
76
|
+
allow(client.connection).to receive(:send).and_raise(Faraday::TimeoutError)
|
77
|
+
|
78
|
+
expect{ client.execute({}) }.to raise_error RSolr::Error::Timeout
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'when an Errno::ECONNREFUSED error is raised' do
|
82
|
+
let(:uri) { URI.parse('http://admin:secret@hostname.local:8983/solr/admin/update?wt=json&q=test') }
|
83
|
+
|
84
|
+
before do
|
85
|
+
allow(client.connection).to receive(:send).and_raise(Errno::ECONNREFUSED)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "maps error to RSolr::Error:ConnectionRefused" do
|
89
|
+
expect { client.execute({ uri: uri }) }.to raise_error RSolr::Error::ConnectionRefused
|
90
|
+
end
|
91
|
+
|
92
|
+
it "removes credentials from uri" do
|
93
|
+
expect {
|
94
|
+
client.execute({ uri: uri })
|
95
|
+
}.to raise_error(RSolr::Error::ConnectionRefused, /http:\/\/REDACTED:REDACTED@hostname\.local:8983/)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
56
100
|
context "post" do
|
57
101
|
it "should pass the expected params to the connection's #execute method" do
|
58
102
|
request_opts = {:data => "the data", :method=>:post, :headers => {"Content-Type" => "text/plain"}}
|
@@ -91,7 +135,7 @@ RSpec.describe RSolr::Client do
|
|
91
135
|
|
92
136
|
context 'when the client is configured for json updates' do
|
93
137
|
let(:client) do
|
94
|
-
RSolr::Client.new nil, :url => "http://localhost:9999/solr", :
|
138
|
+
RSolr::Client.new nil, :url => "http://localhost:9999/solr", :update_format => :json
|
95
139
|
end
|
96
140
|
it "should send json to the connection's #post method" do
|
97
141
|
expect(client).to receive(:execute).
|
@@ -261,6 +305,48 @@ RSpec.describe RSolr::Client do
|
|
261
305
|
|
262
306
|
end
|
263
307
|
|
308
|
+
context "commit" do
|
309
|
+
it "should add hard commit params for hard commit request" do
|
310
|
+
expect(client).to receive(:execute).
|
311
|
+
with(
|
312
|
+
hash_including({
|
313
|
+
:path => "update",
|
314
|
+
:headers => {"Content-Type"=>"text/xml"},
|
315
|
+
:method => :post,
|
316
|
+
:data => "<?xml version=\"1.0\" encoding=\"UTF-8\"?><commit/>",
|
317
|
+
:params => {:wt=>:json},
|
318
|
+
:query => "wt=json"
|
319
|
+
})
|
320
|
+
).
|
321
|
+
and_return(
|
322
|
+
:body => "",
|
323
|
+
:status => 200,
|
324
|
+
:headers => {"Content-Type"=>"text/xml"}
|
325
|
+
)
|
326
|
+
client.commit
|
327
|
+
end
|
328
|
+
|
329
|
+
it "should add soft commit params for soft commit request" do
|
330
|
+
expect(client).to receive(:execute).
|
331
|
+
with(
|
332
|
+
hash_including({
|
333
|
+
:path => "update",
|
334
|
+
:headers => {"Content-Type"=>"text/xml"},
|
335
|
+
:method => :post,
|
336
|
+
:data => "<?xml version=\"1.0\" encoding=\"UTF-8\"?><commit/>",
|
337
|
+
:params => {:softCommit=>true, :wt=>:json},
|
338
|
+
:query => "wt=json&softCommit=true"
|
339
|
+
})
|
340
|
+
).
|
341
|
+
and_return(
|
342
|
+
:body => "",
|
343
|
+
:status => 200,
|
344
|
+
:headers => {"Content-Type"=>"text/xml"}
|
345
|
+
)
|
346
|
+
client.soft_commit
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
264
350
|
context "indifferent access" do
|
265
351
|
it "should raise a RuntimeError if the #with_indifferent_access extension isn't loaded" do
|
266
352
|
hide_const("::RSolr::HashWithIndifferentAccessWithResponse")
|
@@ -324,7 +410,7 @@ RSpec.describe RSolr::Client do
|
|
324
410
|
expect(subject[:headers]).to eq({"Content-Type" => "application/x-www-form-urlencoded; charset=UTF-8"})
|
325
411
|
end
|
326
412
|
end
|
327
|
-
|
413
|
+
|
328
414
|
it "should properly handle proxy configuration" do
|
329
415
|
result = client_with_proxy.build_request('select',
|
330
416
|
:method => :post,
|
data/spec/api/error_spec.rb
CHANGED
@@ -7,7 +7,7 @@ RSpec.describe RSolr::Error do
|
|
7
7
|
exception
|
8
8
|
end
|
9
9
|
let (:response_lines) { (1..15).to_a.map { |i| "line #{i}" } }
|
10
|
-
let(:request)
|
10
|
+
let(:request) { { uri: URI.parse('http://hostname.local:8983/solr/admin/update?wt=json&q=test') } }
|
11
11
|
let(:response_body) { response_lines.join("\n") }
|
12
12
|
let(:response) {{
|
13
13
|
:body => response_body,
|
@@ -43,5 +43,116 @@ RSpec.describe RSolr::Error do
|
|
43
43
|
let(:response_body) { (response_lines << "'error'=>{'msg'=> #{msg}").join("\n") }
|
44
44
|
it { should include msg }
|
45
45
|
end
|
46
|
+
|
47
|
+
context "when the response body is made of multi-byte chars and encoded by ASCII-8bit" do
|
48
|
+
let (:response_lines) { (1..15).to_a.map { |i| "レスポンス #{i}".b } }
|
49
|
+
|
50
|
+
it "encodes errorlogs by UTF-8" do
|
51
|
+
expect(subject.encoding.to_s).to eq 'UTF-8'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when response is JSON" do
|
57
|
+
let(:response) {{
|
58
|
+
:body => response_body,
|
59
|
+
:status => 500,
|
60
|
+
:headers => {
|
61
|
+
"content-type" => "application/json;charset=utf-8"
|
62
|
+
}
|
63
|
+
|
64
|
+
}}
|
65
|
+
|
66
|
+
context "and contains a msg key" do
|
67
|
+
let(:msg) { "field 'description_text4_tesim' was indexed without offsets, cannot highlight" }
|
68
|
+
let(:response_body) {<<~EOS
|
69
|
+
{
|
70
|
+
"responseHeader":{
|
71
|
+
"status":500,
|
72
|
+
"QTime":11,
|
73
|
+
"params":{
|
74
|
+
"q":"supercali",
|
75
|
+
"hl":"true",
|
76
|
+
"hl:fl":"description_text4_tesim",
|
77
|
+
"hl.method":"unified",
|
78
|
+
"hl.offsetSource":"postings"
|
79
|
+
}
|
80
|
+
},
|
81
|
+
"response":{"numFound":0,"start":0,"maxScore":127.32743,"numFoundExact":true,"docs":[]},
|
82
|
+
"facet_counts":{
|
83
|
+
"facet_queries":{},
|
84
|
+
"facet_fields":{}
|
85
|
+
},
|
86
|
+
"error":{
|
87
|
+
"msg":"#{msg}",
|
88
|
+
"trace":"java.lang.IllegalArgumentException: field 'description_text4_tesim' was indexed without offsets, cannot highlight\\n\\tat org.apache.lucene.search.uhighlight.FieldHighlighter.highlightOffsetsEnums(FieldHighlighter.java:149)\\n\\tat org.apache.lucene.search.uhighlight.FieldHighlighter.highlightFieldForDoc(FieldHighlighter.java:79)\\n\\tat org.apache.lucene.search.uhighlight.UnifiedHighlighter.highlightFieldsAsObjects(UnifiedHighlighter.java:641)\\n\\tat org.apache.lucene.search.uhighlight.UnifiedHighlighter.highlightFields(UnifiedHighlighter.java:510)\\n\\tat org.apache.solr.highlight.UnifiedSolrHighlighter.doHighlighting(UnifiedSolrHighlighter.java:149)\\n\\tat org.apache.solr.handler.component.HighlightComponent.process(HighlightComponent.java:172)\\n\\tat org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:331)\\n\\tat org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:214)\\n\\tat org.apache.solr.core.SolrCore.execute(SolrCore.java:2606)\\n\\tat org.apache.solr.servlet.HttpSolrCall.execute(HttpSolrCall.java:815)\\n\\tat org.apache.solr.servlet.HttpSolrCall.call(HttpSolrCall.java:588)\\n\\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:415)\\n\\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:345)\\n\\tat org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1596)\\n\\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:545)\\n\\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)\\n\\tat org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:590)\\n\\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)\\n\\tat org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)\\n\\tat org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1610)\\n\\tat org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)\\n\\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1300)\\n\\tat org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)\\n\\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:485)\\n\\tat org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1580)\\n\\tat org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)\\n\\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1215)\\n\\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)\\n\\tat org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:221)\\n\\tat org.eclipse.jetty.server.handler.InetAccessHandler.handle(InetAccessHandler.java:177)\\n\\tat org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)\\n\\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)\\n\\tat org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:322)\\n\\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)\\n\\tat org.eclipse.jetty.server.Server.handle(Server.java:500)\\n\\tat org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:383)\\n\\tat org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:547)\\n\\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:375)\\n\\tat org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:273)\\n\\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)\\n\\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)\\n\\tat org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)\\n\\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)\\n\\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)\\n\\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)\\n\\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)\\n\\tat org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:375)\\n\\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:806)\\n\\tat org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:938)\\n\\tat java.base/java.lang.Thread.run(Thread.java:834)\\n",
|
89
|
+
"code":500
|
90
|
+
}
|
91
|
+
}
|
92
|
+
EOS
|
93
|
+
}
|
94
|
+
it {
|
95
|
+
should include msg
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
context "and does not contain a msg key" do
|
100
|
+
let(:response_body) {<<~EOS
|
101
|
+
{
|
102
|
+
"responseHeader":{
|
103
|
+
"status":500,
|
104
|
+
"QTime":11,
|
105
|
+
"params":{
|
106
|
+
"q":"supercali",
|
107
|
+
"hl":"true",
|
108
|
+
"hl:fl":"description_text4_tesim",
|
109
|
+
"hl.method":"unified",
|
110
|
+
"hl.offsetSource":"postings"
|
111
|
+
}
|
112
|
+
},
|
113
|
+
"response":{"numFound":0,"start":0,"maxScore":127.32743,"numFoundExact":true,"docs":[]},
|
114
|
+
"facet_counts":{
|
115
|
+
"facet_queries":{},
|
116
|
+
"facet_fields":{}
|
117
|
+
},
|
118
|
+
}
|
119
|
+
EOS
|
120
|
+
}
|
121
|
+
it "shows the first eleven lines of the response" do
|
122
|
+
expect(subject).to include(response_body.split("\n")[0..10].join("\n"))
|
123
|
+
expect(subject).not_to include(response_body.split("\n")[11])
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context "and is not parseable json" do
|
128
|
+
let(:response_body) {<<~EOS
|
129
|
+
one
|
130
|
+
two
|
131
|
+
three
|
132
|
+
four
|
133
|
+
five
|
134
|
+
six
|
135
|
+
seven
|
136
|
+
eight
|
137
|
+
nine
|
138
|
+
ten
|
139
|
+
eleven
|
140
|
+
twelve
|
141
|
+
EOS
|
142
|
+
}
|
143
|
+
end
|
144
|
+
it "shows the first eleven lines of the response" do
|
145
|
+
expect(subject).to include(response_body.split("\n")[0..10].join("\n"))
|
146
|
+
expect(subject).not_to include(response_body.split("\n")[11])
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context "when request uri contains credentials" do
|
151
|
+
let(:request) { { uri: URI.parse('http://admin:admin@hostname.local:8983/solr/admin/update?wt=json&q=test') } }
|
152
|
+
|
153
|
+
|
154
|
+
it 'includes redacted url' do
|
155
|
+
expect(subject).to include 'http://REDACTED:REDACTED@hostname.local:8983/solr/admin/update?wt=json&q=test'
|
156
|
+
end
|
46
157
|
end
|
47
158
|
end
|
data/spec/api/json_spec.rb
CHANGED
@@ -149,6 +149,65 @@ RSpec.describe RSolr::JSON do
|
|
149
149
|
expect(message.first).to eq data
|
150
150
|
end
|
151
151
|
|
152
|
+
it 'should create multiple fields from array values with options' do
|
153
|
+
test_values = [nil, 'matt1', 'matt2']
|
154
|
+
message = JSON.parse(
|
155
|
+
generator.add(id: '1') { |doc| doc.add_field(:name, test_values, boost: 3) },
|
156
|
+
symbolize_names: true
|
157
|
+
)
|
158
|
+
expect(message).to eq [{ id: '1', name: { boost: 3, value: test_values } }]
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'for atomic updates with arrays' do
|
162
|
+
let(:test_values) { %w[value1 value2] }
|
163
|
+
|
164
|
+
it 'creates single field from array values on SET' do
|
165
|
+
expect(
|
166
|
+
JSON.parse(
|
167
|
+
generator.add(id: 'set-id') { |doc| doc.add_field(:name, test_values, update: :set) },
|
168
|
+
symbolize_names: true
|
169
|
+
)
|
170
|
+
).to eq [{ id: 'set-id', name: { set: test_values } }]
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'creates single field from array values on ADD' do
|
174
|
+
expect(
|
175
|
+
JSON.parse(
|
176
|
+
generator.add(id: 'add-id') { |doc| doc.add_field(:name, test_values, update: :add) },
|
177
|
+
symbolize_names: true
|
178
|
+
)
|
179
|
+
).to eq [{ id: 'add-id', name: { add: test_values } }]
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'creates single field from array values on ADD-DISTINCT' do
|
183
|
+
expect(
|
184
|
+
JSON.parse(
|
185
|
+
generator.add(id: 'add-distinct-id') { |doc| doc.add_field(:name, test_values, update: :'add-distinct') },
|
186
|
+
symbolize_names: true
|
187
|
+
)
|
188
|
+
).to eq [{ id: 'add-distinct-id', name: { 'add-distinct': test_values } }]
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'creates single field from array values on REMOVE' do
|
192
|
+
expect(
|
193
|
+
JSON.parse(
|
194
|
+
generator.add(id: 'remove-id') { |doc| doc.add_field(:name, test_values, update: :remove) },
|
195
|
+
symbolize_names: true
|
196
|
+
)
|
197
|
+
).to eq [{ id: 'remove-id', name: { remove: test_values } }]
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'creates single field from array values for child document update' do
|
201
|
+
test_nested_values = [{id: 1, name: 'value1'}, {id: 1, name: 'value2'}]
|
202
|
+
expect(
|
203
|
+
JSON.parse(
|
204
|
+
generator.add(id: 'set-id') { |doc| doc.add_field(:child_documents, test_nested_values, update: :set) },
|
205
|
+
symbolize_names: true
|
206
|
+
)
|
207
|
+
).to eq [{ id: 'set-id', child_documents: { set: test_nested_values } }]
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
152
211
|
describe '#commit' do
|
153
212
|
it 'generates a commit command' do
|
154
213
|
expect(JSON.parse(generator.commit, symbolize_names: true)).to eq(commit: {})
|
@@ -2,6 +2,10 @@ require 'spec_helper'
|
|
2
2
|
require 'solr_wrapper'
|
3
3
|
|
4
4
|
RSpec.describe "Solr basic_configs" do
|
5
|
+
SolrWrapper.default_instance_options = {
|
6
|
+
port: SolrWrapper.default_solr_port,
|
7
|
+
version: '8.11.3'
|
8
|
+
}
|
5
9
|
SOLR_INSTANCE = SolrWrapper.default_instance({})
|
6
10
|
before(:all) { SOLR_INSTANCE.start }
|
7
11
|
after(:all) { SOLR_INSTANCE.stop }
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RSolr::Client do
|
4
|
+
describe "#connection" do
|
5
|
+
it "accepts a timeout parameter it passes to Faraday" do
|
6
|
+
client = described_class.new(nil, timeout: 1000)
|
7
|
+
|
8
|
+
expect(client.connection.options[:timeout]).to eq 1000
|
9
|
+
end
|
10
|
+
it "accepts a deprecated read_timeout" do
|
11
|
+
client = nil
|
12
|
+
expect do
|
13
|
+
client = described_class.new(nil, read_timeout: 1000)
|
14
|
+
end.to output(/`read_timeout` is deprecated/).to_stderr
|
15
|
+
|
16
|
+
expect(client.connection.options[:timeout]).to eq 1000
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rsolr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Antoine Latter
|
@@ -26,10 +26,10 @@ authors:
|
|
26
26
|
- Nathan Witmer
|
27
27
|
- Naomi Dushay
|
28
28
|
- '"shima"'
|
29
|
-
autorequire:
|
29
|
+
autorequire:
|
30
30
|
bindir: bin
|
31
31
|
cert_chain: []
|
32
|
-
date:
|
32
|
+
date: 2024-03-25 00:00:00.000000000 Z
|
33
33
|
dependencies:
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: builder
|
@@ -51,14 +51,26 @@ dependencies:
|
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.9
|
54
|
+
version: '0.9'
|
55
|
+
- - "!="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 2.0.0
|
58
|
+
- - "<"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '3'
|
55
61
|
type: :runtime
|
56
62
|
prerelease: false
|
57
63
|
version_requirements: !ruby/object:Gem::Requirement
|
58
64
|
requirements:
|
59
65
|
- - ">="
|
60
66
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.9
|
67
|
+
version: '0.9'
|
68
|
+
- - "!="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 2.0.0
|
71
|
+
- - "<"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '3'
|
62
74
|
- !ruby/object:Gem::Dependency
|
63
75
|
name: activesupport
|
64
76
|
requirement: !ruby/object:Gem::Requirement
|
@@ -165,9 +177,9 @@ executables: []
|
|
165
177
|
extensions: []
|
166
178
|
extra_rdoc_files: []
|
167
179
|
files:
|
180
|
+
- ".github/workflows/ruby.yml"
|
168
181
|
- ".gitignore"
|
169
182
|
- ".rspec"
|
170
|
-
- ".travis.yml"
|
171
183
|
- CHANGES.txt
|
172
184
|
- Gemfile
|
173
185
|
- LICENSE
|
@@ -203,12 +215,13 @@ files:
|
|
203
215
|
- spec/fixtures/basic_configs/stopwords.txt
|
204
216
|
- spec/fixtures/basic_configs/synonyms.txt
|
205
217
|
- spec/integration/solr5_spec.rb
|
218
|
+
- spec/lib/rsolr/client_spec.rb
|
206
219
|
- spec/spec_helper.rb
|
207
220
|
homepage: https://github.com/rsolr/rsolr
|
208
221
|
licenses:
|
209
222
|
- Apache-2.0
|
210
223
|
metadata: {}
|
211
|
-
post_install_message:
|
224
|
+
post_install_message:
|
212
225
|
rdoc_options: []
|
213
226
|
require_paths:
|
214
227
|
- lib
|
@@ -224,9 +237,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
224
237
|
version: '0'
|
225
238
|
requirements:
|
226
239
|
- Apache Solr
|
227
|
-
|
228
|
-
|
229
|
-
signing_key:
|
240
|
+
rubygems_version: 3.4.10
|
241
|
+
signing_key:
|
230
242
|
specification_version: 4
|
231
243
|
summary: A Ruby client for Apache Solr
|
232
244
|
test_files: []
|