solr-ruby 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/lib/solr/connection.rb +7 -3
  2. data/lib/solr/document.rb +2 -0
  3. data/lib/solr/field.rb +8 -4
  4. data/lib/solr/importer/array_mapper.rb +26 -0
  5. data/lib/solr/importer/delimited_file_source.rb +38 -0
  6. data/lib/solr/importer/hpricot_mapper.rb +20 -0
  7. data/lib/solr/importer/mapper.rb +51 -0
  8. data/lib/solr/importer/solr_source.rb +43 -0
  9. data/lib/solr/importer/xpath_mapper.rb +27 -0
  10. data/lib/solr/importer.rb +19 -0
  11. data/lib/solr/indexer.rb +54 -0
  12. data/lib/solr/request/base.rb +7 -0
  13. data/lib/solr/request/commit.rb +11 -1
  14. data/lib/solr/request/dismax.rb +5 -2
  15. data/lib/solr/request/index_info.rb +4 -2
  16. data/lib/solr/request/select.rb +4 -0
  17. data/lib/solr/request/standard.rb +14 -12
  18. data/lib/solr/request/update.rb +1 -0
  19. data/lib/solr/response/commit.rb +0 -15
  20. data/lib/solr/response/standard.rb +3 -4
  21. data/lib/solr/response/xml.rb +8 -3
  22. data/lib/solr/solrtasks.rb +27 -0
  23. data/lib/solr/util.rb +34 -0
  24. data/lib/solr.rb +4 -1
  25. data/test/unit/add_document_test.rb +3 -3
  26. data/test/unit/array_mapper_test.rb +37 -0
  27. data/test/unit/commit_test.rb +13 -13
  28. data/test/unit/data_mapper_test.rb +75 -0
  29. data/test/unit/delete_test.rb +1 -1
  30. data/test/unit/delimited_file_source_test.rb +29 -0
  31. data/test/unit/document_test.rb +6 -0
  32. data/test/unit/field_test.rb +6 -0
  33. data/test/unit/hpricot_mapper_test.rb +40 -0
  34. data/test/unit/hpricot_test_file.xml +7 -0
  35. data/test/unit/indexer_test.rb +57 -0
  36. data/test/unit/request_test.rb +1 -1
  37. data/test/unit/standard_request_test.rb +11 -0
  38. data/test/unit/suite.rb +4 -13
  39. data/test/unit/tab_delimited.txt +2 -0
  40. data/test/unit/util_test.rb +22 -0
  41. data/test/unit/xpath_mapper_test.rb +33 -0
  42. data/test/unit/xpath_test_file.xml +6 -0
  43. metadata +26 -5
@@ -12,6 +12,8 @@
12
12
 
13
13
  require 'net/http'
14
14
 
15
+ # TODO: add a convenience method to POST a Solr .xml file, like Solr's example post.sh
16
+
15
17
  class Solr::Connection
16
18
  attr_reader :url, :autocommit, :connection
17
19
 
@@ -40,6 +42,8 @@ class Solr::Connection
40
42
 
41
43
  # Not actually opening the connection yet, just setting up the persistent connection.
42
44
  @connection = Net::HTTP.new(@url.host, @url.port)
45
+
46
+ @connection.read_timeout = opts[:timeout] if opts[:timeout]
43
47
  end
44
48
 
45
49
  # add a document to the index. you can pass in either a hash
@@ -85,8 +89,8 @@ class Solr::Connection
85
89
  end
86
90
 
87
91
  # sends a commit message to the server
88
- def commit
89
- response = send(Solr::Request::Commit.new)
92
+ def commit(options={})
93
+ response = send(Solr::Request::Commit.new(options))
90
94
  return response.ok?
91
95
  end
92
96
 
@@ -136,7 +140,7 @@ class Solr::Connection
136
140
  def post(request)
137
141
  response = @connection.post(@url.path + "/" + request.handler,
138
142
  request.to_s,
139
- { "Content-Type" => "application/x-www-form-urlencoded; charset=utf-8" })
143
+ { "Content-Type" => request.content_type })
140
144
 
141
145
  case response
142
146
  when Net::HTTPSuccess then response.body
data/lib/solr/document.rb CHANGED
@@ -15,6 +15,7 @@ require 'solr/field'
15
15
 
16
16
  class Solr::Document
17
17
  include Enumerable
18
+ attr_accessor :boost
18
19
 
19
20
  # Create a new Solr::Document, optionally passing in a hash of
20
21
  # key/value pairs for the fields
@@ -65,6 +66,7 @@ class Solr::Document
65
66
  # convert the Document to a REXML::Element
66
67
  def to_xml
67
68
  e = Solr::XML::Element.new 'doc'
69
+ e.attributes['boost'] = @boost.to_s if @boost
68
70
  @fields.each {|f| e.add_element(f.to_xml)}
69
71
  return e
70
72
  end
data/lib/solr/field.rb CHANGED
@@ -14,13 +14,16 @@ require 'solr/xml'
14
14
  require 'time'
15
15
 
16
16
  class Solr::Field
17
+ VALID_PARAMS = [:boost]
17
18
  attr_accessor :name
18
19
  attr_accessor :value
20
+ attr_accessor :boost
19
21
 
