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