module ScopedSearch::QueryBuilder::AST::OperatorNode

Defines the to_sql method for AST operator nodes

Public Instance Methods

to_default_fields_sql(builder, definition, &block) click to toggle source

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

    # File lib/scoped_search/query_builder.rb
477 def to_default_fields_sql(builder, definition, &block)
478   raise ScopedSearch::QueryNotSupported, "Value not a leaf node" unless rhs.kind_of?(ScopedSearch::QueryLanguage::AST::LeafNode)
479 
480   # Search keywords found without context, just search on all the default fields
481   fragments = definition.default_fields_for(rhs.value, operator).map { |field|
482                   builder.sql_test(field, operator, rhs.value,'', &block) }.compact
483 
484   case fragments.length
485     when 0 then nil
486     when 1 then fragments.first
487     else "#{fragments.join(' OR ')}"
488   end
489 end
to_null_sql(builder, definition) { |:parameter, value.sub(/^.*\./,'')| ... } click to toggle source

Returns an IS (NOT) NULL SQL fragment

    # File lib/scoped_search/query_builder.rb
463 def to_null_sql(builder, definition, &block)
464   field = definition.field_by_name(rhs.value)
465   raise ScopedSearch::QueryNotSupported, "Field '#{rhs.value}' not recognized for searching!" unless field
466 
467   if field.key_field
468     yield(:parameter, rhs.value.to_s.sub(/^.*\./,''))
469   end
470   case operator
471     when :null    then "#{field.to_sql(builder, &block)} IS NULL"
472     when :notnull then "#{field.to_sql(builder, &block)} IS NOT NULL"
473   end
474 end
to_single_field_sql(builder, definition, &block) click to toggle source

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

    # File lib/scoped_search/query_builder.rb
492 def to_single_field_sql(builder, definition, &block)
493   raise ScopedSearch::QueryNotSupported, "Field name not a leaf node" unless lhs.kind_of?(ScopedSearch::QueryLanguage::AST::LeafNode)
494   raise ScopedSearch::QueryNotSupported, "Value not a leaf node"      unless rhs.kind_of?(ScopedSearch::QueryLanguage::AST::LeafNode)
495 
496   # Search only on the given field.
497   field = definition.field_by_name(lhs.value)
498   raise ScopedSearch::QueryNotSupported, "Field '#{lhs.value}' not recognized for searching!" unless field
499 
500   # see if the value passes user defined validation
501   if operator == :in
502     rhs.value.split(',').each { |v| validate_value(field, v) }
503   else
504     validate_value(field, rhs.value)
505   end
506 
507   builder.sql_test(field, operator, rhs.value,lhs.value, &block)
508 end
to_sql(builder, definition, &block) click to toggle source

Convert this AST node to an SQL fragment.

    # File lib/scoped_search/query_builder.rb
511 def to_sql(builder, definition, &block)
512   if operator == :not && children.length == 1
513     builder.to_not_sql(rhs, definition, &block)
514   elsif [:null, :notnull].include?(operator)
515     to_null_sql(builder, definition, &block)
516   elsif children.length == 1
517     to_default_fields_sql(builder, definition, &block)
518   elsif children.length == 2
519     to_single_field_sql(builder, definition, &block)
520   else
521     raise ScopedSearch::QueryNotSupported, "Don't know how to handle this operator node: #{operator.inspect} with #{children.inspect}!"
522   end
523 end

Private Instance Methods

validate_value(field, value) click to toggle source
    # File lib/scoped_search/query_builder.rb
527 def validate_value(field, value)
528   validator = field.validator
529   if validator
530     valid = field.special_values.include?(value) || validator.call(value)
531     raise ScopedSearch::QueryNotSupported, "Value '#{value}' is not valid for field '#{field.field}'" unless valid
532   end
533 end