squeel 1.1.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.gitignore +3 -0
 - data/.rspec +3 -0
 - data/.travis.yml +36 -4
 - data/CHANGELOG.md +15 -0
 - data/Gemfile +1 -1
 - data/README.md +47 -6
 - data/Rakefile +14 -2
 - data/lib/squeel.rb +9 -1
 - data/lib/squeel/adapters/active_record.rb +0 -1
 - data/lib/squeel/adapters/active_record/3.0/join_dependency_extensions.rb +1 -0
 - data/lib/squeel/adapters/active_record/3.0/relation_extensions.rb +12 -1
 - data/lib/squeel/adapters/active_record/3.1/join_dependency_extensions.rb +1 -0
 - data/lib/squeel/adapters/active_record/3.2/join_dependency_extensions.rb +1 -0
 - data/lib/squeel/adapters/active_record/4.0/join_dependency_extensions.rb +1 -0
 - data/lib/squeel/adapters/active_record/4.0/relation_extensions.rb +92 -0
 - data/lib/squeel/adapters/active_record/4.1/compat.rb +15 -0
 - data/lib/squeel/adapters/active_record/4.1/context.rb +88 -0
 - data/lib/squeel/adapters/active_record/4.1/preloader_extensions.rb +31 -0
 - data/lib/squeel/adapters/active_record/4.1/reflection_extensions.rb +37 -0
 - data/lib/squeel/adapters/active_record/4.1/relation_extensions.rb +307 -0
 - data/lib/squeel/adapters/active_record/4.2/compat.rb +1 -0
 - data/lib/squeel/adapters/active_record/4.2/context.rb +1 -0
 - data/lib/squeel/adapters/active_record/4.2/preloader_extensions.rb +1 -0
 - data/lib/squeel/adapters/active_record/4.2/relation_extensions.rb +108 -0
 - data/lib/squeel/adapters/active_record/context.rb +7 -7
 - data/lib/squeel/adapters/active_record/join_dependency_extensions.rb +9 -13
 - data/lib/squeel/adapters/active_record/relation_extensions.rb +38 -8
 - data/lib/squeel/core_ext/symbol.rb +3 -3
 - data/lib/squeel/dsl.rb +1 -1
 - data/lib/squeel/nodes.rb +1 -0
 - data/lib/squeel/nodes/as.rb +12 -0
 - data/lib/squeel/nodes/join.rb +8 -4
 - data/lib/squeel/nodes/key_path.rb +10 -1
 - data/lib/squeel/nodes/node.rb +21 -0
 - data/lib/squeel/nodes/stub.rb +8 -4
 - data/lib/squeel/nodes/subquery_join.rb +44 -0
 - data/lib/squeel/version.rb +1 -1
 - data/lib/squeel/visitors.rb +2 -0
 - data/lib/squeel/visitors/enumeration_visitor.rb +101 -0
 - data/lib/squeel/visitors/order_visitor.rb +9 -2
 - data/lib/squeel/visitors/predicate_visitor.rb +11 -0
 - data/lib/squeel/visitors/preload_visitor.rb +12 -0
 - data/lib/squeel/visitors/visitor.rb +89 -13
 - data/spec/config.travis.yml +13 -0
 - data/spec/config.yml +12 -0
 - data/spec/console.rb +3 -12
 - data/spec/core_ext/symbol_spec.rb +3 -3
 - data/spec/helpers/squeel_helper.rb +8 -5
 - data/spec/spec_helper.rb +4 -16
 - data/spec/squeel/adapters/active_record/context_spec.rb +8 -4
 - data/spec/squeel/adapters/active_record/join_dependency_extensions_spec.rb +123 -38
 - data/spec/squeel/adapters/active_record/relation_extensions_spec.rb +350 -124
 - data/spec/squeel/core_ext/symbol_spec.rb +3 -3
 - data/spec/squeel/nodes/join_spec.rb +4 -4
 - data/spec/squeel/nodes/stub_spec.rb +3 -3
 - data/spec/squeel/nodes/subquery_join_spec.rb +46 -0
 - data/spec/squeel/visitors/order_visitor_spec.rb +3 -3
 - data/spec/squeel/visitors/predicate_visitor_spec.rb +69 -36
 - data/spec/squeel/visitors/select_visitor_spec.rb +1 -1
 - data/spec/squeel/visitors/visitor_spec.rb +7 -6
 - data/spec/support/models.rb +99 -15
 - data/spec/support/schema.rb +109 -4
 - data/squeel.gemspec +8 -6
 - metadata +89 -107
 - data/.ruby-gemset +0 -1
 - data/.ruby-version +0 -1
 - data/spec/blueprints/articles.rb +0 -5
 - data/spec/blueprints/comments.rb +0 -5
 - data/spec/blueprints/notes.rb +0 -3
 - data/spec/blueprints/people.rb +0 -4
 - data/spec/blueprints/tags.rb +0 -3
 
| 
         @@ -3,6 +3,12 @@ require 'squeel/context' 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module Squeel
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Adapters
         
     | 
| 
       5 
5 
     | 
    
         
             
                module ActiveRecord
         
     | 
| 
      
 6 
     | 
    
         
            +
                  JoinPart = if defined?(::ActiveRecord::Associations::JoinDependency::JoinPart)
         
     | 
