solr4r 0.0.3 → 0.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4fc0f7535c323bbbd5658b37a8347ffb480352d8
4
- data.tar.gz: 8adf499638d2dce1b6f145714f19897e35234679
3
+ metadata.gz: 5406b14611075ff4787018f75d1f11cb9c89a79b
4
+ data.tar.gz: 1ed6e0ae00ebd920fe2aaddd7ce6c9d51ea9c1d4
5
5
  SHA512:
6
- metadata.gz: a6c0549a56c70c7b9e7a644a2d1c563bf42dc5ad172db183f01b4966a411b379db21ca751a7295fbfa12f1ccfa84bc3564a9f5a7477ba631599e25643f2c9569
7
- data.tar.gz: 038f091785cb04024a139c4de2f7da174b359496c82dc3f2881e95000e8ba8c3dbf38123023291bd76c845d2b88a2a13808a4bc30590450fbf2b656a395a4b81
6
+ metadata.gz: 95f762843eaf9ecbdfe557df2f7eb786caf1e74ef54a006df1396dedfb1b1d3ff0ef23d75cd6d34bd6a7831015a7c1d26e10b3620a5301fa7373de2a1de021f3
7
+ data.tar.gz: bccd496fa4035ba6a9b39d244bd120eed385cd25779f5a8c943729975c4da00a63a243535fac98a0b36b69eb0d446e42333c8789b20f0fdb259cce09faa09e9c
data/ChangeLog CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  = Revision history for solr4r
4
4
 
5
+ == 0.0.4 [2014-12-19]
6
+
7
+ * Fixed Solr4R::Request#make_request to set request body if string (XML).
8
+ * Fixed Solr4R::Builder#to_xml to replace illegal characters.
9
+ * Added Solr4R::Response#success?.
10
+ * Added Solr4R::Client#add_batch.
11
+ * Added Solr4R::Client#query_string.
12
+ * Added basic logging infrastructure.
13
+ * Extended Solr4R::Result for
14
+ terms[https://wiki.apache.org/solr/TermsComponent] response.
15
+ * Updated Solr4R::Client#json_query to use Solr4R::Client#query_string.
16
+
5
17
  == 0.0.3 [2014-09-19]
6
18
 
7
19
  * Added Solr4R::Client#json.
data/README CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  == VERSION
4
4
 
5
- This documentation refers to solr4r version 0.0.3
5
+ This documentation refers to solr4r version 0.0.4
6
6
 
7
7
 
8
8
  == DESCRIPTION
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- require File.expand_path(%q{../lib/solr4r/version}, __FILE__)
1
+ require_relative 'lib/solr4r/version'
2
2
 
3
3
  begin
4
4
  require 'hen'
@@ -13,7 +13,7 @@ begin
13
13
  email: %q{jens.wille@gmail.com},
14
14
  license: %q{AGPL-3.0},
15
15
  homepage: :blackwinter,
16
- dependencies: { nokogiri: '~> 1.6', 'nuggets' => '~> 1.0' },
16
+ dependencies: { nokogiri: '~> 1.6', 'nuggets' => ['~> 1.0', '>= 1.0.1'] },
17
17
 
18
18
  required_ruby_version: '>= 1.9.3'
19
19
  }
@@ -29,6 +29,8 @@ module Solr4R
29
29
 
30
30
  class Builder < Nokogiri::XML::Builder
31
31
 
32
+ include Logging
33
+
32
34
  class Document < Nokogiri::XML::Document
33
35
 
34
36
  def document
@@ -269,7 +271,11 @@ module Solr4R
269
271
  def to_xml(name, attributes = {}, &block)
270
272
  self.parent = self.doc = @_solr_doc.dup
271
273
  method_missing(name, attributes, &block)
272
- super(&nil)
274
+ replace_illegal_characters(super(&nil))
275
+ end
276
+
277
+ def replace_illegal_characters(string)
278
+ string.gsub(/[\x00-\x08\x0B\x0C\x0E-\x1F]/, '')
273
279
  end
274
280
 
275
281
  def _each(values, &block)
data/lib/solr4r/client.rb CHANGED
@@ -27,6 +27,8 @@ module Solr4R
27
27
 
28
28
  class Client
29
29
 
30
+ include Logging
31
+
30
32
  DEFAULT_HOST = 'localhost'
31
33
  DEFAULT_PATH = 'solr'
32
34
  DEFAULT_PORT = 8983
@@ -35,6 +37,8 @@ module Solr4R
35
37
  wt: :json
36
38
  }
37
39
 
40
+ DEFAULT_BATCH_SIZE = 1000
41
+
38
42
  DEFAULT_ENDPOINTS = %w[select query spell suggest terms] <<
39
43
  ['ping', path: 'admin/ping', method: :head] <<
40
44
  ['dump', path: 'debug/dump']