20
- def initialize(key_val, opts={})
21
- raise "first argument must be a hash" unless key_val.kind_of? Hash
22
- @name = key_val.keys[0].to_s
23
- @value = key_val.values[0]
22
+ # Accepts an optional <tt>:boost</tt> parameter, used to boost the relevance of a particular field.
23
+ def initialize(params)
24
+ @boost = params[:boost]
25
+ name_key = (params.keys - VALID_PARAMS).first
26
+ @name, @value = name_key.to_s, params[name_key]
24
27
  # Convert any Time values into UTC/XML schema format (which Solr requires).
25
28
  @value = @value.respond_to?(:utc) ? @value.utc.xmlschema : @value.to_s
26
29
  end
@@ -28,6 +31,7 @@ class Solr::Field
28
31
  def to_xml
29
32
  e = Solr::XML::Element.new 'field'
30
33
  e.attributes['name'] = @name
34
+ e.attributes['boost'] = @boost.to_s if @boost
31
35
  e.text = @value
32
36
  return e
33
37
  end
@@ -0,0 +1,26 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+
14
+
15
+ class Solr::Importer::ArrayMapper < Solr::Importer::Mapper
16
+ # TODO document that initializer takes an array of Mappers [mapper1, mapper2, ... mapperN]
17
+
18
+ # TODO: make merge conflict handling configurable. as is, the last map fields win.
19
+ def map(orig_data_array)
20
+ mapped_data = {}
21
+ orig_data_array.each_with_index do |data,i|
22
+ mapped_data.merge!(@mapping[i].map(data))
23
+ end
24
+ mapped_data
25
+ end
26
+ end
@@ -0,0 +1,38 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ # For files with the first line containing field names
14
+ # Currently not designed for enormous files, as all lines are
15
+ # read into an array
16
+ class Solr::Importer::DelimitedFileSource
17
+ include Enumerable
18
+
19
+ def initialize(filename, splitter=/\t/)
20
+ @filename = filename
21
+ @splitter = splitter
22
+ end
23
+
24
+ def each
25
+ lines = IO.readlines(@filename)
26
+ headers = lines[0].split(@splitter).collect{|h| h.chomp}
27
+
28
+ lines[1..-1].each do |line|
29
+ data = headers.zip(line.split(@splitter).collect{|s| s.chomp})
30
+ def data.[](key)
31
+ self.assoc(key.to_s)[1]
32
+ end
33
+
34
+ yield(data)
35
+ end
36
+ end
37
+
38
+ end
@@ -0,0 +1,20 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'hpricot'
14
+
15
+ # For files with the first line containing field names
16
+ class Solr::Importer::HpricotMapper < Solr::Importer::Mapper
17
+ def field_data(doc, path)
18
+ doc.search(path.to_s).collect { |e| e.inner_html }
19
+ end
20
+ end
@@ -0,0 +1,51 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ class Solr::Importer::Mapper
14
+ def initialize(mapping, options={})
15
+ @mapping = mapping
16
+ @options = options
17
+ end
18
+
19
+ def field_data(orig_data, field_name)
20
+ orig_data[field_name]
21
+ end
22
+
23
+ def mapped_field_value(orig_data, field_mapping)
24
+ case field_mapping
25
+ when String
26
+ field_mapping
27
+ when Proc
28
+ field_mapping.call(orig_data)
29
+ when Symbol
30
+ field_data(orig_data, @options[:stringify_symbols] ? field_mapping.to_s : field_mapping)
31
+ when Enumerable
32
+ field_mapping.collect {|orig_field_name| mapped_field_value(orig_data, orig_field_name)}.flatten
33
+ else
34
+ raise "Unknown mapping for #{field_mapping}"
35
+ end
36
+ end
37
+
38
+ def map(orig_data)
39
+ mapped_data = {}
40
+ @mapping.each do |solr_name, field_mapping|
41
+ value = mapped_field_value(orig_data, field_mapping)
42
+ mapped_data[solr_name] = value if value
43
+ end
44
+
45
+ mapped_data
46
+ end
47
+
48
+
49
+
50
+
51
+ end
@@ -0,0 +1,43 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'solr'
14
+
15
+ class Solr::Importer::SolrSource
16
+ def initialize(solr_url, query, filter_queries, options={})
17
+ @connection = Solr::Connection.new(solr_url)
18
+ @query = query
19
+ @filter_queries = filter_queries
20
+
21
+ @page_size = options[:page_size] || 1000
22
+ @field_list = options[:field_list] || ["*"]
23
+ end
24
+
25
+ def each
26
+ done = false
27
+ start = 0
28
+ until done do
29
+ # request N documents from a starting point
30
+ request = Solr::Request::Standard.new(:query => @query,
31
+ :rows => @page_size,
32
+ :start => start,
33
+ :field_list => @field_list,
34
+ :filter_queries => @filter_queries)
35
+ response = @connection.send(request)
36
+ response.each do |doc|
37
+ yield doc # TODO: perhaps convert to HashWithIndifferentAccess.new(doc), so stringify_keys isn't necessary
38
+ end
39
+ done = start + @page_size >= response.total_hits
40
+ start = start + @page_size
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,27 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'xml/libxml'
14
+
15
+ # For files with the first line containing field names
16
+ class Solr::Importer::XPathMapper < Solr::Importer::Mapper
17
+ def field_data(doc, xpath)
18
+ doc.find(xpath.to_s).collect do |node|
19
+ case node
20
+ when XML::Attr
21
+ node.value
22
+ when XML::Node
23
+ node.content
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ module Solr; module Importer; end; end
14
+ require 'solr/importer/mapper'
15
+ require 'solr/importer/array_mapper'
16
+ require 'solr/importer/delimited_file_source'
17
+ require 'solr/importer/hpricot_mapper'
18
+ require 'solr/importer/xpath_mapper'
19
+ require 'solr/importer/solr_source'
@@ -0,0 +1,54 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ class Solr::Indexer
14
+ # deprecated, use Indexer.new(ds,mapping).index instead
15
+ def self.index(data_source, mapper_or_mapping, options={})
16
+ indexer = Solr::Indexer.new(data_source, mapper_or_mapping, options)
17
+ indexer.index
18
+ end
19
+
20
+ def initialize(data_source, mapper_or_mapping, options={})
21
+ solr_url = options[:solr_url] || ENV["SOLR_URL"] || "http://localhost:8983/solr"
22
+ @solr = Solr::Connection.new(solr_url, options) #TODO - these options contain the solr_url and debug keys also, so tidy up what gets passed
23
+
24
+ @data_source = data_source
25
+ @mapper = mapper_or_mapping.is_a?(Hash) ? Solr::Importer::Mapper.new(mapper_or_mapping) : mapper_or_mapping
26
+
27
+ @buffer_docs = options[:buffer_docs]
28
+ @debug = options[:debug]
29
+ end
30
+
31
+ def index
32
+ buffer = []
33
+ @data_source.each do |record|
34
+ document = @mapper.map(record)
35
+
36
+ yield(record, document) if block_given? # TODO check return of block, if not true then don't index
37
+
38
+ buffer << document
39
+
40
+ if !@buffer_docs || buffer.size == @buffer_docs
41
+ add_docs(buffer)
42
+ buffer.clear
43
+ end
44
+ end
45
+ add_docs(buffer) if !buffer.empty?
46
+
47
+ @solr.commit unless @debug
48
+ end
49
+
50
+ def add_docs(documents)
51
+ @solr.add(documents) unless @debug
52
+ puts documents.inspect if @debug
53
+ end
54
+ end
@@ -11,6 +11,9 @@
11
11
  # limitations under the License.
