activerecord-jdbc-adapter 1.1.3 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +22 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +42 -0
- data/History.txt +10 -3
- data/{README.txt → README.rdoc} +30 -14
- data/Rakefile +49 -0
- data/activerecord-jdbc-adapter.gemspec +23 -0
- data/bench/bench_attributes.rb +13 -0
- data/bench/bench_attributes_new.rb +14 -0
- data/bench/bench_create.rb +12 -0
- data/bench/bench_find_all.rb +12 -0
- data/bench/bench_find_all_mt.rb +25 -0
- data/bench/bench_model.rb +85 -0
- data/bench/bench_new.rb +12 -0
- data/bench/bench_new_valid.rb +12 -0
- data/bench/bench_valid.rb +13 -0
- data/lib/activerecord-jdbc-adapter.rb +1 -1
- data/lib/arel/visitors/derby.rb +5 -1
- data/lib/arjdbc.rb +12 -17
- data/lib/arjdbc/db2/adapter.rb +91 -4
- data/lib/arjdbc/derby/adapter.rb +8 -8
- data/lib/arjdbc/derby/connection_methods.rb +1 -0
- data/lib/arjdbc/firebird/adapter.rb +4 -4
- data/lib/arjdbc/h2/adapter.rb +3 -2
- data/lib/arjdbc/h2/connection_methods.rb +1 -0
- data/lib/arjdbc/hsqldb/adapter.rb +5 -2
- data/lib/arjdbc/hsqldb/connection_methods.rb +1 -0
- data/lib/arjdbc/informix/adapter.rb +2 -2
- data/lib/arjdbc/informix/connection_methods.rb +1 -0
- data/lib/arjdbc/jdbc/adapter.rb +92 -22
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/mimer/adapter.rb +4 -4
- data/lib/arjdbc/mssql/adapter.rb +10 -8
- data/lib/arjdbc/mssql/connection_methods.rb +1 -0
- data/lib/arjdbc/mssql/limit_helpers.rb +7 -4
- data/lib/arjdbc/mysql/adapter.rb +30 -6
- data/lib/arjdbc/mysql/connection_methods.rb +1 -0
- data/lib/arjdbc/oracle/adapter.rb +15 -12
- data/lib/arjdbc/oracle/connection_methods.rb +1 -0
- data/lib/arjdbc/postgresql/adapter.rb +35 -16
- data/lib/arjdbc/postgresql/connection_methods.rb +1 -0
- data/lib/arjdbc/sqlite3/adapter.rb +13 -10
- data/lib/arjdbc/sqlite3/connection_methods.rb +1 -0
- data/lib/arjdbc/version.rb +1 -1
- data/lib/generators/jdbc/USAGE +10 -0
- data/pom.xml +57 -0
- data/rakelib/rails.rake +1 -1
- data/rakelib/test.rake +20 -6
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +4 -1
- data/src/java/arjdbc/jdbc/SQLBlock.java +1 -1
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +74 -0
- data/test/abstract_db_create.rb +8 -1
- data/test/activerecord/jall.sh +7 -0
- data/test/activerecord/jtest.sh +3 -0
- data/test/jdbc_common.rb +6 -4
- data/test/models/data_types.rb +1 -1
- data/test/models/string_id.rb +2 -0
- data/test/models/thing.rb +16 -0
- data/test/mysql_index_length_test.rb +58 -0
- data/test/mysql_info_test.rb +3 -3
- data/test/postgres_db_create_test.rb +1 -1
- data/test/simple.rb +11 -3
- data/test/sqlite3_simple_test.rb +16 -2
- metadata +167 -108
- data/.gemtest +0 -0
- data/Manifest.txt +0 -187
- data/rakelib/package.rake +0 -92
- data/test/pick_rails_version.rb +0 -3
data/bench/bench_new.rb
ADDED
data/lib/arel/visitors/derby.rb
CHANGED
@@ -7,12 +7,16 @@ module Arel
|
|
7
7
|
[
|
8
8
|
o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join,
|
9
9
|
("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
|
10
|
-
(
|
10
|
+
(visit_Arel_Nodes_Limit(o.limit) if o.limit),
|
11
11
|
(visit(o.offset) if o.offset),
|
12
12
|
(visit(o.lock) if o.lock),
|
13
13
|
].compact.join ' '
|
14
14
|
end
|
15
15
|
|
16
|
+
def visit_Arel_Nodes_Limit o
|
17
|
+
"FETCH FIRST #{limit_for(o)} ROWS ONLY"
|
18
|
+
end
|
19
|
+
|
16
20
|
def visit_Arel_Nodes_Offset o
|
17
21
|
"OFFSET #{visit o.value} ROWS"
|
18
22
|
end
|
data/lib/arjdbc.rb
CHANGED
@@ -1,26 +1,21 @@
|
|
1
1
|
if defined?(JRUBY_VERSION)
|
2
2
|
begin
|
3
|
-
tried_gem ||= false
|
4
3
|
require 'active_record/version'
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
RAILS_CONNECTION_ADAPTERS << %q(jdbc)
|
4
|
+
if ActiveRecord::VERSION::MAJOR < 2
|
5
|
+
if defined?(RAILS_CONNECTION_ADAPTERS)
|
6
|
+
RAILS_CONNECTION_ADAPTERS << %q(jdbc)
|
7
|
+
else
|
8
|
+
RAILS_CONNECTION_ADAPTERS = %w(jdbc)
|
9
|
+
end
|
10
|
+
if ActiveRecord::VERSION::MAJOR == 1 && ActiveRecord::VERSION::MINOR == 14
|
11
|
+
require 'arjdbc/jdbc'
|
12
|
+
end
|
15
13
|
else
|
16
|
-
|
17
|
-
end
|
18
|
-
if ActiveRecord::VERSION::MAJOR == 1 && ActiveRecord::VERSION::MINOR == 14
|
14
|
+
require 'active_record'
|
19
15
|
require 'arjdbc/jdbc'
|
20
16
|
end
|
21
|
-
|
22
|
-
|
23
|
-
require 'arjdbc/jdbc'
|
17
|
+
rescue LoadError
|
18
|
+
warn "activerecord-jdbc-adapter requires ActiveRecord at runtime"
|
24
19
|
end
|
25
20
|
else
|
26
21
|
warn "activerecord-jdbc-adapter is for use with JRuby only"
|
data/lib/arjdbc/db2/adapter.rb
CHANGED
@@ -1,7 +1,29 @@
|
|
1
1
|
module ArJdbc
|
2
2
|
module DB2
|
3
|
+
def self.extended(base)
|
4
|
+
if base.zos?
|
5
|
+
unless @lob_callback_added
|
6
|
+
ActiveRecord::Base.class_eval do
|
7
|
+
def after_save_with_db2zos_blob
|
8
|
+
lobfields = self.class.columns.select { |c| c.sql_type =~ /blob|clob/i }
|
9
|
+
lobfields.each do |c|
|
10
|
+
value = self[c.name]
|
11
|
+
value = value.to_yaml if unserializable_attribute?(c.name, c)
|
12
|
+
next if value.nil?
|
13
|
+
connection.write_large_object(c.type == :binary, c.name, self.class.table_name, self.class.primary_key, quote_value(id), value)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
ActiveRecord::Base.after_save :after_save_with_db2zos_blob
|
19
|
+
|
20
|
+
@lob_callback_added = true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
3
25
|
def self.column_selector
|
4
|
-
[ /(db2|as400)/i,
|
26
|
+
[ /(db2|as400|zos)/i,
|
5
27
|
lambda { |cfg, column| column.extend(::ArJdbc::DB2::Column) } ]
|
6
28
|
end
|
7
29
|
|
@@ -147,15 +169,53 @@ module ArJdbc
|
|
147
169
|
'DB2'
|
148
170
|
end
|
149
171
|
|
150
|
-
def arel2_visitors
|
172
|
+
def self.arel2_visitors(config)
|
151
173
|
require 'arel/visitors/db2'
|
152
|
-
{
|
174
|
+
{}.tap {|v| %w(db2 as400).each {|a| v[a] = ::Arel::Visitors::DB2 } }
|
153
175
|
end
|
154
176
|
|
155
177
|
def add_limit_offset!(sql, options)
|
156
178
|
replace_limit_offset!(sql, options[:limit], options[:offset])
|
157
179
|
end
|
158
180
|
|
181
|
+
|
182
|
+
def create_table(name, options = {}) #:nodoc:
|
183
|
+
if zos?
|
184
|
+
table_definition = ActiveRecord::ConnectionAdapters::TableDefinition.new(self)
|
185
|
+
|
186
|
+
table_definition.primary_key(options[:primary_key] || ActiveRecord::Base.get_primary_key(name)) unless options[:id] == false
|
187
|
+
|
188
|
+
yield table_definition
|
189
|
+
|
190
|
+
# Clobs in DB2 Host have to be created after the Table with an auxiliary Table.
|
191
|
+
# First: Save them for later in Array "clobs"
|
192
|
+
clobs =table_definition.columns.select { |x| x.type == "text" }
|
193
|
+
|
194
|
+
# Second: and delete them from the original Colums-Array
|
195
|
+
table_definition.columns.delete_if { |x| x.type=="text" }
|
196
|
+
|
197
|
+
if options[:force] && table_exists?(name)
|
198
|
+
super.drop_table(name, options)
|
199
|
+
end
|
200
|
+
|
201
|
+
create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE "
|
202
|
+
create_sql << "#{quote_table_name(name)} ("
|
203
|
+
create_sql << table_definition.to_sql
|
204
|
+
create_sql << ") #{options[:options]}"
|
205
|
+
create_sql << " IN #{@config[:database]}.#{@config[:tablespace]}"
|
206
|
+
|
207
|
+
execute create_sql
|
208
|
+
|
209
|
+
clobs.each do |clob_column|
|
210
|
+
execute "ALTER TABLE #{name+" ADD COLUMN "+clob_column.name.to_s+" clob"}"
|
211
|
+
execute "CREATE AUXILIARY TABLE #{name+"_"+clob_column.name.to_s+"_CD_"} IN #{@config[:database]}.#{@config[:lob_tablespaces][name.split(".")[1]]} STORES #{name} COLUMN "+clob_column.name.to_s
|
212
|
+
execute "CREATE UNIQUE INDEX #{name+"_"+clob_column.name.to_s+"_CD_"} ON #{name+"_"+clob_column.name.to_s+"_CD_"};"
|
213
|
+
end
|
214
|
+
else
|
215
|
+
super(name, options)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
159
219
|
def replace_limit_offset!(sql, limit, offset)
|
160
220
|
if limit
|
161
221
|
limit = limit.to_i
|
@@ -200,7 +260,11 @@ module ArJdbc
|
|
200
260
|
if column && column.type == :binary
|
201
261
|
"BLOB('#{quote_string(value)}')"
|
202
262
|
else
|
203
|
-
|
263
|
+
if zos? && column.type == :text
|
264
|
+
"'if_you_see_this_value_the_after_save_hook_in_db2_zos_adapter_went_wrong'"
|
265
|
+
else
|
266
|
+
"'#{quote_string(value)}'"
|
267
|
+
end
|
204
268
|
end
|
205
269
|
else super
|
206
270
|
end
|
@@ -228,6 +292,21 @@ module ArJdbc
|
|
228
292
|
tables.each {|table| drop_table("#{db2_schema}.#{table}")}
|
229
293
|
end
|
230
294
|
|
295
|
+
def add_index(table_name, column_name, options = {})
|
296
|
+
if (!zos? || (table_name.to_s == ActiveRecord::Migrator.schema_migrations_table_name.to_s))
|
297
|
+
super
|
298
|
+
else
|
299
|
+
statement ="CREATE"
|
300
|
+
statement << " UNIQUE " if options[:unique]
|
301
|
+
statement << " INDEX "+"#{ActiveRecord::Base.table_name_prefix}#{options[:name]} "
|
302
|
+
|
303
|
+
statement << " ON #{table_name}(#{column_name})"
|
304
|
+
|
305
|
+
execute statement
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
|
231
310
|
def remove_index(table_name, options = { })
|
232
311
|
execute "DROP INDEX #{quote_column_name(index_name(table_name, options))}"
|
233
312
|
end
|
@@ -311,6 +390,10 @@ module ArJdbc
|
|
311
390
|
def columns(table_name, name = nil)
|
312
391
|
cols = @connection.columns(table_name, name, db2_schema)
|
313
392
|
|
393
|
+
if zos?
|
394
|
+
# Remove the mighty db2_generated_rowid_for_lobs from the list of columns
|
395
|
+
cols = cols.reject { |col| "db2_generated_rowid_for_lobs" == col.name }
|
396
|
+
end
|
314
397
|
# scrub out sizing info when CREATE TABLE doesn't support it
|
315
398
|
# but JDBC reports it (doh!)
|
316
399
|
for col in cols
|
@@ -398,6 +481,10 @@ module ArJdbc
|
|
398
481
|
definition
|
399
482
|
end
|
400
483
|
|
484
|
+
def zos?
|
485
|
+
@config[:driver] == "com.ibm.db2.jcc.DB2Driver"
|
486
|
+
end
|
487
|
+
|
401
488
|
private
|
402
489
|
def as400?
|
403
490
|
@config[:url] =~ /^jdbc:as400:/
|
data/lib/arjdbc/derby/adapter.rb
CHANGED
@@ -7,7 +7,7 @@ module ::ArJdbc
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def self.monkey_rails
|
10
|
-
unless @already_monkeyd
|
10
|
+
unless defined?(@already_monkeyd)
|
11
11
|
# Needed because Rails is broken wrt to quoting of
|
12
12
|
# some values. Most databases are nice about it,
|
13
13
|
# but not Derby. The real issue is that you can't
|
@@ -50,7 +50,7 @@ module ::ArJdbc
|
|
50
50
|
def default_value(value)
|
51
51
|
# jdbc returns column default strings with actual single quotes around the value.
|
52
52
|
return $1 if value =~ /^'(.*)'$/
|
53
|
-
|
53
|
+
return nil if value == "GENERATED_BY_DEFAULT"
|
54
54
|
value
|
55
55
|
end
|
56
56
|
end
|
@@ -59,9 +59,9 @@ module ::ArJdbc
|
|
59
59
|
'Derby'
|
60
60
|
end
|
61
61
|
|
62
|
-
def arel2_visitors
|
62
|
+
def self.arel2_visitors(config)
|
63
63
|
require 'arel/visitors/derby'
|
64
|
-
{
|
64
|
+
{}.tap {|v| %w(derby jdbcderby).each {|a| v[a] = ::Arel::Visitors::Derby } }
|
65
65
|
end
|
66
66
|
|
67
67
|
include ArJdbc::MissingFunctionalityHelper
|
@@ -171,7 +171,8 @@ module ::ArJdbc
|
|
171
171
|
execute(add_column_sql)
|
172
172
|
end
|
173
173
|
|
174
|
-
def execute(sql, name = nil)
|
174
|
+
def execute(sql, name = nil, binds = [])
|
175
|
+
sql = extract_sql(sql)
|
175
176
|
if sql =~ /\A\s*(UPDATE|INSERT)/i
|
176
177
|
i = sql =~ /\swhere\s/im
|
177
178
|
if i
|
@@ -196,8 +197,7 @@ module ::ArJdbc
|
|
196
197
|
|
197
198
|
# construct a clean list of column names from the ORDER BY clause, removing
|
198
199
|
# any asc/desc modifiers
|
199
|
-
order_columns = order_by.split(',').collect { |s| s.split.first }
|
200
|
-
order_columns.delete_if(&:blank?)
|
200
|
+
order_columns = [order_by].flatten.map{|o| o.split(',').collect { |s| s.split.first } }.flatten.reject(&:blank?)
|
201
201
|
order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" }
|
202
202
|
|
203
203
|
# return a DISTINCT clause that's distinct on the columns we want but includes
|
@@ -316,7 +316,7 @@ module ::ArJdbc
|
|
316
316
|
end
|
317
317
|
|
318
318
|
def quote_column_name(name) #:nodoc:
|
319
|
-
%Q{"#{name.to_s.upcase.gsub(
|
319
|
+
%Q{"#{name.to_s.upcase.gsub(/\"/, '""')}"}
|
320
320
|
end
|
321
321
|
|
322
322
|
def quoted_true
|
@@ -4,6 +4,7 @@ module ActiveRecord
|
|
4
4
|
def derby_connection(config)
|
5
5
|
config[:url] ||= "jdbc:derby:#{config[:database]};create=true"
|
6
6
|
config[:driver] ||= "org.apache.derby.jdbc.EmbeddedDriver"
|
7
|
+
config[:adapter_spec] = ::ArJdbc::Derby
|
7
8
|
conn = embedded_driver(config)
|
8
9
|
md = conn.jdbc_connection.meta_data
|
9
10
|
if md.database_major_version < 10 || (md.database_major_version == 10 && md.database_minor_version < 5)
|
@@ -23,9 +23,9 @@ module ::ArJdbc
|
|
23
23
|
'Firebird'
|
24
24
|
end
|
25
25
|
|
26
|
-
def arel2_visitors
|
26
|
+
def self.arel2_visitors(config)
|
27
27
|
require 'arel/visitors/firebird'
|
28
|
-
{
|
28
|
+
{}.tap {|v| %w(firebird firebirdsql).each {|a| v[a] = ::Arel::Visitors::Firebird } }
|
29
29
|
end
|
30
30
|
|
31
31
|
def modify_types(tp)
|
@@ -35,8 +35,8 @@ module ::ArJdbc
|
|
35
35
|
tp
|
36
36
|
end
|
37
37
|
|
38
|
-
def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) # :nodoc:
|
39
|
-
execute(sql, name)
|
38
|
+
def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) # :nodoc:
|
39
|
+
execute(sql, name, binds)
|
40
40
|
id_value
|
41
41
|
end
|
42
42
|
|
data/lib/arjdbc/h2/adapter.rb
CHANGED
@@ -12,8 +12,9 @@ module ArJdbc
|
|
12
12
|
'H2'
|
13
13
|
end
|
14
14
|
|
15
|
-
def arel2_visitors
|
16
|
-
|
15
|
+
def self.arel2_visitors(config)
|
16
|
+
v = HSQLDB.arel2_visitors(config)
|
17
|
+
v.merge({}.tap {|v| %w(h2 jdbch2).each {|a| v[a] = ::Arel::Visitors::HSQLDB } })
|
17
18
|
end
|
18
19
|
|
19
20
|
def h2_adapter
|
@@ -27,6 +27,9 @@ module ::ArJdbc
|
|
27
27
|
|
28
28
|
# Post process default value from JDBC into a Rails-friendly format (columns{-internal})
|
29
29
|
def default_value(value)
|
30
|
+
# H2 auto-generated key default value
|
31
|
+
return nil if value =~ /^\(NEXT VALUE FOR/i
|
32
|
+
|
30
33
|
# jdbc returns column default strings with actual single quotes around the value.
|
31
34
|
return $1 if value =~ /^'(.*)'$/
|
32
35
|
|
@@ -38,9 +41,9 @@ module ::ArJdbc
|
|
38
41
|
'Hsqldb'
|
39
42
|
end
|
40
43
|
|
41
|
-
def arel2_visitors
|
44
|
+
def self.arel2_visitors(config)
|
42
45
|
require 'arel/visitors/hsqldb'
|
43
|
-
{
|
46
|
+
{}.tap {|v| %w(hsqldb jdbchsqldb).each {|a| v[a] = ::Arel::Visitors::HSQLDB } }
|
44
47
|
end
|
45
48
|
|
46
49
|
def modify_types(tp)
|
@@ -130,9 +130,9 @@ module ::ArJdbc
|
|
130
130
|
end
|
131
131
|
|
132
132
|
private
|
133
|
-
def select(sql,
|
133
|
+
def select(sql, *rest)
|
134
134
|
# Informix does not like "= NULL", "!= NULL", or "<> NULL".
|
135
|
-
execute(sql.gsub(/(!=|<>)\s*null/i, "IS NOT NULL").gsub(/=\s*null/i, "IS NULL"),
|
135
|
+
execute(sql.gsub(/(!=|<>)\s*null/i, "IS NOT NULL").gsub(/=\s*null/i, "IS NULL"), *rest)
|
136
136
|
end
|
137
137
|
end # module Informix
|
138
138
|
end # module ::ArJdbc
|
@@ -4,6 +4,7 @@ class ActiveRecord::Base
|
|
4
4
|
config[:port] ||= 9088
|
5
5
|
config[:url] ||= "jdbc:informix-sqli://#{config[:host]}:#{config[:port]}/#{config[:database]}:INFORMIXSERVER=#{config[:servername]}"
|
6
6
|
config[:driver] = 'com.informix.jdbc.IfxDriver'
|
7
|
+
config[:adapter_spec] = ::ArJdbc::Informix
|
7
8
|
jdbc_connection(config)
|
8
9
|
end
|
9
10
|
end
|
data/lib/arjdbc/jdbc/adapter.rb
CHANGED
@@ -25,13 +25,16 @@ module ActiveRecord
|
|
25
25
|
|
26
26
|
def initialize(connection, logger, config)
|
27
27
|
@config = config
|
28
|
-
spec = adapter_spec config
|
28
|
+
spec = config[:adapter_spec] || adapter_spec(config)
|
29
|
+
config[:adapter_spec] ||= spec
|
29
30
|
unless connection
|
30
31
|
connection_class = jdbc_connection_class spec
|
31
32
|
connection = connection_class.new config
|
32
33
|
end
|
33
34
|
super(connection, logger)
|
34
|
-
|
35
|
+
if spec && (config[:adapter_class].nil? || config[:adapter_class] == JdbcAdapter)
|
36
|
+
extend spec
|
37
|
+
end
|
35
38
|
configure_arel2_visitors(config)
|
36
39
|
connection.adapter = self
|
37
40
|
JndiConnectionPoolCallbacks.prepare(self, connection)
|
@@ -89,15 +92,27 @@ module ActiveRecord
|
|
89
92
|
'JDBC'
|
90
93
|
end
|
91
94
|
|
92
|
-
def
|
93
|
-
|
95
|
+
def self.visitor_for(pool)
|
96
|
+
config = pool.spec.config
|
97
|
+
adapter = config[:adapter]
|
98
|
+
adapter_spec = config[:adapter_spec] || self
|
99
|
+
if adapter =~ /^(jdbc|jndi)$/
|
100
|
+
adapter_spec.arel2_visitors(config).values.first.new(pool)
|
101
|
+
else
|
102
|
+
adapter_spec.arel2_visitors(config)[adapter].new(pool)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.arel2_visitors(config)
|
107
|
+
{ 'jdbc' => ::Arel::Visitors::ToSql }
|
94
108
|
end
|
95
109
|
|
96
110
|
def configure_arel2_visitors(config)
|
97
111
|
if defined?(::Arel::Visitors::VISITORS)
|
98
112
|
visitors = ::Arel::Visitors::VISITORS
|
99
113
|
visitor = nil
|
100
|
-
|
114
|
+
adapter_spec = config[:adapter_spec] || self
|
115
|
+
adapter_spec.arel2_visitors(config).each do |k,v|
|
101
116
|
visitor = v
|
102
117
|
visitors[k] = v
|
103
118
|
end
|
@@ -176,7 +191,17 @@ module ActiveRecord
|
|
176
191
|
@connection.disconnect!
|
177
192
|
end
|
178
193
|
|
179
|
-
def
|
194
|
+
def substitute_binds(manager, binds = [])
|
195
|
+
sql = extract_sql(manager)
|
196
|
+
if binds.empty?
|
197
|
+
sql
|
198
|
+
else
|
199
|
+
sql.gsub('?') { quote(*binds.shift.reverse) }
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def execute(sql, name = nil, binds = [])
|
204
|
+
sql = substitute_binds(sql, binds)
|
180
205
|
if name == :skip_logging
|
181
206
|
_execute(sql)
|
182
207
|
else
|
@@ -191,25 +216,31 @@ module ActiveRecord
|
|
191
216
|
@connection.execute(sql)
|
192
217
|
end
|
193
218
|
|
194
|
-
def jdbc_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
|
195
|
-
insert_sql(sql, name, pk, id_value, sequence_name)
|
219
|
+
def jdbc_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
|
220
|
+
insert_sql(sql, name, pk, id_value, sequence_name, binds)
|
196
221
|
end
|
197
222
|
|
198
|
-
def jdbc_update(sql, name = nil) #:nodoc:
|
199
|
-
execute(sql, name)
|
223
|
+
def jdbc_update(sql, name = nil, binds = []) #:nodoc:
|
224
|
+
execute(sql, name, binds)
|
200
225
|
end
|
201
|
-
def jdbc_select_all(sql, name = nil)
|
202
|
-
select(sql, name)
|
226
|
+
def jdbc_select_all(sql, name = nil, binds = [])
|
227
|
+
select(sql, name, binds)
|
203
228
|
end
|
204
229
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
230
|
+
if ActiveRecord::VERSION::MAJOR < 3
|
231
|
+
# Allow query caching to work even when we override alias_method_chain'd methods
|
232
|
+
alias_chained_method :select_all, :query_cache, :jdbc_select_all
|
233
|
+
alias_chained_method :update, :query_dirty, :jdbc_update
|
234
|
+
alias_chained_method :insert, :query_dirty, :jdbc_insert
|
235
|
+
|
236
|
+
# Do we need this? Not in AR 3.
|
237
|
+
def select_one(sql, name = nil)
|
238
|
+
select(sql, name).first
|
239
|
+
end
|
240
|
+
end
|
209
241
|
|
210
|
-
|
211
|
-
|
212
|
-
select(sql, name).first
|
242
|
+
def last_inserted_id(result)
|
243
|
+
result
|
213
244
|
end
|
214
245
|
|
215
246
|
def select_rows(sql, name = nil)
|
@@ -218,11 +249,41 @@ module ActiveRecord
|
|
218
249
|
rows
|
219
250
|
end
|
220
251
|
|
221
|
-
def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
|
222
|
-
id = execute(sql, name = nil)
|
252
|
+
def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
|
253
|
+
id = execute(sql, name = nil, binds)
|
223
254
|
id_value || id
|
224
255
|
end
|
225
256
|
|
257
|
+
### Rails 3.1 prepared statement support
|
258
|
+
|
259
|
+
# Executes +sql+ statement in the context of this connection using
|
260
|
+
# +binds+ as the bind substitutes. +name+ is logged along with
|
261
|
+
# the executed +sql+ statement.
|
262
|
+
def exec_query(sql, name = 'SQL', binds = [])
|
263
|
+
execute(sql, name, binds)
|
264
|
+
end
|
265
|
+
|
266
|
+
# Executes insert +sql+ statement in the context of this connection using
|
267
|
+
# +binds+ as the bind substitutes. +name+ is the logged along with
|
268
|
+
# the executed +sql+ statement.
|
269
|
+
def exec_insert(sql, name, binds)
|
270
|
+
exec_query(sql, name, binds)
|
271
|
+
end
|
272
|
+
|
273
|
+
# Executes delete +sql+ statement in the context of this connection using
|
274
|
+
# +binds+ as the bind substitutes. +name+ is the logged along with
|
275
|
+
# the executed +sql+ statement.
|
276
|
+
def exec_delete(sql, name, binds)
|
277
|
+
exec_query(sql, name, binds)
|
278
|
+
end
|
279
|
+
|
280
|
+
# Executes update +sql+ statement in the context of this connection using
|
281
|
+
# +binds+ as the bind substitutes. +name+ is the logged along with
|
282
|
+
# the executed +sql+ statement.
|
283
|
+
def exec_update(sql, name, binds)
|
284
|
+
exec_query(sql, name, binds)
|
285
|
+
end
|
286
|
+
|
226
287
|
def jdbc_columns(table_name, name = nil)
|
227
288
|
@connection.columns(table_name.to_s)
|
228
289
|
end
|
@@ -277,7 +338,16 @@ module ActiveRecord
|
|
277
338
|
puts e.backtrace if $DEBUG || ENV['DEBUG']
|
278
339
|
super
|
279
340
|
end
|
280
|
-
|
341
|
+
|
342
|
+
def extract_sql(obj)
|
343
|
+
if obj.respond_to? :to_sql
|
344
|
+
obj.send :to_sql
|
345
|
+
else
|
346
|
+
obj
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
protected :translate_exception, :extract_sql
|
281
351
|
end
|
282
352
|
end
|
283
353
|
end
|