Module: ActiveRecord::ConnectionAdapters::Jdbc::ArelSupport::ClassMethods

Defined in:
lib/arjdbc/jdbc/arel_support.rb

Instance Method Summary collapse

Instance Method Details

#arel_visitor_name(spec) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
# File 'lib/arjdbc/jdbc/arel_support.rb', line 13

def arel_visitor_name(spec)
  if spec
    if spec.respond_to?(:arel_visitor_name)
      spec.arel_visitor_name # for AREL built-in visitors
    else
      spec.name.split('::').last.downcase # ArJdbc::PostgreSQL -> postgresql
    end
  else # AR::ConnnectionAdapters::MySQLAdapter => mysql
    name.split('::').last.sub('Adapter', '').downcase
  end
end

#bind_substitution(visitor) ⇒ Class

Generates a class for the given visitor type, this new Class instance is a sub-class of Arel::Visitors::BindVisitor.

Returns:

  • (Class)

    class for given visitor type



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/arjdbc/jdbc/arel_support.rb', line 89

def bind_substitution(visitor)
  # NOTE: similar convention as in AR (but no base substitution type) :
  # class BindSubstitution < ::Arel::Visitors::ToSql
  #   include ::Arel::Visitors::BindVisitor
  # end
  return const_get(:BindSubstitution) if const_defined?(:BindSubstitution)

  @@bind_substitutions ||= Java::JavaUtil::HashMap.new
  unless bind_visitor = @@bind_substitutions.get(visitor)
    @@bind_substitutions.synchronized do
      unless @@bind_substitutions.get(visitor)
        bind_visitor = Class.new(visitor) do
          include ::Arel::Visitors::BindVisitor
        end
        @@bind_substitutions.put(visitor, bind_visitor)
      end
    end
    bind_visitor = @@bind_substitutions.get(visitor)
  end
  bind_visitor
end

#resolve_visitor_type(config) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/arjdbc/jdbc/arel_support.rb', line 32

def resolve_visitor_type(config)
  raise "missing :adapter in #{config.inspect}" unless adapter = config[:adapter]

  visitor_type = RESOLVED_VISITORS[ adapter ]

  if visitor_type.nil? || adapter == 'jdbc'
    if adapter_spec = config[:adapter_spec]
      if adapter_spec.respond_to?(:arel_visitor_type)
        visitor_type = adapter_spec.arel_visitor_type(config)
      elsif adapter_spec.respond_to?(:arel2_visitors) # backwards compat
        visitor_type = adapter_spec.arel2_visitors(config).values.first
      else # auto-convention ArJdbc::MySQL -> Arel::Visitors::MySQL
        const_name = adapter_spec.name.split('::').last
        visitor_type = ::Arel::Visitors.const_get(const_name) rescue nil
      end
    elsif respond_to?(:arel_visitor_type)
      visitor_type = arel_visitor_type(config) # adapter_class' override
    end

    if visitor_type && RESOLVED_VISITORS[ adapter ] # adapter == 'jdbc'
      if visitor_type != RESOLVED_VISITORS[ adapter ]
        ArJdbc.warn("overriding visitor for 'adapter: jdbc' (from #{RESOLVED_VISITORS[ adapter ]} to #{visitor_type})")
      end
    end

    visitor_type ||= ::Arel::Visitors::VISITORS[ arel_visitor_name(adapter_spec) ]
    visitor_type ||= ::Arel::Visitors::ToSql # default (if nothing resolved)

    RESOLVED_VISITORS.to_java.synchronized do
      RESOLVED_VISITORS[ adapter ] = ::Arel::Visitors::VISITORS[ adapter ] = visitor_type
    end
  end

  visitor_type
end

#visitor_for(pool) ⇒ Object

Note:

called from ActiveRecord::ConnectionAdapters::ConnectionPool.checkout (up till AR-3.2)



78
79
80
81
# File 'lib/arjdbc/jdbc/arel_support.rb', line 78

def visitor_for(pool)
  visitor = resolve_visitor_type(config = pool.spec.config)
  ( prepared_statements?(config) ? visitor : bind_substitution(visitor) ).new(pool)
end