12
12
 
13
13
  class Solr::Request::Base
14
+
15
+
16
+ #TODO : Add base support for the debugQuery flag, and such that the response provides debug output easily
14
17
 
15
18
  # returns either :xml or :ruby depending on what the
16
19
  # response type is for a given request
@@ -18,6 +21,10 @@ class Solr::Request::Base
18
21
  def response_format
19
22
  raise "unknown request type: #{self.class}"
20
23
  end
24
+
25
+ def content_type
26
+ 'text/xml; charset=utf-8'
27
+ end
21
28
 
22
29
  # returns the solr handler or url fragment that can
23
30
  # respond to this type of request
@@ -14,8 +14,18 @@ require 'solr/xml'
14
14
 
15
15
  class Solr::Request::Commit < Solr::Request::Update
16
16
 
17
+ def initialize(options={})
18
+ @wait_searcher = options[:wait_searcher] || true
19
+ @wait_flush = options[:wait_flush] || true
20
+ end
21
+
22
+
17
23
  def to_s
18
- Solr::XML::Element.new('commit').to_s
24
+ e = Solr::XML::Element.new('commit')
25
+ e.attributes['waitSearcher'] = @wait_searcher ? 'true' : 'false'
26
+ e.attributes['waitFlush'] = @wait_flush ? 'true' : 'false'
27
+
28
+ e.to_s
19
29
  end
20
30
 
21
31
  end
@@ -16,9 +16,11 @@ class Solr::Request::Dismax < Solr::Request::Standard
16
16
  :boost_query, :boost_functions])
17
17
 
18
18
  def initialize(params)
19
+ @alternate_query = params.delete(:alternate_query)
20
+ @sort_values = params.delete(:sort)
21
+
19
22
  super(params)
20
- @sort_values = @params[:sort]
21
- @params.delete(:sort)
23
+
22
24
  @query_type = "dismax"
23
25
  end
24
26
 
@@ -31,6 +33,7 @@ class Solr::Request::Dismax < Solr::Request::Standard
31
33
  hash[:ps] = @params[:phrase_slop]
32
34
  hash[:bq] = @params[:boost_query]
33
35
  hash[:bf] = @params[:boost_functions]
36
+ hash["q.alt"] = @alternate_query
34
37
  # FIXME: 2007-02-13 <coda.hale@gmail.com> -- This code is duplicated in
35
38
  # Solr::Request::Standard. It should be refactored into a single location.
36
39
  hash[:sort] = @sort_values.collect do |sort|
@@ -11,7 +11,9 @@
11
11
  # limitations under the License.
12
12
 
13
13
  class Solr::Request::IndexInfo < Solr::Request::Select
14
- def initialize
15
- super('indexinfo')
14
+
15
+ def handler
16
+ 'admin/luke'
16
17
  end
18
+
17
19
  end
@@ -31,6 +31,10 @@ class Solr::Request::Select < Solr::Request::Base
31
31
  def handler
32
32
  'select'
33
33
  end
34
+
35
+ def content_type
36
+ 'application/x-www-form-urlencoded; charset=utf-8'
37
+ end
34
38
 
35
39
  def to_hash
36
40
  return {:qt => query_type, :wt => 'ruby'}
@@ -71,18 +71,20 @@ class Solr::Request::Standard < Solr::Request::Select
71
71
  hash["facet.missing"] = @params[:facets][:missing]
72
72
  hash["facet.mincount"] = @params[:facets][:mincount]
73
73
  hash["facet.prefix"] = @params[:facets][:prefix]
74
- @params[:facets][:fields].each do |f|
75
- if f.kind_of? Hash
76
- key = f.keys[0]
77
- value = f[key]
78
- hash["facet.field"] << key
79
- hash["f.#{key}.facet.sort"] = (value[:sort] == :count) if value[:sort]
80
- hash["f.#{key}.facet.limit"] = value[:limit]
81
- hash["f.#{key}.facet.missing"] = value[:missing]
82
- hash["f.#{key}.facet.mincount"] = value[:mincount]
83
- hash["f.#{key}.facet.prefix"] = value[:prefix]
84
- else
85
- hash["facet.field"] << f
74
+ if @params[:facets][:fields] # facet fields are optional (could be facet.query only)
75
+ @params[:facets][:fields].each do |f|
76
+ if f.kind_of? Hash
77
+ key = f.keys[0]
78
+ value = f[key]
79
+ hash["facet.field"] << key
80
+ hash["f.#{key}.facet.sort"] = (value[:sort] == :count) if value[:sort]
81
+ hash["f.#{key}.facet.limit"] = value[:limit]
82
+ hash["f.#{key}.facet.missing"] = value[:missing]
83
+ hash["f.#{key}.facet.mincount"] = value[:mincount]
84
+ hash["f.#{key}.facet.prefix"] = value[:prefix]
85
+ else
86
+ hash["facet.field"] << f
87
+ end
86
88
  end
87
89
  end
88
90
  end
@@ -11,6 +11,7 @@
11
11
  # limitations under the License.
12
12
 
13
13
  # a parent class for all requests that go through the solr update handler
14
+ # TODO: Use new xml update handler for better error responses
14
15
  class Solr::Request::Update < Solr::Request::Base
15
16
  def response_format
16
17
  :xml
@@ -13,20 +13,5 @@
13
13
  require 'rexml/xpath'
14
14
 
15
15
  class Solr::Response::Commit < Solr::Response::Xml
16
- attr_reader :ok
17
-
18
- def initialize(xml)
19
- super(xml)
20
- e = REXML::XPath.first(@doc, './result')
21
- if e and e.attributes['status'] == '0'
22
- @ok = true
23
- else
24
- @ok = false
25
- end
26
- end
27
-
28
- def ok?
29
- @ok
30
- end
31
16
  end
32
17
 
@@ -39,16 +39,15 @@ class Solr::Response::Standard < Solr::Response::Ruby
39
39
  def field_facets(field)
40
40
  facets = []
41
41
  values = @data['facet_counts']['facet_fields'][field]
42
- 0.upto(values.size / 2 - 1) do |i|
43
- n = i * 2
44
- facets << FacetValue.new(values[n], values[n+1])
42
+ Solr::Util.paired_array_each(values) do |key, value|
43
+ facets << FacetValue.new(key, value)
45
44
  end
46
45
 
47
46
  facets
48
47
  end
49
48
 
50
49
  def highlighted(id, field)
51
- @data['highlighting'][id.to_s][field.to_s]
50
+ @data['highlighting'][id.to_s][field.to_s] rescue nil
52
51
  end
53
52
 
54
53
  # supports enumeration of hits
@@ -20,11 +20,16 @@ class Solr::Response::Xml < Solr::Response::Base
20
20
  super(xml)
21
21
  # parse the xml
22
22
  @doc = REXML::Document.new(xml)
23
+
23
24
  # look for the result code and string
24
- result = REXML::XPath.first(@doc, './result')
25
+ # <?xml version="1.0" encoding="UTF-8"?>
26
+ # <response>
27
+ # <lst name="responseHeader"><int name="status">0</int><int name="QTime">2</int></lst>
28
+ # </response>
29
+ result = REXML::XPath.first(@doc, './response/lst[@name="responseHeader"]/int[@name="status"]')
25
30
  if result
26
- @status_code = result.attributes['status']
27
- @status_message = result.text
31
+ @status_code = result.text
32
+ @status_message = result.text # TODO: any need for a message?
28
33
  end
29
34
  rescue REXML::ParseException => e
30
35
  raise Solr::Exception.new("invalid response xml: #{e}")
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # The ASF licenses this file to You under the Apache License, Version 2.0
3
+ # (the "License"); you may not use this file except in compliance with
4
+ # the License. You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+
14
+ # TODO: fill out Solr tasks: start, stop, ping, optimize, etc.
15
+
16
+ require 'rake'
17
+ require 'rake/tasklib'
18
+
19
+ module Solr
20
+ namespace :solr do
21
+ desc "Start Solr"
22
+ task :start do
23
+ # TODO: actually start it up!
24
+ puts "Starting..."
25
+ end
26
+ end
27
+ end
data/lib/solr/util.rb ADDED
@@ -0,0 +1,34 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ class Solr::Util
14
+ # paired_array_each([key1,value1,key2,value2]) yields twice:
15
+ # |key1,value1| and |key2,value2|
16
+ def self.paired_array_each(a, &block)
17
+ 0.upto(a.size / 2 - 1) do |i|
18
+ n = i * 2
19
+ yield(a[n], a[n+1])
20
+ end
21
+ end
22
+
23
+ # paired_array_to_hash([key1,value1,key2,value2]) => {key1 => value1, key2, value2}
24
+ def self.paired_array_to_hash(a)
25
+ h = {}
26
+
27
+ paired_array_each(a) do |key,value|
28
+ h[key] = value
29
+ end
30
+
31
+ h
32
+ end
33
+
34
+ end
data/lib/solr.rb CHANGED
@@ -15,4 +15,7 @@ require 'solr/exception'
15
15
  require 'solr/request'
16
16
  require 'solr/connection'
17
17
  require 'solr/response'
18
- require 'solr/xml'
18
+ require 'solr/util'
19
+ require 'solr/xml'
20
+ require 'solr/importer'
21
+ require 'solr/indexer'
@@ -16,7 +16,7 @@ class AddDocumentTest < SolrMockBaseTestCase
16
16
 
17
17
  def test_add_document_response
18
18
  conn = Solr::Connection.new('http://localhost:9999/solr')
19
- set_post_return('<result status="0"></result>')
19
+ set_post_return('<?xml version="1.0" encoding="UTF-8"?><response><lst name="responseHeader"><int name="status">0</int><int name="QTime">2</int></lst></response>')
20
20
  doc = {:id => '123', :text => 'Tlon, Uqbar, Orbis Tertius'}
21
21
  response = conn.send(Solr::Request::AddDocument.new(doc))
22
22
  assert_equal true, response.ok?
@@ -24,7 +24,7 @@ class AddDocumentTest < SolrMockBaseTestCase
24
24
 
25
25
  def test_bad_add_document_response
26
26
  conn = Solr::Connection.new('http://localhost:9999/solr')
27
- set_post_return('<result status="400"></result>')
27
+ set_post_return('<?xml version="1.0" encoding="UTF-8"?><response><lst name="responseHeader"><int name="status">1</int><int name="QTime">2</int></lst></response>')
28
28
  doc = {:id => '123', :text => 'Tlon, Uqbar, Orbis Tertius'}
29
29
  response = conn.send(Solr::Request::AddDocument.new(doc))
30
30
  assert_equal false, response.ok?
@@ -32,7 +32,7 @@ class AddDocumentTest < SolrMockBaseTestCase
32
32
 
33
33
  def test_shorthand
34
34
  conn = Solr::Connection.new('http://localhost:9999/solr')
35
- set_post_return('<result status="0"></result>')
35
+ set_post_return('<?xml version="1.0" encoding="UTF-8"?><response><lst name="responseHeader"><int name="status">0</int><int name="QTime">2</int></lst></response>')
36
36
  doc = {:id => '123', :text => 'Tlon, Uqbar, Orbis Tertius'}
37
37
  assert_equal true, conn.add(:id => '123', :text => 'Tlon, Uqbar, Orbis Tetius')
38
38
  end
@@ -0,0 +1,37 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'solr'
14
+ require 'test/unit'
15
+
16
+ include Solr::Importer
17
+
18
+ class ArrayMapperTest < Test::Unit::TestCase
19
+ def test_simple
20
+ mapping1 = {:one => "uno"}
21
+ mapping2 = {:two => "dos"}
22
+
23
+ mapper = Solr::Importer::ArrayMapper.new([Mapper.new(mapping1),Mapper.new(mapping2)])
24
+ mapped_data = mapper.map([{},{}])
25
+ assert_equal "uno", mapped_data[:one]
26
+ assert_equal "dos", mapped_data[:two]
27
+ end
28
+
29
+ def test_field_conflict_goes_to_last
30
+ mapping1 = {:same => "uno"}
31
+ mapping2 = {:same => "dos"}
32
+
33
+ mapper = Solr::Importer::ArrayMapper.new([Mapper.new(mapping1),Mapper.new(mapping2)])
34
+ mapped_data = mapper.map([{},{}])
35
+ assert_equal "dos", mapped_data[:same]
36
+ end
37
+ end
@@ -15,27 +15,27 @@ require 'solr_mock_base'
15
15
  class CommitTest < SolrMockBaseTestCase
16
16
 
17
17
  def test_commit
18
- xml = '<result status="0"></result>'
18
+ xml = '<?xml version="1.0" encoding="UTF-8"?><response><lst name="responseHeader"><int name="status">0</int><int name="QTime">2</int></lst></response>'
19
19
  conn = Solr::Connection.new('http://localhost:9999/solr')
20
20
  set_post_return(xml)
21
21
  response = conn.send(Solr::Request::Commit.new)
22
22
  assert_kind_of Solr::Response::Commit, response
23
- assert true, response.ok?
23
+ assert_equal true, response.ok?
24
24
 
25
25
  # test shorthand
26
26
  assert_equal true, conn.commit
27
27
  end
28
28
 
29
- def test_invalid_commit
30
- xml = '<foo>bar</foo>'
31
- conn = Solr::Connection.new('http://localhost:9999/solr')
32
- set_post_return(xml)
33
- response = conn.send(Solr::Request::Commit.new)
34
- assert_kind_of Solr::Response::Commit, response
35
- assert_equal false, response.ok?
36
-
37
- # test shorthand
38
- assert_equal false, conn.commit
39
- end
29
+ # def test_invalid_commit
30
+ # xml = '<?xml version="1.0" encoding="UTF-8"?><response><lst name="responseHeader"><int name="status">1</int><int name="QTime">2</int></lst></response>'
31
+ # conn = Solr::Connection.new('http://localhost:9999/solr')
32
+ # set_post_return(xml)
33
+ # response = conn.send(Solr::Request::Commit.new)
34
+ # assert_kind_of Solr::Response::Commit, response
35
+ # assert_equal false, response.ok?
36
+ #
37
+ # # test shorthand
38
+ # assert_equal false, conn.commit
39
+ # end
40
40
 