| 
      
 7 
     | 
    
         
            +
                      ::ActiveRecord::Associations::JoinDependency::JoinPart
         
     | 
| 
      
 8 
     | 
    
         
            +
                    elsif defined?(::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinBase)
         
     | 
| 
      
 9 
     | 
    
         
            +
                      ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinBase
         
     | 
| 
      
 10 
     | 
    
         
            +
                    end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
       6 
12 
     | 
    
         
             
                  class Context < ::Squeel::Context
         
     | 
| 
       7 
13 
     | 
    
         | 
| 
       8 
14 
     | 
    
         
             
                    def initialize(object)
         
     | 
| 
         @@ -23,7 +29,7 @@ module Squeel 
     | 
|
| 
       23 
29 
     | 
    
         
             
                          }
         
     | 
| 
       24 
30 
     | 
    
         
             
                        when Nodes::Join
         
     | 
| 
       25 
31 
     | 
    
         
             
                          @object.join_associations.detect { |j|
         
     | 
| 
       26 
     | 
    
         
            -
                            j.reflection.name == object. 
     | 
| 
      
 32 
     | 
    
         
            +
                            j.reflection.name == object._name && j.parent == parent &&
         
     | 
| 
       27 
33 
     | 
    
         
             
                            (object.polymorphic? ? j.reflection.klass == object._klass : true)
         
     | 
| 
       28 
34 
     | 
    
         
             
                          }
         
     | 
| 
       29 
35 
     | 
    
         
             
                        else
         
     | 
| 
         @@ -73,12 +79,6 @@ module Squeel 
     | 
|
| 
       73 
79 
     | 
    
         
             
                    end
         
     | 
| 
       74 
80 
     | 
    
         | 
| 
       75 
81 
     | 
    
         
             
                  end
         
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
                  if defined?(::ActiveRecord::Associations::JoinDependency::JoinPart)
         
     | 
| 
       78 
     | 
    
         
            -
                    JoinPart = ::ActiveRecord::Associations::JoinDependency::JoinPart
         
     | 
| 
       79 
     | 
    
         
            -
                  elsif defined?(::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinBase)
         
     | 
| 
       80 
     | 
    
         
            -
                    JoinPart = ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinBase
         
     | 
| 
       81 
     | 
    
         
            -
                  end
         
     | 
| 
       82 
82 
     | 
    
         
             
                end
         
     | 
| 
       83 
83 
     | 
    
         
             
              end
         
     | 
| 
       84 
84 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,17 +1,22 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'polyamorous'
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
1 
     | 
    
         
             
            module Squeel
         
     | 
| 
       4 
2 
     | 
    
         
             
              module Adapters
         
     | 
| 
       5 
3 
     | 
    
         
             
                module ActiveRecord
         
     | 
| 
       6 
     | 
    
         
            -
                   
     | 
| 
      
 4 
     | 
    
         
            +
                  if defined?(::ActiveRecord::Associations::JoinDependency)
         
     | 
| 
      
 5 
     | 
    
         
            +
                    JoinAssociation = ::ActiveRecord::Associations::JoinDependency::JoinAssociation
         
     | 
| 
      
 6 
     | 
    
         
            +
                    JoinDependency = ::ActiveRecord::Associations::JoinDependency
         
     | 
| 
      
 7 
     | 
    
         
            +
                  elsif defined?(::ActiveRecord::Associations::ClassMethods::JoinDependency)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    JoinAssociation = ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation
         
     | 
| 
      
 9 
     | 
    
         
            +
                    JoinDependency = ::ActiveRecord::Associations::ClassMethods::JoinDependency
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
       7 
11 
     | 
    
         | 
| 
      
 12 
     | 
    
         
            +
                  module JoinDependencyExtensions
         
     | 
| 
       8 
13 
     | 
    
         
             
                    def self.included(base)
         
     | 
| 
       9 
14 
     | 
    
         
             
                      base.class_eval do
         
     | 
| 
       10 
15 
     | 
    
         
             
                        alias_method_chain :build, :squeel
         
     | 
| 
       11 
16 
     | 
    
         
             
                      end
         
     | 
| 
       12 
17 
     | 
    
         
             
                    end
         
     | 
| 
       13 
