lib/groonga/expression-builder.rb in groonga-0.0.5 vs lib/groonga/expression-builder.rb in groonga-0.0.6

- old
+ new

@@ -15,41 +15,140 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA module Groonga module ExpressionBuildable - attr_accessor :builder, :expression, :variable + attr_reader :table def initialize(*args) - @builder = self - @expression = nil - @variable = nil @table = nil @name = nil @query = nil @default_column = nil end def build - @expression = Expression.new(:table => @table, - :name => @name, - :query => @query, - :default_column => @default_column) - if block_given? - @variable = @expression.define_variable(:domain => @table) - @expression.append_object(@variable) - yield(self) - @expression.compile + expression = Expression.new(:table => @table, + :name => @name, + :query => @query, + :default_column => @default_column) + variable = expression.define_variable(:domain => @table) + + builder = nil + builder = yield(self) if block_given? + if builder.nil? or builder == self + expression.append_constant(1) + expression.append_constant(1) + expression.append_operation(Groonga::Operation::OR, 2) + else + builder.build(expression, variable) end - @expression + + expression.compile + expression end + + class ExpressionBuilder + def initialize + super() + end + + def &(other) + AndExpressionBuilder.new(self, other) + end + + def |(other) + OrExpressionBuilder.new(self, other) + end + end + + class SetExpressionBuilder < ExpressionBuilder + def initialize(operation, *expression_builders) + super() + @operation = operation + @expression_builders = expression_builders + end + + def build(expression, variable) + return if @expression_builders.empty? + @expression_builders.each do |builder| + builder.build(expression, variable) + end + expression.append_operation(@operation, @expression_builders.size) + end + end + + class AndExpressionBuilder < SetExpressionBuilder + def initialize(*expression_builders) + super(Groonga::Operation::AND, *expression_builders) + end + end + + class OrExpressionBuilder < SetExpressionBuilder + def initialize(*expression_builders) + super(Groonga::Operation::OR, *expression_builders) + end + end + + class BinaryExpressionBuilder < ExpressionBuilder + def initialize(operation, column_name, value) + super() + @operation = operation + @column_name = column_name + @value = value + end + + def build(expression, variable) + expression.append_object(variable) + expression.append_constant(@column_name) + expression.append_operation(Groonga::Operation::OBJECT_GET_VALUE, 2) + expression.append_constant(@value) + expression.append_operation(@operation, 2) + end + end + + class EqualExpressionBuilder < BinaryExpressionBuilder + def initialize(column_name, value) + super(Groonga::Operation::EQUAL, column_name, value) + end + end + + class MatchExpressionBuilder < BinaryExpressionBuilder + def initialize(column_name, value) + super(Groonga::Operation::MATCH, column_name, value) + end + end + + class LessExpressionBuilder < BinaryExpressionBuilder + def initialize(column_name, value) + super(Groonga::Operation::LESS, column_name, value) + end + end + + class LessEqualExpressionBuilder < BinaryExpressionBuilder + def initialize(column_name, value) + super(Groonga::Operation::LESS_EQUAL, column_name, value) + end + end + + class GreaterExpressionBuilder < BinaryExpressionBuilder + def initialize(column_name, value) + super(Groonga::Operation::GREATER, column_name, value) + end + end + + class GreaterEqualExpressionBuilder < BinaryExpressionBuilder + def initialize(column_name, value) + super(Groonga::Operation::GREATER_EQUAL, column_name, value) + end + end end class RecordExpressionBuilder include ExpressionBuildable def initialize(table, name) - super + super() @table = table @name = name end def [](name) @@ -57,85 +156,56 @@ if column.nil? message = "unknown column <#{name.inspect}> " + "for table <#{@table.inspect}>" raise ArgumentError, message end - builder = ColumnExpressionBuilder.new(column, nil, nil) - builder.builder = @builder - builder.expression = @expression - builder.variable = @variable - builder + ColumnExpressionBuilder.new(column, nil, nil) end - - def &(other) - @expression.append_operation(Groonga::Operation::AND, 2) - @builder - end end class ColumnExpressionBuilder include ExpressionBuildable def initialize(column, name, query) - super + super() @table = column.table + @range = column.range @column = column @default_column = column.local_name @name = name @query = query end def ==(other) - @expression.append_object(@variable) - @expression.append_constant(@column.local_name) - @expression.append_operation(Groonga::Operation::OBJECT_GET_VALUE, 2) - @expression.append_constant(other) - @expression.append_operation(Groonga::Operation::EQUAL, 2) - @builder + EqualExpressionBuilder.new(@column.local_name, normalize(other)) end def =~(other) - @expression.append_object(@variable) - @expression.append_constant(@column.local_name) - @expression.append_operation(Groonga::Operation::OBJECT_GET_VALUE, 2) - @expression.append_constant(other) - @expression.append_operation(Groonga::Operation::MATCH, 2) - @builder + MatchExpressionBuilder.new(@column.local_name, normalize(other)) end def <(other) - @expression.append_object(@variable) - @expression.append_constant(@column.local_name) - @expression.append_operation(Groonga::Operation::OBJECT_GET_VALUE, 2) - @expression.append_constant(other) - @expression.append_operation(Groonga::Operation::LESS, 2) - @builder + LessExpressionBuilder.new(@column.local_name, normalize(other)) end def <=(other) - @expression.append_object(@variable) - @expression.append_constant(@column.local_name) - @expression.append_operation(Groonga::Operation::OBJECT_GET_VALUE, 2) - @expression.append_constant(other) - @expression.append_operation(Groonga::Operation::LESS_EQUAL, 2) - @builder + LessEqualExpressionBuilder.new(@column.local_name, normalize(other)) end def >(other) - @expression.append_object(@variable) - @expression.append_constant(@column.local_name) - @expression.append_operation(Groonga::Operation::OBJECT_GET_VALUE, 2) - @expression.append_constant(other) - @expression.append_operation(Groonga::Operation::GREATER, 2) - @builder + GreaterExpressionBuilder.new(@column.local_name, normalize(other)) end def >=(other) - @expression.append_object(@variable) - @expression.append_constant(@column.local_name) - @expression.append_operation(Groonga::Operation::OBJECT_GET_VALUE, 2) - @expression.append_constant(other) - @expression.append_operation(Groonga::Operation::GREATER_EQUAL, 2) - @builder + GreaterEqualExpressionBuilder.new(@column.local_name, normalize(other)) + end + + private + def normalize(other) + if @range.is_a?(Groonga::Table) and other.is_a?(Integer) + Groonga::Record.new(@range, other) + else + other + end end end end