41
41
  end
@@ -0,0 +1,75 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'solr'
14
+ require 'test/unit'
15
+
16
+ class DataMapperTest < Test::Unit::TestCase
17
+
18
+ def test_static_mapping
19
+ mapping = {:static => "value",
20
+ :static_array => ["value1", "value2"]}
21
+
22
+ mapper = Solr::Importer::Mapper.new(mapping)
23
+ mapped_data = mapper.map({})
24
+
25
+ assert_equal "value", mapped_data[:static]
26
+ assert_equal ["value1", "value2"], mapped_data[:static_array]
27
+ end
28
+
29
+ def test_simple_mapping
30
+ orig_data = {:orig_field => "value",
31
+ :multi1 => "val1", :multi2 => "val2"}
32
+ mapping = {:solr_field => :orig_field,
33
+ :mapped_array => [:multi1, :multi2], }
34
+
35
+ mapper = Solr::Importer::Mapper.new(mapping)
36
+ mapped_data = mapper.map(orig_data)
37
+
38
+ assert_equal "value", mapped_data[:solr_field]
39
+ assert_equal ["val1", "val2"], mapped_data[:mapped_array]
40
+ end
41
+
42
+ def test_proc
43
+ orig_data = {:orig_field => "value"}
44
+ mapping = {:solr_field => Proc.new {|record| ">#{record[:orig_field]}<"}}
45
+
46
+ mapper = Solr::Importer::Mapper.new(mapping)
47
+ mapped_data = mapper.map(orig_data)
48
+
49
+ assert_equal ">value<", mapped_data[:solr_field]
50
+ end
51
+
52
+ def test_overridden_field
53
+ mapping = {:solr_field => [:orig_field1, :orig_field2]}
54
+ orig_data = {:orig_field1 => "value1", :orig_field2 => "value2", }
55
+
56
+ mapper = Solr::Importer::Mapper.new(mapping)
57
+ def mapper.field_data(orig_data, field_name)
58
+ ["~#{super(orig_data, field_name)}~"] # array tests that the value is flattened
59
+ end
60
+ mapped_data = mapper.map(orig_data)
61
+
62
+ assert_equal ["~value1~", "~value2~"], mapped_data[:solr_field]
63
+ end
64
+
65
+ def test_unknown_mapping
66
+ mapping = {:solr_field => /foo/} # regexp currently not a valid mapping type
67
+
68
+ mapper = Solr::Importer::Mapper.new(mapping)
69
+
70
+ assert_raise(RuntimeError) do
71
+ mapped_data = mapper.map({})
72
+ end
73
+ end
74
+
75
+ end
@@ -26,7 +26,7 @@ class DeleteTest < SolrMockBaseTestCase
26
26
 
27
27
  def test_delete_response
28
28
  conn = Solr::Connection.new 'http://localhost:9999/solr'
29
- set_post_return('<result status="0"></result>')
29
+ set_post_return('<?xml version="1.0" encoding="UTF-8"?><response><lst name="responseHeader"><int name="status">0</int><int name="QTime">2</int></lst></response>')
30
30
  response = conn.send(Solr::Request::Delete.new(:id => 123))
31
31
  assert_equal true, response.ok?
32
32
  end
@@ -0,0 +1,29 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'solr'
14
+ require 'test/unit'
15
+
16
+ class DelimitedFileSourceTest < Test::Unit::TestCase
17
+
18
+ def test_load
19
+ filename = File.expand_path(File.dirname(__FILE__)) + "/tab_delimited.txt"
20
+
21
+ source = Solr::Importer::DelimitedFileSource.new(filename,/\t/)
22
+ assert_equal source.to_a.size, 1
23
+
24
+ source.each do |data|
25
+ assert_equal data[:asin], '0865681740'
26
+ end
27
+ end
28
+
29
+ end
@@ -55,5 +55,11 @@ class DocumentTest < Test::Unit::TestCase
55
55
  assert_equal 'Lucene in Action', doc[:title]
56
56
  assert_equal 'Search', doc[:subject]
57
57
  end
