Class: ActiveRecord::ConnectionAdapters::JdbcAdapter

Inherits:
AbstractAdapter
  • Object
show all
Extended by:
ShadowCoreMethods
Includes:
CompatibilityMethods, JdbcConnectionPoolCallbacks
Defined in:
lib/arjdbc/jdbc/adapter.rb

Direct Known Subclasses

MysqlAdapter, PostgreSQLAdapter, SQLite3Adapter

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ShadowCoreMethods

alias_chained_method

Methods included from JdbcConnectionPoolCallbacks

included, needed?, #on_checkin, #on_checkout

Methods included from CompatibilityMethods

needed?, #quote_table_name

Constructor Details

#initialize(connection, logger, config) ⇒ JdbcAdapter

Returns a new instance of JdbcAdapter.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/arjdbc/jdbc/adapter.rb', line 25

def initialize(connection, logger, config)
  @config = config
  spec = config[:adapter_spec] || adapter_spec(config)
  config[:adapter_spec] ||= spec
  unless connection
    connection_class = jdbc_connection_class spec
    connection = connection_class.new config
  end
  super(connection, logger)
  if spec && (config[:adapter_class].nil? || config[:adapter_class] == JdbcAdapter)
    extend spec
  end
  configure_arel2_visitors(config)
  connection.adapter = self
  JndiConnectionPoolCallbacks.prepare(self, connection)
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



23
24
25
# File 'lib/arjdbc/jdbc/adapter.rb', line 23

def config
  @config
end

Class Method Details

.arel2_visitors(config) ⇒ Object



117
118
119
# File 'lib/arjdbc/jdbc/adapter.rb', line 117

def self.arel2_visitors(config)
  { 'jdbc' => ::Arel::Visitors::ToSql }
end

.visitor_for(pool) ⇒ Object



106
107
108
109
110
111
112
113
114
115
# File 'lib/arjdbc/jdbc/adapter.rb', line 106

def self.visitor_for(pool)
  config = pool.spec.config
  adapter = config[:adapter]
  adapter_spec = config[:adapter_spec] || self
  if adapter =~ /^(jdbc|jndi)$/
    adapter_spec.arel2_visitors(config).values.first.new(pool)
  else
    adapter_spec.arel2_visitors(config)[adapter].new(pool)
  end
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


193
194
195
# File 'lib/arjdbc/jdbc/adapter.rb', line 193

def active?
  @connection.active?
end

#adapter_nameObject

:nodoc:



102
103
104
# File 'lib/arjdbc/jdbc/adapter.rb', line 102

def adapter_name #:nodoc:
  'JDBC'
end

#adapter_spec(config) ⇒ Object

Locate specialized adapter specification if one exists based on config data



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/arjdbc/jdbc/adapter.rb', line 70

def adapter_spec(config)
  dialect = (config[:dialect] || config[:driver]).to_s
  ::ArJdbc.constants.sort.each do |constant|
    constant = ::ArJdbc.const_get(constant) # e.g. ArJdbc::MySQL

    if constant.respond_to?(:adapter_matcher)
      spec = constant.adapter_matcher(dialect, config)
      return spec if spec
    end
  end

  if config[:jndi] && ! config[:dialect]
    begin
      data_source = Java::JavaxNaming::InitialContext.new.lookup(config[:jndi])
      connection = data_source.getConnection
      config[:dialect] = connection..getDatabaseProductName
    rescue Java::JavaSql::SQLException => e
      warn "failed to set database :dialect from connection meda-data (#{e})"
    else
      return adapter_spec(config) # re-try matching a spec with set config[:dialect]
    ensure
      connection.close if connection  # return to the pool
    end
  end

  nil
end

#begin_db_transactionObject



340
341
342
# File 'lib/arjdbc/jdbc/adapter.rb', line 340

def begin_db_transaction
  @connection.begin
end

#commit_db_transactionObject



344
345
346
# File 'lib/arjdbc/jdbc/adapter.rb', line 344

def commit_db_transaction
  @connection.commit
end

#configure_arel2_visitors(config) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/arjdbc/jdbc/adapter.rb', line 121

def configure_arel2_visitors(config)
  if defined?(::Arel::Visitors::VISITORS)
    visitors = ::Arel::Visitors::VISITORS
    visitor = nil
    adapter_spec = [config[:adapter_spec], self.class].detect {|a| a && a.respond_to?(:arel2_visitors) }
    adapter_spec.arel2_visitors(config).each do |k,v|
      visitor = v
      visitors[k] = v
    end
    if visitor && config[:adapter] =~ /^(jdbc|jndi)$/
      visitors[config[:adapter]] = visitor
    end
    @visitor = visitors[config[:adapter]].new(self)
  end
end

#database_nameObject

:nodoc:



154
155
156
# File 'lib/arjdbc/jdbc/adapter.rb', line 154

def database_name #:nodoc:
  @connection.database_name
end

#disconnect!Object



202
203
204
# File 'lib/arjdbc/jdbc/adapter.rb', line 202

def disconnect!
  @connection.disconnect!
end

#exec_delete(sql, name, binds) ⇒ Object

Executes delete sql statement in the context of this connection using binds as the bind substitutes. name is the logged along with the executed sql statement.



254
255
256
# File 'lib/arjdbc/jdbc/adapter.rb', line 254

def exec_delete(sql, name, binds)
  exec_query(sql, name, binds)
end

#exec_insert(sql, name, binds) ⇒ Object

Executes insert sql statement in the context of this connection using binds as the bind substitutes. name is the logged along with the executed sql statement.



247
248
249
# File 'lib/arjdbc/jdbc/adapter.rb', line 247

def exec_insert(sql, name, binds)
  exec_query(sql, name, binds)
end

#exec_query(sql, name = 'SQL', binds = []) ⇒ Object

Executes sql statement in the context of this connection using binds as the bind substitutes. name is logged along with the executed sql statement.



240
241
242
# File 'lib/arjdbc/jdbc/adapter.rb', line 240

def exec_query(sql, name = 'SQL', binds = [])
  execute(sql, name, binds)
end

#exec_update(sql, name, binds) ⇒ Object

Executes update sql statement in the context of this connection using binds as the bind substitutes. name is the logged along with the executed sql statement.



261
262
263
# File 'lib/arjdbc/jdbc/adapter.rb', line 261

def exec_update(sql, name, binds)
  exec_query(sql, name, binds)
end

#execute(sql, name = nil, binds = []) ⇒ Object

Executes the SQL statement in the context of this connection.



270
271
272
273
274
275
276
277
# File 'lib/arjdbc/jdbc/adapter.rb', line 270

def execute(sql, name = nil, binds = [])
  sql = to_sql(sql, binds)
  if name == :skip_logging
    _execute(sql, name)
  else
    log(sql, name) { _execute(sql, name ||= "SQL") }
  end
end

#indexes(table_name, name = nil, schema_name = nil) ⇒ Object



336
337
338
# File 'lib/arjdbc/jdbc/adapter.rb', line 336

def indexes(table_name, name = nil, schema_name = nil)
  @connection.indexes(table_name, name, schema_name)
end

#insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) ⇒ Object

NOTE: we have an extra binds argument at the end due 2.3 support (due #jdbc_insert).



323
324
325
326
# File 'lib/arjdbc/jdbc/adapter.rb', line 323

def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) # :nodoc:
  id = execute(sql, name = nil, binds)
  id_value || id
end

#is_a?(klass) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


137
138
139
140
141
142
143
144
# File 'lib/arjdbc/jdbc/adapter.rb', line 137

def is_a?(klass) # :nodoc:
  # This is to fake out current_adapter? conditional logic in AR tests
  if Class === klass && klass.name =~ /#{adapter_name}Adapter$/i
    true
  else
    super
  end
end

#jdbc_column_classObject



48
49
50
# File 'lib/arjdbc/jdbc/adapter.rb', line 48

def jdbc_column_class
  ActiveRecord::ConnectionAdapters::JdbcColumn
end

#jdbc_columns(table_name, name = nil) ⇒ Object



232
233
234
# File 'lib/arjdbc/jdbc/adapter.rb', line 232

def jdbc_columns(table_name, name = nil)
  @connection.columns(table_name.to_s)
end

#jdbc_connection(unwrap = nil) ⇒ Object

Retrieve the raw java.sql.Connection object. The unwrap parameter is useful if an attempt to unwrap a pooled (JNDI) connection should be made - to really return the native (SQL) object.



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/arjdbc/jdbc/adapter.rb', line 55

def jdbc_connection(unwrap = nil)
  java_connection = raw_connection.connection
  return java_connection unless unwrap
  connection_class = java.sql.Connection.java_class
  if java_connection.wrapper_for?(connection_class)
    java_connection.unwrap(connection_class) # java.sql.Wrapper.unwrap
  elsif java_connection.respond_to?(:connection)
    # e.g. org.apache.tomcat.jdbc.pool.PooledConnection
    java_connection.connection # getConnection
  else
    java_connection
  end
end

#jdbc_connection_class(spec) ⇒ Object



42
43
44
45
46
# File 'lib/arjdbc/jdbc/adapter.rb', line 42

def jdbc_connection_class(spec)
  connection_class = spec.jdbc_connection_class if spec && spec.respond_to?(:jdbc_connection_class)
  connection_class = ::ActiveRecord::ConnectionAdapters::JdbcConnection unless connection_class
  connection_class
end

#jdbc_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) ⇒ Object

:nodoc:



208
209
210
# File 'lib/arjdbc/jdbc/adapter.rb', line 208

def jdbc_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])  # :nodoc:
  insert_sql(sql, name, pk, id_value, sequence_name, binds)
end

#jdbc_select_all(sql, name = nil, binds = []) ⇒ Object

:nodoc:



216
217
218
# File 'lib/arjdbc/jdbc/adapter.rb', line 216

def jdbc_select_all(sql, name = nil, binds = []) # :nodoc:
  select(sql, name, binds)
