activerecord-jdbc-adapter 5.0.pre1 → 51.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. 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/activerecord-jdbc-adapter.gemspec +1 -2
  9. data/lib/arjdbc/abstract/connection_management.rb +21 -0
  10. data/lib/arjdbc/abstract/core.rb +62 -0
  11. data/lib/arjdbc/abstract/database_statements.rb +46 -0
  12. data/lib/arjdbc/abstract/statement_cache.rb +58 -0
  13. data/lib/arjdbc/abstract/transaction_support.rb +86 -0
  14. data/lib/arjdbc/derby/adapter.rb +6 -1
  15. data/lib/arjdbc/discover.rb +0 -7
  16. data/lib/arjdbc/firebird/adapter.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/jdbc.rb +2 -2
  21. data/lib/arjdbc/mysql/adapter.rb +87 -944
  22. data/lib/arjdbc/mysql/connection_methods.rb +4 -2
  23. data/lib/arjdbc/postgresql/adapter.rb +288 -1023
  24. data/lib/arjdbc/postgresql/base/array_decoder.rb +26 -0
  25. data/lib/arjdbc/postgresql/base/array_encoder.rb +25 -0
  26. data/lib/arjdbc/postgresql/base/pgconn.rb +8 -5
  27. data/lib/arjdbc/postgresql/column.rb +10 -599
  28. data/lib/arjdbc/postgresql/connection_methods.rb +9 -0
  29. data/lib/arjdbc/postgresql/name.rb +24 -0
  30. data/lib/arjdbc/postgresql/oid_types.rb +25 -110
  31. data/lib/arjdbc/sqlite3/adapter.rb +171 -170
  32. data/lib/arjdbc/tasks/database_tasks.rb +1 -3
  33. data/lib/arjdbc/tasks/db2_database_tasks.rb +2 -2
  34. data/lib/arjdbc/version.rb +1 -1
  35. data/pom.xml +3 -3
  36. data/rakelib/02-test.rake +0 -12
  37. data/rakelib/compile.rake +1 -1
  38. data/rakelib/db.rake +7 -5
  39. data/rakelib/rails.rake +63 -64
  40. data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +1 -17
  41. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +518 -1260
  42. data/src/java/arjdbc/mysql/MySQLModule.java +3 -3
  43. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +53 -134
  44. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +214 -240
  45. data/src/java/arjdbc/sqlite3/SQLite3Module.java +0 -20
  46. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +85 -10
  47. metadata +20 -34
  48. data/Appraisals +0 -41
  49. data/lib/active_record/connection_adapters/oracle_adapter.rb +0 -1
  50. data/lib/arjdbc/common_jdbc_methods.rb +0 -89
  51. data/lib/arjdbc/mysql/bulk_change_table.rb +0 -150
  52. data/lib/arjdbc/mysql/column.rb +0 -162
  53. data/lib/arjdbc/mysql/explain_support.rb +0 -82
  54. data/lib/arjdbc/mysql/schema_creation.rb +0 -58
  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/oracle.rb +0 -4
  59. data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +0 -21
  60. data/lib/arjdbc/postgresql/base/oid.rb +0 -412
  61. data/lib/arjdbc/postgresql/base/schema_definitions.rb +0 -131
  62. data/lib/arjdbc/postgresql/explain_support.rb +0 -53
  63. data/lib/arjdbc/postgresql/oid/bytea.rb +0 -2
  64. data/lib/arjdbc/postgresql/schema_creation.rb +0 -60
  65. data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +0 -297
  66. data/lib/arjdbc/tasks/oracle_database_tasks.rb +0 -65
  67. data/src/java/arjdbc/oracle/OracleModule.java +0 -75
  68. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +0 -465
@@ -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