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
Binary file
|
data/lib/arjdbc/mimer/adapter.rb
CHANGED
@@ -44,9 +44,9 @@ module ArJdbc
|
|
44
44
|
execute "DROP INDEX #{index_name(table_name, options)}"
|
45
45
|
end
|
46
46
|
|
47
|
-
def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
|
47
|
+
def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) #:nodoc:
|
48
48
|
if pk.nil? # Who called us? What does the sql look like? No idea!
|
49
|
-
execute sql, name
|
49
|
+
execute sql, name, binds
|
50
50
|
elsif id_value # Pre-assigned id
|
51
51
|
log(sql, name) { @connection.execute_insert sql,pk }
|
52
52
|
else # Assume the sql contains a bind-variable for the id
|
@@ -104,14 +104,14 @@ module ArJdbc
|
|
104
104
|
@offset = options[:offset]
|
105
105
|
end
|
106
106
|
|
107
|
-
def select_all(sql, name = nil)
|
107
|
+
def select_all(sql, name = nil, binds = [])
|
108
108
|
@offset ||= 0
|
109
109
|
if !@limit || @limit == -1
|
110
110
|
range = @offset..-1
|
111
111
|
else
|
112
112
|
range = @offset...(@offset+@limit)
|
113
113
|
end
|
114
|
-
select(sql, name)[range]
|
114
|
+
select(sql, name, binds)[range]
|
115
115
|
ensure
|
116
116
|
@limit = @offset = nil
|
117
117
|
end
|
data/lib/arjdbc/mssql/adapter.rb
CHANGED
@@ -7,7 +7,7 @@ module ::ArJdbc
|
|
7
7
|
include LimitHelpers
|
8
8
|
|
9
9
|
def self.extended(mod)
|
10
|
-
unless @lob_callback_added
|
10
|
+
unless defined?(@lob_callback_added)
|
11
11
|
ActiveRecord::Base.class_eval do
|
12
12
|
def after_save_with_mssql_lob
|
13
13
|
self.class.columns.select { |c| c.sql_type =~ /image/i }.each do |c|
|
@@ -34,10 +34,10 @@ module ::ArJdbc
|
|
34
34
|
::ActiveRecord::ConnectionAdapters::MssqlJdbcConnection
|
35
35
|
end
|
36
36
|
|
37
|
-
def arel2_visitors
|
37
|
+
def self.arel2_visitors(config)
|
38
38
|
require 'arel/visitors/sql_server'
|
39
|
-
visitor_class = sqlserver_version == "2000" ? ::Arel::Visitors::SQLServer2000 : ::Arel::Visitors::SQLServer
|
40
|
-
{
|
39
|
+
visitor_class = config[:sqlserver_version] == "2000" ? ::Arel::Visitors::SQLServer2000 : ::Arel::Visitors::SQLServer
|
40
|
+
{}.tap {|v| %w(mssql sqlserver jdbcmssql).each {|x| v[x] = visitor_class } }
|
41
41
|
end
|
42
42
|
|
43
43
|
def sqlserver_version
|
@@ -45,7 +45,8 @@ module ::ArJdbc
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def add_version_specific_add_limit_offset
|
48
|
-
|
48
|
+
config[:sqlserver_version] = version = sqlserver_version
|
49
|
+
if version == "2000"
|
49
50
|
extend LimitHelpers::SqlServer2000AddLimitOffset
|
50
51
|
else
|
51
52
|
extend LimitHelpers::SqlServerAddLimitOffset
|
@@ -110,7 +111,7 @@ module ::ArJdbc
|
|
110
111
|
def type_cast(value)
|
111
112
|
return nil if value.nil? || value == "(null)" || value == "(NULL)"
|
112
113
|
case type
|
113
|
-
when :integer then value.to_i rescue unquote(value).to_i rescue value ? 1 : 0
|
114
|
+
when :integer then value.delete('()').to_i rescue unquote(value).to_i rescue value ? 1 : 0
|
114
115
|
when :primary_key then value == true || value == false ? value == true ? 1 : 0 : value.to_i
|
115
116
|
when :decimal then self.class.value_to_decimal(unquote(value))
|
116
117
|
when :datetime then cast_to_datetime(value)
|
@@ -347,7 +348,7 @@ module ::ArJdbc
|
|
347
348
|
table_name = table_name.gsub(/[\[\]]/, '')
|
348
349
|
|
349
350
|
return [] if table_name =~ /^information_schema\./i
|
350
|
-
@table_columns
|
351
|
+
@table_columns ||= {}
|
351
352
|
unless @table_columns[table_name]
|
352
353
|
@table_columns[table_name] = super
|
353
354
|
@table_columns[table_name].each do |col|
|
@@ -381,7 +382,8 @@ module ::ArJdbc
|
|
381
382
|
end
|
382
383
|
end
|
383
384
|
|
384
|
-
def select(sql, name = nil)
|
385
|
+
def select(sql, name = nil, binds = [])
|
386
|
+
sql = substitute_binds(sql, binds)
|
385
387
|
log(sql, name) do
|
386
388
|
@connection.execute_query(sql)
|
387
389
|
end
|
@@ -5,6 +5,7 @@ class ActiveRecord::Base
|
|
5
5
|
config[:host] ||= "localhost"
|
6
6
|
config[:port] ||= 1433
|
7
7
|
config[:driver] ||= "net.sourceforge.jtds.jdbc.Driver"
|
8
|
+
config[:adapter_spec] = ::ArJdbc::MsSQL
|
8
9
|
|
9
10
|
url = "jdbc:jtds:sqlserver://#{config[:host]}:#{config[:port]}/#{config[:database]}"
|
10
11
|
|
@@ -31,10 +31,13 @@ module ::ArJdbc
|
|
31
31
|
rest = rest_of_query[/FROM/i=~ rest_of_query.. -1]
|
32
32
|
#need the table name for avoiding amiguity
|
33
33
|
table_name = LimitHelpers.get_table_name(sql)
|
34
|
-
primary_key = order[/(\w*id\w*)/i]
|
34
|
+
primary_key = order[/(\w*id\w*)/i] || "id"
|
35
35
|
#I am not sure this will cover all bases. but all the tests pass
|
36
|
-
|
37
|
-
|
36
|
+
if order[/ORDER/].nil?
|
37
|
+
new_order = "ORDER BY #{order}, #{table_name}.#{primary_key}" if order.index("#{table_name}.#{primary_key}").nil?
|
38
|
+
else
|
39
|
+
new_order ||= order
|
40
|
+
end
|
38
41
|
|
39
42
|
if (rest_of_query.match(/WHERE/).nil?)
|
40
43
|
new_sql = "#{select} TOP #{limit} #{rest_of_query} WHERE #{table_name}.#{primary_key} NOT IN (#{select} TOP #{offset} #{table_name}.#{primary_key} #{rest} #{new_order}) #{order} "
|
@@ -69,7 +72,7 @@ module ::ArJdbc
|
|
69
72
|
find_select = /\b(SELECT(?:\s+DISTINCT)?)\b(.*)/im
|
70
73
|
whole, select, rest_of_query = find_select.match(sql).to_a
|
71
74
|
rest_of_query.strip!
|
72
|
-
if rest_of_query[0] == "1"
|
75
|
+
if rest_of_query[0...1] == "1" && rest_of_query !~ /1 AS/i
|
73
76
|
rest_of_query[0] = "*"
|
74
77
|
end
|
75
78
|
if rest_of_query[0] == "*"
|
data/lib/arjdbc/mysql/adapter.rb
CHANGED
@@ -98,14 +98,18 @@ module ::ArJdbc
|
|
98
98
|
'MySQL'
|
99
99
|
end
|
100
100
|
|
101
|
-
def arel2_visitors
|
102
|
-
{
|
101
|
+
def self.arel2_visitors(config)
|
102
|
+
{}.tap {|v| %w(mysql mysql2 jdbcmysql).each {|a| v[a] = ::Arel::Visitors::MySQL } }
|
103
103
|
end
|
104
104
|
|
105
105
|
def case_sensitive_equality_operator
|
106
106
|
"= BINARY"
|
107
107
|
end
|
108
108
|
|
109
|
+
def case_sensitive_modifier(node)
|
110
|
+
Arel::Nodes::Bin.new(node)
|
111
|
+
end
|
112
|
+
|
109
113
|
def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key)
|
110
114
|
where_sql
|
111
115
|
end
|
@@ -338,6 +342,19 @@ module ::ArJdbc
|
|
338
342
|
end
|
339
343
|
|
340
344
|
protected
|
345
|
+
def quoted_columns_for_index(column_names, options = {})
|
346
|
+
length = options[:length] if options.is_a?(Hash)
|
347
|
+
|
348
|
+
case length
|
349
|
+
when Hash
|
350
|
+
column_names.map { |name| length[name] ? "#{quote_column_name(name)}(#{length[name]})" : quote_column_name(name) }
|
351
|
+
when Fixnum
|
352
|
+
column_names.map { |name| "#{quote_column_name(name)}(#{length})" }
|
353
|
+
else
|
354
|
+
column_names.map { |name| quote_column_name(name) }
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
341
358
|
def translate_exception(exception, message)
|
342
359
|
return super unless exception.respond_to?(:errno)
|
343
360
|
|
@@ -397,10 +414,6 @@ module ActiveRecord::ConnectionAdapters
|
|
397
414
|
configure_connection
|
398
415
|
end
|
399
416
|
|
400
|
-
def adapter_spec(config)
|
401
|
-
# return nil to avoid extending ArJdbc::MySQL, which we've already done
|
402
|
-
end
|
403
|
-
|
404
417
|
def jdbc_connection_class(spec)
|
405
418
|
::ArJdbc::MySQL.jdbc_connection_class
|
406
419
|
end
|
@@ -410,6 +423,17 @@ module ActiveRecord::ConnectionAdapters
|
|
410
423
|
end
|
411
424
|
|
412
425
|
alias_chained_method :columns, :query_cache, :jdbc_columns
|
426
|
+
|
427
|
+
protected
|
428
|
+
def exec_insert(sql, name, binds)
|
429
|
+
binds = binds.dup
|
430
|
+
|
431
|
+
# Pretend to support bind parameters
|
432
|
+
execute sql.gsub('?') { quote(*binds.shift.reverse) }, name
|
433
|
+
end
|
434
|
+
alias :exec_update :exec_insert
|
435
|
+
alias :exec_delete :exec_insert
|
436
|
+
|
413
437
|
end
|
414
438
|
end
|
415
439
|
|
@@ -15,6 +15,7 @@ class ActiveRecord::Base
|
|
15
15
|
config[:url] ||= "jdbc:mysql://#{config[:host]}:#{config[:port]}/#{config[:database]}"
|
16
16
|
config[:driver] ||= "com.mysql.jdbc.Driver"
|
17
17
|
config[:adapter_class] = ActiveRecord::ConnectionAdapters::MysqlAdapter
|
18
|
+
config[:adapter_spec] = ::ArJdbc::MySQL
|
18
19
|
connection = jdbc_connection(config)
|
19
20
|
::ArJdbc::MySQL.kill_cancel_timer(connection.raw_connection)
|
20
21
|
connection
|
@@ -5,7 +5,7 @@ end
|
|
5
5
|
module ::ArJdbc
|
6
6
|
module Oracle
|
7
7
|
def self.extended(mod)
|
8
|
-
unless @lob_callback_added
|
8
|
+
unless defined?(@lob_callback_added)
|
9
9
|
ActiveRecord::Base.class_eval do
|
10
10
|
def after_save_with_oracle_lob
|
11
11
|
self.class.columns.select { |c| c.sql_type =~ /LOB\(|LOB$/i }.each do |c|
|
@@ -21,8 +21,12 @@ module ::ArJdbc
|
|
21
21
|
ActiveRecord::Base.after_save :after_save_with_oracle_lob
|
22
22
|
@lob_callback_added = true
|
23
23
|
end
|
24
|
-
|
25
|
-
ActiveRecord::
|
24
|
+
|
25
|
+
unless ActiveRecord::ConnectionAdapters::AbstractAdapter.instance_methods(false).detect {|m| m.to_s == "prefetch_primary_key?"}
|
26
|
+
require 'arjdbc/jdbc/quoted_primary_key'
|
27
|
+
ActiveRecord::Base.extend ArJdbc::QuotedPrimaryKeyExtension
|
28
|
+
end
|
29
|
+
|
26
30
|
(class << mod; self; end).class_eval do
|
27
31
|
alias_chained_method :insert, :query_dirty, :ora_insert
|
28
32
|
alias_chained_method :columns, :query_cache, :ora_columns
|
@@ -110,14 +114,13 @@ module ::ArJdbc
|
|
110
114
|
'Oracle'
|
111
115
|
end
|
112
116
|
|
113
|
-
def arel2_visitors
|
117
|
+
def self.arel2_visitors(config)
|
114
118
|
{ 'oracle' => Arel::Visitors::Oracle }
|
115
119
|
end
|
116
120
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
# end
|
121
|
+
def prefetch_primary_key?(table_name = nil)
|
122
|
+
columns(table_name).detect {|c| c.primary } if table_name
|
123
|
+
end
|
121
124
|
|
122
125
|
def table_alias_length
|
123
126
|
30
|
@@ -163,12 +166,12 @@ module ::ArJdbc
|
|
163
166
|
defined?(::Arel::SqlLiteral) && ::Arel::SqlLiteral === value
|
164
167
|
end
|
165
168
|
|
166
|
-
def ora_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
|
169
|
+
def ora_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) #:nodoc:
|
167
170
|
if (id_value && !sql_literal?(id_value)) || pk.nil?
|
168
171
|
# Pre-assigned id or table without a primary key
|
169
172
|
# Presence of #to_sql means an Arel literal bind variable
|
170
173
|
# that should use #execute_id_insert below
|
171
|
-
execute sql, name
|
174
|
+
execute sql, name, binds
|
172
175
|
else
|
173
176
|
# Assume the sql contains a bind-variable for the id
|
174
177
|
# Extract the table from the insert sql. Yuck.
|
@@ -406,8 +409,8 @@ module ::ArJdbc
|
|
406
409
|
end
|
407
410
|
end
|
408
411
|
|
409
|
-
def select(sql, name=nil)
|
410
|
-
records = execute(sql,name)
|
412
|
+
def select(sql, name = nil, binds = [])
|
413
|
+
records = execute(sql, name, binds)
|
411
414
|
records.each do |col|
|
412
415
|
col.delete('raw_rnum_')
|
413
416
|
end
|
@@ -4,6 +4,7 @@ class ActiveRecord::Base
|
|
4
4
|
config[:port] ||= 1521
|
5
5
|
config[:url] ||= "jdbc:oracle:thin:@#{config[:host]}:#{config[:port]}:#{config[:database]}"
|
6
6
|
config[:driver] ||= "oracle.jdbc.driver.OracleDriver"
|
7
|
+
config[:adapter_spec] = ::ArJdbc::Oracle
|
7
8
|
jdbc_connection(config)
|
8
9
|
end
|
9
10
|
end
|
@@ -101,8 +101,9 @@ module ::ArJdbc
|
|
101
101
|
'PostgreSQL'
|
102
102
|
end
|
103
103
|
|
104
|
-
|
105
|
-
|
104
|
+
|
105
|
+
def self.arel2_visitors(config)
|
106
|
+
{}.tap {|v| %w(postgresql pg jdbcpostgresql).each {|a| v[a] = ::Arel::Visitors::PostgreSQL } }
|
106
107
|
end
|
107
108
|
|
108
109
|
def postgresql_version
|
@@ -245,7 +246,9 @@ module ::ArJdbc
|
|
245
246
|
nil
|
246
247
|
end
|
247
248
|
|
248
|
-
def pg_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
|
249
|
+
def pg_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
|
250
|
+
sql = substitute_binds(sql, binds)
|
251
|
+
|
249
252
|
# Extract the table from the insert sql. Yuck.
|
250
253
|
table = sql.split(" ", 4)[2].gsub('"', '')
|
251
254
|
|
@@ -253,6 +256,7 @@ module ::ArJdbc
|
|
253
256
|
if supports_insert_with_returning? && id_value.nil?
|
254
257
|
pk, sequence_name = *pk_and_sequence_for(table) unless pk
|
255
258
|
if pk
|
259
|
+
sql = substitute_binds(sql, binds)
|
256
260
|
id_value = select_value("#{sql} RETURNING #{quote_column_name(pk)}")
|
257
261
|
clear_query_cache #FIXME: Why now?
|
258
262
|
return id_value
|
@@ -260,7 +264,7 @@ module ::ArJdbc
|
|
260
264
|
end
|
261
265
|
|
262
266
|
# Otherwise, plain insert
|
263
|
-
execute(sql, name)
|
267
|
+
execute(sql, name, binds)
|
264
268
|
|
265
269
|
# Don't need to look up id_value if we already have it.
|
266
270
|
# (and can't in case of non-sequence PK)
|
@@ -302,35 +306,51 @@ module ::ArJdbc
|
|
302
306
|
return @connection.columns_internal(table_name, name, s)
|
303
307
|
end
|
304
308
|
|
305
|
-
#
|
309
|
+
# Sets the maximum number columns postgres has, default 32
|
310
|
+
def multi_column_index_limit=(limit)
|
311
|
+
@multi_column_index_limit = limit
|
312
|
+
end
|
313
|
+
|
314
|
+
# Gets the maximum number columns postgres has, default 32
|
315
|
+
def multi_column_index_limit
|
316
|
+
defined?(@multi_column_index_limit) && @multi_column_index_limit || 32
|
317
|
+
end
|
318
|
+
|
319
|
+
# Based on postgresql_adapter.rb
|
306
320
|
def indexes(table_name, name = nil)
|
321
|
+
schema_search_path = @config[:schema_search_path] || select_rows('SHOW search_path')[0][0]
|
322
|
+
schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
|
307
323
|
result = select_rows(<<-SQL, name)
|
308
|
-
SELECT i.relname, d.indisunique, a.attname
|
309
|
-
FROM pg_class t, pg_class i, pg_index d, pg_attribute a
|
324
|
+
SELECT i.relname, d.indisunique, a.attname, a.attnum, d.indkey
|
325
|
+
FROM pg_class t, pg_class i, pg_index d, pg_attribute a,
|
326
|
+
generate_series(0,#{multi_column_index_limit - 1}) AS s(i)
|
310
327
|
WHERE i.relkind = 'i'
|
311
328
|
AND d.indexrelid = i.oid
|
312
329
|
AND d.indisprimary = 'f'
|
313
330
|
AND t.oid = d.indrelid
|
314
331
|
AND t.relname = '#{table_name}'
|
332
|
+
AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname IN (#{schemas}) )
|
315
333
|
AND a.attrelid = t.oid
|
316
|
-
AND
|
317
|
-
OR d.indkey[2]=a.attnum OR d.indkey[3]=a.attnum
|
318
|
-
OR d.indkey[4]=a.attnum OR d.indkey[5]=a.attnum
|
319
|
-
OR d.indkey[6]=a.attnum OR d.indkey[7]=a.attnum
|
320
|
-
OR d.indkey[8]=a.attnum OR d.indkey[9]=a.attnum )
|
334
|
+
AND d.indkey[s.i]=a.attnum
|
321
335
|
ORDER BY i.relname
|
322
336
|
SQL
|
323
337
|
|
324
338
|
current_index = nil
|
325
339
|
indexes = []
|
326
340
|
|
341
|
+
insertion_order = []
|
342
|
+
index_order = nil
|
343
|
+
|
327
344
|
result.each do |row|
|
328
345
|
if current_index != row[0]
|
346
|
+
|
347
|
+
(index_order = row[4].split(' ')).each_with_index{ |v, i| index_order[i] = v.to_i }
|
329
348
|
indexes << ::ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, row[0], row[1] == "t", [])
|
330
349
|
current_index = row[0]
|
331
350
|
end
|
332
|
-
|
333
|
-
|
351
|
+
insertion_order = row[3]
|
352
|
+
ind = index_order.index(insertion_order)
|
353
|
+
indexes.last.columns[ind] = row[2]
|
334
354
|
end
|
335
355
|
|
336
356
|
indexes
|
@@ -409,8 +429,7 @@ module ::ArJdbc
|
|
409
429
|
|
410
430
|
# construct a clean list of column names from the ORDER BY clause, removing
|
411
431
|
# any asc/desc modifiers
|
412
|
-
order_columns = order_by.split(',').collect { |s| s.split.first }
|
413
|
-
order_columns.delete_if(&:blank?)
|
432
|
+
order_columns = [order_by].flatten.map{|o| o.split(',').collect { |s| s.split.first } }.flatten.reject(&:blank?)
|
414
433
|
order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" }
|
415
434
|
|
416
435
|
# return a DISTINCT ON() clause that's distinct on the columns we want but includes
|
@@ -10,6 +10,7 @@ class ActiveRecord::Base
|
|
10
10
|
config[:url] ||= "jdbc:postgresql://#{config[:host]}:#{config[:port]}/#{config[:database]}"
|
11
11
|
config[:url] << config[:pg_params] if config[:pg_params]
|
12
12
|
config[:driver] ||= "org.postgresql.Driver"
|
13
|
+
config[:adapter_spec] = ::ArJdbc::PostgreSQL
|
13
14
|
conn = jdbc_connection(config)
|
14
15
|
conn.execute("SET SEARCH_PATH TO #{config[:schema_search_path]}") if config[:schema_search_path]
|
15
16
|
conn
|
@@ -16,7 +16,7 @@ module ::ArJdbc
|
|
16
16
|
|
17
17
|
module Column
|
18
18
|
def init_column(name, default, *args)
|
19
|
-
@default =
|
19
|
+
@default = nil if default =~ /NULL/
|
20
20
|
end
|
21
21
|
|
22
22
|
def type_cast(value)
|
@@ -80,8 +80,8 @@ module ::ArJdbc
|
|
80
80
|
'SQLite'
|
81
81
|
end
|
82
82
|
|
83
|
-
def arel2_visitors
|
84
|
-
{
|
83
|
+
def self.arel2_visitors(config)
|
84
|
+
{}.tap {|v| %w(sqlite3 jdbcsqlite3).each {|x| v[x] = ::Arel::Visitors::SQLite } }
|
85
85
|
end
|
86
86
|
|
87
87
|
def supports_ddl_transactions?
|
@@ -145,7 +145,8 @@ module ::ArJdbc
|
|
145
145
|
end
|
146
146
|
end
|
147
147
|
|
148
|
-
def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
|
148
|
+
def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) #:nodoc:
|
149
|
+
sql = substitute_binds(sql, binds)
|
149
150
|
@connection.execute_update(sql)
|
150
151
|
id_value || last_insert_id
|
151
152
|
end
|
@@ -194,8 +195,8 @@ module ::ArJdbc
|
|
194
195
|
ActiveRecord::ConnectionAdapters::JdbcConnection::insert?(sql) ? last_insert_id : result
|
195
196
|
end
|
196
197
|
|
197
|
-
def select(sql, name=nil)
|
198
|
-
execute(sql, name).map do |row|
|
198
|
+
def select(sql, name=nil, binds = [])
|
199
|
+
execute(sql, name, binds).map do |row|
|
199
200
|
record = {}
|
200
201
|
row.each_key do |key|
|
201
202
|
if key.is_a?(String)
|
@@ -354,10 +355,6 @@ module ActiveRecord::ConnectionAdapters
|
|
354
355
|
class SQLite3Adapter < JdbcAdapter
|
355
356
|
include ArJdbc::SQLite3
|
356
357
|
|
357
|
-
def adapter_spec(config)
|
358
|
-
# return nil to avoid extending ArJdbc::SQLite3, which we've already done
|
359
|
-
end
|
360
|
-
|
361
358
|
def jdbc_connection_class(spec)
|
362
359
|
::ArJdbc::SQLite3.jdbc_connection_class
|
363
360
|
end
|
@@ -367,6 +364,12 @@ module ActiveRecord::ConnectionAdapters
|
|
367
364
|
end
|
368
365
|
|
369
366
|
alias_chained_method :columns, :query_cache, :jdbc_columns
|
367
|
+
|
368
|
+
protected
|
369
|
+
|
370
|
+
def last_inserted_id(result)
|
371
|
+
last_insert_id
|
372
|
+
end
|
370
373
|
end
|
371
374
|
|
372
375
|
SQLiteAdapter = SQLite3Adapter
|