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.
Files changed (68) hide show
  1. data/.gitignore +22 -0
  2. data/Gemfile +14 -0
  3. data/Gemfile.lock +42 -0
  4. data/History.txt +10 -3
  5. data/{README.txt → README.rdoc} +30 -14
  6. data/Rakefile +49 -0
  7. data/activerecord-jdbc-adapter.gemspec +23 -0
  8. data/bench/bench_attributes.rb +13 -0
  9. data/bench/bench_attributes_new.rb +14 -0
  10. data/bench/bench_create.rb +12 -0
  11. data/bench/bench_find_all.rb +12 -0
  12. data/bench/bench_find_all_mt.rb +25 -0
  13. data/bench/bench_model.rb +85 -0
  14. data/bench/bench_new.rb +12 -0
  15. data/bench/bench_new_valid.rb +12 -0
  16. data/bench/bench_valid.rb +13 -0
  17. data/lib/activerecord-jdbc-adapter.rb +1 -1
  18. data/lib/arel/visitors/derby.rb +5 -1
  19. data/lib/arjdbc.rb +12 -17
  20. data/lib/arjdbc/db2/adapter.rb +91 -4
  21. data/lib/arjdbc/derby/adapter.rb +8 -8
  22. data/lib/arjdbc/derby/connection_methods.rb +1 -0
  23. data/lib/arjdbc/firebird/adapter.rb +4 -4
  24. data/lib/arjdbc/h2/adapter.rb +3 -2
  25. data/lib/arjdbc/h2/connection_methods.rb +1 -0
  26. data/lib/arjdbc/hsqldb/adapter.rb +5 -2
  27. data/lib/arjdbc/hsqldb/connection_methods.rb +1 -0
  28. data/lib/arjdbc/informix/adapter.rb +2 -2
  29. data/lib/arjdbc/informix/connection_methods.rb +1 -0
  30. data/lib/arjdbc/jdbc/adapter.rb +92 -22
  31. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  32. data/lib/arjdbc/mimer/adapter.rb +4 -4
  33. data/lib/arjdbc/mssql/adapter.rb +10 -8
  34. data/lib/arjdbc/mssql/connection_methods.rb +1 -0
  35. data/lib/arjdbc/mssql/limit_helpers.rb +7 -4
  36. data/lib/arjdbc/mysql/adapter.rb +30 -6
  37. data/lib/arjdbc/mysql/connection_methods.rb +1 -0
  38. data/lib/arjdbc/oracle/adapter.rb +15 -12
  39. data/lib/arjdbc/oracle/connection_methods.rb +1 -0
  40. data/lib/arjdbc/postgresql/adapter.rb +35 -16
  41. data/lib/arjdbc/postgresql/connection_methods.rb +1 -0
  42. data/lib/arjdbc/sqlite3/adapter.rb +13 -10
  43. data/lib/arjdbc/sqlite3/connection_methods.rb +1 -0
  44. data/lib/arjdbc/version.rb +1 -1
  45. data/lib/generators/jdbc/USAGE +10 -0
  46. data/pom.xml +57 -0
  47. data/rakelib/rails.rake +1 -1
  48. data/rakelib/test.rake +20 -6
  49. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +4 -1
  50. data/src/java/arjdbc/jdbc/SQLBlock.java +1 -1
  51. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +74 -0
  52. data/test/abstract_db_create.rb +8 -1
  53. data/test/activerecord/jall.sh +7 -0
  54. data/test/activerecord/jtest.sh +3 -0
  55. data/test/jdbc_common.rb +6 -4
  56. data/test/models/data_types.rb +1 -1
  57. data/test/models/string_id.rb +2 -0
  58. data/test/models/thing.rb +16 -0
  59. data/test/mysql_index_length_test.rb +58 -0
  60. data/test/mysql_info_test.rb +3 -3
  61. data/test/postgres_db_create_test.rb +1 -1
  62. data/test/simple.rb +11 -3
  63. data/test/sqlite3_simple_test.rb +16 -2
  64. metadata +167 -108
  65. data/.gemtest +0 -0
  66. data/Manifest.txt +0 -187
  67. data/rakelib/package.rake +0 -92
  68. data/test/pick_rails_version.rb +0 -3
Binary file
@@ -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
@@ -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
- { 'mssql' => visitor_class, 'sqlserver' => visitor_class, 'jdbcmssql' => visitor_class}
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
- if sqlserver_version == "2000"
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 = {} unless @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
- new_order = "ORDER BY #{order}, #{table_name}.#{primary_key}" if order.index("#{table_name}.#{primary_key}").nil?
37
- new_order ||= order
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] == "*"
@@ -98,14 +98,18 @@ module ::ArJdbc
98
98
  'MySQL'
99
99
  end
100
100
 
101
- def arel2_visitors
102
- {'jdbcmysql' => ::Arel::Visitors::MySQL}
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
- require 'arjdbc/jdbc/quoted_primary_key'
25
- ActiveRecord::Base.extend ArJdbc::QuotedPrimaryKeyExtension
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
- # TODO: use this instead of the QuotedPrimaryKey logic and execute_id_insert?
118
- # def prefetch_primary_key?(table_name = nil)
119
- # columns(table_name).detect {|c| c.primary } if table_name
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
- def arel2_visitors
105
- {'jdbcpostgresql' => ::Arel::Visitors::PostgreSQL}
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
- # From postgresql_adapter.rb
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 ( d.indkey[0]=a.attnum OR d.indkey[1]=a.attnum
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
- indexes.last.columns << row[2]
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 = '' if default =~ /NULL/
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
- {'jdbcsqlite3' => ::Arel::Visitors::SQLite}
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