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