require_relative 'expression_tree_node' module RailsServersideDatatables class Expression attr_reader :expression def to_s expression.to_s end protected def raw( expr ) ExprTreeNode.raw(expr ) end end class IfThen < Expression def initialize( testexpr, comparison_val, thenexpr, elseexpr ) expression = ExprTreeNode.new('', Type::OPERATOR ) # Concat the statements only expression.add_argument raw( 'CASE' ) expression.add_argument testexpr if comparison_val.nil? expression.add_argument raw( 'IS NULL' ) comparison_val = raw( true ) end expression.add_argument raw( 'WHEN' ) expression.add_argument comparison_val expression.add_argument raw( 'THEN' ) expression.add_argument thenexpr expression.add_argument raw( 'ELSE' ) expression.add_argument elseexpr expression.add_argument raw( 'END' ) @expression = expression end end class FirstNotNull < Expression def initialize( test_value, *default ) f = ExprTreeNode.new(:coalesce, Type::FUNCTION ) f.add_argument test_value default.each { |d| f.add_argument d } @expression = f end end class CastToText < Expression def initialize( expression ) f = ExprTreeNode.new('::', Type::OPERATOR ) f.add_argument expression f.add_argument raw( 'text' ) @expression = f end end class CastToNumeric < Expression def initialize( expression ) f = ExprTreeNode.new('::', Type::OPERATOR ) f.add_argument expression f.add_argument raw( 'numeric' ) @expression = f end end class ExpressionAlias < Expression def initialize( expression, name ) f = ExprTreeNode.new('AS', Type::OPERATOR, false ) f.add_argument expression f.add_argument name @expression = f end end class FilterByText < Expression def initialize( expression, query ) f = ExprTreeNode.new('ILIKE', Type::OPERATOR, false ) f.add_argument CastToText.new( expression ) f.add_argument "%#{query}%" @expression = f end end class OrderBy < Expression def initialize( expression, direction = :ASC ) f = ExprTreeNode.new('', Type::OPERATOR, false ) f.add_argument expression f.add_argument ExprTreeNode.raw( direction.to_s.downcase == 'desc' ? 'DESC' : 'ASC' ) @expression = f end end class ExpressionList < Expression def initialize( expressions ) f = ExprTreeNode.new(',', Type::OPERATOR, false ) expressions.each { |expr| f.add_argument expr } @expression = f end end class NumOp < Expression def initialize( a, op, b ) f = ExprTreeNode.new( op.to_s, Type::OPERATOR ) f.add_argument CastToNumeric.new( a ) f.add_argument CastToNumeric.new( b ) @expression = f end end end