solr4r 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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.