18 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                    def build_with_squeel(associations, parent = nil, join_type =  
     | 
| 
      
 19 
     | 
    
         
            +
                    def build_with_squeel(associations, parent = nil, join_type = InnerJoin)
         
     | 
| 
       15 
20 
     | 
    
         
             
                      case associations
         
     | 
| 
       16 
21 
     | 
    
         
             
                      when Nodes::Stub
         
     | 
| 
       17 
22 
     | 
    
         
             
                        associations = associations.symbol
         
     | 
| 
         @@ -29,15 +34,6 @@ module Squeel 
     | 
|
| 
       29 
34 
     | 
    
         
             
                        build_without_squeel(associations, parent, join_type)
         
     | 
| 
       30 
35 
     | 
    
         
             
                      end
         
     | 
| 
       31 
36 
     | 
    
         
             
                    end
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
                  end
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                  if defined?(::ActiveRecord::Associations::JoinDependency)
         
     | 
| 
       36 
     | 
    
         
            -
                    JoinAssociation = ::ActiveRecord::Associations::JoinDependency::JoinAssociation
         
     | 
| 
       37 
     | 
    
         
            -
                    JoinDependency = ::ActiveRecord::Associations::JoinDependency
         
     | 
| 
       38 
     | 
    
         
            -
                  elsif defined?(::ActiveRecord::Associations::ClassMethods::JoinDependency)
         
     | 
| 
       39 
     | 
    
         
            -
                    JoinAssociation = ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation
         
     | 
| 
       40 
     | 
    
         
            -
                    JoinDependency = ::ActiveRecord::Associations::ClassMethods::JoinDependency
         
     | 
| 
       41 
37 
     | 
    
         
             
                  end
         
     | 
| 
       42 
38 
     | 
    
         | 
| 
       43 
39 
     | 
    
         
             
                  JoinDependency.send :include, Adapters::ActiveRecord::JoinDependencyExtensions
         
     | 
| 
         @@ -45,7 +45,6 @@ module Squeel 
     | 
|
| 
       45 
45 
     | 
    
         
             
                          merge_resolving_duplicate_squeel_equalities(r)
         
     | 
| 
       46 
46 
     | 
    
         
             
                        end
         
     | 
| 
       47 
47 
     | 
    
         
             
                      else
         
     | 
| 
       48 
     | 
    
         
            -
                        puts r.inspect if r.is_a?(Proc)
         
     | 
| 
       49 
48 
     | 
    
         
             
                        super(r)
         
     | 
| 
       50 
49 
     | 
    
         
             
                      end
         
     | 
| 
       51 
50 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -115,6 +114,8 @@ module Squeel 
     | 
|
| 
       115 
114 
     | 
    
         
             
                          :stashed_join
         
     | 
| 
       116 
115 
     | 
    
         
             
                        when Arel::Nodes::Join
         
     | 
| 
       117 
116 
     | 
    
         
             
                          :join_node
         
     | 
| 
      
 117 
     | 
    
         
            +
                        when Nodes::SubqueryJoin
         
     | 
| 
      
 118 
     | 
    
         
            +
                          :subquery_join
         
     | 
| 
       118 
119 
     | 
    
         
             
                        else
         
     | 
| 
       119 
120 
     | 
    
         
             
                          raise 'unknown class: %s' % join.class.name
         
     | 
| 
       120 
121 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -123,6 +124,7 @@ module Squeel 
     | 
|
| 
       123 
124 
     | 
    
         
             
                      association_joins         = buckets[:association_join] || []
         
     | 
| 
       124 
125 
     | 
    
         
             
                      stashed_association_joins = buckets[:stashed_join] || []
         
     | 
| 
       125 
126 
     | 
    
         
             
                      join_nodes                = (buckets[:join_node] || []).uniq
         
     | 
| 
      
 127 
     | 
    
         
            +
                      subquery_joins            = (buckets[:subquery_join] || []).uniq
         
     | 
| 
       126 
128 
     | 
    
         
             
                      string_joins              = (buckets[:string_join] || []).map { |x|
         
     | 
| 
       127 
129 
     | 
    
         
             
                        x.strip
         
     | 
| 
       128 
130 
     | 
    
         
             
                      }.uniq
         
     | 
| 
         @@ -144,11 +146,12 @@ module Squeel 
     | 
|
| 
       144 
146 
     | 
    
         
             
                        association.join_to(manager)
         
     | 
| 
       145 
147 
     | 
    
         
             
                      end
         
     | 
| 
       146 
148 
     | 
    
         | 
| 
       147 
     | 
    
         
            -
                      manager.join_sources.concat 
     | 
| 
      
 149 
     | 
    
         
            +
                      manager.join_sources.concat(join_list)
         
     | 
| 
      
 150 
     | 
    
         
            +
                      manager.join_sources.concat(build_join_from_subquery(subquery_joins))
         
     | 
| 
       148 
151 
     | 
    
         | 
| 
       149 
152 
     | 
    
         
             
                      manager
         
     | 
| 
       150 
153 
     | 
    
         
             
                    end
         
     | 
| 
       151 
     | 
    
         
            -
                    # For 4. 
     | 
| 
      
 154 
     | 
    
         
            +
                    # For 4.0 adapters
         
     | 
| 
       152 
155 
     | 
    
         
             
                    alias :build_joins :build_join_dependency
         
     | 
| 
       153 
156 
     | 
    
         | 
| 
       154 
157 
     | 
    
         
             
                    def includes(*args)
         
     | 
| 
         @@ -279,12 +282,12 @@ module Squeel 
     | 
|
| 
       279 
282 
     | 
    
         
             
                      end
         
     | 
| 
       280 
283 
     | 
    
         
             
                    end
         
     | 
| 
       281 
284 
     | 
    
         | 
| 
       282 
     | 
    
         
            -
                    def find_equality_predicates(nodes)
         
     | 
| 
      
 285 
     | 
    
         
            +
                    def find_equality_predicates(nodes, relation_table_name = table_name)
         
     | 
| 
       283 
286 
     | 
    
         
             
                      nodes.map { |node|
         
     | 
| 
       284 
287 
     | 
    
         
             
                        case node
         
     | 
| 
       285 
288 
     | 
    
         
             
                        when Arel::Nodes::Equality
         
     | 
| 
       286 
289 
     | 
    
         
             
                          if node.left.respond_to?(:relation) &&
         
     | 
| 
       287 
     | 
    
         
            -
                            node.left.relation.name ==  
     | 
| 
      
 290 
     | 
    
         
            +
                            node.left.relation.name == relation_table_name
         
     | 
| 
       288 
291 
     | 
    
         
             
                            node
         
     | 
| 
       289 
292 
     | 
    
         
             
                          end
         
     | 
| 
       290 
293 
     | 
    
         
             
                        when Arel::Nodes::Grouping
         
     | 
| 
         @@ -395,9 +398,8 @@ module Squeel 
     | 
|
| 
       395 
398 
     | 
    
         
             
                    # your model's default scope. We hijack it in order to dig down into
         
     | 
| 
       396 
399 
     | 
    
         
             
                    # And and Grouping nodes, which are equivalent to seeing top-level
         
     | 
| 
       397 
400 
     | 
    
         
             
                    # Equality nodes in stock AR terms.
         
     | 
| 
       398 
     | 
    
         
            -
                    def where_values_hash_with_squeel
         
     | 
| 
       399 
     | 
    
         
            -
                      equalities = find_equality_predicates(where_visit(with_default_scope.where_values))
         
     | 
| 
       400 
     | 
    
         
            -
             
     | 
| 
      
 401 
     | 
    
         
            +
                    def where_values_hash_with_squeel(relation_table_name = table_name)
         
     | 
| 
      
 402 
     | 
    
         
            +
                      equalities = find_equality_predicates(where_visit(with_default_scope.where_values), relation_table_name)
         
     | 
| 
       401 
403 
     | 
    
         
             
                      binds = Hash[bind_values.find_all(&:first).map { |column, v| [column.name, v] }]
         
     | 
| 
       402 
404 
     | 
    
         | 
| 
       403 
405 
     | 
    
         
             
                      Hash[equalities.map { |where|
         
     | 
| 
         @@ -406,6 +408,34 @@ module Squeel 
     | 
|
| 
       406 
408 
     | 
    
         
             
                      }]
         
     | 
| 
       407 
409 
     | 
    
         
             
                    end
         
     | 
| 
       408 
410 
     | 
    
         | 
| 
      
 411 
     | 
    
         
            +
                    def build_join_from_subquery(subquery_joins)
         
     | 
| 
      
 412 
     | 
    
         
            +
                      subquery_joins.map do |join|
         
     | 
| 
      
 413 
     | 
    
         
            +
                        join.type.new(
         
     | 
| 
      
 414 
     | 
    
         
            +
                          Arel::Nodes::TableAlias.new(
         
     | 
| 
      
 415 
     | 
    
         
            +
                            Arel::Nodes::Grouping.new(join.subquery.left.arel.ast),
         
     | 
| 
      
 416 
     | 
    
         
            +
                            join.subquery.right),
         
     | 
| 
      
 417 
     | 
    
         
            +
                          Arel::Nodes::On.new(where_visit(join.constraints))
         
     | 
| 
      
 418 
     | 
    
         
            +
                        )
         
     | 
| 
      
 419 
     | 
    
         
            +
                      end
         
     | 
| 
      
 420 
     | 
    
         
            +
                    end
         
     | 
| 
      
 421 
     | 
    
         
            +
             
     | 
| 
      
 422 
     | 
    
         
            +
                    def preprocess_attrs_with_ar(attributes)
         
     | 
| 
      
 423 
     | 
    
         
            +
                      attributes.map do |key, value|
         
     | 
| 
      
 424 
     | 
    
         
            +
                        case key
         
     | 
| 
      
 425 
     | 
    
         
            +
                          when Squeel::Nodes::Node
         
     | 
| 
      
 426 
     | 
    
         
            +
                            {key => value}
         
     | 
| 
      
 427 
     | 
    
         
            +
                          when Symbol
         
     | 
| 
      
 428 
     | 
    
         
            +
                            if value.is_a?(Hash)
         
     | 
| 
      
 429 
     | 
    
         
            +
                              {key => value}
         
     | 
| 
      
 430 
     | 
    
         
            +
                            else
         
     | 
| 
      
 431 
     | 
    
         
            +
                              ::ActiveRecord::PredicateBuilder.build_from_hash(klass, {key => value}, table)
         
     | 
| 
      
 432 
     | 
    
         
            +
                            end
         
     | 
| 
      
 433 
     | 
    
         
            +
                          else
         
     | 
| 
      
 434 
     | 
    
         
            +
                            ::ActiveRecord::PredicateBuilder.build_from_hash(klass, {key => value}, table)
         
     | 
| 
      
 435 
     | 
    
         
            +
                          end
         
     | 
| 
      
 436 
     | 
    
         
            +
                      end
         
     | 
| 
      
 437 
     | 
    
         
            +
                    end
         
     | 
| 
      
 438 
     | 
    
         
            +
             
     | 
| 
       409 
439 
     | 
    
         
             
                  end
         
     | 
| 
       410 
440 
     | 
    
         
             
                end
         
     | 
| 
       411 
441 
     | 
    
         
             
              end
         
     | 
| 
         @@ -15,15 +15,15 @@ class Symbol 
     | 
|
| 
       15 
15 
     | 
    
         
             
              end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
              def inner
         
     | 
| 
       18 
     | 
    
         
            -
                Squeel::Nodes::Join.new(self,  
     | 
| 
      
 18 
     | 
    
         
            +
                Squeel::Nodes::Join.new(self, Squeel::InnerJoin)
         
     | 
| 
       19 
19 
     | 
    
         
             
              end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
              def outer
         
     | 
| 
       22 
     | 
    
         
            -
                Squeel::Nodes::Join.new(self,  
     | 
| 
      
 22 
     | 
    
         
            +
                Squeel::Nodes::Join.new(self, Squeel::OuterJoin)
         
     | 
| 
       23 
23 
     | 
    
         
             
              end
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
              def of_class(klass)
         
     | 
| 
       26 
     | 
    
         
            -
                Squeel::Nodes::Join.new(self,  
     | 
| 
      
 26 
     | 
    
         
            +
                Squeel::Nodes::Join.new(self, Squeel::InnerJoin, klass)
         
     | 
| 
       27 
27 
     | 
    
         
             
              end
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
            end
         
     | 
    
        data/lib/squeel/dsl.rb
    CHANGED
    
    | 
         @@ -110,7 +110,7 @@ module Squeel 
     | 
|
| 
       110 
110 
     | 
    
         
             
                  if args.empty?
         
     | 
| 
       111 
111 
     | 
    
         
             
                    Nodes::Stub.new method_id
         
     | 
| 
       112 
112 
     | 
    
         
             
                  elsif (args.size == 1) && (Class === args[0])
         
     | 
| 
       113 
     | 
    
         
            -
                    Nodes::Join.new(method_id,  
     | 
| 
      
 113 
     | 
    
         
            +
                    Nodes::Join.new(method_id, InnerJoin, args[0])
         
     | 
| 
       114 
114 
     | 
    
         
             
                  else
         
     | 
| 
       115 
115 
     | 
    
         
             
                    Nodes::Function.new method_id, args
         
     | 
| 
       116 
116 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/squeel/nodes.rb
    CHANGED
    
    
    
        data/lib/squeel/nodes/as.rb
    CHANGED
    
    | 
         @@ -12,6 +12,18 @@ module Squeel 
     | 
|
| 
       12 
12 
     | 
    
         
             
                  def initialize(left, right)
         
     | 
| 
       13 
13 
     | 
    
         
             
                    @left, @right = left, right
         
     | 
| 
       14 
14 
     | 
    
         
             
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def on(*args)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    raise "only can convert ActiveRecord::Relation to a join node" unless left.is_a?(ActiveRecord::Relation)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    proc =
         
     | 
| 
      
 19 
     | 
    
         
            +
                      if block_given?
         
     | 
| 
      
 20 
     | 
    
         
            +
                        DSL.eval(&Proc.new)
         
     | 
| 
      
 21 
     | 
    
         
            +
                      else
         
     | 
| 
      
 22 
     | 
    
         
            +
                        args
         
     | 
| 
      
 23 
     | 
    
         
            +
                      end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    SubqueryJoin.new(self, proc)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
       15 
27 
     | 
    
         
             
                end
         
     | 
| 
       16 
28 
     | 
    
         
             
              end
         
     | 
| 
       17 
29 
     | 
    
         
             
            end
         
     | 
    
        data/lib/squeel/nodes/join.rb
    CHANGED
    
    | 
         @@ -14,21 +14,21 @@ module Squeel 
     | 
|
| 
       14 
14 
     | 
    
         
             
                  # @param [Symbol] name The association name
         
     | 
| 
       15 
15 
     | 
    
         
             
                  # @param [Arel::InnerJoin, Arel::OuterJoin] type The Arel join class
         
     | 
| 
       16 
16 
     | 
    
         
             
                  # @param [Class, String, Symbol] klass The polymorphic belongs_to class or class name
         
     | 
| 
       17 
     | 
    
         
            -
                  def initialize(name, type =  
     | 
| 
      
 17 
     | 
    
         
            +
                  def initialize(name, type = InnerJoin, klass = nil)
         
     | 
| 
       18 
18 
     | 
    
         
             
                    @_join = Polyamorous::Join.new(name, type, klass)
         
     | 
| 
       19 
19 
     | 
    
         
             
                  end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
                  # Set the join type to an inner join
         
     | 
| 
       22 
22 
     | 
    
         
             
                  # @return [Join] The join, with an updated join type.
         
     | 
| 
       23 
23 
     | 
    
         
             
                  def inner
         
     | 
| 
       24 
     | 
    
         
            -
                    self._type =  
     | 
| 
      
 24 
     | 
    
         
            +
                    self._type = InnerJoin
         
     | 
| 
       25 
25 
     | 
    
         
             
                    self
         
     | 
| 
       26 
26 
     | 
    
         
             
                  end
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
                  # Set the join type to an outer join
         
     | 
| 
       29 
29 
     | 
    
         
             
                  # @return [Join] The join, with an updated join type.
         
     | 
| 
       30 
30 
     | 
    
         
             
                  def outer
         
     | 
| 
       31 
     | 
    
         
            -
                    self._type =  
     | 
| 
      
 31 
     | 
    
         
            +
                    self._type = OuterJoin
         
     | 
| 
       32 
32 
     | 
    
         
             
                    self
         
     | 
| 
       33 
33 
     | 
    
         
             
                  end
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
         @@ -61,7 +61,7 @@ module Squeel 
     | 
|
| 
       61 
61 
     | 
    
         
             
                  def method_missing(method_id, *args)
         
     | 
| 
       62 
62 
     | 
    
         
             
                    super if method_id == :to_ary
         
     | 
| 
       63 
63 
     | 
    
         
             
                    if (args.size == 1) && (Class === args[0])
         
     | 
| 
       64 
     | 
    
         
            -
                      KeyPath.new([self, Join.new(method_id,  
     | 
| 
      
 64 
     | 
    
         
            +
                      KeyPath.new([self, Join.new(method_id, InnerJoin, args[0])])
         
     | 
| 
       65 
65 
     | 
    
         
             
                    else
         
     | 
| 
       66 
66 
     | 
    
         
             
                      KeyPath.new([self, method_id])
         
     | 
| 
       67 
67 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -83,6 +83,10 @@ module Squeel 
     | 
|
| 
       83 
83 
     | 
    
         
             
                    nil
         
     | 
| 
       84 
84 
     | 
    
         
             
                  end
         
     | 
| 
       85 
85 
     | 
    
         | 
| 
      
 86 
     | 
    
         
            +
                  def add_to_tree(hash)
         
     | 
| 
      
 87 
     | 
    
         
            +
                    hash[_join] ||= {}
         
     | 
| 
      
 88 
     | 
    
         
            +
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
       86 
90 
     | 
    
         
             
                end
         
     | 
| 
       87 
91 
     | 
    
         
             
              end
         
     | 
| 
       88 
92 
     | 
    
         
             
            end
         
     | 
| 
         @@ -177,6 +177,10 @@ module Squeel 
     | 
|
| 
       177 
177 
     | 
    
         
             
                  end
         
     | 
| 
       178 
178 
     | 
    
         
             
                  alias :to_str :to_s
         
     | 
| 
       179 
179 
     | 
    
         | 
| 
      
 180 
     | 
    
         
            +
                  def add_to_tree(hash)
         
     | 
| 
      
 181 
     | 
    
         
            +
                    walk_through_path(path.dup, hash)
         
     | 
| 
      
 182 
     | 
    
         
            +
                  end
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
       180 
184 
     | 
    
         
             
                  # Appends to the KeyPath or delegates to the endpoint, as appropriate
         
     | 
| 
       181 
185 
     | 
    
         
             
                  # @return [KeyPath] The updated KeyPath
         
     | 
| 
       182 
186 
     | 
    
         
             
                  def method_missing(method_id, *args, &block)
         
     | 
| 
         @@ -194,7 +198,7 @@ module Squeel 
     | 
|
| 
       194 
198 
     | 
    
         
             
                      if args.empty?
         
     | 
| 
       195 
199 
     | 
    
         
             
                        @path << Stub.new(method_id)
         
     | 
| 
       196 
200 
     | 
    
         
             
                      elsif (args.size == 1) && (Class === args[0])
         
     | 
| 
       197 
     | 
    
         
            -
                        @path << Join.new(method_id,  
     | 
| 
      
 201 
     | 
    
         
            +
                        @path << Join.new(method_id, InnerJoin, args[0])
         
     | 
| 
       198 
202 
     | 
    
         
             
                      else
         
     | 
| 
       199 
203 
     | 
    
         
             
                        @path << Nodes::Function.new(method_id, args)
         
     | 
| 
       200 
204 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -213,6 +217,11 @@ module Squeel 
     | 
|
| 
       213 
217 
     | 
    
         
             
                    @path = @path.dup
         
     | 
| 
       214 
218 
     | 
    
         
             
                  end
         
     | 
| 
       215 
219 
     | 
    
         | 
| 
      
 220 
     | 
    
         
            +
                  def walk_through_path(path, hash)
         
     | 
| 
      
 221 
     | 
    
         
            +
                    cache = path.shift.add_to_tree(hash)
         
     | 
| 
      
 222 
     | 
    
         
            +
                    path.empty? ? cache : walk_through_path(path, cache)
         
     | 
| 
      
 223 
     | 
    
         
            +
                  end
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
       216 
225 
     | 
    
         
             
                  # Raises a NoMethodError manually, bypassing #method_missing.
         
     | 
| 
       217 
226 
     | 
    
         
             
                  # Used by special-case operator overrides.
         
     | 
| 
       218 
227 
     | 
    
         
             
                  def no_method_error(method_id)
         
     | 
    
        data/lib/squeel/nodes/node.rb
    CHANGED
    
    | 
         @@ -1,6 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'polyamorous/tree_node'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Squeel
         
     | 
| 
       2 
4 
     | 
    
         
             
              module Nodes
         
     | 
| 
       3 
5 
     | 
    
         
             
                class Node
         
     | 
| 
      
 6 
     | 
    
         
            +
                  include ::Polyamorous::TreeNode
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  def each(&block)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    return enum_for(:each) unless block_given?
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                    Visitors::EnumerationVisitor.new(block).accept(self)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  # We don't want the full Enumerable method list, because it will mess
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # with stuff like KeyPath
         
     | 
| 
      
 16 
     | 
    
         
            +
                  def grep(object, &block)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    if block_given?
         
     | 
| 
      
 18 
     | 
    
         
            +
                      each { |value| yield value if object === value }
         
     | 
| 
      
 19 
     | 
    
         
            +
                    else
         
     | 
| 
      
 20 
     | 
    
         
            +
                      [].tap do |results|
         
     | 
| 
      
 21 
     | 
    
         
            +
                        each { |value| results << value if object === value }
         
     | 
| 
      
 22 
     | 
    
         
            +
                      end
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
       4 
25 
     | 
    
         
             
                end
         
     | 
| 
       5 
26 
     | 
    
         
             
              end
         
     | 
| 
       6 
27 
     | 
    
         
             
            end
         
     | 
    
        data/lib/squeel/nodes/stub.rb
    CHANGED
    
    | 
         @@ -79,7 +79,7 @@ module Squeel 
     | 
|
| 
       79 
79 
     | 
    
         
             
                    if args.empty?
         
     | 
| 
       80 
80 
     | 
    
         
             
                      KeyPath.new([self, method_id])
         
     | 
| 
       81 
81 
     | 
    
         
             
                    elsif (args.size == 1) && (Class === args[0])
         
     | 
| 
       82 
     | 
    
         
            -
                      KeyPath.new([self, Join.new(method_id,  
     | 
| 
      
 82 
     | 
    
         
            +
                      KeyPath.new([self, Join.new(method_id, InnerJoin, args[0])])
         
     | 
| 
       83 
83 
     | 
    
         
             
                    else
         
     | 
| 
       84 
84 
     | 
    
         
             
                      KeyPath.new([self, Nodes::Function.new(method_id, args)])
         
     | 
| 
       85 
85 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -102,7 +102,7 @@ module Squeel 
     | 
|
| 
       102 
102 
     | 
    
         
             
                  # Create an inner Join node for the association named by this Stub
         
     | 
| 
       103 
103 
     | 
    
         
             
                  # @return [Join] The new inner Join node
         
     | 
| 
       104 
104 
     | 
    
         
             
                  def inner
         
     | 
| 
       105 
     | 
    
         
            -
                    Join.new(self.symbol,  
     | 
| 
      
 105 
     | 
    
         
            +
                    Join.new(self.symbol, InnerJoin)
         
     | 
| 
       106 
106 
     | 
    
         
             
                  end
         
     | 
| 
       107 
107 
     | 
    
         | 
| 
       108 
108 
     | 
    
         
             
                  # Create a keypath with a sifter as its endpoint
         
     | 
| 
         @@ -114,14 +114,18 @@ module Squeel 
     | 
|
| 
       114 
114 
     | 
    
         
             
                  # Create an outer Join node for the association named by this Stub
         
     | 
| 
       115 
115 
     | 
    
         
             
                  # @return [Join] The new outer Join node
         
     | 
| 
       116 
116 
     | 
    
         
             
                  def outer
         
     | 
| 
       117 
     | 
    
         
            -
                    Join.new(self.symbol,  
     | 
| 
      
 117 
     | 
    
         
            +
                    Join.new(self.symbol, OuterJoin)
         
     | 
| 
       118 
118 
     | 
    
         
             
                  end
         
     | 
| 
       119 
119 
     | 
    
         | 
| 
       120 
120 
     | 
    
         
             
                  # Create a polymorphic Join node for the association named by this Stub,
         
     | 
| 
       121 
121 
     | 
    
         
             
                  # @param [Class] klass The polymorphic belongs_to class for this Join
         
     | 
| 
       122 
122 
     | 
    
         
             
                  # @return [Join] The new polymorphic Join node
         
     | 
| 
       123 
123 
     | 
    
         
             
                  def of_class(klass)
         
     | 
| 
       124 
     | 
    
         
            -
                    Join.new(self.symbol,  
     | 
| 
      
 124 
     | 
    
         
            +
                    Join.new(self.symbol, InnerJoin, klass)
         
     | 
| 
      
 125 
     | 
    
         
            +
                  end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                  def add_to_tree(hash)
         
     | 
| 
      
 128 
     | 
    
         
            +
                    hash[symbol] ||= {}
         
     | 
| 
       125 
129 
     | 
    
         
             
                  end
         
     | 
| 
       126 
130 
     | 
    
         | 
| 
       127 
131 
     | 
    
         
             
                end
         
     | 
| 
         @@ -0,0 +1,44 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Squeel
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Nodes
         
     | 
| 
      
 3 
     | 
    
         
            +
                class SubqueryJoin < Node
         
     | 
| 
      
 4 
     | 
    
         
            +
                  attr_accessor :subquery, :type, :constraints
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(subquery, constraints, type = Squeel::InnerJoin)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    raise ArgumentError,
         
     | 
| 
      
 8 
     | 
    
         
            +
                      "subquery(#{subquery}) isn't an Squeel::Nodes::As" unless subquery.is_a?(As)
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    raise ArgumentError,
         
     | 
| 
      
 11 
     | 
    
         
            +
                      "constraints(#{constraints}) isn't a Squeel::Nodes::Node" unless constraints.is_a?(Node)
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                    self.subquery = subquery
         
     | 
| 
      
 14 
     | 
    
         
            +
                    self.constraints = constraints
         
     | 
| 
      
 15 
     | 
    
         
            +
                    self.type = type
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  # Implemented for equality testing
         
     | 
| 
      
 19 
     | 
    
         
            +
                  def hash
         
     | 
| 
      
 20 
     | 
    
         
            +
                    [subquery, type, constraints].hash
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                  def inner
         
     | 
| 
      
 24 
     | 
    
         
            +
                    self.type = Squeel::InnerJoin
         
     | 
| 
      
 25 
     | 
    
         
            +
                    self
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                  def outer
         
     | 
| 
      
 29 
     | 
    
         
            +
                    self.type = Squeel::OuterJoin
         
     | 
| 
      
 30 
     | 
    
         
            +
                    self
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  # Compare with other objects
         
     | 
| 
      
 34 
     | 
    
         
            +
                  def eql?(other)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    self.class.eql?(other.class) &&
         
     | 
| 
      
 36 
     | 
    
         
            +
                    self.subquery.eql?(other.subquery) &&
         
     | 
| 
      
 37 
     | 
    
         
            +
                    self.type.eql?(other.type) &&
         
     | 
| 
      
 38 
     | 
    
         
            +
                    self.constraints.eql?(other.constraints)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                  alias :== :eql?
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/squeel/version.rb
    CHANGED
    
    
    
        data/lib/squeel/visitors.rb
    CHANGED
    
    
| 
         @@ -0,0 +1,101 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_support/core_ext/module'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'squeel/nodes'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Squeel
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Visitors
         
     | 
| 
      
 6 
     | 
    
         
            +
                # The Enumeration visitor class, used to implement Node#each
         
     | 
| 
      
 7 
     | 
    
         
            +
                class EnumerationVisitor
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  # Create a new EnumerationVisitor.
         
     | 
| 
      
 10 
     | 
    
         
            +
                  #
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # @param [Proc] block The block to execute against each node.
         
     | 
| 
      
 12 
     | 
    
         
            +
                  def initialize(block = Proc.new)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @block = block
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  # Accept an object.
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # @param object The object to visit
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # @return The results of the node visitation, which will be the last
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #   call to the @block
         
     | 
| 
      
 21 
     | 
    
         
            +
                  def accept(object)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    visit(object)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  private
         
     | 
| 
      
 26 
     | 
    
         
            +
                  # A hash that caches the method name to use for a visitor for a given
         
     | 
| 
      
 27 
     | 
    
         
            +
                  # class
         
     | 
| 
      
 28 
     | 
    
         
            +
                  DISPATCH = Hash.new do |hash, klass|
         
     | 
| 
      
 29 
     | 
    
         
            +
                    hash[klass] = "visit_#{(klass.name || '').gsub('::', '_')}"
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  # Visit the object.
         
     | 
| 
      
 33 
     | 
    
         
            +
                  #
         
     | 
| 
      
 34 
     | 
    
         
            +
                  # @param object The object to visit
         
     | 
| 
      
 35 
     | 
    
         
            +
                  def visit(object)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    send(DISPATCH[object.class], object)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    @block.call(object)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  rescue NoMethodError => e
         
     | 
| 
      
 39 
     | 
    
         
            +
                    raise e if respond_to?(DISPATCH[object.class], true)
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                    superklass = object.class.ancestors.find { |klass|
         
     | 
| 
      
 42 
     | 
    
         
            +
                      respond_to?(DISPATCH[klass], true)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    }
         
     | 
| 
      
 44 
     | 
    
         
            +
                    raise(TypeError, "Cannot visit #{object.class}") unless superklass
         
     | 
| 
      
 45 
     | 
    
         
            +
                    DISPATCH[object.class] = DISPATCH[superklass]
         
     | 
| 
      
 46 
     | 
    
         
            +
                    retry
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  def visit_terminal(o)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
                  alias :visit_Object :visit_terminal
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  def visit_Array(o)
         
     | 
| 
      
 54 
     | 
    
         
            +
                    o.map { |v| visit(v) }
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  def visit_Hash(o)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    o.each { |k, v| visit(k); visit(v) }
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                  def visit_Squeel_Nodes_Nary(o)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    visit(o.children)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  def visit_Squeel_Nodes_Binary(o)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    visit(o.left)
         
     | 
| 
      
 67 
     | 
    
         
            +
                    visit(o.right)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  def visit_Squeel_Nodes_Unary(o)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    visit(o.expr)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                  def visit_Squeel_Nodes_Order(o)
         
     | 
| 
      
 75 
     | 
    
         
            +
                    visit(o.expr)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                  def visit_Squeel_Nodes_Function(o)
         
     | 
| 
      
 79 
     | 
    
         
            +
                    visit(o.args)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                  def visit_Squeel_Nodes_Predicate(o)
         
     | 
| 
      
 83 
     | 
    
         
            +
                    visit(o.expr)
         
     | 
| 
      
 84 
     | 
    
         
            +
                    visit(o.value)
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                  def visit_Squeel_Nodes_KeyPath(o)
         
     | 
| 
      
 88 
     | 
    
         
            +
                    visit(o.path)
         
     | 
| 
      
 89 
     | 
    
         
            +
                  end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                  def visit_Squeel_Nodes_Join(o)
         
     | 
| 
      
 92 
     | 
    
         
            +
                    visit(o._join)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                  def visit_Squeel_Nodes_Literal(o)
         
     | 
| 
      
 96 
     | 
    
         
            +
                    visit(o.expr)
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
              end
         
     | 
| 
      
 101 
     | 
    
         
            +
            end
         
     |