@@ -48,16 +52,16 @@ module Solr4R
48
52
  MATCH_ALL_QUERY = '*:*'
49
53
 
50
54
  def initialize(options = {})
51
- if options.is_a?(String)
52
- uri, options = options, {}
53
- else
54
- uri = options.fetch(:uri, default_uri(options))
55
- end
55
+ uri, options = options, {} unless options.is_a?(Hash)
56
56
 
57
57
  self.options = options
58
58
 
59
- self.builder = options.fetch(:builder, Builder.new)
60
- self.request = options.fetch(:request, Request.new(uri))
59
+ uri ||= options.fetch(:uri, default_uri)
60
+
61
+ self.logger = options.fetch(:logger, default_logger)
62
+
63
+ self.builder = options.fetch(:builder) { forward_logger(Builder.new) }
64
+ self.request = options.fetch(:request) { forward_logger(Request.new(uri)) }
61
65
 
62
66
  self.default_params = options.fetch(:default_params, DEFAULT_PARAMS)
63
67
 
@@ -112,6 +116,19 @@ module Solr4R
112
116
  update(builder.add(doc, attributes), options, &block)
113
117
  end
114
118
 
119
+ def add_batch(docs, attributes = {}, options = {}, batch_size = DEFAULT_BATCH_SIZE, &block)
120
+ failed = []
121
+
122
+ docs.each_slice(batch_size) { |batch|
123
+ unless add(batch, attributes, options, &block).success?
124
+ failed.concat(batch_size == 1 ? batch : add_batch(
125
+ batch, attributes, options, batch_size / 10, &block))
126
+ end
127
+ }
128
+
129
+ failed
130
+ end
131
+
115
132
  # See Builder#commit.
116
133
  def commit(attributes = {}, options = {}, &block)
117
134
  update(builder.commit(attributes), options, &block)
@@ -154,7 +171,24 @@ module Solr4R
154
171
  end
155
172
 
156
173
  def json_query(params = {}, options = {}, path = DEFAULT_SELECT_PATH, &block)
157
- json(path, params, options, &block)
174
+ json(path, params.merge(q: query_string(params[:q])), options, &block)
175
+ end
176
+
177
+ def query_string(query)
178
+ case query
179
+ when nil
180
+ # ignore
181
+ when String
182
+ query.gsub('&', '%26')
183
+ when Array, Hash
184
+ query.flat_map { |key, values|
185
+ Array(values).map { |value|
186
+ query_string("#{key}:#{value}")
187
+ }
188
+ }.join(' ')
189
+ else
190
+ query_string(query.to_s)
191
+ end
158
192
  end
159
193
 
160
194
  def solr_version(type = :spec)
@@ -169,7 +203,7 @@ module Solr4R
169
203
 
170
204
  private
171
205
 
172
- def default_uri(options)
206
+ def default_uri
173
207
  'http://%s:%d/%s' % [
174
208
  options.fetch(:host, DEFAULT_HOST),
175
209
  options.fetch(:port, DEFAULT_PORT),
@@ -0,0 +1,71 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ ###############################################################################
5
+ # #
6
+ # solr4r -- A Ruby client for Apache Solr #
7
+ # #
8
+ # Copyright (C) 2014 Jens Wille #
9
+ # #
10
+ # Mir is free software: you can redistribute it and/or modify it under the #
11
+ # terms of the GNU Affero General Public License as published by the Free #
12
+ # Software Foundation, either version 3 of the License, or (at your option) #
13
+ # any later version. #
14
+ # #
15
+ # solr4r is distributed in the hope that it will be useful, but WITHOUT ANY #
16
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
17
+ # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
18
+ # more details. #
19
+ # #
20
+ # You should have received a copy of the GNU Affero General Public License #
21
+ # along with solr4r. If not, see <http://www.gnu.org/licenses/>. #
22
+ # #
23
+ ###############################################################################
24
+ #++
25
+
26
+ require 'logger'
27
+ require 'nuggets/module/lazy_attr'
28
+
29
+ module Solr4R
30
+
31
+ module Logging
32
+
33
+ DEFAULT_LOG_DEVICE = $stderr
34
+ DEFAULT_LOG_LEVEL = Logger::WARN
35
+ DEFAULT_LOG_NAME = "Solr4R/#{VERSION}"
36
+
37
+ NULL_LOGGER = Logger.new(nil)
38
+
39
+ class << self
40
+
41
+ def set_log_level(logger, level = nil, default_level = nil)
42
+ level ||= begin
43
+ value = ENV.fetch('SOLR4R_LOG_LEVEL', '')
44
+ value.empty? ? default_level || DEFAULT_LOG_LEVEL : value
45
+ end
46
+
47
+ logger.level = level.respond_to?(:upcase) ?
48
+ Logger.const_get(level.upcase) : level
49
+ end
50
+
51
+ end
52
+
53
+ lazy_accessor(:logger) { NULL_LOGGER }
54
+
55
+ def default_logger(options = options(), mod = self.class)
56
+ logger = Logger.new(options.fetch(:log_device, mod::DEFAULT_LOG_DEVICE))
57
+ logger.progname = options.fetch(:log_name, mod::DEFAULT_LOG_NAME)
58
+
59
+ Logging.set_log_level(logger, options[:log_level], mod::DEFAULT_LOG_LEVEL)
60
+
61
+ logger
62
+ end
63
+
64
+ def forward_logger(object)
65
+ object.logger = logger
66
+ object
67
+ end
68
+
69
+ end
70
+
71
+ end
@@ -32,6 +32,8 @@ module Solr4R
32
32
 
33
33
  class Request
34
34
 
35
+ include Logging
36
+
35
37
  DEFAULT_METHOD = :get
36
38
 
37
39
  DEFAULT_USER_AGENT = "Solr4R/#{VERSION}"
@@ -115,7 +117,7 @@ module Solr4R
115
117
  req = request_for(method, uri)
116
118
  when :post
117
119
  req = request_for(method, uri)
118
- req.set_form_data(Array(data))
120
+ set_data(req, data)
119
121
  else
120
122
  raise ArgumentError, "method not supported: #{method}"
121
123
  end
@@ -136,6 +138,10 @@ module Solr4R
136
138
  }
