mirror of https://github.com/apache/lucene.git
Cosmetic cleanup, eliminating double nesting of modules which visually reads a bit cleaner, less nesting
git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@501320 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8e82ba6386
commit
a877d34a49
|
@ -12,139 +12,138 @@
|
|||
|
||||
require 'net/http'
|
||||
|
||||
module Solr
|
||||
class Connection
|
||||
attr_reader :url, :autocommit, :connection
|
||||
|
||||
# create a connection to a solr instance using the url for the solr
|
||||
# application context:
|
||||
#
|
||||
# conn = Solr::Connection.new("http://example.com:8080/solr")
|
||||
#
|
||||
# if you would prefer to have all adds/updates autocommitted,
|
||||
# use :autocommit => :on
|
||||
#
|
||||
# conn = Solr::Connection.new('http://example.com:8080/solr',
|
||||
# :autocommit => :on)
|
||||
|
||||
def initialize(url, opts={})
|
||||
@url = URI.parse(url)
|
||||
unless @url.kind_of? URI::HTTP
|
||||
raise "invalid http url: #{url}"
|
||||
end
|
||||
|
||||
# TODO: Autocommit seems nice at one level, but it currently is confusing because
|
||||
# only calls to Connection#add/#update/#delete, though a Connection#send(AddDocument.new(...))
|
||||
# does not autocommit. Maybe #send should check for the request types that require a commit and
|
||||
# commit in #send instead of the individual methods?
|
||||
@autocommit = opts[:autocommit] == :on
|
||||
|
||||
# Not actually opening the connection yet, just setting up the persistent connection.
|
||||
@connection = Net::HTTP.new(@url.host, @url.port)
|
||||
end
|
||||
class Solr::Connection
|
||||
attr_reader :url, :autocommit, :connection
|
||||
|
||||
# add a document to the index. you can pass in either a hash
|
||||
#
|
||||
# conn.add(:id => 123, :title => 'Tlon, Uqbar, Orbis Tertius')
|
||||
#
|
||||
# or a Solr::Document
|
||||
#
|
||||
# conn.add(Solr::Document.new(:id => 123, :title = 'On Writing')
|
||||
#
|
||||
# true/false will be returned to designate success/failure
|
||||
|
||||
def add(doc)
|
||||
request = Solr::Request::AddDocument.new(doc)
|
||||
response = send(request)
|
||||
commit if @autocommit
|
||||
# create a connection to a solr instance using the url for the solr
|
||||
# application context:
|
||||
#
|
||||
# conn = Solr::Connection.new("http://example.com:8080/solr")
|
||||
#
|
||||
# if you would prefer to have all adds/updates autocommitted,
|
||||
# use :autocommit => :on
|
||||
#
|
||||
# conn = Solr::Connection.new('http://example.com:8080/solr',
|
||||
# :autocommit => :on)
|
||||
|
||||
def initialize(url, opts={})
|
||||
@url = URI.parse(url)
|
||||
unless @url.kind_of? URI::HTTP
|
||||
raise "invalid http url: #{url}"
|
||||
end
|
||||
|
||||
# TODO: Autocommit seems nice at one level, but it currently is confusing because
|
||||
# only calls to Connection#add/#update/#delete, though a Connection#send(AddDocument.new(...))
|
||||
# does not autocommit. Maybe #send should check for the request types that require a commit and
|
||||
# commit in #send instead of the individual methods?
|
||||
@autocommit = opts[:autocommit] == :on
|
||||
|
||||
# Not actually opening the connection yet, just setting up the persistent connection.
|
||||
@connection = Net::HTTP.new(@url.host, @url.port)
|
||||
end
|
||||
|
||||
# add a document to the index. you can pass in either a hash
|
||||
#
|
||||
# conn.add(:id => 123, :title => 'Tlon, Uqbar, Orbis Tertius')
|
||||
#
|
||||
# or a Solr::Document
|
||||
#
|
||||
# conn.add(Solr::Document.new(:id => 123, :title = 'On Writing')
|
||||
#
|
||||
# true/false will be returned to designate success/failure
|
||||
|
||||
def add(doc)
|
||||
request = Solr::Request::AddDocument.new(doc)
|
||||
response = send(request)
|
||||
commit if @autocommit
|
||||
return response.ok?
|
||||
end
|
||||
|
||||
# update a document in the index (really just an alias to add)
|
||||
|
||||
def update(doc)
|
||||
return add(doc)
|
||||
end
|
||||
|
||||
# performs a standard query and returns a Solr::Response::Standard
|
||||
#
|
||||
# response = conn.query('borges')
|
||||
#
|
||||
# alternative you can pass in a block and iterate over hits
|
||||
#
|
||||
# conn.query('borges') do |hit|
|
||||
# puts hit
|
||||
# end
|
||||
|
||||
def query(query, options={}, &action)
|
||||
# TODO: Shouldn't this return an exception if the Solr status is not ok? (rather than true/false).
|
||||
options[:query] = query
|
||||
request = Solr::Request::Standard.new(options)
|
||||
response = send(request)
|
||||
return response unless action
|
||||
response.each {|hit| action.call(hit)}
|
||||
end
|
||||
|
||||
# sends a commit message to the server
|
||||
def commit
|
||||
response = send(Solr::Request::Commit.new)
|
||||
return response.ok?
|
||||
end
|
||||
|
||||
# TODO add optimize, which can be hacked like this, interestingly!
|
||||
# class OptimizeRequest
|
||||
# def handler
|
||||
# "update"
|
||||
# end
|
||||
# def to_s
|
||||
# "<optimize/>"
|
||||
# end
|
||||
# end
|
||||
|
||||
# pings the connection and returns true/false if it is alive or not
|
||||
def ping
|
||||
begin
|
||||
response = send(Solr::Request::Ping.new)
|
||||
return response.ok?
|
||||
end
|
||||
|
||||
# update a document in the index (really just an alias to add)
|
||||
|
||||
def update(doc)
|
||||
return add(doc)
|
||||
end
|
||||
|
||||
# performs a standard query and returns a Solr::Response::Standard
|
||||
#
|
||||
# response = conn.query('borges')
|
||||
#
|
||||
# alternative you can pass in a block and iterate over hits
|
||||
#
|
||||
# conn.query('borges') do |hit|
|
||||
# puts hit
|
||||
# end
|
||||
|
||||
def query(query, options={}, &action)
|
||||
# TODO: Shouldn't this return an exception if the Solr status is not ok? (rather than true/false).
|
||||
options[:query] = query
|
||||
request = Solr::Request::Standard.new(options)
|
||||
response = send(request)
|
||||
return response unless action
|
||||
response.each {|hit| action.call(hit)}
|
||||
end
|
||||
|
||||
# sends a commit message to the server
|
||||
def commit
|
||||
response = send(Solr::Request::Commit.new)
|
||||
return response.ok?
|
||||
end
|
||||
|
||||
# TODO add optimize, which can be hacked like this, interestingly!
|
||||
# class OptimizeRequest
|
||||
# def handler
|
||||
# "update"
|
||||
# end
|
||||
# def to_s
|
||||
# "<optimize/>"
|
||||
# end
|
||||
# end
|
||||
|
||||
# pings the connection and returns true/false if it is alive or not
|
||||
def ping
|
||||
begin
|
||||
response = send(Solr::Request::Ping.new)
|
||||
return response.ok?
|
||||
rescue
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
# delete a document from the index using the document id
|
||||
def delete(document_id)
|
||||
response = send(Solr::Request::Delete.new(:id => document_id))
|
||||
commit if @autocommit
|
||||
return response.ok?
|
||||
end
|
||||
|
||||
# delete using a query
|
||||
def delete_by_query(query)
|
||||
response = send(Solr::Request::Delete.new(:query => query))
|
||||
commit if @autocommit
|
||||
return response.ok?
|
||||
end
|
||||
|
||||
# send a given Solr::Request and return a RubyResponse or XmlResponse
|
||||
# depending on the type of request
|
||||
def send(request)
|
||||
data = post(request)
|
||||
return Solr::Response::Base.make_response(request, data)
|
||||
end
|
||||
|
||||
# send the http post request to solr; for convenience there are shortcuts
|
||||
# to some requests: add(), query(), commit(), delete() or send()
|
||||
def post(request)
|
||||
response = @connection.post(@url.path + "/" + request.handler,
|
||||
request.to_s,
|
||||
{ "Content-Type" => "application/x-www-form-urlencoded; charset=utf-8" })
|
||||
|
||||
case response
|
||||
when Net::HTTPSuccess then response.body
|
||||
else
|
||||
response.error!
|
||||
end
|
||||
|
||||
rescue
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
# delete a document from the index using the document id
|
||||
def delete(document_id)
|
||||
response = send(Solr::Request::Delete.new(:id => document_id))
|
||||
commit if @autocommit
|
||||
return response.ok?
|
||||
end
|
||||
|
||||
# delete using a query
|
||||
def delete_by_query(query)
|
||||
response = send(Solr::Request::Delete.new(:query => query))
|
||||
commit if @autocommit
|
||||
return response.ok?
|
||||
end
|
||||
|
||||
# send a given Solr::Request and return a RubyResponse or XmlResponse
|
||||
# depending on the type of request
|
||||
def send(request)
|
||||
data = post(request)
|
||||
return Solr::Response::Base.make_response(request, data)
|
||||
end
|
||||
|
||||
# send the http post request to solr; for convenience there are shortcuts
|
||||
# to some requests: add(), query(), commit(), delete() or send()
|
||||
def post(request)
|
||||
response = @connection.post(@url.path + "/" + request.handler,
|
||||
request.to_s,
|
||||
{ "Content-Type" => "application/x-www-form-urlencoded; charset=utf-8" })
|
||||
|
||||
case response
|
||||
when Net::HTTPSuccess then response.body
|
||||
else
|
||||
response.error!
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -13,61 +13,59 @@
|
|||
require 'rexml/document'
|
||||
require 'solr/field'
|
||||
|
||||
module Solr
|
||||
class Document
|
||||
include Enumerable
|
||||
class Solr::Document
|
||||
include Enumerable
|
||||
|
||||
# Create a new Solr::Document, optionally passing in a hash of
|
||||
# key/value pairs for the fields
|
||||
#
|
||||
# doc = Solr::Document.new(:creator => 'Jorge Luis Borges')
|
||||
def initialize(hash={})
|
||||
@fields = []
|
||||
self << hash
|
||||
end
|
||||
# Create a new Solr::Document, optionally passing in a hash of
|
||||
# key/value pairs for the fields
|
||||
#
|
||||
# doc = Solr::Document.new(:creator => 'Jorge Luis Borges')
|
||||
def initialize(hash={})
|
||||
@fields = []
|
||||
self << hash
|
||||
end
|
||||
|
||||
# Append a Solr::Field
|
||||
#
|
||||
# doc << Solr::Field.new(:creator => 'Jorge Luis Borges')
|
||||
#
|
||||
# If you are truly lazy you can simply pass in a hash:
|
||||
#
|
||||
# doc << {:creator => 'Jorge Luis Borges'}
|
||||
def <<(fields)
|
||||
case fields
|
||||
when Hash
|
||||
fields.each_pair do |name,value|
|
||||
if value.respond_to?(:each)
|
||||
value.each {|v| @fields << Solr::Field.new(name => v)}
|
||||
else
|
||||
@fields << Solr::Field.new(name => value)
|
||||
end
|
||||
# Append a Solr::Field
|
||||
#
|
||||
# doc << Solr::Field.new(:creator => 'Jorge Luis Borges')
|
||||
#
|
||||
# If you are truly lazy you can simply pass in a hash:
|
||||
#
|
||||
# doc << {:creator => 'Jorge Luis Borges'}
|
||||
def <<(fields)
|
||||
case fields
|
||||
when Hash
|
||||
fields.each_pair do |name,value|
|
||||
if value.respond_to?(:each)
|
||||
value.each {|v| @fields << Solr::Field.new(name => v)}
|
||||
else
|
||||
@fields << Solr::Field.new(name => value)
|
||||
end
|
||||
when Solr::Field
|
||||
@fields << fields
|
||||
else
|
||||
raise "must pass in Solr::Field or Hash"
|
||||
end
|
||||
end
|
||||
|
||||
# shorthand to allow hash lookups
|
||||
# doc['name']
|
||||
def [](name)
|
||||
field = @fields.find {|f| f.name == name.to_s}
|
||||
return field.value if field
|
||||
return nil
|
||||
end
|
||||
|
||||
# shorthand to assign as a hash
|
||||
def []=(name,value)
|
||||
@fields << Solr::Field.new(name => value)
|
||||
end
|
||||
|
||||
# convert the Document to a REXML::Element
|
||||
def to_xml
|
||||
e = REXML::Element.new 'doc'
|
||||
@fields.each {|f| e.add_element(f.to_xml)}
|
||||
return e
|
||||
when Solr::Field
|
||||
@fields << fields
|
||||
else
|
||||
raise "must pass in Solr::Field or Hash"
|
||||
end
|
||||
end
|
||||
|
||||
# shorthand to allow hash lookups
|
||||
# doc['name']
|
||||
def [](name)
|
||||
field = @fields.find {|f| f.name == name.to_s}
|
||||
return field.value if field
|
||||
return nil
|
||||
end
|
||||
|
||||
# shorthand to assign as a hash
|
||||
def []=(name,value)
|
||||
@fields << Solr::Field.new(name => value)
|
||||
end
|
||||
|
||||
# convert the Document to a REXML::Element
|
||||
def to_xml
|
||||
e = REXML::Element.new 'doc'
|
||||
@fields.each {|f| e.add_element(f.to_xml)}
|
||||
return e
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,6 +10,4 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
module Solr
|
||||
class Exception < Exception; end
|
||||
end
|
||||
class Solr::Exception < Exception; end
|
||||
|
|
|
@ -12,23 +12,21 @@
|
|||
|
||||
require 'rexml/document'
|
||||
|
||||
module Solr
|
||||
class Field
|
||||
attr_accessor :name
|
||||
attr_accessor :value
|
||||
|
||||
def initialize(key_val, opts={})
|
||||
raise "first argument must be a hash" unless key_val.kind_of? Hash
|
||||
@name = key_val.keys[0].to_s
|
||||
@value = key_val.values[0].to_s
|
||||
end
|
||||
|
||||
def to_xml
|
||||
e = REXML::Element.new 'field'
|
||||
e.attributes['name'] = @name
|
||||
e.text = @value
|
||||
return e
|
||||
end
|
||||
class Solr::Field
|
||||
attr_accessor :name
|
||||
attr_accessor :value
|
||||
|
||||
def initialize(key_val, opts={})
|
||||
raise "first argument must be a hash" unless key_val.kind_of? Hash
|
||||
@name = key_val.keys[0].to_s
|
||||
@value = key_val.values[0].to_s
|
||||
end
|
||||
|
||||
def to_xml
|
||||
e = REXML::Element.new 'field'
|
||||
e.attributes['name'] = @name
|
||||
e.text = @value
|
||||
return e
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -15,54 +15,49 @@ require 'solr/document'
|
|||
require 'solr/request/update'
|
||||
require 'rexml/document'
|
||||
|
||||
module Solr
|
||||
module Request
|
||||
class AddDocument < Solr::Request::Update
|
||||
class Solr::Request::AddDocument < Solr::Request::Update
|
||||
|
||||
# create the request, optionally passing in a Solr::Document
|
||||
#
|
||||
# request = Solr::Request::AddDocument.new doc
|
||||
#
|
||||
# as a short cut you can pass in a Hash instead:
|
||||
#
|
||||
# request = Solr::Request.new :creator => 'Jorge Luis Borges'
|
||||
#
|
||||
# or an array, to add multiple documents at the same time:
|
||||
#
|
||||
# request = Solr::Request::AddDocument.new([doc1, doc2, doc3])
|
||||
|
||||
def initialize(doc={})
|
||||
@docs = []
|
||||
if doc.is_a?(Array)
|
||||
doc.each { |d| add_doc(d) }
|
||||
else
|
||||
add_doc(doc)
|
||||
end
|
||||
end
|
||||
|
||||
# returns the request as a string suitable for posting
|
||||
|
||||
def to_s
|
||||
e = REXML::Element.new 'add'
|
||||
for doc in @docs
|
||||
e.add_element doc.to_xml
|
||||
end
|
||||
return e.to_s
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def add_doc(doc)
|
||||
case doc
|
||||
when Hash
|
||||
@docs << Solr::Document.new(doc)
|
||||
when Solr::Document
|
||||
@docs << doc
|
||||
else
|
||||
raise "must pass in Solr::Document or Hash"
|
||||
end
|
||||
end
|
||||
|
||||
# create the request, optionally passing in a Solr::Document
|
||||
#
|
||||
# request = Solr::Request::AddDocument.new doc
|
||||
#
|
||||
# as a short cut you can pass in a Hash instead:
|
||||
#
|
||||
# request = Solr::Request.new :creator => 'Jorge Luis Borges'
|
||||
#
|
||||
# or an array, to add multiple documents at the same time:
|
||||
#
|
||||
# request = Solr::Request::AddDocument.new([doc1, doc2, doc3])
|
||||
|
||||
def initialize(doc={})
|
||||
@docs = []
|
||||
if doc.is_a?(Array)
|
||||
doc.each { |d| add_doc(d) }
|
||||
else
|
||||
add_doc(doc)
|
||||
end
|
||||
end
|
||||
|
||||
# returns the request as a string suitable for posting
|
||||
|
||||
def to_s
|
||||
e = REXML::Element.new 'add'
|
||||
for doc in @docs
|
||||
e.add_element doc.to_xml
|
||||
end
|
||||
return e.to_s
|
||||
end
|
||||
|
||||
private
|
||||
def add_doc(doc)
|
||||
case doc
|
||||
when Hash
|
||||
@docs << Solr::Document.new(doc)
|
||||
when Solr::Document
|
||||
@docs << doc
|
||||
else
|
||||
raise "must pass in Solr::Document or Hash"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -10,24 +10,20 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
module Solr
|
||||
module Request
|
||||
class Base
|
||||
class Solr::Request::Base
|
||||
|
||||
# returns either :xml or :ruby depending on what the
|
||||
# response type is for a given request
|
||||
|
||||
def response_format
|
||||
raise "unknown request type: #{self.class}"
|
||||
end
|
||||
|
||||
# returns the solr handler or url fragment that can
|
||||
# respond to this type of request
|
||||
|
||||
def handler
|
||||
raise "unkown request type: #{self.class}"
|
||||
end
|
||||
|
||||
end
|
||||
# returns either :xml or :ruby depending on what the
|
||||
# response type is for a given request
|
||||
|
||||
def response_format
|
||||
raise "unknown request type: #{self.class}"
|
||||
end
|
||||
|
||||
# returns the solr handler or url fragment that can
|
||||
# respond to this type of request
|
||||
|
||||
def handler
|
||||
raise "unkown request type: #{self.class}"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -12,14 +12,10 @@
|
|||
|
||||
require 'rexml/document'
|
||||
|
||||
module Solr
|
||||
module Request
|
||||
class Commit < Solr::Request::Update
|
||||
class Solr::Request::Commit < Solr::Request::Update
|
||||
|
||||
def to_s
|
||||
return REXML::Element.new('commit').to_s
|
||||
end
|
||||
|
||||
end
|
||||
def to_s
|
||||
REXML::Element.new('commit').to_s
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -12,44 +12,39 @@
|
|||
|
||||
require 'rexml/document'
|
||||
|
||||
module Solr
|
||||
module Request
|
||||
class Solr::Request::Delete < Solr::Request::Update
|
||||
|
||||
class Delete < Solr::Request::Update
|
||||
|
||||
# A delete request can be for a specific document id
|
||||
#
|
||||
# request = Solr::Request::Delete.new(:id => 1234)
|
||||
#
|
||||
# or by query:
|
||||
#
|
||||
# request = Solr::Request::Delete.new(:query =>
|
||||
#
|
||||
def initialize(options)
|
||||
unless options.kind_of?(Hash) and (options[:id] or options[:query])
|
||||
raise Solr::Exception.new("must pass in :id or :query")
|
||||
end
|
||||
if options[:id] and options[:query]
|
||||
raise Solr::Exception.new("can't pass in both :id and :query")
|
||||
end
|
||||
@document_id = options[:id]
|
||||
@query = options[:query]
|
||||
end
|
||||
|
||||
def to_s
|
||||
delete_element = REXML::Element.new('delete')
|
||||
if @document_id
|
||||
id_element = REXML::Element.new('id')
|
||||
id_element.text = @document_id
|
||||
delete_element.add_element(id_element)
|
||||
elsif @query
|
||||
query = REXML::Element.new('query')
|
||||
query.text = @query
|
||||
delete_element.add_element(query)
|
||||
end
|
||||
return delete_element.to_s
|
||||
end
|
||||
# A delete request can be for a specific document id
|
||||
#
|
||||
# request = Solr::Request::Delete.new(:id => 1234)
|
||||
#
|
||||
# or by query:
|
||||
#
|
||||
# request = Solr::Request::Delete.new(:query =>
|
||||
#
|
||||
def initialize(options)
|
||||
unless options.kind_of?(Hash) and (options[:id] or options[:query])
|
||||
raise Solr::Exception.new("must pass in :id or :query")
|
||||
end
|
||||
if options[:id] and options[:query]
|
||||
raise Solr::Exception.new("can't pass in both :id and :query")
|
||||
end
|
||||
@document_id = options[:id]
|
||||
@query = options[:query]
|
||||
end
|
||||
|
||||
def to_s
|
||||
delete_element = REXML::Element.new('delete')
|
||||
if @document_id
|
||||
id_element = REXML::Element.new('id')
|
||||
id_element.text = @document_id
|
||||
delete_element.add_element(id_element)
|
||||
elsif @query
|
||||
query = REXML::Element.new('query')
|
||||
query.text = @query
|
||||
delete_element.add_element(query)
|
||||
end
|
||||
delete_element.to_s
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -10,12 +10,8 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
module Solr
|
||||
module Request
|
||||
class IndexInfo < Solr::Request::Select
|
||||
def initialize
|
||||
super('indexinfo')
|
||||
end
|
||||
end
|
||||
class Solr::Request::IndexInfo < Solr::Request::Select
|
||||
def initialize
|
||||
super('indexinfo')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,16 +10,27 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
module Solr
|
||||
module Request
|
||||
class Ping < Solr::Request::Base
|
||||
def response_format
|
||||
:xml
|
||||
end
|
||||
|
||||
def handler
|
||||
'admin/ping'
|
||||
end
|
||||
end
|
||||
# TODO: Consider something lazy like this?
|
||||
# Solr::Request::Ping = Solr::Request.simple_request :format=>:xml, :handler=>'admin/ping'
|
||||
# class Solr::Request
|
||||
# def self.simple_request(options)
|
||||
# Class.new do
|
||||
# def response_format
|
||||
# options[:format]
|
||||
# end
|
||||
# def handler
|
||||
# options[:handler]
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
|
||||
class Solr::Request::Ping < Solr::Request::Base
|
||||
def response_format
|
||||
:xml
|
||||
end
|
||||
|
||||
def handler
|
||||
'admin/ping'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,47 +12,43 @@
|
|||
|
||||
require 'erb'
|
||||
|
||||
module Solr
|
||||
module Request
|
||||
# "Abstract" base class, only useful with subclasses that add parameters
|
||||
class Select < Solr::Request::Base
|
||||
# "Abstract" base class, only useful with subclasses that add parameters
|
||||
class Solr::Request::Select < Solr::Request::Base
|
||||
|
||||
# TODO add a constant for the all-docs query, which currently is [* TO *]
|
||||
# (caveat, that is all docs that have a value in the default field)
|
||||
# When the Lucene JAR is upgraded in Solr, the all-docs query becomes simply *
|
||||
attr_reader :query_type
|
||||
|
||||
def initialize(qt=nil)
|
||||
@query_type = qt
|
||||
end
|
||||
|
||||
def response_format
|
||||
:ruby
|
||||
end
|
||||
|
||||
def handler
|
||||
'select'
|
||||
end
|
||||
|
||||
def to_hash
|
||||
return {:qt => query_type, :wt => 'ruby'}
|
||||
end
|
||||
|
||||
def to_s
|
||||
raw_params = self.to_hash
|
||||
|
||||
http_params = []
|
||||
raw_params.each do |key,value|
|
||||
if value.respond_to? :each
|
||||
value.each { |v| http_params << "#{key}=#{ERB::Util::url_encode(v)}" unless v.nil?}
|
||||
else
|
||||
http_params << "#{key}=#{ERB::Util::url_encode(value)}" unless value.nil?
|
||||
end
|
||||
end
|
||||
|
||||
http_params.join("&")
|
||||
end
|
||||
|
||||
end
|
||||
# TODO add a constant for the all-docs query, which currently is [* TO *]
|
||||
# (caveat, that is all docs that have a value in the default field)
|
||||
# When the Lucene JAR is upgraded in Solr, the all-docs query becomes simply *
|
||||
attr_reader :query_type
|
||||
|
||||
def initialize(qt=nil)
|
||||
@query_type = qt
|
||||
end
|
||||
|
||||
def response_format
|
||||
:ruby
|
||||
end
|
||||
|
||||
def handler
|
||||
'select'
|
||||
end
|
||||
|
||||
def to_hash
|
||||
return {:qt => query_type, :wt => 'ruby'}
|
||||
end
|
||||
|
||||
def to_s
|
||||
raw_params = self.to_hash
|
||||
|
||||
http_params = []
|
||||
raw_params.each do |key,value|
|
||||
if value.respond_to? :each
|
||||
value.each { |v| http_params << "#{key}=#{ERB::Util::url_encode(v)}" unless v.nil?}
|
||||
else
|
||||
http_params << "#{key}=#{ERB::Util::url_encode(value)}" unless value.nil?
|
||||
end
|
||||
end
|
||||
|
||||
http_params.join("&")
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -10,90 +10,86 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
module Solr
|
||||
module Request
|
||||
class Standard < Solr::Request::Select
|
||||
class Solr::Request::Standard < Solr::Request::Select
|
||||
|
||||
VALID_PARAMS = [:query, :sort, :default_field, :operator, :start, :rows,
|
||||
:filter_queries, :field_list, :debug_query, :explain_other, :facets]
|
||||
|
||||
def initialize(params)
|
||||
super('standard')
|
||||
VALID_PARAMS = [:query, :sort, :default_field, :operator, :start, :rows,
|
||||
:filter_queries, :field_list, :debug_query, :explain_other, :facets]
|
||||
|
||||
def initialize(params)
|
||||
super('standard')
|
||||
|
||||
raise "Invalid parameters: #{(params.keys - VALID_PARAMS).join(',')}" unless
|
||||
(params.keys - VALID_PARAMS).empty?
|
||||
|
||||
raise ":query parameter required" unless params[:query]
|
||||
|
||||
@params = params.dup
|
||||
|
||||
# Validate operator
|
||||
if params[:operator]
|
||||
raise "Only :and/:or operators allowed" unless
|
||||
[:and, :or].include?(params[:operator])
|
||||
|
||||
raise "Invalid parameters: #{(params.keys - VALID_PARAMS).join(',')}" unless
|
||||
(params.keys - VALID_PARAMS).empty?
|
||||
|
||||
raise ":query parameter required" unless params[:query]
|
||||
|
||||
@params = params.dup
|
||||
|
||||
# Validate operator
|
||||
if params[:operator]
|
||||
raise "Only :and/:or operators allowed" unless
|
||||
[:and, :or].include?(params[:operator])
|
||||
|
||||
@params[:operator] = params[:operator].to_s.upcase
|
||||
end
|
||||
|
||||
# Validate start, rows can be transformed to ints
|
||||
@params[:start] = params[:start].to_i if params[:start]
|
||||
@params[:rows] = params[:rows].to_i if params[:rows]
|
||||
|
||||
@params[:field_list] ||= ["*","score"]
|
||||
|
||||
#TODO model highlighting parameters: http://wiki.apache.org/solr/HighlightingParameters
|
||||
end
|
||||
|
||||
def to_hash
|
||||
hash = {}
|
||||
|
||||
# standard request param processing
|
||||
sort = @params[:sort].collect do |sort|
|
||||
key = sort.keys[0]
|
||||
"#{key.to_s} #{sort[key] == :descending ? 'desc' : 'asc'}"
|
||||
end.join(',') if @params[:sort]
|
||||
hash[:q] = sort ? "#{@params[:query]};#{sort}" : @params[:query]
|
||||
hash["q.op"] = @params[:operator]
|
||||
hash[:df] = @params[:default_field]
|
||||
|
||||
# common parameter processing
|
||||
hash[:start] = @params[:start]
|
||||
hash[:rows] = @params[:rows]
|
||||
hash[:fq] = @params[:filter_queries]
|
||||
hash[:fl] = @params[:field_list].join(',')
|
||||
hash[:debugQuery] = @params[:debug_query]
|
||||
hash[:explainOther] = @params[:explain_other]
|
||||
|
||||
# facet parameter processing
|
||||
if @params[:facets]
|
||||
# TODO need validation of all that is under the :facets Hash too
|
||||
hash[:facet] = true
|
||||
hash["facet.field"] = []
|
||||
hash["facet.query"] = @params[:facets][:queries]
|
||||
hash["facet.sort"] = (@params[:facets][:sort] == :count) if @params[:facets][:sort]
|
||||
hash["facet.limit"] = @params[:facets][:limit]
|
||||
hash["facet.missing"] = @params[:facets][:missing]
|
||||
hash["facet.mincount"] = @params[:facets][:mincount]
|
||||
hash["facet.prefix"] = @params[:facets][:prefix]
|
||||
@params[:facets][:fields].each do |f|
|
||||
if f.kind_of? Hash
|
||||
key = f.keys[0]
|
||||
value = f[key]
|
||||
hash["facet.field"] << key
|
||||
hash["f.#{key}.facet.sort"] = (value[:sort] == :count) if value[:sort]
|
||||
hash["f.#{key}.facet.limit"] = value[:limit]
|
||||
hash["f.#{key}.facet.missing"] = value[:missing]
|
||||
hash["f.#{key}.facet.mincount"] = value[:mincount]
|
||||
hash["f.#{key}.facet.prefix"] = value[:prefix]
|
||||
else
|
||||
hash["facet.field"] << f
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hash.merge(super.to_hash)
|
||||
end
|
||||
|
||||
@params[:operator] = params[:operator].to_s.upcase
|
||||
end
|
||||
|
||||
# Validate start, rows can be transformed to ints
|
||||
@params[:start] = params[:start].to_i if params[:start]
|
||||
@params[:rows] = params[:rows].to_i if params[:rows]
|
||||
|
||||
@params[:field_list] ||= ["*","score"]
|
||||
|
||||
#TODO model highlighting parameters: http://wiki.apache.org/solr/HighlightingParameters
|
||||
end
|
||||
|
||||
def to_hash
|
||||
hash = {}
|
||||
|
||||
# standard request param processing
|
||||
sort = @params[:sort].collect do |sort|
|
||||
key = sort.keys[0]
|
||||
"#{key.to_s} #{sort[key] == :descending ? 'desc' : 'asc'}"
|
||||
end.join(',') if @params[:sort]
|
||||
hash[:q] = sort ? "#{@params[:query]};#{sort}" : @params[:query]
|
||||
hash["q.op"] = @params[:operator]
|
||||
hash[:df] = @params[:default_field]
|
||||
|
||||
# common parameter processing
|
||||
hash[:start] = @params[:start]
|
||||
hash[:rows] = @params[:rows]
|
||||
hash[:fq] = @params[:filter_queries]
|
||||
hash[:fl] = @params[:field_list].join(',')
|
||||
hash[:debugQuery] = @params[:debug_query]
|
||||
hash[:explainOther] = @params[:explain_other]
|
||||
|
||||
# facet parameter processing
|
||||
if @params[:facets]
|
||||
# TODO need validation of all that is under the :facets Hash too
|
||||
hash[:facet] = true
|
||||
hash["facet.field"] = []
|
||||
hash["facet.query"] = @params[:facets][:queries]
|
||||
hash["facet.sort"] = (@params[:facets][:sort] == :count) if @params[:facets][:sort]
|
||||
hash["facet.limit"] = @params[:facets][:limit]
|
||||
hash["facet.missing"] = @params[:facets][:missing]
|
||||
hash["facet.mincount"] = @params[:facets][:mincount]
|
||||
hash["facet.prefix"] = @params[:facets][:prefix]
|
||||
@params[:facets][:fields].each do |f|
|
||||
if f.kind_of? Hash
|
||||
key = f.keys[0]
|
||||
value = f[key]
|
||||
hash["facet.field"] << key
|
||||
hash["f.#{key}.facet.sort"] = (value[:sort] == :count) if value[:sort]
|
||||
hash["f.#{key}.facet.limit"] = value[:limit]
|
||||
hash["f.#{key}.facet.missing"] = value[:missing]
|
||||
hash["f.#{key}.facet.mincount"] = value[:mincount]
|
||||
hash["f.#{key}.facet.prefix"] = value[:prefix]
|
||||
else
|
||||
hash["facet.field"] << f
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hash.merge(super.to_hash)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -10,18 +10,13 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
module Solr
|
||||
module Request
|
||||
# a parent class for all requests that go through the solr update handler
|
||||
class Solr::Request::Update < Solr::Request::Base
|
||||
def response_format
|
||||
:xml
|
||||
end
|
||||
|
||||
# a parent class for all requests that go through the solr update handler
|
||||
class Update < Solr::Request::Base
|
||||
def response_format
|
||||
:xml
|
||||
end
|
||||
|
||||
def handler
|
||||
'update'
|
||||
end
|
||||
end
|
||||
def handler
|
||||
'update'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
module Solr; module Response; end; end
|
||||
require 'solr/response/base'
|
||||
require 'solr/response/xml'
|
||||
require 'solr/response/ruby'
|
||||
|
|
|
@ -10,14 +10,8 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
module Solr
|
||||
module Response
|
||||
|
||||
class AddDocument < Solr::Response::Xml
|
||||
def initialize(xml)
|
||||
super(xml)
|
||||
end
|
||||
end
|
||||
|
||||
class Solr::Response::AddDocument < Solr::Response::Xml
|
||||
def initialize(xml)
|
||||
super(xml)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,44 +10,40 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
module Solr
|
||||
module Response
|
||||
class Base
|
||||
attr_reader :raw_response
|
||||
class Solr::Response::Base
|
||||
attr_reader :raw_response
|
||||
|
||||
def initialize(raw_response)
|
||||
@raw_response = raw_response
|
||||
end
|
||||
def initialize(raw_response)
|
||||
@raw_response = raw_response
|
||||
end
|
||||
|
||||
# factory method for creating a Solr::Response::* from
|
||||
# a request and the raw response content
|
||||
def self.make_response(request, raw)
|
||||
# factory method for creating a Solr::Response::* from
|
||||
# a request and the raw response content
|
||||
def self.make_response(request, raw)
|
||||
|
||||
# make sure response format seems sane
|
||||
unless [:xml, :ruby].include?(request.response_format)
|
||||
raise Solr::Exception.new("unknown response format: #{request.response_format}" )
|
||||
end
|
||||
|
||||
# TODO: Factor out this case... perhaps the request object should provide the response class instead? Or dynamically align by class name?
|
||||
# Maybe the request itself could have the response handling features that get mixed in with a single general purpose response object?
|
||||
case request
|
||||
when Solr::Request::Ping
|
||||
return Solr::Response::Ping.new(raw)
|
||||
when Solr::Request::AddDocument
|
||||
return Solr::Response::AddDocument.new(raw)
|
||||
when Solr::Request::Commit
|
||||
return Solr::Response::Commit.new(raw)
|
||||
when Solr::Request::Standard
|
||||
return Solr::Response::Standard.new(raw)
|
||||
when Solr::Request::Delete
|
||||
return Solr::Response::Delete.new(raw)
|
||||
when Solr::Request::IndexInfo
|
||||
return Solr::Response::IndexInfo.new(raw)
|
||||
else
|
||||
raise Solr::Exception.new("unknown request type: #{request.class}")
|
||||
end
|
||||
end
|
||||
# make sure response format seems sane
|
||||
unless [:xml, :ruby].include?(request.response_format)
|
||||
raise Solr::Exception.new("unknown response format: #{request.response_format}" )
|
||||
end
|
||||
|
||||
# TODO: Factor out this case... perhaps the request object should provide the response class instead? Or dynamically align by class name?
|
||||
# Maybe the request itself could have the response handling features that get mixed in with a single general purpose response object?
|
||||
case request
|
||||
when Solr::Request::Ping
|
||||
return Solr::Response::Ping.new(raw)
|
||||
when Solr::Request::AddDocument
|
||||
return Solr::Response::AddDocument.new(raw)
|
||||
when Solr::Request::Commit
|
||||
return Solr::Response::Commit.new(raw)
|
||||
when Solr::Request::Standard
|
||||
return Solr::Response::Standard.new(raw)
|
||||
when Solr::Request::Delete
|
||||
return Solr::Response::Delete.new(raw)
|
||||
when Solr::Request::IndexInfo
|
||||
return Solr::Response::IndexInfo.new(raw)
|
||||
else
|
||||
raise Solr::Exception.new("unknown request type: #{request.class}")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -12,25 +12,21 @@
|
|||
|
||||
require 'rexml/xpath'
|
||||
|
||||
module Solr
|
||||
module Response
|
||||
class Commit < Solr::Response::Xml
|
||||
attr_reader :ok
|
||||
class Solr::Response::Commit < Solr::Response::Xml
|
||||
attr_reader :ok
|
||||
|
||||
def initialize(xml)
|
||||
super(xml)
|
||||
e = REXML::XPath.first(@doc, './result')
|
||||
if e and e.attributes['status'] == '0'
|
||||
@ok = true
|
||||
else
|
||||
@ok = false
|
||||
end
|
||||
end
|
||||
|
||||
def ok?
|
||||
@ok
|
||||
end
|
||||
def initialize(xml)
|
||||
super(xml)
|
||||
e = REXML::XPath.first(@doc, './result')
|
||||
if e and e.attributes['status'] == '0'
|
||||
@ok = true
|
||||
else
|
||||
@ok = false
|
||||
end
|
||||
end
|
||||
|
||||
def ok?
|
||||
@ok
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -10,9 +10,4 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
module Solr
|
||||
module Response
|
||||
class Delete < Solr::Response::Xml
|
||||
end
|
||||
end
|
||||
end
|
||||
class Solr::Response::Delete < Solr::Response::Xml; end
|
||||
|
|
|
@ -10,21 +10,17 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
module Solr
|
||||
module Response
|
||||
class IndexInfo < Solr::Response::Ruby
|
||||
def initialize(ruby_code)
|
||||
super(ruby_code)
|
||||
end
|
||||
|
||||
def num_docs
|
||||
return @data['index']['numDocs']
|
||||
end
|
||||
|
||||
def field_names
|
||||
return @data['fields'].keys
|
||||
end
|
||||
|
||||
end
|
||||
class Solr::Response::IndexInfo < Solr::Response::Ruby
|
||||
def initialize(ruby_code)
|
||||
super(ruby_code)
|
||||
end
|
||||
|
||||
def num_docs
|
||||
return @data['index']['numDocs']
|
||||
end
|
||||
|
||||
def field_names
|
||||
return @data['fields'].keys
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -12,21 +12,17 @@
|
|||
|
||||
require 'rexml/xpath'
|
||||
|
||||
module Solr
|
||||
module Response
|
||||
class Ping < Solr::Response::Xml
|
||||
class Solr::Response::Ping < Solr::Response::Xml
|
||||
|
||||
def initialize(xml)
|
||||
super(xml)
|
||||
@ok = REXML::XPath.first(@doc, './solr/ping') ? true : false
|
||||
end
|
||||
|
||||
# returns true or false depending on whether the ping
|
||||
# was successful or not
|
||||
def ok?
|
||||
@ok
|
||||
end
|
||||
|
||||
end
|
||||
def initialize(xml)
|
||||
super(xml)
|
||||
@ok = REXML::XPath.first(@doc, './solr/ping') ? true : false
|
||||
end
|
||||
|
||||
# returns true or false depending on whether the ping
|
||||
# was successful or not
|
||||
def ok?
|
||||
@ok
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -10,39 +10,33 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
module Solr
|
||||
module Response
|
||||
|
||||
class Ruby < Solr::Response::Base
|
||||
attr_reader :data
|
||||
|
||||
def initialize(ruby_code)
|
||||
super(ruby_code)
|
||||
begin
|
||||
#TODO: what about pulling up data/header/response to ResponseBase,
|
||||
# or maybe a new middle class like SelectResponseBase since
|
||||
# all Select queries return this same sort of stuff??
|
||||
# XML (&wt=xml) and Ruby (&wt=ruby) responses contain exactly the same structure.
|
||||
# a goal of solrb is to make it irrelevant which gets used under the hood,
|
||||
# but favor Ruby responses.
|
||||
@data = eval(ruby_code)
|
||||
@header = @data['responseHeader']
|
||||
raise "response should be a hash" unless @data.kind_of? Hash
|
||||
raise "response header missing" unless @header.kind_of? Hash
|
||||
rescue SyntaxError => e
|
||||
raise Solr::Exception.new("invalid ruby code: #{e}")
|
||||
end
|
||||
end
|
||||
|
||||
def ok?
|
||||
return @header['status'] == 0
|
||||
end
|
||||
|
||||
def query_time
|
||||
return @header['QTime']
|
||||
end
|
||||
class Solr::Response::Ruby < Solr::Response::Base
|
||||
attr_reader :data
|
||||
|
||||
def initialize(ruby_code)
|
||||
super(ruby_code)
|
||||
begin
|
||||
#TODO: what about pulling up data/header/response to ResponseBase,
|
||||
# or maybe a new middle class like SelectResponseBase since
|
||||
# all Select queries return this same sort of stuff??
|
||||
# XML (&wt=xml) and Ruby (&wt=ruby) responses contain exactly the same structure.
|
||||
# a goal of solrb is to make it irrelevant which gets used under the hood,
|
||||
# but favor Ruby responses.
|
||||
@data = eval(ruby_code)
|
||||
@header = @data['responseHeader']
|
||||
raise "response should be a hash" unless @data.kind_of? Hash
|
||||
raise "response header missing" unless @header.kind_of? Hash
|
||||
rescue SyntaxError => e
|
||||
raise Solr::Exception.new("invalid ruby code: #{e}")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def ok?
|
||||
@header['status'] == 0
|
||||
end
|
||||
|
||||
def query_time
|
||||
@header['QTime']
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -10,43 +10,39 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
module Solr
|
||||
module Response
|
||||
class Standard < Solr::Response::Ruby
|
||||
include Enumerable
|
||||
|
||||
def initialize(ruby_code)
|
||||
super(ruby_code)
|
||||
@response = @data['response']
|
||||
raise "response section missing" unless @response.kind_of? Hash
|
||||
end
|
||||
|
||||
def total_hits
|
||||
return @response['numFound']
|
||||
end
|
||||
|
||||
def start
|
||||
return @response['start']
|
||||
end
|
||||
|
||||
def hits
|
||||
return @response['docs']
|
||||
end
|
||||
|
||||
def max_score
|
||||
return @response['maxScore']
|
||||
end
|
||||
|
||||
def field_facets(field)
|
||||
@data['facet_counts']['facet_fields'][field].sort {|a,b| b[1] <=> a[1]}
|
||||
end
|
||||
|
||||
|
||||
# supports enumeration of hits
|
||||
def each
|
||||
@response['docs'].each {|hit| yield hit}
|
||||
end
|
||||
|
||||
end
|
||||
class Solr::Response::Standard < Solr::Response::Ruby
|
||||
include Enumerable
|
||||
|
||||
def initialize(ruby_code)
|
||||
super(ruby_code)
|
||||
@response = @data['response']
|
||||
raise "response section missing" unless @response.kind_of? Hash
|
||||
end
|
||||
|
||||
def total_hits
|
||||
@response['numFound']
|
||||
end
|
||||
|
||||
def start
|
||||
@response['start']
|
||||
end
|
||||
|
||||
def hits
|
||||
@response['docs']
|
||||
end
|
||||
|
||||
def max_score
|
||||
@response['maxScore']
|
||||
end
|
||||
|
||||
def field_facets(field)
|
||||
@data['facet_counts']['facet_fields'][field].sort {|a,b| b[1] <=> a[1]}
|
||||
end
|
||||
|
||||
|
||||
# supports enumeration of hits
|
||||
def each
|
||||
@response['docs'].each {|hit| yield hit}
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -13,33 +13,25 @@
|
|||
require 'rexml/document'
|
||||
require 'solr/exception'
|
||||
|
||||
module Solr
|
||||
module Response
|
||||
|
||||
class Xml < Solr::Response::Base
|
||||
attr_reader :doc, :status_code, :status_message
|
||||
|
||||
def initialize(xml)
|
||||
super(xml)
|
||||
begin
|
||||
# parse the xml
|
||||
@doc = REXML::Document.new(xml)
|
||||
# look for the result code and string
|
||||
result = REXML::XPath.first(@doc, './result')
|
||||
if result
|
||||
@status_code = result.attributes['status']
|
||||
@status_message = result.text
|
||||
end
|
||||
rescue REXML::ParseException => e
|
||||
raise Solr::Exception.new("invalid response xml: #{e}")
|
||||
end
|
||||
end
|
||||
|
||||
def ok?
|
||||
return @status_code == '0'
|
||||
end
|
||||
class Solr::Response::Xml < Solr::Response::Base
|
||||
attr_reader :doc, :status_code, :status_message
|
||||
|
||||
def initialize(xml)
|
||||
super(xml)
|
||||
# parse the xml
|
||||
@doc = REXML::Document.new(xml)
|
||||
# look for the result code and string
|
||||
result = REXML::XPath.first(@doc, './result')
|
||||
if result
|
||||
@status_code = result.attributes['status']
|
||||
@status_message = result.text
|
||||
end
|
||||
|
||||
rescue REXML::ParseException => e
|
||||
raise Solr::Exception.new("invalid response xml: #{e}")
|
||||
end
|
||||
|
||||
def ok?
|
||||
return @status_code == '0'
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue