mwmitchell-rsolr 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES.txt CHANGED
@@ -1,3 +1,8 @@
1
+ 0.6.2 - January 14, 2009
2
+ Removed mapping and indexer modules -- seems to me that a general purpose mapping library
3
+ would be more valuable than an embedded module in RSolr ( RMapper ?)
4
+ This helps lighten RSolr a bit too
5
+
1
6
  0.6.1 - January 13, 2009
2
7
  Removed SearchExt and mapping until this library gets some real use
3
8
  The only param mapping now is for :page and :per_page via the #search method
data/README.rdoc CHANGED
@@ -59,9 +59,9 @@ If you use WillPaginate, just pass-in the response to the #will_paginate view he
59
59
 
60
60
  <%= will_paginate(@response) %>
61
61
 
62
- The #search method automatically figure out the :start and :rows value, based on the values of :page and :per_page. The will_paginate view helper just needs the right methods (#current_page, #previous_page, #next_page and #total_pages) to create the pagination view widget.
62
+ The #search method automatically figures out the :start and :rows values, based on the values of :page and :per_page. The will_paginate view helper uses the methods: #current_page, #previous_page, #next_page and #total_pages to create the pagination view widget.
63
63
 
64
- The #search method will be providing more param mapping, but not until RSolr gets more use. If you have ideas for a param mapping interface, let me know!
64
+ The #search method will be providing more param mapping, but not until RSolr gets more use. If you have ideas for a param mapping interface, let me know! I'll be throwing some stuff together as well.
65
65
 
66
66
 
67
67
  === Updating Solr
data/examples/direct.rb CHANGED
@@ -9,7 +9,7 @@ solr = RSolr.connect(:direct, :home_dir=>home, :dist_dir=>dist)
9
9
 
10
10
  `cd ../apache-solr/example/exampledocs && ./post.sh ./*.xml`
11
11
 
12
- response = solr.search 'ipod', :filters=>{:price=>(0..50)}, :per_page=>2, :page=>1
12
+ response = solr.search :q=>'ipod', :fq=>'price:[0 TO 50]', :per_page=>2, :page=>1
13
13
 
14
14
  solr.delete_by_query('*:*')
15
15
 
data/examples/http.rb CHANGED
@@ -5,7 +5,7 @@ solr = RSolr.connect(:http)
5
5
 
6
6
  `cd ../apache-solr/example/exampledocs && ./post.sh ./*.xml`
7
7
 
8
- response = solr.search 'ipod', :filters=>{:price=>(0..50)}, :per_page=>2, :page=>1
8
+ response = solr.search :q=>'ipod', :fq=>'price:[0 TO 50]', :per_page=>2, :page=>1
9
9
 
10
10
  solr.delete_by_query('*:*')
11
11
 
data/lib/rsolr.rb CHANGED
@@ -7,12 +7,11 @@ proc {|base, files|
7
7
 
8
8
  module RSolr
9
9
 
10
- VERSION = '0.6.0'
10
+ VERSION = '0.6.2'
11
11
 
12
12
  autoload :Message, 'rsolr/message'
13
13
  autoload :Response, 'rsolr/response'
14
14
  autoload :Connection, 'rsolr/connection'
15
- autoload :Mapper, 'rsolr/mapper'
16
15
  autoload :Indexer, 'rsolr/indexer'
17
16
  autoload :HTTPClient, 'rsolr/http_client'
18
17
 
@@ -21,7 +21,7 @@ class RSolr::Connection::Adapter::HTTP
21
21
  #
22
22
  def initialize(opts={}, &block)
23
23
  opts[:url]||='http://127.0.0.1:8983/solr'
24
- @opts = default_options.merge(opts)
24
+ @opts = default_options.merge(opts) # default_options are coming from RSolr::Connection::Adapter::CommonMethods
25
25
  end
26
26
 
27
27
  def connection
@@ -41,6 +41,8 @@ class RSolr::Connection::Base
41
41
 
42
42
  # same as the #query method, but with additional param mapping
43
43
  # currently only :page and :per_page
44
+ # TODO: need to get some nice and friendly param mapping here:
45
+ # search(:fields=>'', :facet_fields=>[], :filters=>{})
44
46
  def search(params)
45
47
  self.query(modify_params_for_pagination(params))
46
48
  end
@@ -108,9 +110,18 @@ class RSolr::Connection::Base
108
110
  RSolr::Message
109
111
  end
110
112
 
113
+ # given a hash, this method will attempt to produce the
114
+ # correct :start and :rows values for Solr
115
+ # -- if the hash contains a :per_page value, it's used for the rows
116
+ # if the :per_page value doesn't exist (nil), the :rows value is
117
+ # used, and if :rows is not set, the default value is 10
118
+ # -- if the hash contains a :page value (the current page)
119
+ # it is used to calculate the :start value
120
+ # returns a hash with the :rows and :start values
121
+ # :per_page and :page are deleted
111
122
  def modify_params_for_pagination(p)
112
123
  per_page = p.delete(:per_page).to_s.to_i
113
- p[:rows] = per_page==0 ? 10 : per_page
124
+ p[:rows] = per_page==0 ? (p[:rows] || 10) : per_page
114
125
  page = p.delete(:page).to_s.to_i
115
126
  page = page > 0 ? page : 1
116
127
  p[:start] = (page - 1) * (p[:rows] || 0)
@@ -1,11 +1,9 @@
1
- #require 'uri'
2
-
3
1
  # A simple wrapper for different http client implementations.
4
2
  # Supports #get and #post
5
3
  # This was motivated by: http://apocryph.org/2008/11/09/more_indepth_analysis_ruby_http_client_performance/
6
4
  # Net::HTTP is the default adapter
7
5
 
8
- # Each adapter response should be a hash with the following keys:
6
+ # Each adapters response should be a hash with the following keys:
9
7
  # :status_code
10
8
  # :url
11
9
  # :body
@@ -6,24 +6,24 @@ class RSolr::HTTPClient::Adapter::Curb
6
6
  include RSolr::HTTPClient::Util
7
7
 
8
8
  attr :uri
9
- attr :c
9
+ attr :connection
10
10
 
11
11
  def initialize(url)
12
12
  @uri = URI.parse(url)
13
- @c = ::Curl::Easy.new
13
+ @connection = ::Curl::Easy.new
14
14
  end
15
15
 
16
16
  def get(path, params={})
17
- @c.url = _build_url(path, params)
18
- @c.multipart_form_post = false
19
- @c.perform
17
+ @connection.url = _build_url(path, params)
18
+ @connection.multipart_form_post = false
19
+ @connection.perform
20
20
  create_http_context(path, params)
21
21
  end
22
22
 
23
23
  def post(path, data, params={}, headers={})
24
- @c.url = _build_url(path, params)
25
- @c.headers = headers
26
- @c.http_post(data)
24
+ @connection.url = _build_url(path, params)
25
+ @connection.headers = headers
26
+ @connection.http_post(data)
27
27
  create_http_context(path, params, data, headers)
28
28
  end
29
29
 
@@ -31,9 +31,9 @@ class RSolr::HTTPClient::Adapter::Curb
31
31
 
32
32
  def create_http_context(path, params, data=nil, headers={})
33
33
  {
34
- :status_code=>@c.response_code.to_i,
35
- :url=>@c.url,
36
- :body=>@c.body_str,
34
+ :status_code=>@connection.response_code.to_i,
35
+ :url=>@connection.url,
36
+ :body=>@connection.body_str,
37
37
  :path=>path,
38
38
  :params=>params,
39
39
  :data=>data,
@@ -45,7 +45,7 @@ class RSolr::HTTPClient::Adapter::Curb
45
45
  url = @uri.scheme + '://' + @uri.host
46
46
  url += ':' + @uri.port.to_s if @uri.port
47
47
  url += @uri.path + path
48
- build_url(url, params, @uri.query)
48
+ build_url(url, params, @uri.query) # build_url is coming from RSolr::HTTPClient::Util
49
49
  end
50
50
 
51
51
  end
@@ -5,22 +5,22 @@ class RSolr::HTTPClient::Adapter::NetHTTP
5
5
  include RSolr::HTTPClient::Util
6
6
 
7
7
  attr :uri
8
- attr :c
8
+ attr :connection
9
9
 
10
10
  def initialize(url)
11
11
  @uri = URI.parse(url)
12
- @c = Net::HTTP.new(@uri.host, @uri.port)
12
+ @connection = Net::HTTP.new(@uri.host, @uri.port)
13
13
  end
14
14
 
15
15
  def get(path, params={})
16
16
  url = _build_url(path, params)
17
- net_http_response = @c.get(url)
17
+ net_http_response = @connection.get(url)
18
18
  create_http_context(net_http_response, url, path, params)
19
19
  end
20
20
 
21
21
  def post(path, data, params={}, headers={})
22
22
  url = _build_url(path, params)
23
- net_http_response = @c.post(url, data, headers)
23
+ net_http_response = @connection.post(url, data, headers)
24
24
  create_http_context(net_http_response, url, path, params, data, headers)
25
25
  end
26
26
 
@@ -42,7 +42,7 @@ class RSolr::HTTPClient::Adapter::NetHTTP
42
42
  end
43
43
 
44
44
  def _build_url(path, params={})
45
- build_url(@uri.path + path, params, @uri.query)
45
+ build_url(@uri.path + path, params, @uri.query) # build_url is coming from RSolr::HTTPClient::Util
46
46
  end
47
47
 
48
48
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mwmitchell-rsolr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Mitchell
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-07 00:00:00 -08:00
12
+ date: 2009-01-14 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -49,8 +49,6 @@ files:
49
49
  - lib/rsolr/http_client/adapter.rb
50
50
  - lib/rsolr/http_client.rb
51
51
  - lib/rsolr/indexer.rb
52
- - lib/rsolr/mapper/rss.rb
53
- - lib/rsolr/mapper.rb
54
52
  - lib/rsolr/message.rb
55
53
  - lib/rsolr/response/base.rb
56
54
  - lib/rsolr/response/index_info.rb
@@ -98,7 +96,6 @@ test_files:
98
96
  - test/http_client/test_methods.rb
99
97
  - test/http_client/util_test.rb
100
98
  - test/indexer.rb
101
- - test/mapper_test.rb
102
99
  - test/message_test.rb
103
100
  - test/response/base_test.rb
104
101
  - test/response/pagination_test.rb
data/lib/rsolr/indexer.rb DELETED
@@ -1,23 +0,0 @@
1
- class RSolr::Indexer
2
-
3
- attr_reader :solr, :mapper, :opts
4
-
5
- def initialize(solr, mapping_or_mapper, opts={})
6
- @solr = solr
7
- @mapper = mapping_or_mapper.is_a?(Hash) ? RSolr::Mapper::Base.new(mapping_or_mapper) : mapping_or_mapper
8
- @opts = opts
9
- end
10
-
11
- # data - the raw data to send into the mapper
12
- # params - url query params for solr /update handler
13
- # commit - boolean; true==commit after adding, false==no commit after adding
14
- # block can be used for modifying the "add", "doc" and "field" xml elements (for boosting etc.)
15
- def index(data, params={}, &block)
16
- docs = data.collect {|d| @mapper.map(d)}
17
- @solr.add(docs, params) do |add, doc, field|
18
- # check opts for :debug etc.?
19
- yield add, doc, field if block_given?
20
- end
21
- end
22
-
23
- end
data/lib/rsolr/mapper.rb DELETED
@@ -1,62 +0,0 @@
1
- module RSolr::Mapper
2
-
3
- autoload :RSS, 'rsolr/mapper/rss'
4
-
5
- class UnkownMappingValue < RuntimeError; end
6
-
7
- class Base
8
-
9
- attr_reader :mapping, :opts
10
-
11
- def initialize(mapping={}, opts={}, &block)
12
- @mapping = mapping
13
- @opts = opts
14
- yield @mapping if block_given?
15
- end
16
-
17
- # source - a hash or array of source data
18
- # override_mapping - an alternate mapper
19
- # returns an array with one or more mapped hashes
20
- def map(source, override_mapping=nil, &block)
21
- source = [source] if source.is_a?(Hash)
22
- mapping = override_mapping || @mapping
23
- index = -1
24
- # collect a bunch of hashes...
25
- source.collect do |src|
26
- index += 1
27
- # for each mapping item, inject data into a new hash
28
- final_hash = mapping.inject({}) do |a_new_hash, (map_key, map_value)|
29
- value = mapped_field_value(src, map_value, index)
30
- value.to_s.empty? ? a_new_hash : a_new_hash.merge!({map_key=>value})
31
- end
32
- yield final_hash if block_given?
33
- final_hash
34
- end
35
- end
36
-
37
- protected
38
-
39
- # This is a hook method useful for subclassing
40
- def source_field_value(source, field_name, index)
41
- source[field_name]
42
- end
43
-
44
- def mapped_field_value(source, mapped_value, index)
45
- case mapped_value
46
- when String
47
- mapped_value
48
- when Symbol
49
- source_field_value(source, mapped_value, index)
50
- when Proc
51
- mapped_value.call(source, index)
52
- when Enumerable
53
- mapped_value.collect {|key| source_field_value(source, key, index)}.flatten
54
- else
55
- # try to turn it into a string, else raise UnkownMappingValue
56
- mapped_value.respond_to?(:to_s) ? mapped_value.to_s : raise(UnkownMappingValue.new(mapped_value))
57
- end
58
- end
59
-
60
- end
61
-
62
- end
@@ -1,29 +0,0 @@
1
- #TODO - this could use the http wrapper stuff instead of open-uri/net::http
2
-
3
- require 'rss'
4
- require 'open-uri'
5
-
6
- class RSolr::Mapper::RSS < RSolr::Mapper::Base
7
-
8
- attr_reader :rss
9
-
10
- # rss_file_or_url is file path or url (see open-uri)
11
- # override_mapping is an alternate mapping (see Solr::Mapper::Base)
12
- # returns array of mapped hashes
13
- def map(rss_file_or_url, override_mapping=nil)
14
- open(rss_file_or_url) do |feed|
15
- @rss = RSS::Parser.parse(feed.read, false)
16
- super(rss.items.collect, override_mapping)
17
- end
18
- end
19
-
20
- # sends methods chain down into the @rss object
21
- # example: :'channel.title' == @rss.channel.title
22
- # if the method chain doesn't exist, the super #source_field_value method is called
23
- def source_field_value(source, method_path, index)
24
- method_path.to_s.split('.').inject(@rss) do |rss, m|
25
- rss.respond_to?(m) ? rss.send(m.to_sym) : super(source, method_path, index)
26
- end
27
- end
28
-
29
- end
data/test/mapper_test.rb DELETED
@@ -1,123 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'test_helpers')
2
-
3
- require 'rss'
4
-
5
- class MapperTest < RSolrBaseTest
6
-
7
- # simple replacement
8
- def test_string_map
9
- data = {
10
- :skip_this=>'!'
11
- }
12
- mapping = {
13
- :id=>'one',
14
- :name=>'foo'
15
- }
16
- mapper = RSolr::Mapper::Base.new(mapping)
17
- expected = [mapping]
18
- assert_equal expected, mapper.map(data)
19
- end
20
-
21
- def test_map_yields_if_block_given
22
- data = {
23
- :NUMID=>100,
24
- :type=>:type_val,
25
- :code=>:code_val
26
- }
27
- mapping = {
28
- :id=>:NUMID,
29
- :name=>'foo',
30
- :category=>[:type, :code]
31
- }
32
- mapper = RSolr::Mapper::Base.new(mapping)
33
- expected = [{:name=>"foo", :category=>[:type_val, :code_val], :id=>100}]
34
- result = mapper.map(data) do |doc|
35
- assert expected, doc
36
- end
37
- end
38
-
39
- # test enumerable/array mappings
40
- def test_array_multi_value
41
- data = {
42
- :NUMID=>100,
43
- :type=>:type_val,
44
- :code=>:code_val
45
- }
46
- mapping = {
47
- :id=>:NUMID,
48
- :name=>'foo',
49
- :category=>[:type, :code]
50
- }
51
- mapper = RSolr::Mapper::Base.new(mapping)
52
- expected = [{:name=>"foo", :category=>[:type_val, :code_val], :id=>100}]
53
- assert_equal expected, mapper.map(data)
54
- end
55
-
56
- # test the proc mapping type
57
- # test that the second arg in the block is a Solr::Mapper
58
- def test_proc
59
- data = [{:name=>'-bach;'}]
60
- mapping = {
61
- :name=>proc{|d,index|
62
- assert_equal Fixnum, index.class
63
- d[:name].gsub(/\W+/, '')
64
- }
65
- }
66
- mapper = RSolr::Mapper::Base.new(mapping)
67
- expected = [{:name=>"bach"}]
68
- assert_equal expected, mapper.map(data)
69
- end
70
-
71
- def rss_file
72
- @rss_file ||= File.join(File.dirname(__FILE__), 'ruby-lang.org.rss.xml')
73
- end
74
-
75
- # load an rss feed
76
- # create a mapping
77
- # map it and test the fields
78
- def raw_mapping_rss_docs
79
- rss = RSS::Parser.parse(File.read(rss_file), false)
80
- mapping = {
81
- :channel=>rss.channel.title,
82
- :url=>rss.channel.link,
83
- :total=>rss.items.size,
84
- :title=>proc {|item,index| item.title },
85
- :link=>proc{|item,index| item.link },
86
- :published=>proc{|item,index| item.date },
87
- :description=>proc{|item,index| item.description }
88
- }
89
- mapper = RSolr::Mapper::Base.new(mapping)
90
- mapper.map(rss.items)
91
- end
92
-
93
- # load an rss feed
94
- # create a mapping
95
- # map it and test the fields
96
- def rss_mapper_docs
97
- m = RSolr::Mapper::RSS.new
98
- mapping = {
99
- :channel=>:'channel.title',
100
- :url=>:'channel.link',
101
- :total=>:'items.size',
102
- :title=>proc {|item,index| item.title },
103
- :link=>proc {|item,index| item.link },
104
- :published=>proc {|item,index| item.date },
105
- :description=>proc {|item,index| item.description }
106
- }
107
- m.map(rss_file, mapping)
108
- end
109
-
110
- def test_rss
111
- [rss_mapper_docs, raw_mapping_rss_docs].each do |docs|
112
- assert_equal 10, docs.size
113
- first = docs.first
114
- # make sure the mapped solr docs have all of the keys from the mapping
115
- #assert mapping.keys.all?{|mapping_key| first.keys.include?(mapping_key) }
116
- assert_equal docs.size, docs.first[:total].to_i
117
- assert_equal Time.parse('Mon Nov 10 09:55:53 -0500 2008'), first[:published]
118
- assert_equal 'http://www.ruby-lang.org/en/feeds/news.rss/', first[:url]
119
- assert_equal 'Scotland on Rails 2009', first[:title]
120
- end
121
- end
122
-
123
- end