require './parser' class TextToSqlQuery def initialize(text, fields, default_field, fields_mappings = {}) @text = text.to_s.strip @fields = fields.map(&:to_sym) @default_field = default_field.to_sym @fields_mappings = fields_mappings.merge(@fields.reduce({}) do |mappings, field| _table_name, field_name = field.to_s.split('.') mappings[field_name.to_sym] = field mappings end) end def where_clause @parser = Query.new @parsed_tree = @parser.parse(@text) generate_sql @parsed_tree end private def generate_sql(tree) @first_key = tree.keys.first case @first_key when :DEFAULT_COLUMN ["#{@default_field.to_s} LIKE ?", "%#{tree[@first_key]}%"] when :OPERATOR_OR generate_expression_for_logical_operator(:OR, tree[@first_key]) when :OPERATOR_AND generate_expression_for_logical_operator(:AND, tree[@first_key]) when :OPERATOR_NOT @not_array = generate_sql tree[@first_key] if @not_array.length < 2 raise "There should be more than 1 element for expression following NOT operator" end @not_expression = @not_array.first @not_params = @not_array[1..] ["NOT #{@not_expression}"] + @not_params else # key is column name @mapping = @fields_mappings[@first_key.to_sym] if @mapping.nil? ["#{@default_field.to_s} LIKE ?", "%#{tree[@first_key]}%"] else ["#{@mapping.to_s} LIKE ?", "%#{tree[@first_key]}%"] end end end def generate_expression_for_logical_operator(operator, operator_array) if operator_array.length != 2 raise "There should be two array elements for #{operator.to_s} operator" end @first_operand = generate_sql operator_array.first @second_operand = generate_sql operator_array.last if @first_operand.length < 2 raise 'There should be more than 1 element in first operand array' end if @second_operand.length < 2 raise 'There should be more than 1 element in second operand array' end @first_operand_expression = @first_operand.first @first_operand_params = @first_operand[1..] @second_operand_expression = @second_operand.first @second_operand_params = @second_operand[1..] ["#{@first_operand_expression} #{operator.to_s} #{@second_operand_expression}"] + @first_operand_params + @second_operand_params end end