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
511 def to_default_fields_sql(builder, definition, &block)
512   raise ScopedSearch::QueryNotSupported, "Value not a leaf node" unless rhs.kind_of?(ScopedSearch::QueryLanguage::AST::LeafNode)
513 
514   # Search keywords found without context, just search on all the default fields
515   fragments = definition.default_fields_for(rhs.value, operator).map { |field|
516                   builder.sql_test(field, operator, rhs.value,'', &block) }.compact
517 
518   case fragments.length
519     when 0 then nil
520     when 1 then fragments.first
521     else "#{fragments.join(' OR ')}"
522   end
523 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
492 def to_null_sql(builder, definition, &block)
493   field = definition.field_by_name(rhs.value)
494   raise ScopedSearch::QueryNotSupported, "Field '#{rhs.value}' not recognized for searching!" unless field
495 
496   if field.virtual?
497     sql_operator = operator == :notnull ? 'IS NOT NULL' : 'IS NULL'
498     return field.to_ext_method_sql(rhs.value, sql_operator, nil, &block)
499   end
500 
501   if field.key_field
502     yield(:parameter, rhs.value.to_s.sub(/^.*\./,''))
503   end
504   case operator
505     when :null    then "#{field.to_sql(builder, &block)} IS NULL"
506     when :notnull then "#{field.to_sql(builder, &block)} IS NOT NULL"
507   end
508 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
526 def to_single_field_sql(builder, definition, &block)
527   raise ScopedSearch::QueryNotSupported, "Field name not a leaf node" unless lhs.kind_of?(ScopedSearch::QueryLanguage::AST::LeafNode)
528   raise ScopedSearch::QueryNotSupported, "Value not a leaf node"      unless rhs.kind_of?(ScopedSearch::QueryLanguage::AST::LeafNode)
529 
530   # Search only on the given field.
531   field = definition.field_by_name(lhs.value)
532   raise ScopedSearch::QueryNotSupported, "Field '#{lhs.value}' not recognized for searching!" unless field
533 
534   # see if the value passes user defined validation
535   if [:in, :notin].include?(operator)
536     rhs.value.split(',').each { |v| validate_value(field, v) }
537   else
538     validate_value(field, rhs.value)
539   end
540 
541   builder.sql_test(field, operator, rhs.value,lhs.value, &block)
542 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
545 def to_sql(builder, definition, &block)
546   if operator == :not && children.length == 1
547     builder.to_not_sql(rhs, definition, &block)
548   elsif [:null, :notnull].include?(operator)
549     to_null_sql(builder, definition, &block)
550   elsif children.length == 1
551     to_default_fields_sql(builder, definition, &block)
552   elsif children.length == 2
553     to_single_field_sql(builder, definition, &block)
554   else
555     raise ScopedSearch::QueryNotSupported, "Don't know how to handle this operator node: #{operator.inspect} with #{children.inspect}!"
556   end
557 end

Private Instance Methods

validate_value(field, value) click to toggle source
    # File lib/scoped_search/query_builder.rb
561 def validate_value(field, value)
562   validator = field.validator
563   if validator
564     valid = field.special_values.include?(value) || validator.call(value)
565     raise ScopedSearch::QueryNotSupported, "Value '#{value}' is not valid for field '#{field.field}'" unless valid
566   end
567 end