end

#jdbc_update(sql, name = nil, binds = []) ⇒ Object

:nodoc:



212
213
214
# File 'lib/arjdbc/jdbc/adapter.rb', line 212

def jdbc_update(sql, name = nil, binds = []) # :nodoc:
  execute(sql, name, binds)
end

#modify_types(types) ⇒ Object



98
99
100
# File 'lib/arjdbc/jdbc/adapter.rb', line 98

def modify_types(types)
  types
end

#native_database_typesObject

:nodoc:



150
151
152
# File 'lib/arjdbc/jdbc/adapter.rb', line 150

def native_database_types #:nodoc:
  @connection.native_database_types
end

#native_sql_to_type(type) ⇒ Object



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/arjdbc/jdbc/adapter.rb', line 158

def native_sql_to_type(type)
  if /^(.*?)\(([0-9]+)\)/ =~ type
    tname, limit = $1, $2.to_i
    ntypes = native_database_types
    if ntypes[:primary_key] == type
      return :primary_key, nil
    else
      ntypes.each do |name, val|
        if name == :primary_key
          next
        end
        if val[:name].downcase == tname.downcase && 
            ( val[:limit].nil? || val[:limit].to_i == limit )
          return name, limit
        end
      end
    end
  elsif /^(.*?)/ =~ type
    tname = $1
    ntypes = native_database_types
    if ntypes[:primary_key] == type
      return :primary_key, nil
    else
      ntypes.each do |name, val|
        if val[:name].downcase == tname.downcase && val[:limit].nil?
          return name, nil
        end
      end
    end
  else
    return :string, 255
  end
  return nil, nil
end

#pk_and_sequence_for(table) ⇒ Object



356
357
358
359
# File 'lib/arjdbc/jdbc/adapter.rb', line 356

def pk_and_sequence_for(table)
  key = primary_key(table)
  [key, nil] if key
end

#primary_key(table) ⇒ Object



361
362
363
# File 'lib/arjdbc/jdbc/adapter.rb', line 361

def primary_key(table)
  primary_keys(table).first
end

#primary_keys(table) ⇒ Object



365
366
367
# File 'lib/arjdbc/jdbc/adapter.rb', line 365

def primary_keys(table)
  @connection.primary_keys(table)
end

#reconnect!Object



197
198
199
200
# File 'lib/arjdbc/jdbc/adapter.rb', line 197

def reconnect!
  @connection.reconnect!
  @connection
end

#rollback_db_transactionObject



348
349
350
# File 'lib/arjdbc/jdbc/adapter.rb', line 348

def rollback_db_transaction
  @connection.rollback
end

#select(*args) ⇒ Object

Note:

on AR-3.2 expects “only” 2 arguments ‘select(sql, name = nil)` we accept 3 arguments as well `select(sql, name = nil, binds = [])`

Returns an array of record hashes with the column names as keys and column values as values.



312
313
314
# File 'lib/arjdbc/jdbc/adapter.rb', line 312

def select(*args)
  execute(*args)
end

#select_one(sql, name = nil) ⇒ Object

Do we need this? Not in AR 3.



226
227
228
# File 'lib/arjdbc/jdbc/adapter.rb', line 226

def select_one(sql, name = nil)
  select(sql, name).first
end

#select_rows(sql, name = nil) ⇒ Object



316
317
318
319
320
# File 'lib/arjdbc/jdbc/adapter.rb', line 316

def select_rows(sql, name = nil)
  rows = []
  select(sql, name).each {|row| rows << row.values }
  rows
end

#supports_migrations?Boolean

Returns:

  • (Boolean)


146
147
148
# File 'lib/arjdbc/jdbc/adapter.rb', line 146

def supports_migrations?
  true
end

#table_exists?(name) ⇒ Boolean

Returns:

  • (Boolean)


332
333
334
# File 'lib/arjdbc/jdbc/adapter.rb', line 332

def table_exists?(name)
  jdbc_columns(name) rescue nil
end

#tables(name = nil) ⇒ Object



328
329
330
# File 'lib/arjdbc/jdbc/adapter.rb', line 328

def tables(name = nil)
  @connection.tables
end

#to_sql(sql, binds = []) ⇒ Object

Substitutes SQL bind (?) parameters



372
373
374
375
376
377
378
379
380
381
382
# File 'lib/arjdbc/jdbc/adapter.rb', line 372

def to_sql(arel, binds = [])
  if arel.respond_to?(:ast)
    visitor.accept(arel.ast) do
      quote(*binds.shift.reverse)
    end
  else # for backwards compatibility :
    sql = arel.respond_to?(:to_sql) ? arel.send(:to_sql) : arel
    return sql if binds.blank?
    sql.gsub('?') { quote(*binds.shift.reverse) }
  end
end

#write_large_object(*args) ⇒ Object



352
353
354
# File 'lib/arjdbc/jdbc/adapter.rb', line 352

def write_large_object(*args)
  @connection.write_large_object(*args)
end