activerecord-jdbc-adapter 5.0.pre1 → 51.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|