Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added the batcher class.

  • Loading branch information...
commit 49dfd4ffdf7859cf3977e8efe2be0b03fc31637d 1 parent 48c40a9
@thhermansen thhermansen authored alindeman committed
View
76 sunspot/lib/sunspot/batcher.rb
@@ -0,0 +1,76 @@
+module Sunspot
+
+ #
+ # Keeps a stack of batches and helps out when Indexer is asked to batch documents.
+ #
+ # If the client does something like
+ #
+ # Sunspot.batch do
+ # some_code_here
+ # which_triggers_some_other_code
+ # which_again_calls
+ # Sunspot.batch { ... }
+ # end
+ #
+ # it is the Batcher's job to keep track of these nestings. The inner will
+ # be sent of to be indexed first.
+ #
+ class Batcher
+ include Enumerable
+
+ # Raised if you ask to end current, but no current exists
+ class NoCurrentBatchError < StandardError; end
+
+
+ def initialize
+ @stack = []
+ end
+
+
+
+ def current
+ stack.last or start_new
+ end
+
+ def start_new
+ (stack << []).last
+ end
+
+ def end_current
+ fail NoCurrentBatchError if stack.empty?
+
+ stack.pop
+ end
+
+
+
+ def depth
+ stack.length
+ end
+
+ def batching?
+ depth > 0
+ end
+
+
+
+ def each
+ current.each { |v| yield v }
+ end
+
+ def push(value)
+ current << value
+ end
+ alias << push
+
+ def concat(values)
+ current.concat values
+ end
+
+
+
+ private
+
+ attr_reader :stack
+ end
+end
View
2  sunspot/lib/sunspot/indexer.rb
@@ -1,3 +1,5 @@
+require 'sunspot/batcher'
+
module Sunspot
#
# This class presents a service for adding, updating, and removing data
View
112 sunspot/spec/api/batcher_spec.rb
@@ -0,0 +1,112 @@
+require File.expand_path('spec_helper', File.dirname(__FILE__))
+
+describe Sunspot::Batcher do
+ it "includes Enumerable" do
+ described_class.should include Enumerable
+ end
+
+ describe "#each" do
+ let(:current) { [:foo, :bar] }
+ before { subject.stub(:current).and_return current }
+
+ it "iterates over current" do
+ yielded_values = []
+
+ subject.each do |value|
+ yielded_values << value
+ end
+
+ yielded_values.should eq current
+ end
+ end
+
+ describe "adding to current batch" do
+ it "#push pushes to current" do
+ subject.push :foo
+ subject.current.should include :foo
+ end
+
+ it "#<< pushes to current" do
+ subject.push :foo
+ subject.current.should include :foo
+ end
+
+ it "#concat concatinates on current batch" do
+ subject << :foo
+ subject.concat [:bar, :mix]
+ should include :foo, :bar, :mix
+ end
+ end
+
+
+ describe "#current" do
+ context "no current" do
+ it "starts a new" do
+ expect { subject.current }.to change(subject, :depth).by 1
+ end
+
+ it "is empty by default" do
+ subject.current.should be_empty
+ end
+ end
+
+ context "with a current" do
+ before { subject.start_new }
+
+ it "does not start a new" do
+ expect { subject.current }.to_not change(subject, :depth)
+ end
+
+ it "returns the same as last time" do
+ subject.current.should eq subject.current
+ end
+ end
+ end
+
+ describe "#start_new" do
+ it "creates a new batches" do
+ expect { 2.times { subject.start_new } }.to change(subject, :depth).by 2
+ end
+
+ it "changes current" do
+ subject << :foo
+ subject.start_new
+ should_not include :foo
+ end
+ end
+
+ describe "#end_current" do
+ context "no current batch" do
+ it "fails" do
+ expect { subject.end_current }.to raise_error Sunspot::Batcher::NoCurrentBatchError
+ end
+ end
+
+ context "with current batch" do
+ before { subject.start_new }
+
+ it "changes current" do
+ subject << :foo
+ subject.end_current
+ should_not include :foo
+ end
+
+ it "returns current" do
+ subject << :foo
+ subject.end_current.should include :foo
+ end
+ end
+ end
+
+ describe "#batching?" do
+ it "is false when depth is 0" do
+ subject.should_receive(:depth).and_return 0
+ should_not be_batching
+ end
+
+ it "is true when depth is more than 0" do
+ subject.should_receive(:depth).and_return 1
+ should be_batching
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.