From 4d9c4504e1c1f1c9f88040ecc6dc0bd5105ecf28 Mon Sep 17 00:00:00 2001 From: Erik Hatcher Date: Wed, 3 Jan 2007 04:57:00 +0000 Subject: [PATCH] sooner rather than later, tease the Solr DSL out from the web framework git-svn-id: https://svn.apache.org/repos/asf/incubator/solr/trunk@492042 13f79535-47bb-0310-9956-ffa450edef68 --- client/ruby/solrb/Changes | 3 + client/ruby/solrb/README | 52 +++++++++ client/ruby/solrb/Rakefile | 45 ++++++++ client/ruby/solrb/lib/solr.rb | 15 +++ client/ruby/solrb/lib/solr/connection.rb | 33 ++++++ client/ruby/solrb/lib/solr/request.rb | 133 ++++++++++++++++++++++ client/ruby/solrb/lib/solr/response.rb | 35 ++++++ client/ruby/solrb/lib/solrb | 1 + client/ruby/solrb/test/connection_test.rb | 23 ++++ client/ruby/solrb/test/request_test.rb | 34 ++++++ 10 files changed, 374 insertions(+) create mode 100644 client/ruby/solrb/Changes create mode 100644 client/ruby/solrb/README create mode 100644 client/ruby/solrb/Rakefile create mode 100755 client/ruby/solrb/lib/solr.rb create mode 100755 client/ruby/solrb/lib/solr/connection.rb create mode 100755 client/ruby/solrb/lib/solr/request.rb create mode 100755 client/ruby/solrb/lib/solr/response.rb create mode 120000 client/ruby/solrb/lib/solrb create mode 100755 client/ruby/solrb/test/connection_test.rb create mode 100755 client/ruby/solrb/test/request_test.rb diff --git a/client/ruby/solrb/Changes b/client/ruby/solrb/Changes new file mode 100644 index 00000000000..5ab218075c8 --- /dev/null +++ b/client/ruby/solrb/Changes @@ -0,0 +1,3 @@ +v0.0.1 +- initial release + diff --git a/client/ruby/solrb/README b/client/ruby/solrb/README new file mode 100644 index 00000000000..993d89fdf68 --- /dev/null +++ b/client/ruby/solrb/README @@ -0,0 +1,52 @@ +solrb exposes the power of Solr as a Ruby DSL (domain specific language). + + Visit the Solr Flare wiki for more information: http://wiki.apache.org/solr/Flare + +USAGE + +First launch Solr. + +In a separate shell, launch script/console. + +# Set up a connection to Solr: + + connection = Solr::Connection.new("http://localhost:8983") + +# To add a document: + + doc = {:id => "529", :text => "Solr Flare in Action"} + request = Solr::AddDocumentRequest.new(doc) + connection.send(request) + +# Commit changes: + + request = Solr::UpdateRequest.new("") # TODO: yes, this will be mapped as a simpler command! + connection.send(request) + +# Search: + + request = Solr::StandardRequest.new + request.query = "solr flare" + connection.send(request) + + + +INSTALLATION + +First run the tests: + + rake test + +then build the gem: + + rake package + +and install the versioned gem: + + gem install pkg/solr-x.x.x.gem + +LICENSE + +This package is licensed using the Apache Software License 2.0. + + diff --git a/client/ruby/solrb/Rakefile b/client/ruby/solrb/Rakefile new file mode 100644 index 00000000000..7c1d71e76f6 --- /dev/null +++ b/client/ruby/solrb/Rakefile @@ -0,0 +1,45 @@ +SOLRB_VERSION = '0.0.1' + +require 'rubygems' +require 'rake' +require 'rake/testtask' +require 'rake/rdoctask' +require 'rake/packagetask' +require 'rake/gempackagetask' + +task :default => [:test] + +Rake::TestTask.new('test') do |t| + t.libs << 'lib' + t.pattern = 'test/*_test.rb' + t.verbose = true + t.ruby_opts = ['-r solr', '-r test/unit'] +end + +spec = Gem::Specification.new do |s| + s.name = 'solr' + s.version = SOLRB_VERSION + s.author = 'Apache Solr' + s.email = 'solr-user@lucene.apache.org' + s.homepage = 'http://wiki.apache.org/solr/Flare' + s.platform = Gem::Platform::RUBY + s.summary = 'A ruby library for working with Apache Solr' + s.files = Dir.glob("{lib,test}/**/*") + s.require_path = 'lib' + s.autorequire = 'solr' + s.has_rdoc = true + +# s.test_file = 'test/ts_solr.rb' +# s.bindir = 'bin' +end + +Rake::GemPackageTask.new(spec) do |pkg| + pkg.need_zip = true + pkg.need_tar = true +end + +Rake::RDocTask.new('doc') do |rd| + rd.rdoc_files.include("lib/**/*.rb") + rd.main = 'Solr::Connection' + rd.rdoc_dir = 'doc' +end diff --git a/client/ruby/solrb/lib/solr.rb b/client/ruby/solrb/lib/solr.rb new file mode 100755 index 00000000000..8ecd326bc23 --- /dev/null +++ b/client/ruby/solrb/lib/solr.rb @@ -0,0 +1,15 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'solr/request' +require 'solr/connection' +require 'solr/response' \ No newline at end of file diff --git a/client/ruby/solrb/lib/solr/connection.rb b/client/ruby/solrb/lib/solr/connection.rb new file mode 100755 index 00000000000..be5fa139a76 --- /dev/null +++ b/client/ruby/solrb/lib/solr/connection.rb @@ -0,0 +1,33 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'net/http' + +module Solr + class Connection + attr_reader :url + + def initialize(url) + @url = URI.parse(url) + end + + def send(request) + post = Net::HTTP::Post.new(request.url_path) + post.body = request.to_http_body + post.content_type = 'application/x-www-form-urlencoded; charset=utf-8' + response = Net::HTTP.start(@url.host, @url.port) do |http| + http.request(post) + end + return request.response_format == :ruby ? RubyResponse.new(response.body) : XmlResponse.new(response.body) + end + end +end diff --git a/client/ruby/solrb/lib/solr/request.rb b/client/ruby/solrb/lib/solr/request.rb new file mode 100755 index 00000000000..9d3511616de --- /dev/null +++ b/client/ruby/solrb/lib/solr/request.rb @@ -0,0 +1,133 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require "erb" +require 'rexml/document' +include ERB::Util + +module Solr + class Request + attr_reader :url_path + attr_reader :response_format + + def initialize + @url_path = "/solr/select" + end + end + + class UpdateRequest < Request + # sent to /solr/update with XML body + def initialize(body) + @body = body.to_s + @url_path = "/solr/update" + @response_format = :xml + end + + def to_http_body + @body + end + end + + class AddDocumentRequest < UpdateRequest + def initialize(doc_hash) + xml = REXML::Element.new('add') + + doc = REXML::Element.new('doc') + + doc_hash.each do |key,value| + #TODO: add handling of array values + doc.add_element field(key.to_s, value) + end + + xml.add_element doc + super(xml.to_s) + end + + private + def field(name, value) + field = REXML::Element.new("field") + field.add_attribute("name", name) + field.add_text(value) + + field + end + end + + class SelectRequest < Request + # sent to /solr/select, with url query string parameters in the body + + def initialize + @response_format = :ruby + super + end + + def to_http_body + raw_params = self.to_hash + + http_params = [] + raw_params.each do |key,value| + #TODO: Add array value handling + http_params << "#{key}=#{url_encode(value)}" if value + end + + http_params.join("&") + end + + def to_hash + {:wt => "ruby"} + end + end + + class CommonRequestBase < SelectRequest + # supported by both standard and dismax request handlers + # start + # rows + # filter query (multiple) + # field list + attr_accessor :start + attr_accessor :rows + attr_accessor :filter_queries + attr_accessor :field_list + + # debug + # explainOther + + def to_hash + {:start => @start, + :rows => @rows, + :fq => @filter_queries, + :fl => @field_list}.merge(super) + end + end + + class StandardRequest < CommonRequestBase + # sort + # default field + # query + # query operator (AND/OR) + attr_accessor :sort + attr_accessor :default_field + attr_accessor :query + attr_accessor :operator + + def to_hash + {:df => @default_field, + :q => @sort ? "#{@query};#{@sort}" : @query, + :op => @operator}.merge(super) + end + end + +end + +#s = Solr::Request.new("http://localhost:8983") +#s.add({:title => "foo"}) + diff --git a/client/ruby/solrb/lib/solr/response.rb b/client/ruby/solrb/lib/solr/response.rb new file mode 100755 index 00000000000..ac235a7525f --- /dev/null +++ b/client/ruby/solrb/lib/solr/response.rb @@ -0,0 +1,35 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module Solr + class Response + attr_reader :header, :raw_response, :data + def initialize(body) + @raw_response = body + end + end + + class RubyResponse < Response + def initialize(body) + super(body) + parsed_response = eval(body) + @header = parsed_response['responseHeader'] + @data = parsed_response['response'] + end + end + + class XmlResponse < Response + def initialize(body) + super(body) + end + end +end diff --git a/client/ruby/solrb/lib/solrb b/client/ruby/solrb/lib/solrb new file mode 120000 index 00000000000..3da1a97ff1d --- /dev/null +++ b/client/ruby/solrb/lib/solrb @@ -0,0 +1 @@ +/Users/erik/dev/solr/client/ruby/solrb \ No newline at end of file diff --git a/client/ruby/solrb/test/connection_test.rb b/client/ruby/solrb/test/connection_test.rb new file mode 100755 index 00000000000..dd764535571 --- /dev/null +++ b/client/ruby/solrb/test/connection_test.rb @@ -0,0 +1,23 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'test/unit' +require 'solr' + +class ConnectionTest < Test::Unit::TestCase + def test_connection_initialize + request = Solr::UpdateRequest.new("") + connection = Solr::Connection.new("http://localhost:8983") + assert_equal("localhost", connection.url.host) + assert_equal(8983, connection.url.port) + end +end diff --git a/client/ruby/solrb/test/request_test.rb b/client/ruby/solrb/test/request_test.rb new file mode 100755 index 00000000000..336d190d2de --- /dev/null +++ b/client/ruby/solrb/test/request_test.rb @@ -0,0 +1,34 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'test/unit' +require 'solr' + +class RequestTest < Test::Unit::TestCase + def test_basic_params + request = Solr::StandardRequest.new + assert_equal("/solr/select", request.url_path) + + request.query = "term" + assert_equal "term", request.to_hash[:q] + end + + def test_update_request + request = Solr::UpdateRequest.new("") + assert_equal("/solr/update", request.url_path) + end + + def test_add_doc_request + request = Solr::AddDocumentRequest.new({:title => "title"}) + assert_equal("title", request.to_http_body) + end +end