rsolr 1.0.0.beta5 → 1.0.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.
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/lib/rsolr/char.rb +13 -1
- data/lib/rsolr/client.rb +11 -9
- data/lib/rsolr/connection.rb +12 -1
- data/lib/rsolr/pagination.rb +13 -22
- data/lib/rsolr/uri.rb +9 -8
- data/spec/api/pagination_spec.rb +39 -1
- metadata +6 -9
data/README.rdoc
CHANGED
@@ -8,7 +8,7 @@ Notice: This document is only for the the 1.0 (pre-release) in the master branch
|
|
8
8
|
The code docs can be viewed here : http://rdoc.info/projects/mwmitchell/rsolr
|
9
9
|
|
10
10
|
== Installation:
|
11
|
-
sudo gem install rsolr
|
11
|
+
sudo gem install rsolr --pre
|
12
12
|
|
13
13
|
== Example:
|
14
14
|
require 'rubygems'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.0
|
1
|
+
1.0.0
|
data/lib/rsolr/char.rb
CHANGED
@@ -1,9 +1,21 @@
|
|
1
1
|
# A module that contains (1) string related methods
|
2
2
|
module RSolr::Char
|
3
3
|
|
4
|
-
# backslash everything
|
4
|
+
# backslash everything
|
5
|
+
# that isn't a word character
|
5
6
|
def escape value
|
6
7
|
value.gsub /(\W)/, '\\\\\1'
|
7
8
|
end
|
8
9
|
|
10
|
+
# LUCENE_CHAR_RX = /([\+\-\!\(\)\[\]\^\"\~\*\?\:\\]+)/
|
11
|
+
# LUCENE_WORD_RX = /(OR|AND|NOT)/
|
12
|
+
#
|
13
|
+
# # More specific/lucene escape sequence
|
14
|
+
# def lucene_escape string
|
15
|
+
# delim = " "
|
16
|
+
# string.gsub(LUCENE_CHAR_RX, '\\\\\1').split(delim).map { |v|
|
17
|
+
# v.gsub(LUCENE_WORD_RX, '\\\\\1')
|
18
|
+
# }.join(delim)
|
19
|
+
# end
|
20
|
+
|
9
21
|
end
|
data/lib/rsolr/client.rb
CHANGED
@@ -4,19 +4,21 @@ class RSolr::Client
|
|
4
4
|
|
5
5
|
def initialize connection, options = {}
|
6
6
|
@connection = connection
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
unless false === options[:url]
|
8
|
+
url = options[:url] || 'http://127.0.0.1:8983/solr/'
|
9
|
+
url << "/" unless url[-1] == ?/
|
10
|
+
proxy_url = options[:proxy]
|
11
|
+
proxy_url << "/" unless proxy_url.nil? or proxy_url[-1] == ?/
|
12
|
+
@uri = RSolr::Uri.create url
|
13
|
+
@proxy = RSolr::Uri.create proxy_url if proxy_url
|
14
|
+
end
|
13
15
|
@options = options
|
14
16
|
extend RSolr::Pagination::Client
|
15
17
|
end
|
16
18
|
|
17
19
|
# returns the actual request uri object.
|
18
20
|
def base_request_uri
|
19
|
-
base_uri.request_uri
|
21
|
+
base_uri.request_uri if base_uri
|
20
22
|
end
|
21
23
|
|
22
24
|
# returns the uri proxy if present,
|
@@ -117,7 +119,7 @@ class RSolr::Client
|
|
117
119
|
update opts.merge(:data => xml.delete_by_query(query))
|
118
120
|
end
|
119
121
|
|
120
|
-
# shortcut to RSolr::
|
122
|
+
# shortcut to RSolr::Xml::Generator
|
121
123
|
def xml
|
122
124
|
@xml ||= RSolr::Xml::Generator.new
|
123
125
|
end
|
@@ -125,7 +127,7 @@ class RSolr::Client
|
|
125
127
|
# +send_and_receive+ is the main request method responsible for sending requests to the +connection+ object.
|
126
128
|
#
|
127
129
|
# "path" : A string value that usually represents a solr request handler
|
128
|
-
# "
|
130
|
+
# "opts" : A hash, which can contain the following keys:
|
129
131
|
# :method : required - the http method (:get, :post or :head)
|
130
132
|
# :params : optional - the query string params in hash form
|
131
133
|
# :data : optional - post data -- if a hash is given, it's sent as "application/x-www-form-urlencoded"
|
data/lib/rsolr/connection.rb
CHANGED
@@ -44,6 +44,8 @@ class RSolr::Connection
|
|
44
44
|
when :get
|
45
45
|
Net::HTTP::Get
|
46
46
|
when :post
|
47
|
+
#require 'net/http/post/multipart'
|
48
|
+
#File === request_context[:data] ? Net::HTTP::Post::Multipart : Net::HTTP::Post
|
47
49
|
Net::HTTP::Post
|
48
50
|
when :head
|
49
51
|
Net::HTTP::Head
|
@@ -51,7 +53,16 @@ class RSolr::Connection
|
|
51
53
|
raise "Only :get, :post and :head http method types are allowed."
|
52
54
|
end
|
53
55
|
headers = request_context[:headers] || {}
|
54
|
-
|
56
|
+
# if http_method.to_s == "Net::HTTP::Post::Multipart"
|
57
|
+
# io = request_context[:data]
|
58
|
+
# UploadIO.convert! io, request_context[:headers]["Content-Type"], io.path, io.path
|
59
|
+
# raw_request =
|
60
|
+
# Net::HTTP::Post::Multipart.new(
|
61
|
+
# request_context[:path],
|
62
|
+
# :file => io)
|
63
|
+
# else
|
64
|
+
raw_request = http_method.new request_context[:uri].to_s
|
65
|
+
# end
|
55
66
|
raw_request.initialize_http_header headers
|
56
67
|
raw_request
|
57
68
|
end
|
data/lib/rsolr/pagination.rb
CHANGED
@@ -3,7 +3,7 @@ module RSolr::Pagination
|
|
3
3
|
# Calculates the "start" and "rows" Solr params
|
4
4
|
# by inspecting the :per_page and :page params.
|
5
5
|
def self.calculate_start_and_rows page, per_page
|
6
|
-
per_page
|
6
|
+
per_page = per_page.to_s.to_i
|
7
7
|
page = page.to_s.to_i-1
|
8
8
|
page = page < 1 ? 0 : page
|
9
9
|
start = page * per_page
|
@@ -16,16 +16,16 @@ module RSolr::Pagination
|
|
16
16
|
module Client
|
17
17
|
|
18
18
|
# A paginated request method.
|
19
|
-
def paginate page, per_page, path, opts =
|
20
|
-
request_context = build_paginated_request page, per_page, path, opts
|
21
|
-
puts request_context.inspect
|
19
|
+
def paginate page, per_page, path, opts = nil
|
20
|
+
request_context = build_paginated_request page, per_page, path, opts
|
22
21
|
execute request_context
|
23
22
|
end
|
24
23
|
|
25
24
|
# Just like RSolr::Client #build_request
|
26
25
|
# but converts the page and per_page
|
27
26
|
# arguments into :rows and :start.
|
28
|
-
def build_paginated_request page, per_page, path, opts =
|
27
|
+
def build_paginated_request page, per_page, path, opts = nil
|
28
|
+
opts ||= {}
|
29
29
|
opts[:page] = page
|
30
30
|
opts[:per_page] = per_page
|
31
31
|
opts[:params] ||= {}
|
@@ -48,7 +48,7 @@ module RSolr::Pagination
|
|
48
48
|
# RSolr::Client #method_missing
|
49
49
|
# method is called.
|
50
50
|
def method_missing name, *args
|
51
|
-
if name.to_s =~ /^
|
51
|
+
if name.to_s =~ /^paginated?_(.+)$/
|
52
52
|
paginate args[0], args[1], $1, *args[2..-1]
|
53
53
|
else
|
54
54
|
super name, *args
|
@@ -58,31 +58,22 @@ module RSolr::Pagination
|
|
58
58
|
# Overrides the RSolr::Client #evaluate_ruby_response method.
|
59
59
|
# Calls the original/super
|
60
60
|
# RSolr::Client #evaluate_ruby_response method.
|
61
|
-
# Mixes in the
|
61
|
+
# Mixes in the PaginatedDocSet if
|
62
62
|
# the request[:page] and request[:per_page]
|
63
63
|
# opts are set.
|
64
64
|
def evaluate_ruby_response request, response
|
65
65
|
result = super request, response
|
66
|
-
|
66
|
+
if request[:page] && request[:per_page] && result["response"] && result["response"]["docs"]
|
67
|
+
d = result['response']['docs'].extend PaginatedDocSet
|
68
|
+
d.per_page = request[:per_page]
|
69
|
+
d.start = request[:params][:start]
|
70
|
+
d.total = result["response"]["numFound"].to_s.to_i
|
71
|
+
end
|
67
72
|
result
|
68
73
|
end
|
69
74
|
|
70
75
|
end
|
71
76
|
|
72
|
-
module PaginatedResponse
|
73
|
-
# TODO: self["responseHeader"]["params"]["rows"]
|
74
|
-
# will not be available if omitHeader is false...
|
75
|
-
# so, a simple "extend" probably isn't going to cut it.
|
76
|
-
def self.extended base
|
77
|
-
return unless base["response"] && base["response"]["docs"]
|
78
|
-
d = base['response']['docs']
|
79
|
-
d.extend PaginatedDocSet
|
80
|
-
d.per_page = self["responseHeader"]["params"]["rows"].to_s.to_i rescue 10
|
81
|
-
d.start = base["response"]["start"].to_s.to_i
|
82
|
-
d.total = base["response"]["numFound"].to_s.to_i
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
77
|
# A response module which gets mixed into the solr ["response"]["docs"] array.
|
87
78
|
module PaginatedDocSet
|
88
79
|
|
data/lib/rsolr/uri.rb
CHANGED
@@ -2,14 +2,16 @@ require 'uri'
|
|
2
2
|
|
3
3
|
module RSolr::Uri
|
4
4
|
|
5
|
-
def
|
5
|
+
def create url
|
6
6
|
::URI.parse url[-1] == ?/ ? url : "#{url}/"
|
7
7
|
end
|
8
8
|
|
9
9
|
# Returns a query string param pair as a string.
|
10
10
|
# Both key and value are escaped.
|
11
|
-
def build_param(k,v)
|
12
|
-
|
11
|
+
def build_param(k,v, escape = true)
|
12
|
+
escape ?
|
13
|
+
"#{escape_query_value(k)}=#{escape_query_value(v)}" :
|
14
|
+
"#{k}=#{v}"
|
13
15
|
end
|
14
16
|
|
15
17
|
# Return the bytesize of String; uses String#size under Ruby 1.8 and
|
@@ -29,13 +31,13 @@ module RSolr::Uri
|
|
29
31
|
# params_to_solr(:q => 'query', :fq => ['a', 'b'])
|
30
32
|
# is converted to:
|
31
33
|
# ?q=query&fq=a&fq=b
|
32
|
-
def params_to_solr(params)
|
34
|
+
def params_to_solr(params, escape = true)
|
33
35
|
mapped = params.map do |k, v|
|
34
36
|
next if v.to_s.empty?
|
35
37
|
if v.class == Array
|
36
|
-
params_to_solr(v.map { |x| [k, x] })
|
38
|
+
params_to_solr(v.map { |x| [k, x] }, escape)
|
37
39
|
else
|
38
|
-
build_param k, v
|
40
|
+
build_param k, v, escape
|
39
41
|
end
|
40
42
|
end
|
41
43
|
mapped.compact.join("&")
|
@@ -46,8 +48,7 @@ module RSolr::Uri
|
|
46
48
|
# version since it's faster.
|
47
49
|
# (Stolen from Rack).
|
48
50
|
def escape_query_value(s)
|
49
|
-
s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/
|
50
|
-
#'%'+$1.unpack('H2'*$1.size).join('%').upcase
|
51
|
+
s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/u) {
|
51
52
|
'%'+$1.unpack('H2'*bytesize($1)).join('%').upcase
|
52
53
|
}.tr(' ', '+')
|
53
54
|
end
|
data/spec/api/pagination_spec.rb
CHANGED
@@ -1,4 +1,42 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
describe "RSolr::Pagination" do
|
3
|
-
|
3
|
+
context "calculate_start_and_rows" do
|
4
|
+
it "should return an array with 2 ints" do
|
5
|
+
values = RSolr::Pagination.calculate_start_and_rows 2, 10
|
6
|
+
values[0].should == 10
|
7
|
+
values[1].should == 10
|
8
|
+
end
|
9
|
+
it "should handle string values" do
|
10
|
+
values = RSolr::Pagination.calculate_start_and_rows "1", "22"
|
11
|
+
values[0].should == 0
|
12
|
+
values[1].should == 22
|
13
|
+
end
|
14
|
+
end
|
15
|
+
context "build_paginated_request" do
|
16
|
+
it "should create the proper solr params and query string" do
|
17
|
+
c = RSolr::Client.new(nil, {}).extend(RSolr::Pagination::Client)
|
18
|
+
r = c.build_paginated_request 3, 25, "select", {:params => {:q => "test"}}
|
19
|
+
r[:page].should == 3
|
20
|
+
r[:per_page].should == 25
|
21
|
+
r[:params][:start].should == 50
|
22
|
+
r[:params][:rows].should == 25
|
23
|
+
r[:uri].query.should =~ /rows=25/
|
24
|
+
r[:uri].query.should =~ /start=50/
|
25
|
+
end
|
26
|
+
end
|
27
|
+
context "paginate" do
|
28
|
+
it "should build a paginated request context and call execute" do
|
29
|
+
c = RSolr::Client.new(nil, {}).extend(RSolr::Pagination::Client)
|
30
|
+
c.should_receive(:execute).with(hash_including({
|
31
|
+
:page => 1,
|
32
|
+
:per_page => 10,
|
33
|
+
:params => {
|
34
|
+
:rows => 10,
|
35
|
+
:start => 0,
|
36
|
+
:wt => :ruby
|
37
|
+
}
|
38
|
+
}))
|
39
|
+
c.paginate 1, 10, "select"
|
40
|
+
end
|
41
|
+
end
|
4
42
|
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rsolr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
4
|
+
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
|
10
|
-
version: 1.0.0.beta5
|
9
|
+
version: 1.0.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Matt Mitchell
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date:
|
17
|
+
date: 2011-01-05 00:00:00 -05:00
|
19
18
|
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
@@ -71,13 +70,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
71
70
|
version: "0"
|
72
71
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
72
|
requirements:
|
74
|
-
- - "
|
73
|
+
- - ">="
|
75
74
|
- !ruby/object:Gem::Version
|
76
75
|
segments:
|
77
|
-
-
|
78
|
-
|
79
|
-
- 1
|
80
|
-
version: 1.3.1
|
76
|
+
- 0
|
77
|
+
version: "0"
|
81
78
|
requirements: []
|
82
79
|
|
83
80
|
rubyforge_project:
|