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
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
|