137
139
  end
138
140
 
141
+ def set_data(req, data)
142
+ data.is_a?(String) ? req.body = data : req.form_data = data
143
+ end
144
+
139
145
  end
140
146
 
141
147
  end
@@ -46,6 +46,10 @@ module Solr4R
46
46
  '"%s %s" %d' % [request_method.upcase, request_url, response_code]
47
47
  end
48
48
 
49
+ def success?
50
+ response_code / 100 == 2
51
+ end
52
+
49
53
  def result
50
54
  @result ||= evaluate_result if @evaluate
51
55
  end
data/lib/solr4r/result.rb CHANGED
@@ -35,13 +35,22 @@ module Solr4R
35
35
  include Enumerable
36
36
 
37
37
  extend Forwardable
38
+ def_delegators :to_hash, :fetch, :deep_fetch, :%
39
+
40
+ def self.type_for(hash)
41
+ constants.find { |const|
42
+ if hash.key?(const.to_s.downcase)
43
+ mod = const_get(const)
44
+ return mod if mod.is_a?(Module)
45
+ end
46
+ }
38
47
 
39
- def_delegators :response, :to_i
40
- def_delegators :to_hash, :%, :deep_fetch
48
+ raise TypeError, "could not find supported type: #{hash.keys.join(', ')}"
49
+ end
41
50
 
42
51
  def initialize(response, hash)
52
+ extend(self.class.type_for(hash))
43
53
  @response, @hash = response, hash.extend(Nuggets::Hash::DeepFetchMixin)
44
- extend(Error) if hash.key?('error')
45
54
  end
46
55
 
47
56
  attr_reader :response
@@ -50,26 +59,59 @@ module Solr4R
50
59
  @hash
51
60
  end
52
61
 
53
- def each
54
- return enum_for(:each) unless block_given?
62
+ def to_i
63
+ 0
64
+ end
65
+
66
+ def each(&block)
67
+ block ? _each(&block) : enum_for(:each)
68
+ end
55
69
 
56
- deep_fetch('response/docs').each { |hash|
57
- yield Document.new(self, hash)
58
- }
70
+ def empty?
71
+ to_i.zero?
59
72
  end
60
73
 
61
74
  def error?
62
75
  is_a?(Error)
63
76
  end
64
77
 
78
+ private
79
+
80
+ def _each
81
+ []
82
+ end
83
+
65
84
  module Error
85
+ end
86
+
87
+ module Response
66
88
 
67
89
  def to_i
68
- 0
90
+ response.to_i
69
91
  end
70
92
 
71
- def each
72
- []
93
+ private
94
+
95
+ def _each
96
+ deep_fetch('response/docs').each { |hash|
97
+ yield Document.new(self, hash)
98
+ }
99
+ end
100
+
101
+ end
102
+
103
+ module Terms
104
+
105
+ def to_i
106
+ fetch('terms').size
107
+ end
108
+
109
+ private
110
+
111
+ def _each
112
+ fetch('terms').each { |key, value|
113
+ yield key, Hash[*value]
114
+ }
73
115
  end
74
116
 
75
117
  end
@@ -4,7 +4,7 @@ module Solr4R
4
4
 
5
5
  MAJOR = 0
6
6
  MINOR = 0
7
- TINY = 3
7
+ TINY = 4
8
8
 
9
9
  class << self
10
10
 
data/lib/solr4r.rb CHANGED
@@ -36,6 +36,7 @@ module Solr4R
36
36
  end
37
37
 
38
38
  require_relative 'solr4r/version'
39
+ require_relative 'solr4r/logging'
39
40
  require_relative 'solr4r/builder'
40
41
  require_relative 'solr4r/request'
41
42
  require_relative 'solr4r/response'
@@ -84,6 +84,20 @@ describe Solr4R::Builder do
84
84
  EOT
85
85
  end
86
86
 
87
+ example do
88
+ @builder.add(employeeId: '05991', office: "\fBridgew\ate\r", skills: %w[Perl Java]).should == <<-EOT
89
+ <?xml version="1.0" encoding="UTF-8"?>
90
+ <add>
91
+ <doc>
92
+ <field name="employeeId">05991</field>
93
+ <field name="office">Bridgewte&#13;</field>
94
+ <field name="skills">Perl</field>
95
+ <field name="skills">Java</field>
96
+ </doc>
97
+ </add>
98
+ EOT
99
+ end
100
+
87
101
  end
88
102
 
89
103
  describe '#commit' do
@@ -205,6 +219,15 @@ describe Solr4R::Builder do
205
219
  EOT
206
220
  end
207
221
 
222
+ example do
223
+ @builder.delete(query: "office:\fBridgew\ate\r").should == <<-EOT
224
+ <?xml version="1.0" encoding="UTF-8"?>
225
+ <delete>
226
+ <query>office:Bridgewte&#13;</query>
227
+ </delete>
228
+ EOT
229
+ end
230
+
208
231
  end
209
232
 
210
233
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solr4r
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jens Wille
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-19 00:00:00.000000000 Z
11
+ date: 2014-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -31,6 +31,9 @@ dependencies:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.0'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 1.0.1
34
37
  type: :runtime
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
@@ -38,20 +41,29 @@ dependencies:
38
41
  - - "~>"
39
42
  - !ruby/object:Gem::Version
40
43
  version: '1.0'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.0.1
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: hen
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '0.8'
45
54
  - - ">="
46
55
  - !ruby/object:Gem::Version
47
- version: '0'
56
+ version: 0.8.1
48
57
  type: :development
49
58
  prerelease: false
50
59
  version_requirements: !ruby/object:Gem::Requirement
51
60
  requirements:
61
+ - - "~>"
62
+ - !ruby/object:Gem::Version
63
+ version: '0.8'
52
64
  - - ">="
53
65
  - !ruby/object:Gem::Version
54
- version: '0'
66
+ version: 0.8.1
55
67
  - !ruby/object:Gem::Dependency
56
68
  name: rake
57
69
  requirement: !ruby/object:Gem::Requirement
@@ -98,6 +110,7 @@ files:
98
110
  - lib/solr4r/builder.rb
99
111
  - lib/solr4r/client.rb
100
112
  - lib/solr4r/document.rb
113
+ - lib/solr4r/logging.rb
101
114
  - lib/solr4r/request.rb
102
115
  - lib/solr4r/request_extension.rb
103
116
  - lib/solr4r/response.rb
@@ -112,18 +125,21 @@ licenses:
112
125
  metadata: {}
113
126
  post_install_message: |2+
114
127
 
115
- solr4r-0.0.3 [2014-09-19]:
128
+ solr4r-0.0.4 [2014-12-19]:
116
129
 
117
- * Added Solr4R::Client#json.
118
- * Added Solr4R::Client#json_query.
119
- * Added Solr4R::Client#solr_version.
120
- * Updated Solr4R::Request with some fixes.
121
- * Refactored Solr4R::Response to use wrapper object.
122
- * Refactored Solr4R::Builder to use custom document class.
130
+ * Fixed Solr4R::Request#make_request to set request body if string (XML).
131
+ * Fixed Solr4R::Builder#to_xml to replace illegal characters.
132
+ * Added Solr4R::Response#success?.
133
+ * Added Solr4R::Client#add_batch.
134
+ * Added Solr4R::Client#query_string.
135
+ * Added basic logging infrastructure.
136
+ * Extended Solr4R::Result for
137
+ terms[https://wiki.apache.org/solr/TermsComponent] response.
138
+ * Updated Solr4R::Client#json_query to use Solr4R::Client#query_string.
123
139
 
124
140
  rdoc_options:
125
141
  - "--title"
126
- - solr4r Application documentation (v0.0.3)
142
+ - solr4r Application documentation (v0.0.4)
127
143
  - "--charset"
128
144
  - UTF-8
129
145
  - "--line-numbers"
@@ -144,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
144
160
  version: '0'
145
161
  requirements: []
146
162
  rubyforge_project:
147
- rubygems_version: 2.4.1
163
+ rubygems_version: 2.4.5
148
164
  signing_key:
149
165
  specification_version: 4
150
166
  summary: A Ruby client for Apache Solr.