mwmitchell-rsolr 0.9.0 → 0.9.1

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/CHANGES.txt CHANGED
@@ -1,3 +1,6 @@
1
+ 0.9.1 - July 22, 2009
2
+ Added LibXml builder support (Thanks to Mat Brown - github.com/outoftime)
3
+
1
4
  0.9.0 - July 17, 2009
2
5
  Added ability to use DirectSolrConnection instance when connecting
3
6
  Loading Java classes using full package name
@@ -0,0 +1,85 @@
1
+ require 'builder'
2
+
3
+ class RSolr::Message::Builders::Builder
4
+
5
+ # shortcut method -> xml = RSolr::Message.xml
6
+ def xml
7
+ ::Builder::XmlMarkup.new
8
+ end
9
+
10
+ # generates "add" xml for updating solr
11
+ # "data" can be a hash or an array of hashes.
12
+ # - each hash should be a simple key=>value pair representing a solr doc.
13
+ # If a value is an array, multiple fields will be created.
14
+ #
15
+ # "add_attrs" can be a hash for setting the add xml element attributes.
16
+ #
17
+ # This method can also accept a block.
18
+ # The value yielded to the block is a Message::Document; for each solr doc in "data".
19
+ # You can set xml element attributes for each "doc" element or individual "field" elements.
20
+ #
21
+ # For example:
22
+ #
23
+ # solr.add({:id=>1, :nickname=>'Tim'}, {:boost=>5.0, :commitWithin=>1.0}) do |doc_msg|
24
+ # doc_msg.attrs[:boost] = 10.00 # boost the document
25
+ # nickname = doc_msg.field_by_name(:nickname)
26
+ # nickname.attrs[:boost] = 20 if nickname.value=='Tim' # boost a field
27
+ # end
28
+ #
29
+ # would result in an add element having the attributes boost="10.0"
30
+ # and a commitWithin="1.0".
31
+ # Each doc element would have a boost="10.0".
32
+ # The "nickname" field would have a boost="20.0"
33
+ # if the doc had a "nickname" field with the value of "Tim".
34
+ #
35
+ def add(documents, add_attrs={})
36
+ xml.add(add_attrs) do |add_node|
37
+ documents.each do |doc|
38
+ # create doc, passing in fields
39
+ add_node.doc(doc.attrs) do |doc_node|
40
+ doc.fields.each do |field_obj|
41
+ doc_node.field(field_obj.value, field_obj.attrs)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ # generates a <commit/> message
49
+ def commit(opts={})
50
+ xml.commit(opts)
51
+ end
52
+
53
+ # generates a <optimize/> message
54
+ def optimize(opts={})
55
+ xml.optimize(opts)
56
+ end
57
+
58
+ # generates a <rollback/> message
59
+ def rollback
60
+ xml.rollback
61
+ end
62
+
63
+ # generates a <delete><id>ID</id></delete> message
64
+ # "ids" can be a single value or array of values
65
+ def delete_by_id(ids)
66
+ ids = [ids] unless ids.is_a?(Array)
67
+ xml.delete do |xml|
68
+ ids.each do |id|
69
+ xml.id(id)
70
+ end
71
+ end
72
+ end
73
+
74
+ # generates a <delete><query>ID</query></delete> message
75
+ # "queries" can be a single value or an array of values
76
+ def delete_by_query(queries)
77
+ queries = [queries] unless queries.is_a?(Array)
78
+ xml.delete do |xml|
79
+ queries.each do |query|
80
+ xml.query(query)
81
+ end
82
+ end
83
+ end
84
+
85
+ end
@@ -0,0 +1,59 @@
1
+ require 'libxml'
2
+
3
+ class RSolr::Message::Builders::Libxml
4
+
5
+ def add(documents, attributes = {})
6
+ add_node = new_node('add', attributes)
7
+ for document in documents
8
+ add_node << doc_node = new_node('doc', document.attrs)
9
+ for field in document.fields
10
+ doc_node << field_node = new_node('field', field.attrs)
11
+ field_node << field.value
12
+ end
13
+ end
14
+ add_node.to_s(:indent => false)
15
+ end
16
+
17
+ def delete_by_id(ids)
18
+ delete = new_node('delete')
19
+ for id in Array(ids)
20
+ id_node = new_node('id')
21
+ id_node << id
22
+ delete << id_node
23
+ end
24
+ delete.to_s(:indent => false)
25
+ end
26
+
27
+ def delete_by_query(queries)
28
+ delete = new_node('delete')
29
+ for query in Array(queries)
30
+ query_node = new_node('query')
31
+ query_node << query
32
+ delete << query_node
33
+ end
34
+ delete.to_s(:indent => false)
35
+ end
36
+
37
+ def optimize(opts)
38
+ new_node('optimize', opts).to_s
39
+ end
40
+
41
+ def rollback
42
+ new_node('rollback').to_s
43
+ end
44
+
45
+ def commit(opts = {})
46
+ new_node('commit', opts).to_s
47
+ end
48
+
49
+ private
50
+
51
+ def new_node(name, opts = {})
52
+ node = LibXML::XML::Node.new(name)
53
+ opts.each_pair do |attr, value|
54
+ node[attr.to_s] = value.to_s
55
+ end
56
+ node
57
+ end
58
+
59
+ end
@@ -0,0 +1,6 @@
1
+ module RSolr::Message::Builders
2
+
3
+ autoload :Builder, 'rsolr/message/builders/builder'
4
+ autoload :Libxml, 'rsolr/message/builders/libxml'
5
+
6
+ end
data/lib/rsolr/message.rb CHANGED
@@ -1,11 +1,9 @@
1
- # http://builder.rubyforge.org/
2
- require 'rubygems'
3
- require 'builder'
4
-
5
1
  # The Solr::Message class is the XML generation module for sending updates to Solr.
