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.
@@ -0,0 +1,5 @@
1
+ rvm:
2
+ - jruby
3
+ branches:
4
+ only:
5
+ - master
@@ -24,7 +24,7 @@ GEM
24
24
  mocha (0.9.8)
25
25
  rake
26
26
  multi_json (1.0.3)
27
- rake (0.9.2)
27
+ rake (0.9.2.2)
28
28
  ruby-debug (0.10.4)
29
29
  columnize (>= 0.1)
30
30
  ruby-debug-base (~> 0.10.4.0)
@@ -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 => [:java_compile, :test]
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 => :java_compile
13
- task :install => :java_compile
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 "Build all adapters"
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 "Release all adapters"
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
@@ -40,7 +40,6 @@ module ::ArJdbc
40
40
  case field_type
41
41
  when /smallint/i then :boolean
42
42
  when /real/i then :float
43
- when /decimal/i then :decimal
44
43
  else
45
44
  super
46
45
  end
@@ -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
@@ -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'] == '2'}],
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'] == '-7'},
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}]
@@ -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::Column)}]
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 Column
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 /decimal/i then :decimal
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
- "1"
140
+ "1"
136
141
  end
137
142
 
138
143
  def quoted_false
139
- "0"
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::MysqlColumn.new(field["Field"], field["Default"], field["Type"], field["Null"] == "YES")
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
- row = res.detect {|row| row["Variable_name"] == var }
312
- row && row["Value"]
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::MysqlColumn
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
- execute sql.gsub('?') { quote(*binds.shift.reverse) }, name
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
- Integer(select_value("SELECT last_insert_rowid()"))
155
+ @connection.last_insert_row_id
156
156
  end
157
157
 
158
158
  def tables(name = nil) #:nodoc:
@@ -1,6 +1,6 @@
1
1
  module ArJdbc
2
2
  module Version
3
- VERSION = "1.2.0"
3
+ VERSION = "1.2.1"
4
4
  end
5
5
  end
6
6
  # Compatibility with older versions of ar-jdbc for other extensions out there
@@ -0,0 +1,11 @@
1
+ module Bundler
2
+ class GemHelper
3
+ def guard_already_tagged
4
+ # parent project performs the tag
5
+ end
6
+ def tag_version
7
+ Bundler.ui.confirm "Parent project tagged #{version_tag}"
8
+ yield if block_given?
9
+ end
10
+ end
11
+ end
@@ -1,25 +1,23 @@
1
- def java_classpath_arg # myriad of ways to discover JRuby classpath
2
- begin
3
- cpath = Java::java.lang.System.getProperty('java.class.path').split(File::PATH_SEPARATOR)
4
- cpath += Java::java.lang.System.getProperty('sun.boot.class.path').split(File::PATH_SEPARATOR)
5
- jruby_cpath = cpath.compact.join(File::PATH_SEPARATOR)
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
- jar_name = File.join(*%w(lib arjdbc jdbc adapter_java.jar))
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
- desc "Compile the native Java code."
18
- task :java_compile do
19
- debug = ENV['DEBUG'] ? '-g' : ''
20
- pkg_classes = File.join(*%w(pkg classes))
21
- mkdir_p pkg_classes
22
- sh "javac -target 1.5 -source 1.5 #{debug} -d pkg/classes #{java_classpath_arg} #{FileList['src/java/**/*.java'].join(' ')}"
23
- sh "jar cf #{jar_name} -C #{pkg_classes} ."
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