activerecord-jdbc-adapter 5.0.pre1 → 50.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.

Potentially problematic release.


This version of activerecord-jdbc-adapter might be problematic. Click here for more details.

Files changed (66) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -2
  3. data/.travis.yml +15 -416
  4. data/Gemfile +35 -37
  5. data/README.md +23 -118
  6. data/RUNNING_TESTS.md +31 -26
  7. data/Rakefile +2 -3
  8. data/lib/arjdbc/abstract/connection_management.rb +21 -0
  9. data/lib/arjdbc/abstract/core.rb +62 -0
  10. data/lib/arjdbc/abstract/database_statements.rb +46 -0
  11. data/lib/arjdbc/abstract/statement_cache.rb +58 -0
  12. data/lib/arjdbc/abstract/transaction_support.rb +86 -0
  13. data/lib/arjdbc/derby/adapter.rb +6 -1
  14. data/lib/arjdbc/discover.rb +0 -7
  15. data/lib/arjdbc/firebird/adapter.rb +2 -2
  16. data/lib/arjdbc/jdbc.rb +2 -2
  17. data/lib/arjdbc/jdbc/adapter.rb +10 -252
  18. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  19. data/lib/arjdbc/jdbc/connection.rb +6 -0
  20. data/lib/arjdbc/mysql/adapter.rb +82 -946
  21. data/lib/arjdbc/mysql/connection_methods.rb +4 -2
  22. data/lib/arjdbc/postgresql/adapter.rb +270 -970
  23. data/lib/arjdbc/postgresql/base/array_decoder.rb +26 -0
  24. data/lib/arjdbc/postgresql/base/array_encoder.rb +25 -0
  25. data/lib/arjdbc/postgresql/base/pgconn.rb +8 -5
  26. data/lib/arjdbc/postgresql/column.rb +10 -599
  27. data/lib/arjdbc/postgresql/connection_methods.rb +9 -0
  28. data/lib/arjdbc/postgresql/name.rb +24 -0
  29. data/lib/arjdbc/postgresql/oid_types.rb +28 -109
  30. data/lib/arjdbc/sqlite3/adapter.rb +18 -42
  31. data/lib/arjdbc/tasks/database_tasks.rb +1 -3
  32. data/lib/arjdbc/tasks/db2_database_tasks.rb +2 -2
  33. data/lib/arjdbc/version.rb +1 -1
  34. data/pom.xml +3 -3
  35. data/rakelib/02-test.rake +0 -12
  36. data/rakelib/compile.rake +1 -1
  37. data/rakelib/db.rake +7 -5
  38. data/rakelib/rails.rake +67 -64
  39. data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +1 -17
  40. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +518 -1260
  41. data/src/java/arjdbc/mysql/MySQLModule.java +3 -3
  42. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +53 -134
  43. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +214 -240
  44. data/src/java/arjdbc/sqlite3/SQLite3Module.java +0 -20
  45. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +85 -10
  46. metadata +16 -29
  47. data/Appraisals +0 -41
  48. data/lib/active_record/connection_adapters/oracle_adapter.rb +0 -1
  49. data/lib/arjdbc/common_jdbc_methods.rb +0 -89
  50. data/lib/arjdbc/mysql/bulk_change_table.rb +0 -150
  51. data/lib/arjdbc/mysql/column.rb +0 -162
  52. data/lib/arjdbc/mysql/explain_support.rb +0 -82
  53. data/lib/arjdbc/mysql/schema_creation.rb +0 -58
  54. data/lib/arjdbc/oracle.rb +0 -4
  55. data/lib/arjdbc/oracle/adapter.rb +0 -952
  56. data/lib/arjdbc/oracle/column.rb +0 -126
  57. data/lib/arjdbc/oracle/connection_methods.rb +0 -21
  58. data/lib/arjdbc/postgresql/base/oid.rb +0 -412
  59. data/lib/arjdbc/postgresql/base/schema_definitions.rb +0 -131
  60. data/lib/arjdbc/postgresql/explain_support.rb +0 -53
  61. data/lib/arjdbc/postgresql/oid/bytea.rb +0 -2
  62. data/lib/arjdbc/postgresql/schema_creation.rb +0 -60
  63. data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +0 -297
  64. data/lib/arjdbc/tasks/oracle_database_tasks.rb +0 -65
  65. data/src/java/arjdbc/oracle/OracleModule.java +0 -75
  66. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +0 -465
