lib/kasket/visitor.rb in kasket-4.4.3 vs lib/kasket/visitor.rb in kasket-4.4.4

- old
+ new

@@ -1,5 +1,6 @@ +# frozen_string_literal: true require 'arel' module Kasket class Visitor < Arel::Visitors::Visitor def initialize(model_class, binds) @@ -11,10 +12,12 @@ def accept(node) self.last_column = nil super end + private + def last_column=(col) Thread.current[:arel_visitors_to_sql_last_column] = col end def last_column @@ -27,11 +30,11 @@ def visit_Arel_Nodes_SelectStatement(node, *_) return :unsupported if node.with return :unsupported if node.offset return :unsupported if node.lock - return :unsupported if node.orders.any? + return :unsupported if ordered?(node) return :unsupported if node.cores.size != 1 query = visit_Arel_Nodes_SelectCore(node.cores[0]) return query if query == :unsupported @@ -43,13 +46,13 @@ query end def visit_Arel_Nodes_SelectCore(node, *_) return :unsupported if node.groups.any? - return :unsupported if (ActiveRecord::VERSION::MAJOR < 5 ? node.having : node.havings.present?) + return :unsupported if ActiveRecord::VERSION::MAJOR < 5 ? node.having : node.havings.present? return :unsupported if node.set_quantifier - return :unsupported if (!node.source || node.source.empty?) + return :unsupported if !node.source || node.source.empty? return :unsupported if node.projections.size != 1 select = node.projections[0] select = select.name if select.respond_to?(:name) return :unsupported if select != '*' @@ -60,66 +63,65 @@ parts.include?(:unsupported) ? :unsupported : parts end def visit_Arel_Nodes_Limit(node, *_) - if ActiveRecord::VERSION::MAJOR < 5 - {:limit => node.value.to_i} - else - {:limit => visit(node.value).to_i} - end + if ActiveRecord::VERSION::MAJOR < 5 + { limit: node.value.to_i } + else + { limit: visit(node.value).to_i } + end end def visit_Arel_Nodes_JoinSource(node, *_) return :unsupported if !node.left || node.right.any? - return :unsupported if !node.left.is_a?(Arel::Table) + return :unsupported unless node.left.is_a?(Arel::Table) visit(node.left) end def visit_Arel_Table(node, *_) - {:from => node.name} + { from: node.name } end def visit_Arel_Nodes_And(node, *_) attributes = node.children.map { |child| visit(child) } return :unsupported if attributes.include?(:unsupported) attributes.sort! { |pair1, pair2| pair1[0].to_s <=> pair2[0].to_s } - { :attributes => attributes } + { attributes: attributes } end def visit_Arel_Nodes_In(node, *_) left = visit(node.left) return :unsupported if left != :id [left, visit(node.right)] end def visit_Arel_Nodes_Equality(node, *_) - right = case node.right - when false then 0 # This should probably be removed when Rails 3.2 is not supported anymore - when nil then nil - else - visit(node.right) - end + right = + case node.right + when false then 0 # This should probably be removed when Rails 3.2 is not supported anymore + when nil then nil + else visit(node.right) + end [visit(node.left), right] end def visit_Arel_Attributes_Attribute(node, *_) self.last_column = column_for(node.name) node.name.to_sym end def literal(node, *_) if node == '?' - column, value = @binds.shift - value.to_s + @binds.shift.last.to_s else node.to_s end end - def visit_Arel_Nodes_BindParam(x, *_) + def visit_Arel_Nodes_BindParam(_x, *_) if ActiveRecord::VERSION::MAJOR < 5 visit(@binds.shift[1]) else visit(@binds.shift) end @@ -131,22 +133,27 @@ def visit_Arel_Nodes_Casted(node, *_) quoted(node.val) unless node.val.nil? end - def visit_TrueClass(node) + def visit_TrueClass(_node) 1 end - def visit_FalseClass(node) + def visit_FalseClass(_node) 0 end def quoted(node) @model_class.connection.quote(node) end - alias :visit_String :literal - alias :visit_Fixnum :literal - alias :visit_Arel_Nodes_SqlLiteral :literal + # any non `id asc` ordering + def ordered?(node) + !node.orders.all? { |o| o.is_a?(Arel::Nodes::Ascending) && o.expr.name == "id" } + end + + alias_method :visit_String, :literal + alias_method :visit_Fixnum, :literal + alias_method :visit_Arel_Nodes_SqlLiteral, :literal end end