activerecord-jdbc-adapter 1.1.3 → 1.2.0
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.
- 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
|