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.
- checksums.yaml +5 -5
- data/.gitignore +1 -2
- data/.travis.yml +15 -416
- data/Gemfile +35 -37
- data/README.md +23 -118
- data/RUNNING_TESTS.md +31 -26
- data/Rakefile +2 -3
- data/activerecord-jdbc-adapter.gemspec +1 -2
- data/lib/arjdbc/abstract/connection_management.rb +21 -0
- data/lib/arjdbc/abstract/core.rb +62 -0
- data/lib/arjdbc/abstract/database_statements.rb +46 -0
- data/lib/arjdbc/abstract/statement_cache.rb +58 -0
- data/lib/arjdbc/abstract/transaction_support.rb +86 -0
- data/lib/arjdbc/derby/adapter.rb +6 -1
- data/lib/arjdbc/discover.rb +0 -7
- data/lib/arjdbc/firebird/adapter.rb +2 -2
- data/lib/arjdbc/jdbc/adapter.rb +10 -252
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/connection.rb +6 -0
- data/lib/arjdbc/jdbc.rb +2 -2
- data/lib/arjdbc/mysql/adapter.rb +87 -944
- data/lib/arjdbc/mysql/connection_methods.rb +4 -2
- data/lib/arjdbc/postgresql/adapter.rb +288 -1023
- data/lib/arjdbc/postgresql/base/array_decoder.rb +26 -0
- data/lib/arjdbc/postgresql/base/array_encoder.rb +25 -0
- data/lib/arjdbc/postgresql/base/pgconn.rb +8 -5
- data/lib/arjdbc/postgresql/column.rb +10 -599
- data/lib/arjdbc/postgresql/connection_methods.rb +9 -0
- data/lib/arjdbc/postgresql/name.rb +24 -0
- data/lib/arjdbc/postgresql/oid_types.rb +25 -110
- data/lib/arjdbc/sqlite3/adapter.rb +171 -170
- data/lib/arjdbc/tasks/database_tasks.rb +1 -3
- data/lib/arjdbc/tasks/db2_database_tasks.rb +2 -2
- data/lib/arjdbc/version.rb +1 -1
- data/pom.xml +3 -3
- data/rakelib/02-test.rake +0 -12
- data/rakelib/compile.rake +1 -1
- data/rakelib/db.rake +7 -5
- data/rakelib/rails.rake +63 -64
- data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +1 -17
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +518 -1260
- data/src/java/arjdbc/mysql/MySQLModule.java +3 -3
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +53 -134
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +214 -240
- data/src/java/arjdbc/sqlite3/SQLite3Module.java +0 -20
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +85 -10
- metadata +20 -34
- data/Appraisals +0 -41
- data/lib/active_record/connection_adapters/oracle_adapter.rb +0 -1
- data/lib/arjdbc/common_jdbc_methods.rb +0 -89
- data/lib/arjdbc/mysql/bulk_change_table.rb +0 -150
- data/lib/arjdbc/mysql/column.rb +0 -162
- data/lib/arjdbc/mysql/explain_support.rb +0 -82
- data/lib/arjdbc/mysql/schema_creation.rb +0 -58
- data/lib/arjdbc/oracle/adapter.rb +0 -952
- data/lib/arjdbc/oracle/column.rb +0 -126
- data/lib/arjdbc/oracle/connection_methods.rb +0 -21
- data/lib/arjdbc/oracle.rb +0 -4
- data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +0 -21
- data/lib/arjdbc/postgresql/base/oid.rb +0 -412
- data/lib/arjdbc/postgresql/base/schema_definitions.rb +0 -131
- data/lib/arjdbc/postgresql/explain_support.rb +0 -53
- data/lib/arjdbc/postgresql/oid/bytea.rb +0 -2
- data/lib/arjdbc/postgresql/schema_creation.rb +0 -60
- data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +0 -297
- data/lib/arjdbc/tasks/oracle_database_tasks.rb +0 -65
- data/src/java/arjdbc/oracle/OracleModule.java +0 -75
- data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +0 -465
data/lib/arjdbc/mysql/column.rb
DELETED
@@ -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
|