6
2
 
7
3
  class RSolr::Message
8
4
 
5
+ autoload :Builders, 'rsolr/message/builders'
6
+
9
7
  # A class that represents a "doc" xml element for a solr update
10
8
  class Document
11
9
 
@@ -77,10 +75,10 @@ class RSolr::Message
77
75
  end
78
76
 
79
77
  class << self
80
-
81
- # shortcut method -> xml = RSolr::Message.xml
82
- def xml
83
- ::Builder::XmlMarkup.new
78
+ attr_writer :builder
79
+
80
+ def builder
81
+ @builder ||= Builders::Builder.new
84
82
  end
85
83
 
86
84
  # generates "add" xml for updating solr
@@ -108,59 +106,41 @@ class RSolr::Message
108
106
  # The "nickname" field would have a boost="20.0"
109
107
  # if the doc had a "nickname" field with the value of "Tim".
110
108
  #
111
- def add(data, add_attrs={}, &blk)
109
+ def add(data, add_attrs={})
112
110
  data = [data] unless data.is_a?(Array)
113
- xml.add(add_attrs) do |add_node|
114
- data.each do |doc|
115
- # create doc, passing in fields
116
- doc = Document.new(doc) if doc.respond_to?(:each_pair)
117
- yield doc if block_given?
118
- add_node.doc(doc.attrs) do |doc_node|
119
- doc.fields.each do |field_obj|
120
- doc_node.field(field_obj.value, field_obj.attrs)
121
- end
122
- end
123
- end
111
+ documents = data.map do |doc|
112
+ doc = Document.new(doc) if doc.respond_to?(:each_pair)
113
+ yield doc if block_given?
114
+ doc
124
115
  end
116
+ builder.add(documents, add_attrs)
125
117
  end
126
118
 
127
119
  # generates a <commit/> message
128
120
  def commit(opts={})
129
- xml.commit(opts)
121
+ builder.commit(opts)
130
122
  end
131
123
 
132
124
  # generates a <optimize/> message
133
125
  def optimize(opts={})
134
- xml.optimize(opts)
126
+ builder.optimize(opts)
135
127
  end
136
128
 
137
129
  # generates a <rollback/> message
138
130
  def rollback
139
- xml.rollback
131
+ builder.rollback
140
132
  end
141
133
 