58
+
59
+ def test_boost
60
+ doc = Solr::Document.new :name => "McGrump"
61
+ doc.boost = 300.28
62
+ assert_match(/<doc boost=['"]300.28['"]>[\s]+<field name=['"]name['"]>McGrump<\/field>[\s]+<\/doc>/, doc.to_xml.to_s)
63
+ end
58
64
 
59
65
  end
@@ -39,4 +39,10 @@ class FieldTest < Test::Unit::TestCase
39
39
  assert_match(/<field name=["']i18nstring["']>Äêâîôû Öëäïöü<\/field>/m, field.to_xml.to_s)
40
40
  end
41
41
 
42
+ def test_boost_values
43
+ field = Solr::Field.new(:blah => "squee", :boost => 3.0)
44
+ assert_kind_of Solr::XML::Element, field.to_xml
45
+ assert_match(/<field name=["']blah["'] boost=["']3.0["']>squee<\/field>/, field.to_xml.to_s)
46
+ end
47
+
42
48
  end
@@ -0,0 +1,40 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'solr'
14
+ require 'test/unit'
15
+ require 'hpricot'
16
+
17
+ class HpricotMapperTest < Test::Unit::TestCase
18
+
19
+ def setup
20
+ @doc = open(File.expand_path(File.dirname(__FILE__)) + "/hpricot_test_file.xml"){|f| Hpricot.XML(f)}
21
+ end
22
+
23
+ def test_simple_hpricot_path
24
+ mapping = {:field1 => :'child[@attribute="attribute1"]',
25
+ :field2 => :'child[@attribute="attribute2"]',
26
+ :field3 => :'child[@attribute="attribute3"]',
27
+ :field4 => :'child[@attribute="attribute3"] grandchild',
28
+ :field5 => :'child'}
29
+
30
+ mapper = Solr::Importer::HpricotMapper.new(mapping)
31
+ mapped_data = mapper.map(@doc)
32
+
33
+ assert_equal ['text1'], mapped_data[:field1]
34
+ assert_equal ['text2'], mapped_data[:field2]
35
+ assert_equal ['text3<grandchild>grandchild 3 text</grandchild>'], mapped_data[:field3]
36
+ assert_equal ['grandchild 3 text'], mapped_data[:field4]
37
+ assert_equal ['text1', 'text2', 'text3<grandchild>grandchild 3 text</grandchild>'], mapped_data[:field5]
38
+ end
39
+
40
+ end
@@ -0,0 +1,7 @@
1
+ <root>
2
+ <parent>
3
+ <child attribute="attribute1">text1</child>
4
+ <child attribute="attribute2">text2</child>
5
+ <child attribute="attribute3">text3<grandchild>grandchild 3 text</grandchild></child>
6
+ </parent>
7
+ </root>
@@ -0,0 +1,57 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'test/unit'
14
+ require 'solr'
15
+
16
+ class Solr::Indexer
17
+ attr_reader :added
18
+ def add_docs(doc)
19
+ @added ||= []
20
+ @added << doc
21
+ end
22
+ end
23
+
24
+ class IndexerTest < Test::Unit::TestCase
25
+ def test_mapping_or_mapping
26
+ mapping = {:field => "foo"}
27
+ indexer = Solr::Indexer.new([1,2,3], mapping, :debug => true)
28
+ indexer.index
29
+ assert_equal 3, indexer.added.size
30
+
31
+ indexer = Solr::Indexer.new([1,2,3,4], Solr::Importer::Mapper.new(mapping), :debug => true)
32
+ indexer.index
33
+ assert_equal 4, indexer.added.size
34
+ end
35
+
36
+ def test_batch
37
+ mapping = {:field => "foo"}
38
+ indexer = Solr::Indexer.new([1,2,3], mapping, :debug => true, :buffer_docs => 2)
39
+ indexer.index
40
+ assert_equal 2, indexer.added.size
41
+ end
42
+
43
+ end
44
+
45
+
46
+ # source = DataSource.new
47
+ #
48
+ # mapping = {
49
+ # :id => :isbn,
50
+ # :name => :author,
51
+ # :source => "BOOKS",
52
+ # :year => Proc.new {|record| record.date[0,4] },
53
+ # }
54
+ #
55
+ # Solr::Indexer.index(source, mapper) do |orig_data, solr_document|
56
+ # solr_document[:timestamp] = Time.now
57
+ # end
@@ -22,7 +22,7 @@ class RequestTest < Test::Unit::TestCase
22
22
  request = Solr::Request::Commit.new
23
23
  assert_equal :xml, request.response_format
24
24
  assert_equal 'update', request.handler
25
- assert_equal '<commit/>', request.to_s
25
+ assert_equal '<commit waitSearcher="true" waitFlush="true"/>', request.to_s
26
26
  end
27
27
 
28
28
  def test_add_doc_request
@@ -55,6 +55,17 @@ class StandardRequestTest < Test::Unit::TestCase
55
55
  assert_match /debugQuery/, request.to_s
56
56
  end
57
57
 
58
+ def test_only_facet_query
59
+ request = Solr::Request::Standard.new(:query => 'query',
60
+ :facets => {
61
+ :queries => ["q1", "q2"],
62
+ }
63
+ )
64
+
65
+ hash = request.to_hash
66
+ assert_equal ["q1", "q2"], hash["facet.query"]
67
+ end
68
+
58
69
  def test_facet_params_all
59
70
  request = Solr::Request::Standard.new(:query => 'query',
60
71
  :facets => {
data/test/unit/suite.rb CHANGED
@@ -10,16 +10,7 @@
10
10
  # See the License for the specific language governing permissions and
11
11
  # limitations under the License.
12
12
 
13
- # TODO dynamically require all *_test files
14
-
15
- require 'add_document_test'
16
- require 'commit_test'
17
- require 'connection_test'
18
- require 'delete_test'
19
- require 'document_test'
20
- require 'field_test'
21
- require 'ping_test'
22
- require 'request_test'
23
- require 'response_test'
24
- require 'standard_request_test'
25
- require 'standard_response_test'
13
+ # dynamically require all tests files
14
+ Dir.glob("*_test.rb").each do | file |
15
+ require file
16
+ end
@@ -0,0 +1,2 @@
1
+ medium associatedURL boxHeightInInches boxLengthInInches boxWeightInPounds boxWidthInInches scannednumber upc asin country title fullTitle series numberInSeries edition aspect mediacount genre price currentValue language netrating description owner publisher published rare purchaseDate rating used signed hasExperienced notes location paid condition notowned author illustrator pages
2
+ book 9780865681743 0865681740 us Xing Yi Nei Gong: Xing Yi Health Maintenance and Internal Strength Development Xing Yi Nei Gong: Xing Yi Health Maintenance and Internal Strength Development Paperback $21.95 $14.05 4.5 This is the most complete book on the art of xing yi (hsing Yi) available. It includes the complete xing yi history and lineage going back eight generations; manuscripts handed down from famous practitioners Dai Long Bang and Li Neng Ran; 16 health maintenance and power development exercises; qigong (chi kung) exerices; xing yi long spear power training exercises; and more. Unique Publications 1998-02-10 12:00:00 +0000 2007-02-03 02:22:25 -0500 Dan Miller/ Tim Cartmell 200
@@ -0,0 +1,22 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'solr'
14
+ require 'test/unit'
15
+
16
+ class UtilTest < Test::Unit::TestCase
17
+
18
+ def test_paired_array_to_hash
19
+ assert_equal({:key1 => :value1, :key2 => :value2}, Solr::Util.paired_array_to_hash([:key1, :value1, :key2, :value2]))
20
+ end
21
+
22
+ end
@@ -0,0 +1,33 @@
1
+ # The ASF licenses this file to You under the Apache License, Version 2.0
2
+ # (the "License"); you may not use this file except in compliance with
3
+ # the License. You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'solr'
14
+ require 'test/unit'
15
+
16
+ class XPathMapperTest < Test::Unit::TestCase
17
+
18
+ def setup
19
+ @doc = XML::Document.file(File.expand_path(File.dirname(__FILE__)) + "/xpath_test_file.xml")
20
+ end
21
+
22
+ def test_simple_xpath
23
+ mapping = {:solr_field1 => :'/root/parent/child',
24
+ :solr_field2 => :'/root/parent/child/@attribute'}
25
+
26
+ mapper = Solr::Importer::XPathMapper.new(mapping)
27
+ mapped_data = mapper.map(@doc)
28
+
29
+ assert_equal ['text1', 'text2'], mapped_data[:solr_field1]
30
+ assert_equal ['attribute1', 'attribute2'], mapped_data[:solr_field2]
31
+ end
32
+
33
+ end
@@ -0,0 +1,6 @@
1
+ <root>
2
+ <parent>
3
+ <child attribute="attribute1">text1</child>
4
+ <child attribute="attribute2">text2</child>
5
+ </parent>
6
+ </root>
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.0
2
+ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: solr-ruby
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.1
7
- date: 2007-02-15 00:00:00 -05:00
6
+ version: 0.0.2
7
+ date: 2007-05-14 00:00:00 -04:00
8
8
  summary: Ruby library for working with Apache Solr
9
9
  require_paths:
10
10
  - lib
11
- email: solr-user@lucene.apache.org
12
- homepage: http://wiki.apache.org/solr/Flare
11
+ email: ruby-dev@lucene.apache.org
12
+ homepage: http://wiki.apache.org/solr/solr-ruby
13
13
  rubyforge_project:
14
14
  description:
15
15
  autorequire: solr
@@ -35,11 +35,22 @@ files:
35
35
  - lib/solr/document.rb
36
36
  - lib/solr/exception.rb
37
37
  - lib/solr/field.rb
38
+ - lib/solr/importer
39
+ - lib/solr/importer.rb
40
+ - lib/solr/indexer.rb
38
41
  - lib/solr/request
39
42
  - lib/solr/request.rb
40
43
  - lib/solr/response
41
44
  - lib/solr/response.rb
45
+ - lib/solr/solrtasks.rb
46
+ - lib/solr/util.rb
42
47
  - lib/solr/xml.rb
48
+ - lib/solr/importer/array_mapper.rb
49
+ - lib/solr/importer/delimited_file_source.rb
50
+ - lib/solr/importer/hpricot_mapper.rb
51
+ - lib/solr/importer/mapper.rb
52
+ - lib/solr/importer/solr_source.rb
53
+ - lib/solr/importer/xpath_mapper.rb
43
54
  - lib/solr/request/add_document.rb
44
55
  - lib/solr/request/base.rb
45
56
  - lib/solr/request/commit.rb
@@ -63,12 +74,18 @@ files:
63
74
  - lib/solr/response/standard.rb
64
75
  - lib/solr/response/xml.rb
65
76
  - test/unit/add_document_test.rb
77
+ - test/unit/array_mapper_test.rb
66
78
  - test/unit/commit_test.rb
67
79
  - test/unit/connection_test.rb
80
+ - test/unit/data_mapper_test.rb
68
81
  - test/unit/delete_test.rb
82
+ - test/unit/delimited_file_source_test.rb
69
83
  - test/unit/dismax_request_test.rb
70
84
  - test/unit/document_test.rb
71
85
  - test/unit/field_test.rb
86
+ - test/unit/hpricot_mapper_test.rb
87
+ - test/unit/hpricot_test_file.xml
88
+ - test/unit/indexer_test.rb
72
89
  - test/unit/ping_test.rb
73
90
  - test/unit/request_test.rb
74
91
  - test/unit/response_test.rb
@@ -76,6 +93,10 @@ files:
76
93
  - test/unit/standard_request_test.rb
77
94
  - test/unit/standard_response_test.rb
78
95
  - test/unit/suite.rb
96
+ - test/unit/tab_delimited.txt
97
+ - test/unit/util_test.rb
98
+ - test/unit/xpath_mapper_test.rb
99
+ - test/unit/xpath_test_file.xml
79
100
  test_files: []
80
101
 
81
102
  rdoc_options: []