activerecord-jdbc-adapter 1.2.0 → 1.2.1
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/.travis.yml +5 -0
- data/Gemfile.lock +1 -1
- data/History.txt +10 -0
- data/Rakefile +5 -5
- data/lib/arel/visitors/firebird.rb +10 -3
- data/lib/arjdbc/derby/adapter.rb +0 -1
- data/lib/arjdbc/h2/adapter.rb +17 -0
- data/lib/arjdbc/hsqldb/adapter.rb +1 -2
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/type_converter.rb +2 -2
- data/lib/arjdbc/mysql/adapter.rb +34 -43
- data/lib/arjdbc/postgresql/adapter.rb +35 -1
- data/lib/arjdbc/postgresql/connection_methods.rb +1 -0
- data/lib/arjdbc/sqlite3/adapter.rb +2 -2
- data/lib/arjdbc/version.rb +1 -1
- data/rakelib/bundler_ext.rb +11 -0
- data/rakelib/compile.rake +20 -22
- data/rakelib/db.rake +21 -13
- data/rakelib/rails.rake +1 -1
- data/src/java/arjdbc/derby/DerbyModule.java +69 -67
- data/src/java/arjdbc/sqlite3/Sqlite3RubyJdbcConnection.java +62 -0
- data/test/db/mysql.rb +3 -3
- data/test/db/postgres.rb +3 -3
- data/test/h2_change_column_test.rb +68 -0
- data/test/helper.rb +69 -0
- data/test/mysql_simple_test.rb +16 -4
- data/test/postgres_native_type_mapping_test.rb +6 -1
- data/test/postgres_simple_test.rb +12 -6
- data/test/postgres_type_conversion_test.rb +34 -0
- data/test/simple.rb +78 -6
- data/test/sqlite3_simple_test.rb +25 -3
- metadata +8 -2
data/Gemfile.lock
CHANGED
data/History.txt
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
== 1.2.1 (11/23/11)
|
2
|
+
|
3
|
+
- #117: Skip ? substitution when no bind parameters are given
|
4
|
+
- #115: Work around bug in ResultSetMetaData in SQLite
|
5
|
+
- Enhance the 'change_column' in H2 adapter to support additional options
|
6
|
+
- Deal with changes in RubyBigDecimal in trunk
|
7
|
+
- Decimal with scale zero handling (George Murphy)
|
8
|
+
- Fix blob handling for SQLite3 since SQLiteJDBC does not support
|
9
|
+
getBinary (Jean-Dominique Morani)
|
10
|
+
|
1
11
|
== 1.2.0 (09/13/11)
|
2
12
|
|
3
13
|
- Support for Rails 3.1
|
data/Rakefile
CHANGED
@@ -6,11 +6,11 @@ require 'bundler'
|
|
6
6
|
Bundler::GemHelper.install_tasks
|
7
7
|
require 'bundler/setup'
|
8
8
|
|
9
|
-
task :default => [:
|
9
|
+
task :default => [:jar, :test]
|
10
10
|
|
11
11
|
#ugh, bundler doesn't use tasks, so gotta hook up to both tasks.
|
12
|
-
task :build => :
|
13
|
-
task :install => :
|
12
|
+
task :build => :jar
|
13
|
+
task :install => :jar
|
14
14
|
|
15
15
|
ADAPTERS = %w[derby h2 hsqldb mssql mysql postgresql sqlite3].map {|a| "activerecord-jdbc#{a}-adapter" }
|
16
16
|
DRIVERS = %w[derby h2 hsqldb jtds mysql postgres sqlite3].map {|a| "jdbc-#{a}" }
|
@@ -44,13 +44,13 @@ end
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
desc "
|
47
|
+
desc "Release all adapters"
|
48
48
|
task "all:release" => ["release", *ADAPTERS.map { |f| "#{f}:release" }]
|
49
49
|
|
50
50
|
desc "Install all adapters"
|
51
51
|
task "all:install" => ["install", *ADAPTERS.map { |f| "#{f}:install" }]
|
52
52
|
|
53
|
-
desc "
|
53
|
+
desc "Build all adapters"
|
54
54
|
task "all:build" => ["build", *ADAPTERS.map { |f| "#{f}:build" }]
|
55
55
|
|
56
56
|
task :filelist do
|
@@ -4,12 +4,19 @@ module Arel
|
|
4
4
|
module Visitors
|
5
5
|
class Firebird < Arel::Visitors::ToSql
|
6
6
|
def visit_Arel_Nodes_SelectStatement o
|
7
|
-
[
|
7
|
+
lim_off = [
|
8
|
+
("FIRST #{visit(o.limit.expr)}" if o.limit),
|
9
|
+
("SKIP #{visit(o.offset.expr)}" if o.offset)
|
10
|
+
].compact.join(' ').strip
|
11
|
+
|
12
|
+
sql = [
|
8
13
|
o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join,
|
9
14
|
("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
|
10
|
-
("ROWS #{limit_for(o.limit)} " if o.limit),
|
11
|
-
("TO #{o.offset} " if o.offset),
|
12
15
|
].compact.join ' '
|
16
|
+
|
17
|
+
sql.sub!(/\A(\s*SELECT\s)/i, '\&' + lim_off + ' ') unless lim_off.empty?
|
18
|
+
|
19
|
+
sql
|
13
20
|
end
|
14
21
|
|
15
22
|
end
|
data/lib/arjdbc/derby/adapter.rb
CHANGED
data/lib/arjdbc/h2/adapter.rb
CHANGED
@@ -29,7 +29,24 @@ module ArJdbc
|
|
29
29
|
@connection.columns_internal(table_name.to_s, name, h2_schema)
|
30
30
|
end
|
31
31
|
|
32
|
+
def change_column(table_name, column_name, type, options = {}) #:nodoc:
|
33
|
+
execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
|
34
|
+
change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
|
35
|
+
change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
|
36
|
+
end
|
37
|
+
|
32
38
|
private
|
39
|
+
def change_column_null(table_name, column_name, null, default = nil)
|
40
|
+
if !null && !default.nil?
|
41
|
+
execute("UPDATE #{table_name} SET #{column_name}=#{quote(default)} WHERE #{column_name} IS NULL")
|
42
|
+
end
|
43
|
+
if null
|
44
|
+
execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET NULL"
|
45
|
+
else
|
46
|
+
execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET NOT NULL"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
33
50
|
def h2_schema
|
34
51
|
@config[:schema] || ''
|
35
52
|
end
|
@@ -11,7 +11,6 @@ module ::ArJdbc
|
|
11
11
|
when /longvarchar/i then :text
|
12
12
|
when /tinyint/i then :boolean
|
13
13
|
when /real/i then :float
|
14
|
-
when /decimal/i then :decimal
|
15
14
|
else
|
16
15
|
super
|
17
16
|
end
|
@@ -71,7 +70,7 @@ module ::ArJdbc
|
|
71
70
|
if respond_to?(:h2_adapter) && value.empty?
|
72
71
|
"''"
|
73
72
|
elsif column && column.type == :binary
|
74
|
-
"'#{value.unpack("H*")}'"
|
73
|
+
"'#{value.unpack("H*")[0]}'"
|
75
74
|
elsif column && (column.type == :integer ||
|
76
75
|
column.respond_to?(:primary) && column.primary && column.klass != String)
|
77
76
|
value.to_i.to_s
|
Binary file
|
@@ -34,7 +34,7 @@ module ActiveRecord
|
|
34
34
|
lambda {|r| r['type_name'] =~ /^number$/i},
|
35
35
|
lambda {|r| r['type_name'] =~ /^real$/i},
|
36
36
|
lambda {|r| r['precision'] == '38'},
|
37
|
-
lambda {|r| r['data_type'] ==
|
37
|
+
lambda {|r| r['data_type'].to_i == Jdbc::Types::DECIMAL}],
|
38
38
|
:float => [ lambda {|r| [Jdbc::Types::FLOAT,Jdbc::Types::DOUBLE, Jdbc::Types::REAL].include?(r['data_type'].to_i)},
|
39
39
|
lambda {|r| r['data_type'].to_i == Jdbc::Types::REAL}, #Prefer REAL to DOUBLE for Postgresql
|
40
40
|
lambda {|r| r['type_name'] =~ /^float/i},
|
@@ -67,7 +67,7 @@ module ActiveRecord
|
|
67
67
|
lambda {|r| r['type_name'] =~ /^binary$/i}, ],
|
68
68
|
:boolean => [ lambda {|r| [Jdbc::Types::TINYINT].include?(r['data_type'].to_i)},
|
69
69
|
lambda {|r| r['type_name'] =~ /^bool/i},
|
70
|
-
lambda {|r| r['data_type'] ==
|
70
|
+
lambda {|r| r['data_type'].to_i == Jdbc::Types::BIT},
|
71
71
|
lambda {|r| r['type_name'] =~ /^tinyint$/i},
|
72
72
|
lambda {|r| r['type_name'] =~ /^decimal$/i},
|
73
73
|
lambda {|r| r['type_name'] =~ /^integer$/i}]
|
data/lib/arjdbc/mysql/adapter.rb
CHANGED
@@ -3,7 +3,7 @@ require 'active_record/connection_adapters/abstract/schema_definitions'
|
|
3
3
|
module ::ArJdbc
|
4
4
|
module MySQL
|
5
5
|
def self.column_selector
|
6
|
-
[/mysql/i, lambda {|cfg,col| col.extend(::ArJdbc::MySQL::
|
6
|
+
[/mysql/i, lambda {|cfg,col| col.extend(::ArJdbc::MySQL::ColumnExtensions)}]
|
7
7
|
end
|
8
8
|
|
9
9
|
def self.extended(adapter)
|
@@ -18,7 +18,7 @@ module ::ArJdbc
|
|
18
18
|
::ActiveRecord::ConnectionAdapters::MySQLJdbcConnection
|
19
19
|
end
|
20
20
|
|
21
|
-
module
|
21
|
+
module ColumnExtensions
|
22
22
|
def extract_default(default)
|
23
23
|
if sql_type =~ /blob/i || type == :text
|
24
24
|
if default.blank?
|
@@ -42,7 +42,7 @@ module ::ArJdbc
|
|
42
42
|
case field_type
|
43
43
|
when /tinyint\(1\)|bit/i then :boolean
|
44
44
|
when /enum/i then :string
|
45
|
-
when /
|
45
|
+
when /year/i then :integer
|
46
46
|
else
|
47
47
|
super
|
48
48
|
end
|
@@ -61,6 +61,7 @@ module ::ArJdbc
|
|
61
61
|
else
|
62
62
|
nil # we could return 65535 here, but we leave it undecorated by default
|
63
63
|
end
|
64
|
+
when /^enum/i; 255
|
64
65
|
when /^bigint/i; 8
|
65
66
|
when /^int/i; 4
|
66
67
|
when /^mediumint/i; 3
|
@@ -131,30 +132,16 @@ module ::ArJdbc
|
|
131
132
|
end
|
132
133
|
end
|
133
134
|
|
135
|
+
def quote_column_name(name)
|
136
|
+
"`#{name.to_s.gsub('`', '``')}`"
|
137
|
+
end
|
138
|
+
|
134
139
|
def quoted_true
|
135
|
-
|
140
|
+
"1"
|
136
141
|
end
|
137
142
|
|
138
143
|
def quoted_false
|
139
|
-
|
140
|
-
end
|
141
|
-
|
142
|
-
def begin_db_transaction #:nodoc:
|
143
|
-
@connection.begin
|
144
|
-
rescue Exception
|
145
|
-
# Transactions aren't supported
|
146
|
-
end
|
147
|
-
|
148
|
-
def commit_db_transaction #:nodoc:
|
149
|
-
@connection.commit
|
150
|
-
rescue Exception
|
151
|
-
# Transactions aren't supported
|
152
|
-
end
|
153
|
-
|
154
|
-
def rollback_db_transaction #:nodoc:
|
155
|
-
@connection.rollback
|
156
|
-
rescue Exception
|
157
|
-
# Transactions aren't supported
|
144
|
+
"0"
|
158
145
|
end
|
159
146
|
|
160
147
|
def supports_savepoints? #:nodoc:
|
@@ -208,7 +195,7 @@ module ::ArJdbc
|
|
208
195
|
def jdbc_columns(table_name, name = nil)#:nodoc:
|
209
196
|
sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}"
|
210
197
|
execute(sql, :skip_logging).map do |field|
|
211
|
-
::ActiveRecord::ConnectionAdapters::
|
198
|
+
::ActiveRecord::ConnectionAdapters::MysqlAdapter::Column.new(field["Field"], field["Default"], field["Type"], field["Null"] == "YES")
|
212
199
|
end
|
213
200
|
end
|
214
201
|
|
@@ -308,8 +295,8 @@ module ::ArJdbc
|
|
308
295
|
|
309
296
|
def show_variable(var)
|
310
297
|
res = execute("show variables like '#{var}'")
|
311
|
-
|
312
|
-
|
298
|
+
result_row = res.detect {|row| row["Variable_name"] == var }
|
299
|
+
result_row && result_row["Value"]
|
313
300
|
end
|
314
301
|
|
315
302
|
def charset
|
@@ -391,21 +378,6 @@ module ActiveRecord::ConnectionAdapters
|
|
391
378
|
remove_const(:MysqlColumn) if const_defined?(:MysqlColumn)
|
392
379
|
remove_const(:MysqlAdapter) if const_defined?(:MysqlAdapter)
|
393
380
|
|
394
|
-
class MysqlColumn < JdbcColumn
|
395
|
-
include ArJdbc::MySQL::Column
|
396
|
-
|
397
|
-
def initialize(name, *args)
|
398
|
-
if Hash === name
|
399
|
-
super
|
400
|
-
else
|
401
|
-
super(nil, name, *args)
|
402
|
-
end
|
403
|
-
end
|
404
|
-
|
405
|
-
def call_discovered_column_callbacks(*)
|
406
|
-
end
|
407
|
-
end
|
408
|
-
|
409
381
|
class MysqlAdapter < JdbcAdapter
|
410
382
|
include ArJdbc::MySQL
|
411
383
|
|
@@ -419,17 +391,36 @@ module ActiveRecord::ConnectionAdapters
|
|
419
391
|
end
|
420
392
|
|
421
393
|
def jdbc_column_class
|
422
|
-
ActiveRecord::ConnectionAdapters::
|
394
|
+
ActiveRecord::ConnectionAdapters::MysqlAdapter::Column
|
423
395
|
end
|
424
396
|
|
425
397
|
alias_chained_method :columns, :query_cache, :jdbc_columns
|
426
398
|
|
399
|
+
remove_const(:Column) if const_defined?(:Column)
|
400
|
+
class Column < JdbcColumn
|
401
|
+
include ArJdbc::MySQL::ColumnExtensions
|
402
|
+
|
403
|
+
def initialize(name, *args)
|
404
|
+
if Hash === name
|
405
|
+
super
|
406
|
+
else
|
407
|
+
super(nil, name, *args)
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
def call_discovered_column_callbacks(*)
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
427
415
|
protected
|
428
416
|
def exec_insert(sql, name, binds)
|
429
417
|
binds = binds.dup
|
430
418
|
|
431
419
|
# Pretend to support bind parameters
|
432
|
-
|
420
|
+
unless binds.empty?
|
421
|
+
sql = sql.gsub('?') { quote(*binds.shift.reverse) }
|
422
|
+
end
|
423
|
+
execute sql, name
|
433
424
|
end
|
434
425
|
alias :exec_update :exec_insert
|
435
426
|
alias :exec_delete :exec_insert
|
@@ -44,6 +44,7 @@ module ::ArJdbc
|
|
44
44
|
return :integer if field_type =~ /^(big|)serial/i
|
45
45
|
return :string if field_type =~ /\[\]$/i || field_type =~ /^interval/i
|
46
46
|
return :string if field_type =~ /^(?:point|lseg|box|"?path"?|polygon|circle)/i
|
47
|
+
return :string if field_type =~ /^uuid/i
|
47
48
|
return :datetime if field_type =~ /^timestamp/i
|
48
49
|
return :float if field_type =~ /^(?:real|double precision)$/i
|
49
50
|
return :binary if field_type =~ /^bytea/i
|
@@ -494,7 +495,7 @@ module ::ArJdbc
|
|
494
495
|
end
|
495
496
|
|
496
497
|
def quote_column_name(name)
|
497
|
-
%("#{name}")
|
498
|
+
%("#{name.to_s.gsub("\"", "\"\"")}")
|
498
499
|
end
|
499
500
|
|
500
501
|
def quoted_date(value) #:nodoc:
|
@@ -615,3 +616,36 @@ module ::ArJdbc
|
|
615
616
|
end
|
616
617
|
end
|
617
618
|
|
619
|
+
module ActiveRecord::ConnectionAdapters
|
620
|
+
remove_const(:PostgreSQLAdapter) if const_defined?(:PostgreSQLAdapter)
|
621
|
+
|
622
|
+
class PostgreSQLColumn < JdbcColumn
|
623
|
+
include ArJdbc::PostgreSQL::Column
|
624
|
+
|
625
|
+
def initialize(name, *args)
|
626
|
+
if Hash === name
|
627
|
+
super
|
628
|
+
else
|
629
|
+
super(nil, name, *args)
|
630
|
+
end
|
631
|
+
end
|
632
|
+
|
633
|
+
def call_discovered_column_callbacks(*)
|
634
|
+
end
|
635
|
+
end
|
636
|
+
|
637
|
+
class PostgreSQLAdapter < JdbcAdapter
|
638
|
+
include ArJdbc::PostgreSQL
|
639
|
+
|
640
|
+
def jdbc_connection_class(spec)
|
641
|
+
::ArJdbc::PostgreSQL.jdbc_connection_class
|
642
|
+
end
|
643
|
+
|
644
|
+
def jdbc_column_class
|
645
|
+
ActiveRecord::ConnectionAdapters::PostgreSQLColumn
|
646
|
+
end
|
647
|
+
|
648
|
+
alias_chained_method :insert, :query_dirty, :pg_insert
|
649
|
+
alias_chained_method :columns, :query_cache, :pg_columns
|
650
|
+
end
|
651
|
+
end
|
@@ -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_class] = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
|
13
14
|
config[:adapter_spec] = ::ArJdbc::PostgreSQL
|
14
15
|
conn = jdbc_connection(config)
|
15
16
|
conn.execute("SET SEARCH_PATH TO #{config[:schema_search_path]}") if config[:schema_search_path]
|
@@ -120,7 +120,7 @@ module ::ArJdbc
|
|
120
120
|
end
|
121
121
|
|
122
122
|
def quote_column_name(name) #:nodoc:
|
123
|
-
%Q("#{name}")
|
123
|
+
%Q("#{name.to_s.gsub('"', '""')}")
|
124
124
|
end
|
125
125
|
|
126
126
|
def quote_string(str)
|
@@ -152,7 +152,7 @@ module ::ArJdbc
|
|
152
152
|
end
|
153
153
|
|
154
154
|
def last_insert_id
|
155
|
-
|
155
|
+
@connection.last_insert_row_id
|
156
156
|
end
|
157
157
|
|
158
158
|
def tables(name = nil) #:nodoc:
|
data/lib/arjdbc/version.rb
CHANGED
data/rakelib/compile.rake
CHANGED
@@ -1,25 +1,23 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
rescue => e
|
7
|
-
end
|
8
|
-
unless jruby_cpath
|
9
|
-
jruby_cpath = ENV['JRUBY_PARENT_CLASSPATH'] || ENV['JRUBY_HOME'] &&
|
10
|
-
FileList["#{ENV['JRUBY_HOME']}/lib/*.jar"].join(File::PATH_SEPARATOR)
|
11
|
-
end
|
12
|
-
jruby_cpath ? "-cp \"#{jruby_cpath}\"" : ""
|
13
|
-
end
|
1
|
+
jar_file = File.join(*%w(lib arjdbc jdbc adapter_java.jar))
|
2
|
+
begin
|
3
|
+
require 'ant'
|
4
|
+
directory "pkg/classes"
|
5
|
+
CLEAN << "pkg"
|
14
6
|
|
15
|
-
|
7
|
+
file jar_file => FileList['src/java/**/*.java', 'pkg/classes'] do
|
8
|
+
rm_rf FileList['pkg/classes/**/*']
|
9
|
+
ant.javac :srcdir => "src/java", :destdir => "pkg/classes",
|
10
|
+
:source => "1.5", :target => "1.5", :debug => true,
|
11
|
+
:classpath => "${java.class.path}:${sun.boot.class.path}",
|
12
|
+
:includeantRuntime => false
|
16
13
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
14
|
+
ant.jar :basedir => "pkg/classes", :destfile => jar_file, :includes => "**/*.class"
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Compile the native Java code."
|
18
|
+
task :jar => jar_file
|
19
|
+
rescue LoadError
|
20
|
+
task :jar do
|
21
|
+
puts "Run 'jar' with JRuby to re-compile the agent extension class"
|
22
|
+
end
|
24
23
|
end
|
25
|
-
file jar_name => :java_compile
|