142
134
  # generates a <delete><id>ID</id></delete> message
143
135
  # "ids" can be a single value or array of values
144
136
  def delete_by_id(ids)
145
- ids = [ids] unless ids.is_a?(Array)
146
- xml.delete do |xml|
147
- ids.each do |id|
148
- xml.id(id)
149
- end
150
- end
137
+ builder.delete_by_id(ids)
151
138
  end
152
139
 
153
140
  # generates a <delete><query>ID</query></delete> message
154
141
  # "queries" can be a single value or an array of values
155
142
  def delete_by_query(queries)
156
- queries = [queries] unless queries.is_a?(Array)
157
- xml.delete do |xml|
158
- queries.each do |query|
159
- xml.query(query)
160
- end
161
- end
143
+ builder.delete_by_query(queries)
162
144
  end
163
-
164
145
  end
165
-
166
146
  end
data/rsolr.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "rsolr"
3
- s.version = "0.9.0"
4
- s.date = "2009-07-17"
3
+ s.version = "0.9.1"
4
+ s.date = "2009-07-22"
5
5
  s.summary = "A Ruby client for Apache Solr"
6
6
  s.email = "goodieboy@gmail.com"
7
7
  s.homepage = "http://github.com/mwmitchell/rsolr"
@@ -20,6 +20,9 @@ Gem::Specification.new do |s|
20
20
  "lib/rsolr/http_client/adapter/net_http.rb",
21
21
  "lib/rsolr/http_client/adapter.rb",
22
22
  "lib/rsolr/http_client.rb",
23
+ "lib/rsolr/message/builders/builder.rb",
24
+ "lib/rsolr/message/builders/libxml.rb",
25
+ "lib/rsolr/message/builders.rb",
23
26
  "lib/rsolr/message.rb",
24
27
  "LICENSE",
25
28
  "Rakefile",
data/test/message_test.rb CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  require 'helper'
3
3
 
4
- class MessageTest < RSolrBaseTest
4
+ module MessageTestMethods
5
5
 
6
6
  # call all of the simple methods...
7
7
  # make sure the xml string is valid
@@ -13,7 +13,7 @@ class MessageTest < RSolrBaseTest
13
13
  assert_equal String, result.class
14
14
  end
15
15
  end
16
-
16
+
17
17
  def test_add_yields_doc_objects_if_block_given
18
18
  documents = [{:id=>1, :name=>'sam', :cat=>['cat 1', 'cat 2']}]
19
19
  add_attrs = {:boost=>200.00}
@@ -36,31 +36,31 @@ class MessageTest < RSolrBaseTest
36
36
  assert result =~ %r(boost="10")
37
37
  assert result =~ %r(<field name="id">1</field>)
38
38
  end
39
-
39
+
40
40
  def test_delete_by_id
41
41
  result = RSolr::Message.delete_by_id(10)
42
42
  assert_equal String, result.class
43
43
  assert_equal '<delete><id>10</id></delete>', result.to_s
44
44
  end
45
-
45
+
46
46
  def test_delete_by_multiple_ids
47
47
  result = RSolr::Message.delete_by_id([1, 2, 3])
48
48
  assert_equal String, result.class
49
49
  assert_equal '<delete><id>1</id><id>2</id><id>3</id></delete>', result.to_s
50
50
  end
51
-
51
+
52
52
  def test_delete_by_query
53
- result = RSolr::Message.delete_by_id('status:"LOST"')
53
+ result = RSolr::Message.delete_by_query('status:"LOST"')
54
54
  assert_equal String, result.class
55
- assert_equal '<delete><id>status:"LOST"</id></delete>', result.to_s
55
+ assert_equal '<delete><query>status:"LOST"</query></delete>', result.to_s
56
56
  end
57
-
57
+
58
58
  def test_delete_by_multiple_queries
59
- result = RSolr::Message.delete_by_id(['status:"LOST"', 'quantity:0'])
59
+ result = RSolr::Message.delete_by_query(['status:"LOST"', 'quantity:0'])
60
60
  assert_equal String, result.class
