Skip to content

Instantly share code, notes, and snippets.

@akm
Created January 28, 2009 01:52
Show Gist options
  • Save akm/53766 to your computer and use it in GitHub Desktop.
Save akm/53766 to your computer and use it in GitHub Desktop.
# 仕事用に作ってみたクラス
# 結局ボツにしました
class WhereBuilder
attr_accessor :joiner, 'AND'
attr_accessor :where_parts
attr_accessor :values
attr_accessor :filters
attr_accessor :wrapper
def initialize(*filters)
@filters = filters
@where_parts, @values = [], []
@joiner = 'AND'
end
def add(where_part, *vals, &block)
return self if block_given? and !yield(where_part, *vals)
return self unless filters.all?{|filter| filter.call(where_part, *vals) }
where_parts << where_part
vals.each{|val| values << val}
self
end
def to_wheres
wheres = where_parts.map{|part| part.respond_to?(:to_wheres) ? part.to_wheres : part}.flatten
where_part = wheres.join(" #{joiner} ")
where_part = wrapper % where_part if wrapper
where_part
end
def to_values
values.map{|val| val.respond_to?(:to_values) ? val.to_values : val}.flatten
end
def to_conditions
[to_wheres] + to_values
end
def with(joiner, *filters, &block)
if block_given?
sub = self.class.new(*filters).with(joiner)
sub.wrapper = '(%s)'
sub.instance_eval(&block)
unless sub.where_parts.empty?
where_parts << sub
values << sub
end
else
@joiner = joiner
end
self
end
end
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
describe WhereBuilder do
it "should support simple WHERE building" do
where = EcRider::WhereBuilder.new.
add("user_name like ?", "%ABE%").
add("birthday >= ?", Date.new(1973, 1, 1)).to_conditions.should ==
['user_name like ? AND birthday >= ?', '%ABE%', Date.new(1973, 1, 1)]
end
it "should add multiple values" do
where = EcRider::WhereBuilder.new.
add("user_name like ? AND birthday >= ?", "%ABE%", Date.new(1973, 1, 1)).to_conditions.should ==
['user_name like ? AND birthday >= ?', '%ABE%', Date.new(1973, 1, 1)]
end
it "should add value with filter" do
blank_filter = Proc.new{|cond, val| !val.blank?}
where = EcRider::WhereBuilder.new.
add("user_name like ?", "%ABE%", &blank_filter).
add("birthday >= ?", Date.new(1973, 1, 1), &blank_filter).to_conditions.should ==
['user_name like ? AND birthday >= ?', '%ABE%', Date.new(1973, 1, 1)]
where = EcRider::WhereBuilder.new.
add("user_name like ?", nil, &blank_filter).
add("birthday >= ?", Date.new(1973, 1, 1), &blank_filter).to_conditions.should ==
['birthday >= ?', Date.new(1973, 1, 1)]
where = EcRider::WhereBuilder.new.
add("user_name like ?", nil, &blank_filter).
add("birthday >= ?", nil, &blank_filter).to_conditions.should == ['']
end
it "should work with filters" do
blank_filter = Proc.new{|cond, val| !val.blank?}
where = EcRider::WhereBuilder.new(blank_filter).
add("user_name like ?", "%ABE%").
add("birthday >= ?", Date.new(1973, 1, 1)).to_conditions.should ==
['user_name like ? AND birthday >= ?', '%ABE%', Date.new(1973, 1, 1)]
where = EcRider::WhereBuilder.new(blank_filter).
add("user_name like ?", nil).
add("birthday >= ?", Date.new(1973, 1, 1)).to_conditions.should ==
['birthday >= ?', Date.new(1973, 1, 1)]
where = EcRider::WhereBuilder.new(blank_filter).
add("user_name like ?", nil).
add("birthday >= ?", nil).to_conditions.should == ['']
end
it "should work with with" do
where = EcRider::WhereBuilder.new.with('OR')
where.add("user_name like ?", '%AEG%')
where.with('AND') do
add("birthday >= ?", Date.new(2001, 1, 1))
add("birthday <= ?", Date.new(2004,12,31))
end
where.to_conditions.should ==
['user_name like ? OR (birthday >= ? AND birthday <= ?)', '%AEG%', Date.new(2001, 1, 1), Date.new(2004,12,31)]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment