solrb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +69 -0
  3. data/.circleci/run-with-local-config.sh +7 -0
  4. data/.gitignore +11 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +30 -0
  7. data/.ruby-version +1 -0
  8. data/Gemfile +6 -0
  9. data/Gemfile.lock +83 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +259 -0
  12. data/Rakefile +6 -0
  13. data/bin/console +14 -0
  14. data/bin/setup +8 -0
  15. data/lib/solr/commit/request.rb +15 -0
  16. data/lib/solr/configuration.rb +66 -0
  17. data/lib/solr/connection.rb +33 -0
  18. data/lib/solr/core_configuration/core_config.rb +44 -0
  19. data/lib/solr/core_configuration/core_config_builder.rb +51 -0
  20. data/lib/solr/core_configuration/dynamic_field.rb +17 -0
  21. data/lib/solr/core_configuration/field.rb +20 -0
  22. data/lib/solr/delete/request.rb +34 -0
  23. data/lib/solr/document.rb +26 -0
  24. data/lib/solr/document_collection.rb +55 -0
  25. data/lib/solr/errors/ambiguous_core_error.rb +9 -0
  26. data/lib/solr/errors/solr_query_error.rb +4 -0
  27. data/lib/solr/errors/solr_url_not_defined_error.rb +16 -0
  28. data/lib/solr/grouped_document_collection.rb +38 -0
  29. data/lib/solr/indexing/document.rb +25 -0
  30. data/lib/solr/indexing/request.rb +22 -0
  31. data/lib/solr/query/request/boost_magnitude.rb +9 -0
  32. data/lib/solr/query/request/boosting/dictionary_boost_function.rb +36 -0
  33. data/lib/solr/query/request/boosting/exists_boost_function.rb +27 -0
  34. data/lib/solr/query/request/boosting/field_value_less_than_boost_function.rb +25 -0
  35. data/lib/solr/query/request/boosting/field_value_match_boost_function.rb +24 -0
  36. data/lib/solr/query/request/boosting/geodist_function.rb +37 -0
  37. data/lib/solr/query/request/boosting/ln_function_boost.rb +28 -0
  38. data/lib/solr/query/request/boosting/numeric_field_value_match_boost_function.rb +13 -0
  39. data/lib/solr/query/request/boosting/phrase_proximity_boost.rb +27 -0
  40. data/lib/solr/query/request/boosting/ranking_field_boost_function.rb +20 -0
  41. data/lib/solr/query/request/boosting/recent_field_value_boost_function.rb +26 -0
  42. data/lib/solr/query/request/boosting/scale_function_boost.rb +28 -0
  43. data/lib/solr/query/request/boosting/textual_field_value_match_boost_function.rb +13 -0
  44. data/lib/solr/query/request/boosting.rb +46 -0
  45. data/lib/solr/query/request/edismax_adapter.rb +163 -0
  46. data/lib/solr/query/request/facet.rb +68 -0
  47. data/lib/solr/query/request/field_with_boost.rb +18 -0
  48. data/lib/solr/query/request/filter.rb +73 -0
  49. data/lib/solr/query/request/geo_filter.rb +26 -0
  50. data/lib/solr/query/request/grouping.rb +37 -0
  51. data/lib/solr/query/request/or_filter.rb +16 -0
  52. data/lib/solr/query/request/runner.rb +46 -0
  53. data/lib/solr/query/request/sorting/field.rb +16 -0
  54. data/lib/solr/query/request/sorting.rb +34 -0
  55. data/lib/solr/query/request/spellcheck.rb +74 -0
  56. data/lib/solr/query/request.rb +49 -0
  57. data/lib/solr/query/response/facet_value.rb +16 -0
  58. data/lib/solr/query/response/field_facets.rb +25 -0
  59. data/lib/solr/query/response/parser.rb +154 -0
  60. data/lib/solr/query/response/spellcheck.rb +42 -0
  61. data/lib/solr/query/response.rb +48 -0
  62. data/lib/solr/response/header.rb +25 -0
  63. data/lib/solr/response/http_status.rb +27 -0
  64. data/lib/solr/response/parser.rb +47 -0
  65. data/lib/solr/response/solr_error.rb +31 -0
  66. data/lib/solr/response.rb +52 -0
  67. data/lib/solr/support/connection_helper.rb +12 -0
  68. data/lib/solr/support/hash_extensions.rb +29 -0
  69. data/lib/solr/support/schema_helper.rb +11 -0
  70. data/lib/solr/support/string_extensions.rb +12 -0
  71. data/lib/solr/support/url_helper.rb +12 -0
  72. data/lib/solr/support.rb +5 -0
  73. data/lib/solr/testing.rb +19 -0
  74. data/lib/solr/version.rb +3 -0
  75. data/lib/solr.rb +65 -0
  76. data/solrb.gemspec +36 -0
  77. metadata +261 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e90b9041817aa81077a2d05c9be0105682dedac1bb681d7cdd0802e2dd82e829
4
+ data.tar.gz: ac2d9553669c73c72e57bbba5636cd325c31141c859463dbf88908e0e0f070c6
5
+ SHA512:
6
+ metadata.gz: 154b62204ff427c13b7eedf8cf0dbe18d18d73093402f6a74a0f292e4f226929bce30a874d7586e50beff08b1b74c792f2702f9f277351e825a80d9367c1af18
7
+ data.tar.gz: 1bfd971cb1973195288dec35d37911fceb98fc4ef4a76123a9e09261b97d7e8c9ead7ec851074ce3df9698421423298ea00aed3d38bee0b3eb78e6ae575b34e9
@@ -0,0 +1,69 @@
1
+ # Ruby CircleCI 2.0 configuration file
2
+ #
3
+ # Check https://circleci.com/docs/2.0/language-ruby/ for more details
4
+ #
5
+ version: 2
6
+ jobs:
7
+ build:
8
+ docker:
9
+ # primary image where all specs are run
10
+ - image: circleci/ruby:2.5.1-node-browsers
11
+ environment:
12
+ SOLR_URL: http://localhost:8983/solr/test-core
13
+ # service images that primary image will use
14
+ - image: solr:7.4.0
15
+
16
+ working_directory: ~/repo
17
+
18
+ steps:
19
+ - checkout
20
+
21
+ # Download and cache dependencies
22
+ - restore_cache:
23
+ keys:
24
+ - v1-dependencies-{{ checksum "Gemfile.lock" }}
25
+ # fallback to using the latest cache if no exact match is found
26
+ - v1-dependencies-
27
+
28
+ - run:
29
+ name: install dependencies
30
+ command: |
31
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
32
+
33
+ - save_cache:
34
+ paths:
35
+ - ./vendor/bundle
36
+ key: v1-dependencies-{{ checksum "Gemfile.lock" }}
37
+
38
+ - run:
39
+ name: Wait for Solr
40
+ command: dockerize -wait tcp://localhost:8983 -timeout 1m
41
+
42
+ - run:
43
+ name: Create a test core
44
+ command: curl 'http://localhost:8983/solr/admin/cores?action=CREATE&name=test-core&configSet=_default'
45
+
46
+ - run:
47
+ name: Disable field type guessing
48
+ command: |
49
+ curl http://localhost:8983/solr/test-core/config -d '{"set-user-property": {"update.autoCreateFields":"false"}}'
50
+
51
+
52
+ - run:
53
+ name: run tests
54
+ command: |
55
+ mkdir /tmp/test-results
56
+ TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
57
+
58
+ bundle exec rspec --format progress \
59
+ --format RspecJunitFormatter \
60
+ --out /tmp/test-results/rspec.xml \
61
+ --format progress \
62
+ $TEST_FILES
63
+
64
+ # collect reports
65
+ - store_test_results:
66
+ path: /tmp/test-results
67
+ - store_artifacts:
68
+ path: /tmp/test-results
69
+ destination: test-results
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bash
2
+ curl --user ${CIRCLE_TOKEN}: \
3
+ --request POST \
4
+ --form revision=67d7c5937163 \
5
+ --form config=@config.yml \
6
+ --form notify=false \
7
+ https://circleci.com/api/v1.1/project/github/machinio/solrb/tree/master
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,30 @@
1
+ AllCops:
2
+ Exclude:
3
+ - db/schema.rb
4
+ - node_modules/**/*
5
+ - bin/*
6
+ TargetRubyVersion: '2.5'
7
+ Metrics/LineLength:
8
+ Max: 120
9
+ Documentation:
10
+ Enabled: false
11
+ FrozenStringLiteralComment:
12
+ Enabled: false
13
+ Metrics/MethodLength:
14
+ Max: 20
15
+ Metrics/AbcSize:
16
+ Max: 20
17
+ # Removing Blocks Cop for RSpec
18
+ Style/BlockDelimiters:
19
+ Exclude:
20
+ - 'spec/**/*'
21
+ # Removing Indentation Cop for RSpec
22
+ Layout/MultilineMethodCallIndentation:
23
+ Exclude:
24
+ - 'spec/**/*'
25
+ Metrics/BlockLength:
26
+ Exclude:
27
+ - 'Rakefile'
28
+ - '**/*.rake'
29
+ - 'spec/**/*'
30
+ - 'config/environments/**/*'
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.5.1
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in solr.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,83 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ solrb (0.1.0)
5
+ addressable
6
+ faraday
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ addressable (2.5.2)
12
+ public_suffix (>= 2.0.2, < 4.0)
13
+ ast (2.4.0)
14
+ byebug (10.0.2)
15
+ coderay (1.1.2)
16
+ diff-lcs (1.3)
17
+ docile (1.3.1)
18
+ faraday (0.15.2)
19
+ multipart-post (>= 1.2, < 3)
20
+ jaro_winkler (1.5.1)
21
+ json (2.1.0)
22
+ method_source (0.9.0)
23
+ multipart-post (2.0.0)
24
+ parallel (1.12.1)
25
+ parser (2.5.1.2)
26
+ ast (~> 2.4.0)
27
+ powerpack (0.1.2)
28
+ pry (0.11.3)
29
+ coderay (~> 1.1.0)
30
+ method_source (~> 0.9.0)
31
+ pry-byebug (3.6.0)
32
+ byebug (~> 10.0)
33
+ pry (~> 0.10)
34
+ public_suffix (3.0.2)
35
+ rainbow (3.0.0)
36
+ rake (10.5.0)
37
+ rspec (3.8.0)
38
+ rspec-core (~> 3.8.0)
39
+ rspec-expectations (~> 3.8.0)
40
+ rspec-mocks (~> 3.8.0)
41
+ rspec-core (3.8.0)
42
+ rspec-support (~> 3.8.0)
43
+ rspec-expectations (3.8.0)
44
+ diff-lcs (>= 1.2.0, < 2.0)
45
+ rspec-support (~> 3.8.0)
46
+ rspec-mocks (3.8.0)
47
+ diff-lcs (>= 1.2.0, < 2.0)
48
+ rspec-support (~> 3.8.0)
49
+ rspec-support (3.8.0)
50
+ rspec_junit_formatter (0.4.1)
51
+ rspec-core (>= 2, < 4, != 2.12.0)
52
+ rubocop (0.58.2)
53
+ jaro_winkler (~> 1.5.1)
54
+ parallel (~> 1.10)
55
+ parser (>= 2.5, != 2.5.1.1)
56
+ powerpack (~> 0.1)
57
+ rainbow (>= 2.2.2, < 4.0)
58
+ ruby-progressbar (~> 1.7)
59
+ unicode-display_width (~> 1.0, >= 1.0.1)
60
+ ruby-progressbar (1.10.0)
61
+ simplecov (0.16.1)
62
+ docile (~> 1.1)
63
+ json (>= 1.8, < 3)
64
+ simplecov-html (~> 0.10.0)
65
+ simplecov-html (0.10.2)
66
+ unicode-display_width (1.4.0)
67
+
68
+ PLATFORMS
69
+ ruby
70
+
71
+ DEPENDENCIES
72
+ bundler (~> 1.16)
73
+ pry
74
+ pry-byebug
75
+ rake (~> 10.0)
76
+ rspec (~> 3.0)
77
+ rspec_junit_formatter
78
+ rubocop
79
+ simplecov
80
+ solrb!
81
+
82
+ BUNDLED WITH
83
+ 1.16.3
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Adriano Luz, Valentin Vasilyev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,259 @@
1
+ [![CircleCI](https://circleci.com/gh/machinio/solrb/tree/master.svg?style=svg)](https://circleci.com/gh/machinio/solrb/tree/master)
2
+ [![Maintainability](https://api.codeclimate.com/v1/badges/81e84c1c42f10f9da801/maintainability)](https://codeclimate.com/github/machinio/solrb/maintainability)
3
+
4
+ # Solrb [WIP]
5
+
6
+ Object-Oriented approach to Solr in Ruby.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'solrb', require: 'solr'
14
+ ```
15
+
16
+ ## Configuration
17
+
18
+ The simplest way to use Solrb is `SORL_URL` environment variable (that has a core name in it):
19
+
20
+ ```bash
21
+ ENV['SOLR_URL'] = 'http://localhost:8983/solr/demo'
22
+ ```
23
+
24
+ or through `Solr.configure` to specify the solr URL:
25
+
26
+ ```ruby
27
+ # Single core configuration
28
+ Solr.configure do |config|
29
+ config.url = 'http://localhost:8983/solr/demo'
30
+ end
31
+ ```
32
+
33
+ Use `Solr.configure` for an additional configuration:
34
+
35
+ ```ruby
36
+ # Single core configuration
37
+ Solr.configure do |config|
38
+ config.url = 'http://localhost:8983/solr/demo'
39
+
40
+ # This gem uses faraday to make requests to Solr. You can specify additional faraday
41
+ # options here.
42
+ config.faraday_options = {}
43
+
44
+ # Core's URL is 'http://localhost:8983/solr/demo'
45
+ # Adding fields to work with
46
+ config.define_core do |f|
47
+ f.field :title, dynamic_field: :text
48
+ f.dynamic_field :text, solr_name: '*_text'
49
+ end
50
+ end
51
+ ```
52
+
53
+ ```ruby
54
+ # Multiple core configuration
55
+ Solr.configure do |config|
56
+ config.url = 'http://localhost:8983/solr'
57
+
58
+ # Define a core with fields that will be used with Solr.
59
+ # Core URL is 'http://localhost:8983/solr/listings'
60
+ config.define_core(name: :listings) do |f|
61
+ # When a dynamic_field is present, the field name will be mapped to match the dynamic field.
62
+ # Here, "title" will be mapped to "title_text"
63
+ # You must define a dynamic field to be able to use the dynamic_field option
64
+ f.field :title, dynamic_field: :text
65
+
66
+ # When solr_name is present, the field name will be mapped to the solr_name at runtime
67
+ f.field :tags, solr_name: :tags_array
68
+
69
+ # define a dynamic field
70
+ f.dynamic_field :text, solr_name: '*_text'
71
+ end
72
+
73
+ # Pass `default: true` to use one core as a default.
74
+ # Core's URL is 'http://localhost:8983/solr/cars'
75
+ config.define_core(name: :cars, default: true) do |f|
76
+ f.field :manufacturer, solr_name: :manuf_s
77
+ f.field :model, solr_name: :model_s
78
+ end
79
+ end
80
+ ```
81
+
82
+ It's important to note that those fields that are not configured, will be passed as-is to solr.
83
+ *So you only need to specify fields in configuration if you want Solrb to modify them at runtime*.
84
+
85
+
86
+ Warning: Solrb doesn't support fields with the same name. If you have two fields with the same name mapping
87
+ to a single solr field, you'll have to rename one of the fields.
88
+
89
+ ```ruby
90
+ ...
91
+ config.define_core do |f|
92
+ ...
93
+ # Not allowed: Two fields with same name 'title'
94
+ f.field :title, solr_name: :article_title
95
+ f.field :title, solr_name: :page_title
96
+ end
97
+ ...
98
+ ```
99
+
100
+ ## Usage
101
+
102
+ ### Indexing
103
+
104
+ ```ruby
105
+ # creates a single document and commits it to index
106
+ doc = Solr::Indexing::Document.new
107
+ doc.add_field(:id, 1)
108
+ doc.add_field(:name, 'Solrb!!!')
109
+
110
+ request = Solr::Indexing::Request.new(documents: [doc])
111
+ request.run(commit: true)
112
+ ```
113
+
114
+ You can also create indexing document directly from attributes:
115
+
116
+ ```ruby
117
+ doc = Solr::Indexing::Document.new(id: 5, name: 'John')
118
+ ```
119
+
120
+ ### Querying
121
+
122
+ #### Simple Query
123
+
124
+ ```ruby
125
+ field = Solr::Query::Request::FieldWithBoost.new(field: :name)
126
+
127
+ request = Solr::Query::Request.new(search_term: 'term', fields: [field])
128
+ request.run(page: 1, page_size: 10)
129
+ ```
130
+
131
+ #### Query with field boost
132
+
133
+ ```ruby
134
+ fields = [
135
+ # Use boost_magnitude argument to apply boost to a specific field that you query
136
+ Solr::Query::Request::FieldWithBoost.new(field: :name, boost_magnitude: 16),
137
+ Solr::Query::Request::FieldWithBoost.new(field: :title)
138
+ ]
139
+ request = Solr::Query::Request.new(search_term: 'term', fields: fields)
140
+ request.run(page: 1, page_size: 10)
141
+ ```
142
+
143
+ #### Query with filters
144
+
145
+ ```ruby
146
+ fields = [
147
+ Solr::Query::Request::FieldWithBoost.new(field: :name),
148
+ Solr::Query::Request::FieldWithBoost.new(field: :title)
149
+ ]
150
+ filters = [Solr::Query::Request::Filter.new(type: :equal, field: :title, value: 'A title')]
151
+ request = Solr::Query::Request.new(search_term: 'term', fields: fields, filters: filters)
152
+ request.run(page: 1, page_size: 10)
153
+ ```
154
+
155
+
156
+ #### Query with sorting
157
+
158
+ ```ruby
159
+ fields = [
160
+ Solr::Query::Request::FieldWithBoost.new(field: :name),
161
+ Solr::Query::Request::FieldWithBoost.new(field: :title)
162
+ ]
163
+ sort_fields = [Solr::Query::Request::Sorting::Field.new(name: :name, direction: :asc)]
164
+ request = Solr::Query::Request.new(search_term: 'term', fields: fields)
165
+ request.sorting = Solr::Query::Request::Sorting.new(fields: sort_fields)
166
+ request.run(page: 1, page_size: 10)
167
+ ```
168
+
169
+ #### Query with grouping
170
+
171
+ ```ruby
172
+ fields = [
173
+ Solr::Query::Request::FieldWithBoost.new(field: :name),
174
+ Solr::Query::Request::FieldWithBoost.new(field: :category)
175
+ ]
176
+ request = Solr::Query::Request.new(search_term: 'term', fields: fields)
177
+ request.grouping = Solr::Query::Request::Grouping.new(field: :category, limit: 10)
178
+ request.run(page: 1, page_size: 10)
179
+ ```
180
+
181
+ #### Query with facets
182
+
183
+ ```ruby
184
+ fields = [
185
+ Solr::Query::Request::FieldWithBoost.new(field: :name),
186
+ Solr::Query::Request::FieldWithBoost.new(field: :category)
187
+ ]
188
+ request = Solr::Query::Request.new(search_term: 'term', fields: fields)
189
+ request.facets = [Solr::Query::Request::Facet.new(type: :terms, field: :category, options: { limit: 10 })]
190
+ request.run(page: 1, page_size: 10)
191
+ ```
192
+
193
+ #### Query with boosting functions
194
+
195
+ ```ruby
196
+ fields = [
197
+ Solr::Query::Request::FieldWithBoost.new(field: :name),
198
+ Solr::Query::Request::FieldWithBoost.new(field: :category)
199
+ ]
200
+ request = Solr::Query::Request.new(search_term: 'term', fields: fields)
201
+ request.boosting = Solr::Query::Request::Boosting.new(
202
+ multiplicative_boost_functions: [Solr::Query::Request::Boosting::RankingFieldBoostFunction.new(field: :name)],
203
+ phrase_boosts: [Solr::Query::Request::Boosting::PhraseProximityBoost.new(field: :category, boost_magnitude: 4)]
204
+ )
205
+ request.run(page: 1, page_size: 10)
206
+ ```
207
+
208
+ #### Field list
209
+
210
+
211
+ ```ruby
212
+ fields = [
213
+ Solr::Query::Request::FieldWithBoost.new(field: :name),
214
+ Solr::Query::Request::FieldWithBoost.new(field: :category)
215
+ ]
216
+ request = Solr::Query::Request.new(search_term: 'term', fields: fields)
217
+ # Solr::Query::Request will return only :id field by default.
218
+ # Specify additional return fields (fl param) by setting the request response_fields
219
+ request.response_fields = [:name, :category]
220
+ request.run(page: 1, page_size: 10)
221
+ ```
222
+
223
+ ### Deleting documents
224
+
225
+ ```ruby
226
+ Solr.delete_by_id(3242343)
227
+ Solr.delete_by_id(3242343, commit: true)
228
+ Solr.delete_by_query('*:*')
229
+ Solr.delete_by_query('*:*', commit: true)
230
+ ```
231
+
232
+ ### Using multi-core configuration
233
+
234
+ For multi-core configuration use `Solr.with_core` block:
235
+
236
+ ```ruby
237
+ Solr.with_core(:models) do
238
+ Solr.delete_by_id(3242343)
239
+ Solr::Query::Request.new(search_term: 'term', fields: fields)
240
+ Solr::Indexing::Request.new(documents: [doc])
241
+ end
242
+ ```
243
+
244
+ ## Running specs
245
+
246
+ This project is setup to use CI to run all specs agains a real solr.
247
+
248
+ If you want to run it locally, you can either use [CircleCI CLI](https://circleci.com/docs/2.0/local-cli/)
249
+ or do a completely manual setup (for up-to-date steps see circleci config)
250
+
251
+ ```sh
252
+ docker pull solr:7.4.0
253
+ docker run -it --name test-solr -p 8983:8983/tcp -t solr:7.4.0
254
+ # create a core
255
+ curl 'http://localhost:8983/solr/admin/cores?action=CREATE&name=test-core&configSet=_default'
256
+ # disable field guessing
257
+ curl http://localhost:8983/solr/test-core/config -d '{"set-user-property": {"update.autoCreateFields":"false"}}'
258
+ SOLR_URL=http://localhost:8983/solr/test-core rspec
259
+ ```
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "solr"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,15 @@
1
+ module Solr
2
+ module Commit
3
+ class Request
4
+ include Solr::Support::ConnectionHelper
5
+ PATH = '/update'.freeze
6
+
7
+ def run
8
+ # the way to do commit message in SOLR is to send an empty
9
+ # request with ?commit=true in the URL.
10
+ raw_response = connection(PATH, commit: true).post
11
+ Solr::Response.from_raw_response(raw_response)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,66 @@
1
+ require 'solr/core_configuration/dynamic_field'
2
+ require 'solr/core_configuration/field'
3
+ require 'solr/core_configuration/core_config'
4
+ require 'solr/core_configuration/core_config_builder'
5
+ require 'solr/errors/solr_url_not_defined_error'
6
+ require 'solr/errors/ambiguous_core_error'
7
+
8
+ module Solr
9
+ class Configuration
10
+ attr_accessor :faraday_options, :cores, :test_connection
11
+ attr_reader :url
12
+
13
+ def initialize
14
+ @faraday_options = {
15
+ request: { timeout: 2, open_timeout: 8 },
16
+ headers: { user_agent: "Solrb v#{Solr::VERSION}" }
17
+ }
18
+ @cores = {}
19
+ end
20
+
21
+ def url=(value)
22
+ if value.nil?
23
+ raise ArgumentError, "Solr's URL can't be nil"
24
+ else
25
+ @url = value
26
+ end
27
+ end
28
+
29
+ def core_config_by_name(core)
30
+ cores[core.to_sym] || build_env_url_core_config(name: core)
31
+ end
32
+
33
+ def default_core_config
34
+ defined_default_core_config = cores.values.detect(&:default?)
35
+ return defined_default_core_config if defined_default_core_config
36
+ raise Errors::AmbiguousCoreError if cores.count > 1
37
+ cores.values.first || build_env_url_core_config
38
+ end
39
+
40
+ def define_core(name: nil, default: false)
41
+ validate_default_core_config!(default: default)
42
+ builder = Solr::CoreConfiguration::CoreConfigBuilder.new(
43
+ name: name,
44
+ default: default
45
+ )
46
+ yield builder
47
+ core = builder.build
48
+ if cores.has_key?(core.name)
49
+ raise "A core with name '#{core.name}' has been already defined"
50
+ else
51
+ cores[core.name] = core
52
+ end
53
+ end
54
+
55
+ def build_env_url_core_config(name: nil)
56
+ Solr::CoreConfiguration::EnvUrlCoreConfig.new(name: name)
57
+ end
58
+
59
+ def validate_default_core_config!(default:)
60
+ return unless default
61
+ if cores.any? { |name, core_config| core_config.default? }
62
+ raise ArgumentError, 'Only one default core can be specified'
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,33 @@
1
+ module Solr
2
+ # low-level connection that can do network requests to Solr
3
+ class Connection
4
+ INSTRUMENT_KEY = 'solrb.request'.freeze
5
+
6
+ def initialize(url, faraday_options: Solr.configuration.faraday_options)
7
+ # Allow mock the connection for testing
8
+ @raw_connection = Solr.configuration.test_connection || Faraday.new(url, faraday_options)
9
+ freeze
10
+ end
11
+
12
+ def get
13
+ Solr.instrument(name: INSTRUMENT_KEY) { @raw_connection.get }
14
+ end
15
+
16
+ def post(data = {})
17
+ Solr.instrument(name: INSTRUMENT_KEY) do
18
+ @raw_connection.post do |req|
19
+ req.body = data
20
+ end
21
+ end
22
+ end
23
+
24
+ def post_as_json(data)
25
+ Solr.instrument(name: INSTRUMENT_KEY, data: data) do
26
+ @raw_connection.post do |req|
27
+ req.headers['Content-Type'] = 'application/json'.freeze
28
+ req.body = JSON.generate(data)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end