Module: ScopedSearch::QueryBuilder::AST::OperatorNode

Defined in:
lib/scoped_search/query_builder.rb

Overview

Defines the to_sql method for AST operator nodes

Instance Method Summary collapse

Instance Method Details

#to_default_fields_sql(definition, &block) ⇒ Object

No explicit field name given, run the operator on all default fields



163
164
165
166
167
168
169
170
# File 'lib/scoped_search/query_builder.rb', line 163

def to_default_fields_sql(definition, &block)
  raise ScopedSearch::QueryNotSupported, "Value not a leaf node" unless rhs.kind_of?(ScopedSearch::QueryLanguage::AST::LeafNode)          
  
  # Search keywords found without context, just search on all the default fields
  fragments = definition.default_fields_for(rhs.value, operator).map { |field|
    ScopedSearch::QueryBuilder.sql_test(field, operator, rhs.value, &block) }.compact
  fragments.empty? ? nil : "(#{fragments.join(' OR ')})"
end

#to_not_sql(definition, &block) ⇒ Object

Returns a NOT(…) SQL fragment that negates the current AST node’s children



147
148
149
# File 'lib/scoped_search/query_builder.rb', line 147

def to_not_sql(definition, &block)
  "(NOT(#{rhs.to_sql(definition, &block)}) OR #{rhs.to_sql(definition, &block)} IS NULL)"
end

#to_null_sql(definition, &block) ⇒ Object

Returns a IS (NOT) NULL SQL fragment



152
153
154
155
156
157
158
159
160
# File 'lib/scoped_search/query_builder.rb', line 152

def to_null_sql(definition, &block)
  field = definition.fields[rhs.value.to_sym]  
  raise ScopedSearch::QueryNotSupported, "Field '#{rhs.value}' not recognized for searching!" unless field
  
  case operator
    when :null    then "#{field.to_sql(&block)} IS NULL"
    when :notnull then "#{field.to_sql(&block)} IS NOT NULL"
  end
end

#to_single_field_sql(definition, &block) ⇒ Object

Explicit field name given, run the operator on the specified field only



173
174
175
176
177
178
179
180
181
# File 'lib/scoped_search/query_builder.rb', line 173

def to_single_field_sql(definition, &block)
  raise ScopedSearch::QueryNotSupported, "Field name not a leaf node" unless lhs.kind_of?(ScopedSearch::QueryLanguage::AST::LeafNode)
  raise ScopedSearch::QueryNotSupported, "Value not a leaf node"      unless rhs.kind_of?(ScopedSearch::QueryLanguage::AST::LeafNode)
  
  # Search only on the given field.
  field = definition.fields[lhs.value.to_sym]
  raise ScopedSearch::QueryNotSupported, "Field '#{lhs.value}' not recognized for searching!" unless field
  ScopedSearch::QueryBuilder.sql_test(field, operator, rhs.value, &block)
end

#to_sql(definition, &block) ⇒ Object

Convert this AST node to an SQL fragment.



184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/scoped_search/query_builder.rb', line 184

def to_sql(definition, &block)
  if operator == :not && children.length == 1
    to_not_sql(definition, &block)
  elsif [:null, :notnull].include?(operator)
    to_null_sql(definition, &block)
  elsif children.length == 1
    to_default_fields_sql(definition, &block)            
  elsif children.length == 2
    to_single_field_sql(definition, &block)
  else
    raise ScopedSearch::QueryNotSupported, "Don't know how to handle this operator node: #{operator.inspect} with #{children.inspect}!"
  end
end