61
- assert_equal '<delete><id>status:"LOST"</id><id>quantity:0</id></delete>', result.to_s
61
+ assert_equal '<delete><query>status:"LOST"</query><query>quantity:0</query></delete>', result.to_s
62
62
  end
63
-
63
+
64
64
  # add a single hash ("doc")
65
65
  def test_add_hash
66
66
  data = {
@@ -70,7 +70,7 @@ class MessageTest < RSolrBaseTest
70
70
  assert RSolr::Message.add(data).to_s =~ /<field name="name">matt<\/field>/
71
71
  assert RSolr::Message.add(data).to_s =~ /<field name="id">1<\/field>/
72
72
  end
73
-
73
+
74
74
  # add an array of hashes
75
75
  def test_add_array
76
76
  data = [
@@ -83,35 +83,35 @@ class MessageTest < RSolrBaseTest
83
83
  :name=>'sam'
84
84
  }
85
85
  ]
86
-
86
+
87
87
  message = RSolr::Message.add(data)
88
88
  expected = '<add><doc><field name="id">1</field><field name="name">matt</field></doc><doc><field name="id">2</field><field name="name">sam</field></doc></add>'
89
-
89
+
90
90
  assert message.to_s=~/<field name="name">matt<\/field>/
91
91
  assert message.to_s=~/<field name="name">sam<\/field>/
92
92
  end
93
-
93
+
94
94
  # multiValue field support test, thanks to Fouad Mardini!
95
95
  def test_add_multi_valued_field
96
96
  data = {
97
97
  :id => 1,
98
98
  :name => ['matt1', 'matt2']
99
99
  }
100
-
100
+
101
101
  result = RSolr::Message.add(data)
102
-
102
+
103
103
  assert result.to_s =~ /<field name="name">matt1<\/field>/
104
104
  assert result.to_s =~ /<field name="name">matt2<\/field>/
105
105
  end
106
-
106
+
107
107
  def test_add_single_document
108
108
  document = RSolr::Message::Document.new
109
109
  document.add_field('id', 1)
110
110
  document.add_field('name', 'matt', :boost => 2.0)
111
111
  result = RSolr::Message.add(document)
112
-
112
+
113
113
  assert result.to_s =~ /<field name="id">1<\/field>/
114
-
114
+
115
115
  # depending on which ruby version, the attributes can be out of place
116
116
  # so we need to test both... there's gotta be a better way to do this?
117
117
  assert(
@@ -132,4 +132,33 @@ class MessageTest < RSolrBaseTest
132
132
  assert result.to_s =~ /<field name="name">matt1<\/field>/
133
133
  assert result.to_s =~ /<field name="name">matt2<\/field>/
134
134
  end
135
+
136
+ end
137
+
138
+ #####
139
+
140
+ unless defined?(JRUBY_VERSION)
141
+ class LibxmlMessageTest < RSolrBaseTest
142
+
143
+ include MessageTestMethods
144
+
145
+ def setup
146
+ RSolr::Message.builder = RSolr::Message::Builders::Libxml.new
147
+ end
148
+
149
+ end
135
150
  end
151
+
152
+
153
+ #####
154
+
155
+ class BuilderMessageTest < RSolrBaseTest
156
+
157
+ include MessageTestMethods
158
+
159
+ def setup
160
+ # RSolr::Message::Builders::Libxml.new
161
+ RSolr::Message.builder = RSolr::Message::Builders::Builder.new
162
+ end
163
+
164
+ 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.9.0
4
+ version: 0.9.1
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-07-17 00:00:00 -07:00
12
+ date: 2009-07-22 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -45,6 +45,9 @@ files:
45
45
  - lib/rsolr/http_client/adapter/net_http.rb
46
46
  - lib/rsolr/http_client/adapter.rb
47
47
  - lib/rsolr/http_client.rb
48
+ - lib/rsolr/message/builders/builder.rb
49
+ - lib/rsolr/message/builders/libxml.rb
50
+ - lib/rsolr/message/builders.rb
48
51
  - lib/rsolr/message.rb
49
52
  - LICENSE
50
53
  - Rakefile