Skip to content

Commit

Permalink
Generation of xmlpipe2 data source implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
eddloschi committed Nov 7, 2013
1 parent e7ea522 commit c3be62a
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/mongoid-giza.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require "mongoid-giza/instance"
require "mongoid-giza/search"
require "mongoid-giza/version"
require "mongoid-giza/xml_pipe2"

module Mongoid
##
Expand Down
52 changes: 52 additions & 0 deletions lib/mongoid-giza/xml_pipe2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
require "builder"

module Mongoid
module Giza
class XMLPipe2
##
# Creates a new XMLPipe2 object based on the specified index and that will write to the specified buffer.
# Note that the actual XML will be generated only when {#generate!} is called
#
# @param index [Mongoid::Giza::Index] the index which will be used to generate the data
# @param buffer any object that supports the method <<
def initialize(index, buffer)
@index = index
@xml = Builder::XmlMarkup.new(target: buffer)
end
##
# Generates a XML document with the {http://sphinxsearch.com/docs/current.html#xmlpipe2 xmlpipe2 specification}.
# The buffer passed on object creation will contain the XML
def generate!
@xml.instruct! :xml, version: "1.0", encoding: "utf-8"
@xml.sphinx :docset do |docset|
generate_schema
generate_docset
end
end
##
# Generates the schema part of the XML document.
# Used internally by {#generate!} so you should never need to call it directly
def generate_schema
@xml.sphinx :schema do |schema|
@index.fields.each do |field|
attrs = {name: field.name}
attrs[:attr] = :string if field.attribute
schema.sphinx :field, attrs
end
@index.attributes.each { |attribute| schema.sphinx :attr, name: attribute.name, type: attribute.type }
end
end
##
# Generates the content part of the XML document.
# Used internally by {#generate!} so you should never need to call it directly
def generate_docset
@index.klass.collection.find.each do |object|
@xml.sphinx :document, id: object["giza_id"] do |document|
@index.fields.each { |field| document.tag! field.name, object[field.name.to_s].to_s }
@index.attributes.each { |attribute| document.tag! attribute.name, object[attribute.name.to_s].to_s }
end
end
end
end
end
end
1 change: 1 addition & 0 deletions mongoid-giza.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ Gem::Specification.new do |spec|

spec.add_runtime_dependency "mongoid", ">= 3.1"
spec.add_runtime_dependency "riddle", ">= 1.5"
spec.add_runtime_dependency "builder", ">= 3.0"
end
71 changes: 71 additions & 0 deletions spec/mongoid-giza/xml_pipe2_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
require "spec_helper"

describe Mongoid::Giza::XMLPipe2 do
let(:xmlpipe2) { Mongoid::Giza::XMLPipe2.new(@index, @buffer) }

before do
@buffer = ""
@index = double("index")
end

describe "generate_schema" do
before do
@field = double("field")
@attribute = double("attribute")
allow(@index).to receive(:fields) { [@field] }
allow(@index).to receive(:attributes) { [@attribute] }
allow(@field).to receive(:name) { :name }
allow(@attribute).to receive(:name) { :age }
allow(@attribute).to receive(:type) { :uint }
end

it "should generate the schema of the docset" do
allow(@field).to receive(:attribute) { false }
xmlpipe2.generate_schema
expect(@buffer).to eql('<sphinx:schema><sphinx:field name="name"/><sphinx:attr name="age" type="uint"/></sphinx:schema>')
end

it "should generate a field attribute" do
allow(@field).to receive(:attribute) { true }
xmlpipe2.generate_schema
expect(@buffer).to eql('<sphinx:schema><sphinx:field name="name" attr="string"/><sphinx:attr name="age" type="uint"/></sphinx:schema>')
end
end

describe "generate_docset" do
it "should generate the document entries" do
person = double("Person")
collection = double("collection")
field = double("field")
attribute = double("attribute")
allow(@index).to receive(:klass) { person }
allow(@index).to receive(:fields) { [field] }
allow(@index).to receive(:attributes) { [attribute] }
allow(person).to receive(:collection) { collection }
allow(collection).to receive(:find) { [{"giza_id" => 1, "name" => "Person One", "age" => 25}] }
allow(field).to receive(:name) { :name }
allow(attribute).to receive(:name) { :age }
xmlpipe2.generate_docset
expect(@buffer).to eql('<sphinx:document id="1"><name>Person One</name><age>25</age></sphinx:document>')
end
end

describe "generate!" do
it "should generate a xml file of the index" do
result = '<?xml version="1.0" encoding="utf-8"?>'
result << '<sphinx:docset><sphinx:schema>'
result << '<sphinx:field name="name"/><sphinx:attr name="age" type="uint"/>'
result << '</sphinx:schema>'
result << '<sphinx:document id="1"><name>Person One</name><age>25</age></sphinx:document>'
result << '</sphinx:docset>'
expect(xmlpipe2).to receive(:generate_schema) do
@buffer << '<sphinx:schema><sphinx:field name="name"/><sphinx:attr name="age" type="uint"/></sphinx:schema>'
end
expect(xmlpipe2).to receive(:generate_docset) do
@buffer << '<sphinx:document id="1"><name>Person One</name><age>25</age></sphinx:document>'
end
xmlpipe2.generate!
expect(@buffer).to eql(result)
end
end
end

0 comments on commit c3be62a

Please sign in to comment.