Skip to content

Commit

Permalink
added some response.docs pagination blips
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Mitchell committed Aug 23, 2010
1 parent 64952f8 commit 548985d
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 10 deletions.
12 changes: 8 additions & 4 deletions example.rb
@@ -1,15 +1,19 @@
require 'lib/rsolr'
require "#{File.dirname(__FILE__)}/lib/rsolr"
require 'rubygems'
require 'builder'

solr = RSolr.connect :url => "http://localhost:8983/solr/production"
solr = RSolr.connect :url => "http://localhost:8983/solr/development"

begin
r = solr.get 'select', :params => {:q => '*:*', :wt => :ruby}
r = solr.get 'select', :page => 1, :per_page => 0, :params => {:q => '*:*', :wt => :ruby}
rescue
puts $!
puts $!.backtrace
exit
end

puts r.inspect
puts r["response"]["docs"].total
exit

r = solr.connection.build_request "select", :params => {:q => "hello", :fq => ["one:1", "two:2"]}
puts r.inspect
Expand Down
90 changes: 87 additions & 3 deletions lib/rsolr/connectable.rb
@@ -1,6 +1,6 @@
# Connectable is designed to be shared across solr driver implementations.
# If the driver uses an http url/proxy and returns the standard http respon
# data (status, body, headers) then this module could be used.
# If the driver uses an http url/proxy and returns the standard http response
# data (status, body, headers) then this module can be used.
module RSolr::Connectable

attr_reader :uri, :proxy, :options
Expand Down Expand Up @@ -40,7 +40,7 @@ def execute request_context
end

# build_request sets up the uri/query string
# and converts the +data+ arg to form-urlencoded
# and converts the +data+ arg to form-urlencoded,
# if the +data+ arg is a hash.
# returns a hash with the following keys:
# :method
Expand All @@ -55,6 +55,7 @@ def build_request path, opts
path = path.to_s
opts[:method] ||= :get
raise "The :data option can only be used if :method => :post" if opts[:method] != :post and opts[:data]
calculate_start_and_rows opts
opts[:params] = opts[:params].nil? ? {:wt => :ruby} : {:wt => :ruby}.merge(opts[:params])
query = RSolr::Uri.params_to_solr(opts[:params]) unless opts[:params].empty?
opts[:query] = query
Expand All @@ -68,6 +69,11 @@ def build_request path, opts
opts
end

#
# TODO: The code below, related to responses,
# should be moved to a response module/class!
#

# This method will evaluate the :body value
# if the params[:uri].params[:wt] == :ruby
# ... otherwise, the body is returned as is.
Expand All @@ -87,11 +93,89 @@ def adapt_response request, response
if request[:params][:wt] == :ruby
begin
data = Kernel.eval data.to_s
decorate_ruby_response request, data
rescue SyntaxError
raise RSolr::Error::InvalidRubyResponse.new request, response
end
end
data
end

# TODO: Might want to move the logic from
# PaginatedResponse.extended to this method,
# since we have access to the original
# reuqest and wouldn't require that
# omitHeader != false.
def decorate_ruby_response request, data
if request[:page] and request[:per_page] and data["response"]["docs"]
data.extend PaginatedResponse
end
end

# figures out the "start" and "rows" Solr params
# by inspecting the :per_page and :page params.
def calculate_start_and_rows request
page, per_page = request[:page], request[:per_page]
per_page ||= 10
page = page.to_s.to_i-1
page = page < 1 ? 0 : page
start = page * per_page
request[:params].merge! :start => start, :rows => per_page
end

module PaginatedDocSet

attr_accessor :start, :per_page, :total

# Returns the current page calculated from 'rows' and 'start'
# WillPaginate hook
def current_page
return 1 if start < 1
per_page_normalized = per_page < 1 ? 1 : per_page
@current_page ||= (start / per_page_normalized).ceil + 1
end

# Calcuates the total pages from 'numFound' and 'rows'
# WillPaginate hook
def total_pages
@total_pages ||= per_page > 0 ? (total / per_page.to_f).ceil : 1
end

# returns the previous page number or 1
# WillPaginate hook
def previous_page
@previous_page ||= (current_page > 1) ? current_page - 1 : 1
end

# returns the next page number or the last
# WillPaginate hook
def next_page
@next_page ||= (current_page == total_pages) ? total_pages : current_page+1
end

def has_next?
current_page < total_pages
end

def has_previous?
current_page > 1
end

end

module PaginatedResponse

# TODO: self["responseHeader"]["params"]["rows"]
# will not be available if omitHeader is false...
# so, a simple "extend" probably isn't going to cut it.
def self.extended base
d = base['response']['docs']
d.extend PaginatedDocSet
d.per_page = self["responseHeader"]["params"]["rows"].to_s.to_i rescue 10
d.start = base["response"]["start"].to_s.to_i
d.total = base["response"]["numFound"].to_s.to_i
end

end

end
5 changes: 2 additions & 3 deletions rsolr.gemspec
Expand Up @@ -9,7 +9,7 @@ Gem::Specification.new do |s|

s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
s.authors = ["Matt Mitchell"]
s.date = %q{2010-08-11}
s.date = %q{2010-08-18}
s.description = %q{RSolr aims to provide a simple and extensible library for working with Solr}
s.email = %q{goodieboy@gmail.com}
s.extra_rdoc_files = [
Expand All @@ -26,7 +26,6 @@ Gem::Specification.new do |s|
"lib/rsolr/connectable.rb",
"lib/rsolr/error.rb",
"lib/rsolr/http.rb",
"lib/rsolr/mapper.rb",
"lib/rsolr/uri.rb",
"lib/rsolr/xml.rb"
]
Expand All @@ -39,8 +38,8 @@ Gem::Specification.new do |s|
"spec/api/char_spec.rb",
"spec/api/client_spec.rb",
"spec/api/connectable_spec.rb",
"spec/api/error_spec.rb",
"spec/api/http_spec.rb",
"spec/api/mapper_spec.rb",
"spec/api/uri_spec.rb",
"spec/api/xml_spec.rb",
"spec/spec_helper.rb",
Expand Down

0 comments on commit 548985d

Please sign in to comment.