@@ -1,150 +0,0 @@
1
- module ArJdbc
2
- module MySQL
3
- module BulkChangeTable
4
-
5
- # @private
6
- AR41 = ::ActiveRecord::VERSION::STRING >= '4.1'
7
-
8
- # @private
9
- #ActiveRecordError = ActiveRecord::ActiveRecordError
10
-
11
- # @private
12
- ChangeColumnDefinition = ::ActiveRecord::ConnectionAdapters::ChangeColumnDefinition if AR41
13
-
14
- # @override
15
- def supports_bulk_alter?; true end
16
-
17
- def bulk_change_table(table_name, operations)
18
- sqls = operations.map do |command, args|
19
- table, arguments = args.shift, args
20
- method = :"#{command}_sql"
21
-
22
- if respond_to?(method, true)
23
- send(method, table, *arguments)
24
- else
25
- raise "Unknown method called : #{method}(#{arguments.inspect})"
26
- end
27
- end
28
- sqls.flatten!
29
-
30
- execute("ALTER TABLE #{quote_table_name(table_name)} #{sqls.join(", ")}")
31
- end
32
-
33
- protected
34
-
35
- def add_column_sql(table_name, column_name, type, options = {})
36
- add_column_sql = "ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
37
- add_column_options!(add_column_sql, options)
38
- add_column_position!(add_column_sql, options)
39
- add_column_sql
40
- end unless AR41
41
-
42
- def add_column_sql(table_name, column_name, type, options = {})
43
- td = create_table_definition table_name, options[:temporary], options[:options]
44
- cd = td.new_column_definition(column_name, type, options)
45
- schema_creation.visit_AddColumn cd
46
- end if AR41
47
-
48
- def change_column_sql(table_name, column_name, type, options = {})
49
- column = column_for(table_name, column_name)
50
-
51
- unless options_include_default?(options)
52
- options[:default] = column.default
53
- end
54
-
55
- unless options.has_key?(:null)
56
- options[:null] = column.null
57
- end
58
-
59
- change_column_sql = "CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
60
- add_column_options!(change_column_sql, options)
61
- add_column_position!(change_column_sql, options)
62
- change_column_sql
63
- end unless AR41
64
-
65
- def change_column_sql(table_name, column_name, type, options = {})
66
- column = column_for(table_name, column_name)
67
-
68
- unless options_include_default?(options)
69
- options[:default] = column.default
70
- end
71
-
72
- unless options.has_key?(:null)
73
- options[:null] = column.null
74
- end
75
-
76
- options[:name] = column.name
77
- schema_creation.accept ChangeColumnDefinition.new column, type, options
78
- end if AR41
79
-
80
- def rename_column_sql(table_name, column_name, new_column_name)
81
- options = {}
82
-
83
- if column = columns(table_name).find { |c| c.name == column_name.to_s }
84
- options[:default] = column.default
85
- options[:null] = column.null
86
- options[:auto_increment] = (column.extra == "auto_increment")
87
- else
88
- raise ActiveRecordError, "No such column: #{table_name}.#{column_name}"
89
- end
90
-
91
- current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'", 'SCHEMA')["Type"]
92
- rename_column_sql = "CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{current_type}"
93
- add_column_options!(rename_column_sql, options)
94
- rename_column_sql
95
- end unless AR41
96
-
97
- def rename_column_sql(table_name, column_name, new_column_name)
98
- options = { :name => new_column_name }
99
-
100
- if column = columns(table_name).find { |c| c.name == column_name.to_s }
101
- options[:default] = column.default
102
- options[:null] = column.null
103
- options[:auto_increment] = (column.extra == "auto_increment")
104
- else
105
- raise ActiveRecordError, "No such column: #{table_name}.#{column_name}"
106
- end
107
-
108
- current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'", 'SCHEMA')["Type"]
109
- schema_creation.accept ChangeColumnDefinition.new column, current_type, options
110
- end if AR41
111
-
112
- def remove_column_sql(table_name, column_name, type = nil, options = nil)
113
- "DROP #{quote_column_name(column_name)}"
114
- end
115
-
116
- def remove_columns_sql(table_name, *column_names)
117
- column_names.map { |column_name| remove_column_sql(table_name, column_name) }
118
- end
119
-
120
- def add_index_sql(table_name, column_name, options = {})
121
- index_name, index_type, index_columns = add_index_options(table_name, column_name, options)
122
- "ADD #{index_type} INDEX #{index_name} (#{index_columns})"
123
- end
124
-
125
- def remove_index_sql(table_name, options = {})
126
- index_name = index_name_for_remove(table_name, options)
127
- "DROP INDEX #{index_name}"
128
- end
129
-
130
- def add_timestamps_sql(table_name, options = {})
131
- [add_column_sql(table_name, :created_at, :datetime, options), add_column_sql(table_name, :updated_at, :datetime, options)]
132
- end
133
-
134
- def remove_timestamps_sql(table_name, options = nil)
135
- [remove_column_sql(table_name, :updated_at), remove_column_sql(table_name, :created_at)]
136
- end
137
-
138
- private
139
-
140
- def add_column_position!(sql, options)
141
- if options[:first]
142
- sql << " FIRST"
143
- elsif options[:after]
144
- sql << " AFTER #{quote_column_name(options[:after])}"
145
- end
146
- end
147
-
148
- end
149
- end
150
- end
@@ -1,162 +0,0 @@
1
- module ArJdbc
2
- module MySQL
3
-
4
- # @see ActiveRecord::ConnectionAdapters::JdbcColumn#column_types
5
- def self.column_selector
6
- [ /mysql/i, lambda { |config, column| column.extend(Column) } ]
7
- end
8
-
9
- # Column behavior based on (abstract) MySQL adapter in Rails.
10
- # @see ActiveRecord::ConnectionAdapters::JdbcColumn
11
- module Column
12
-
13
- attr_reader :collation, :strict, :extra
14
-
15
- def initialize(name, default, sql_type = nil, null = true, collation = nil, strict = false, extra = '')
16
- if name.is_a?(Hash)
17
- super # first arg: config
18
- else
19
- @strict = strict; @collation = collation; @extra = extra
20
- super(name, default, sql_type, null)
21
- # base 4.1: (name, default, sql_type = nil, null = true)
22
- end
23
- end unless AR42
24
-
25
- def initialize(name, default, cast_type, sql_type = nil, null = true, collation = nil, strict = false, extra = '')
26
- if name.is_a?(Hash)
27
- super # first arg: config
28
- else
29
- @strict = strict; @collation = collation; @extra = extra
30
- super(name, default, cast_type, sql_type, null)
31
- # base 4.2: (name, default, cast_type, sql_type = nil, null = true)
32
- #assert_valid_default(default) done with #extract_default
33
- #@default = null || ( strict ? nil : '' ) if blob_or_text_column?
34
- end
35
- end if AR42
36
-
37
- def extract_default(default)
38
- if blob_or_text_column?
39
- return null || strict ? nil : '' if default.blank?
40
- raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}"
41
- elsif missing_default_forged_as_empty_string?(default)
42
- nil
43
- else
44
- super
45
- end
46
- end
47
-
48
- def has_default?
49
- return false if blob_or_text_column? #mysql forbids defaults on blob and text columns
50
- super
51
- end
52
-
53
- def blob_or_text_column?
54
- sql_type.index('blob') || type == :text
55
- end
56
-
57
- def case_sensitive?
58
- collation && !collation.match(/_ci$/)
59
- end
60
-
61
- def ==(other)
62
- collation == other.collation &&
63
- strict == other.strict &&
64
- extra == other.extra &&
65
- super
66
- end if AR42
67
-
68
- def simplified_type(field_type)
69
- if adapter && adapter.emulate_booleans?
70
- return :boolean if field_type.downcase.index('tinyint(1)')
71
- end
72
-
73
- case field_type
74
- when /enum/i, /set/i then :string
75
- when /year/i then :integer
76
- # :tinyint : {:name=>"tinyint", :limit=>3}
77
- # :"tinyint unsigned" : {:name=>"tinyint unsigned", :limit=>3}
78
- # :bigint : {:name=>"bigint", :limit=>19}
79
- # :"bigint unsigned" : {:name=>"bigint unsigned", :limit=>20}
80
- # :integer : {:name=>"integer", :limit=>10}
81
- # :"integer unsigned" : {:name=>"integer unsigned", :limit=>10}
82
- # :int : {:name=>"int", :limit=>10}
83
- # :"int unsigned" : {:name=>"int unsigned", :limit=>10}
84
- # :mediumint : {:name=>"mediumint", :limit=>7}
85
- # :"mediumint unsigned" : {:name=>"mediumint unsigned", :limit=>8}
86
- # :smallint : {:name=>"smallint", :limit=>5}
87
- # :"smallint unsigned" : {:name=>"smallint unsigned", :limit=>5}
88
- when /int/i then :integer
89
- when /double/i then :float # double precision (alias)
90
- when 'bool' then :boolean
91
- when 'char' then :string
92
- # :mediumtext => {:name=>"mediumtext", :limit=>16777215}
93
- # :longtext => {:name=>"longtext", :limit=>2147483647}
94
- # :text => {:name=>"text"}
95
- # :tinytext => {:name=>"tinytext", :limit=>255}
96
- when /text/i then :text
97
- when 'long varchar' then :text
98
- # :"long varbinary" => {:name=>"long varbinary", :limit=>16777215}
99
- # :varbinary => {:name=>"varbinary", :limit=>255}
100
- when /binary/i then :binary
101
- # :mediumblob => {:name=>"mediumblob", :limit=>16777215}
102
- # :longblob => {:name=>"longblob", :limit=>2147483647}
103
- # :blob => {:name=>"blob", :limit=>65535}
104
- # :tinyblob => {:name=>"tinyblob", :limit=>255}
105
- when /blob/i then :binary
106
- when /^bit/i then :binary
107
- else
108
- super
109
- end
110
- end
111
-
112
- def extract_limit(sql_type)
113
- case sql_type
114
- when /blob|text/i
115
- case sql_type
116
- when /tiny/i
117
- 255
118
- when /medium/i
119
- 16777215
120
- when /long/i
121
- 2147483647 # mysql only allows 2^31-1, not 2^32-1, somewhat inconsistently with the tiny/medium/normal cases
122
- else
123
- super # we could return 65535 here, but we leave it undecorated by default
124
- end
125
- when /^bigint/i; 8
126
- when /^int/i; 4
127
- when /^mediumint/i; 3
128
- when /^smallint/i; 2
129
- when /^tinyint/i; 1
130
- when /^enum\((.+)\)/i # 255
131
- $1.split(',').map{ |enum| enum.strip.length - 2 }.max
132
- when /^(bool|date|float|int|time)/i
133
- nil
134
- else
135
- super
136
- end
137
- end unless AR42 # on AR 4.2 limit is delegated to cast_type.limit
138
-
139
- private
140
-
141
- # MySQL misreports NOT NULL column default when none is given.
142
- # We can't detect this for columns which may have a legitimate ''
143
- # default (string) but we can for others (integer, datetime, boolean,
144
- # and the rest).
145
- #
146
- # Test whether the column has default '', is not null, and is not
147
- # a type allowing default ''.
148
- def missing_default_forged_as_empty_string?(default)
149
- type != :string && ! null && default == ''
150
- end
151
-
152
- def attributes_for_hash; super + [collation, strict, extra] end
153
-
154
- def adapter; end
155
-
156
- end
157
-
158
- # @private backwards-compatibility
159
- ColumnExtensions = Column
160
-
161
- end
162
- end
@@ -1,82 +0,0 @@
1
- module ArJdbc
2
- module MySQL
3
- module ExplainSupport
4
- def supports_explain?
5
- true
6
- end
7
-
8
- def explain(arel, binds = [])
9
- sql = "EXPLAIN #{to_sql(arel, binds)}"
10
- start = Time.now.to_f
11
- result = exec_query(sql, "EXPLAIN", binds)
12
- elapsed = Time.now.to_f - start
13
- ExplainPrettyPrinter.new.pp result, elapsed
14
- end
15
-
16
- # @private
17
- class ExplainPrettyPrinter
18
- # Pretty prints the result of a EXPLAIN in a way that resembles the output of the
19
- # MySQL shell:
20
- #
21
- # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
22
- # | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
23
- # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
24
- # | 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | |
25
- # | 1 | SIMPLE | posts | ALL | NULL | NULL | NULL | NULL | 1 | Using where |
26
- # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
27
- # 2 rows in set (0.00 sec)
28
- #
29
- # This is an exercise in Ruby hyperrealism :).
30
- def pp(result, elapsed)
31
- widths = compute_column_widths(result)
32
- separator = build_separator(widths)
33
-
34
- pp = []
35
-
36
- pp << separator
37
- pp << build_cells(result.columns, widths)
38
- pp << separator
39
-
40
- result.rows.each do |row|
41
- pp << build_cells(row, widths)
42
- end
43
-
44
- pp << separator
45
- pp << build_footer(result.rows.length, elapsed)
46
-
47
- pp.join(sep = "\n") << sep
48
- end
49
-
50
- private
51
-
52
- def compute_column_widths(result)
53
- [].tap do |widths|
54
- result.columns.each_with_index do |column, i|
55
- cells_in_column = [column] + result.rows.map {|r| r[i].nil? ? 'NULL' : r[i].to_s}
56
- widths << cells_in_column.map(&:length).max
57
- end
58
- end
59
- end
60
-
61
- def build_separator(widths)
62
- padding = 1; "+#{widths.map { |w| '-' * (w + (padding * 2 )) }.join('+')}+"
63
- end
64
-
65
- def build_cells(items, widths)
66
- cells = []
67
- items.each_with_index do |item, i|
68
- item = 'NULL' if item.nil?
69
- justifier = item.is_a?(Numeric) ? 'rjust' : 'ljust'
70
- cells << item.to_s.send(justifier, widths[i])
71
- end
72
- "|#{cells.join(' | ')}|"
73
- end
74
-
75
- def build_footer(nrows, elapsed)
76
- rows_label = nrows == 1 ? 'row' : 'rows'
77
- "#{nrows} #{rows_label} in set (%.2f sec)" % elapsed
78
- end
79
- end
80
- end
81
- end
82
- end
@@ -1,58 +0,0 @@
1
- module ArJdbc
2
- module MySQL
3
- # @private copied from native adapter 4.0/4.1
4
- class SchemaCreation < ::ActiveRecord::ConnectionAdapters::AbstractAdapter::SchemaCreation
5
-
6
- def visit_AddColumn(o)
7
- add_column_position!(super, column_options(o))
8
- end
9
-
10
- private
11
-
12
- def visit_DropForeignKey(name)
13
- "DROP FOREIGN KEY #{name}"
14
- end
15
-
16
- def visit_TableDefinition(o)
17
- name = o.name
18
- create_sql = "CREATE#{' TEMPORARY' if o.temporary} TABLE #{quote_table_name(name)} "
19
-
20
- statements = o.columns.map { |c| accept c }
21
- statements.concat(o.indexes.map { |column_name, options| index_in_create(name, column_name, options) })
22
-
23
- create_sql << "(#{statements.join(', ')}) " if statements.present?
24
- create_sql << "#{o.options}"
25
- create_sql << " AS #{@conn.to_sql(o.as)}" if o.as
26
- create_sql
27
- end if AR42
28
-
29
- def visit_ChangeColumnDefinition(o)
30
- column = o.column
31
- options = o.options
32
- sql_type = type_to_sql(o.type, options[:limit], options[:precision], options[:scale])
33
- change_column_sql = "CHANGE #{quote_column_name(column.name)} #{quote_column_name(options[:name])} #{sql_type}"
34
- add_column_options!(change_column_sql, options.merge(:column => column))
35
- add_column_position!(change_column_sql, options)
36
- end
37
-
38
- def add_column_position!(sql, options)
39
- if options[:first]
40
- sql << " FIRST"
41
- elsif options[:after]
42
- sql << " AFTER #{quote_column_name(options[:after])}"
43
- end
44
- sql
45
- end
46
-
47
- def index_in_create(table_name, column_name, options)
48
- index_name, index_type, index_columns, index_options, index_algorithm, index_using = @conn.add_index_options(table_name, column_name, options)
49
- "#{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})#{index_options} #{index_algorithm}"
50
- end
51
- end
52
- end
53
-
54
- def schema_creation
55
- SchemaCreation.new self
56
- end
57
-
58
- end if ::ActiveRecord::ConnectionAdapters::AbstractAdapter.const_defined? :SchemaCreation