activerecord-jdbc-alt-adapter 51.7.0-java → 52.2.0-java
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 +4 -4
- data/.gitignore +0 -3
- data/.travis.yml +24 -28
- data/Gemfile +2 -3
- data/README.md +27 -19
- data/Rakefile +4 -30
- data/activerecord-jdbc-adapter.gemspec +2 -2
- data/activerecord-jdbc-alt-adapter.gemspec +4 -4
- data/lib/arel/visitors/sqlserver.rb +2 -1
- data/lib/arjdbc/abstract/core.rb +12 -2
- data/lib/arjdbc/abstract/database_statements.rb +22 -8
- data/lib/arjdbc/abstract/statement_cache.rb +1 -0
- data/lib/arjdbc/db2/adapter.rb +77 -8
- data/lib/arjdbc/db2/as400.rb +12 -0
- data/lib/arjdbc/db2/column.rb +3 -0
- data/lib/arjdbc/db2/connection_methods.rb +4 -0
- data/lib/arjdbc/jdbc/adapter.rb +4 -6
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/column.rb +14 -6
- data/lib/arjdbc/jdbc.rb +7 -0
- data/lib/arjdbc/mssql/adapter.rb +20 -32
- data/lib/arjdbc/mssql/connection_methods.rb +1 -5
- data/lib/arjdbc/mssql/database_limits.rb +29 -0
- data/lib/arjdbc/mssql/database_statements.rb +41 -1
- data/lib/arjdbc/mssql/explain_support.rb +6 -1
- data/lib/arjdbc/mssql/quoting.rb +9 -2
- data/lib/arjdbc/mssql/schema_creation.rb +2 -1
- data/lib/arjdbc/mssql/schema_dumper.rb +1 -1
- data/lib/arjdbc/mssql/schema_statements.rb +11 -3
- data/lib/arjdbc/mssql/transaction.rb +3 -3
- data/lib/arjdbc/mssql.rb +1 -1
- data/lib/arjdbc/mysql/adapter.rb +20 -4
- data/lib/arjdbc/mysql/connection_methods.rb +7 -13
- data/lib/arjdbc/postgresql/adapter.rb +23 -20
- data/lib/arjdbc/postgresql/column.rb +3 -6
- data/lib/arjdbc/postgresql/connection_methods.rb +1 -3
- data/lib/arjdbc/postgresql/oid_types.rb +6 -11
- data/lib/arjdbc/sqlite3/adapter.rb +86 -91
- data/lib/arjdbc/sqlite3/connection_methods.rb +0 -1
- data/lib/arjdbc/tasks/database_tasks.rb +1 -0
- data/lib/arjdbc/tasks/sqlite_database_tasks_patch.rb +17 -0
- data/lib/arjdbc/version.rb +1 -1
- data/rakelib/01-tomcat.rake +2 -2
- data/rakelib/02-test.rake +2 -0
- data/rakelib/rails.rake +1 -1
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +10 -65
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +38 -282
- data/src/java/arjdbc/postgresql/PostgreSQLResult.java +69 -4
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +69 -13
- data/src/java/arjdbc/util/DateTimeUtils.java +17 -28
- data/src/java/arjdbc/util/PG.java +8 -0
- metadata +15 -12
- data/lib/activerecord-jdbc-alt-adapter.rb +0 -1
data/lib/arjdbc/jdbc/column.rb
CHANGED
@@ -26,12 +26,20 @@ module ActiveRecord
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
if ArJdbc::AR52
|
30
|
+
# undefined method `cast' for #<ActiveRecord::ConnectionAdapters::SqlTypeMetadata> on AR52
|
31
|
+
elsif ArJdbc::AR50
|
32
|
+
default = args[0].cast(default)
|
33
|
+
|
34
|
+
sql_type = args.delete_at(1)
|
35
|
+
type = args.delete_at(0)
|
36
|
+
|
37
|
+
args.unshift(SqlTypeMetadata.new(:sql_type => sql_type, :type => type))
|
38
|
+
elsif ArJdbc::AR42
|
39
|
+
default = args[0].type_cast_from_database(default)
|
40
|
+
else
|
41
|
+
default = default_value(default)
|
42
|
+
end
|
35
43
|
|
36
44
|
# super <= 4.1: (name, default, sql_type = nil, null = true)
|
37
45
|
# super >= 4.2: (name, default, cast_type, sql_type = nil, null = true)
|
data/lib/arjdbc/jdbc.rb
CHANGED
@@ -2,8 +2,15 @@ require 'active_support/deprecation'
|
|
2
2
|
|
3
3
|
module ArJdbc
|
4
4
|
|
5
|
+
# @private
|
6
|
+
AR40 = ::ActiveRecord::VERSION::MAJOR > 3
|
5
7
|
# @private
|
6
8
|
AR42 = ::ActiveRecord::VERSION::STRING >= '4.2'
|
9
|
+
# @private
|
10
|
+
AR50 = ::ActiveRecord::VERSION::MAJOR > 4
|
11
|
+
|
12
|
+
# @private
|
13
|
+
AR52 = ::ActiveRecord::VERSION::STRING >= '5.2'
|
7
14
|
|
8
15
|
class << self
|
9
16
|
|
data/lib/arjdbc/mssql/adapter.rb
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
ArJdbc.load_java_part :MSSQL
|
4
4
|
|
5
5
|
require 'arel'
|
6
|
-
require 'arel/visitors/bind_visitor'
|
7
6
|
require 'arel/visitors/sqlserver'
|
8
7
|
require 'active_record/connection_adapters/abstract_adapter'
|
9
8
|
|
@@ -27,6 +26,7 @@ require 'arjdbc/mssql/explain_support'
|
|
27
26
|
require 'arjdbc/mssql/transaction'
|
28
27
|
require 'arjdbc/mssql/errors'
|
29
28
|
require 'arjdbc/mssql/schema_creation'
|
29
|
+
require 'arjdbc/mssql/database_limits'
|
30
30
|
|
31
31
|
module ActiveRecord
|
32
32
|
module ConnectionAdapters
|
@@ -54,9 +54,9 @@ module ActiveRecord
|
|
54
54
|
|
55
55
|
include MSSQL::Quoting
|
56
56
|
include MSSQL::SchemaStatements
|
57
|
-
include MSSQL::ColumnDumper
|
58
57
|
include MSSQL::DatabaseStatements
|
59
58
|
include MSSQL::ExplainSupport
|
59
|
+
include MSSQL::DatabaseLimits
|
60
60
|
|
61
61
|
@cs_equality_operator = 'COLLATE Latin1_General_CS_AS_WS'
|
62
62
|
|
@@ -85,12 +85,6 @@ module ActiveRecord
|
|
85
85
|
::ActiveRecord::ConnectionAdapters::MSSQLColumn
|
86
86
|
end
|
87
87
|
|
88
|
-
# Does this adapter support DDL rollbacks in transactions? That is, would
|
89
|
-
# CREATE TABLE or ALTER TABLE get rolled back by a transaction?
|
90
|
-
def supports_ddl_transactions?
|
91
|
-
true
|
92
|
-
end
|
93
|
-
|
94
88
|
# Does this adapter support creating foreign key constraints?
|
95
89
|
def supports_foreign_keys?
|
96
90
|
true
|
@@ -106,16 +100,6 @@ module ActiveRecord
|
|
106
100
|
true
|
107
101
|
end
|
108
102
|
|
109
|
-
# Does this adapter support index sort order?
|
110
|
-
def supports_index_sort_order?
|
111
|
-
true
|
112
|
-
end
|
113
|
-
|
114
|
-
# Also known as filtered index
|
115
|
-
def supports_partial_index?
|
116
|
-
true
|
117
|
-
end
|
118
|
-
|
119
103
|
# Does this adapter support views?
|
120
104
|
def supports_views?
|
121
105
|
true
|
@@ -132,13 +116,6 @@ module ActiveRecord
|
|
132
116
|
super
|
133
117
|
end
|
134
118
|
|
135
|
-
def reset!
|
136
|
-
# execute 'IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION'
|
137
|
-
# NOTE: it seems the above line interferes with the jdbc driver
|
138
|
-
# and ending up in connection closed, issue seen in rails 5.2 and 6.0
|
139
|
-
reconnect!
|
140
|
-
end
|
141
|
-
|
142
119
|
def disable_referential_integrity
|
143
120
|
tables = tables_with_referential_integrity
|
144
121
|
|
@@ -213,23 +190,31 @@ module ActiveRecord
|
|
213
190
|
# get the collation per column basis. At the moment we only use
|
214
191
|
# the global database collation
|
215
192
|
def case_sensitive_comparison(table, attribute, column, value)
|
216
|
-
if
|
217
|
-
table[attribute].eq(value)
|
218
|
-
elsif [:string, :text].include?(column.type) && collation && !collation.match(/_CS/)
|
219
|
-
table[attribute].eq(Arel::Nodes::Bin.new(Arel::Nodes::BindParam.new))
|
193
|
+
if [:string, :text].include?(column.type) && collation && !collation.match(/_CS/)
|
194
|
+
table[attribute].eq(Arel::Nodes::Bin.new(value))
|
220
195
|
# elsif value.acts_like?(:string)
|
221
196
|
# table[attribute].eq(Arel::Nodes::Bin.new(Arel::Nodes::BindParam.new))
|
222
197
|
else
|
223
|
-
|
198
|
+
super
|
224
199
|
end
|
225
200
|
end
|
226
201
|
|
227
202
|
def configure_connection
|
228
|
-
|
203
|
+
execute("SET LOCK_TIMEOUT #{lock_timeout}")
|
229
204
|
|
230
205
|
set_session_transaction_isolation
|
231
206
|
end
|
232
207
|
|
208
|
+
def lock_timeout
|
209
|
+
timeout = config[:lock_timeout].to_i
|
210
|
+
|
211
|
+
if timeout.positive?
|
212
|
+
timeout
|
213
|
+
else
|
214
|
+
5_000
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
233
218
|
def set_session_transaction_isolation
|
234
219
|
isolation_level = config[:transaction_isolation]
|
235
220
|
|
@@ -290,7 +275,7 @@ module ActiveRecord
|
|
290
275
|
# This method is called indirectly by the abstract method
|
291
276
|
# 'fetch_type_metadata' which then it is called by the java part when
|
292
277
|
# calculating a table's columns.
|
293
|
-
def initialize_type_map(map)
|
278
|
+
def initialize_type_map(map = type_map)
|
294
279
|
# Build the type mapping from SQL Server to ActiveRecord
|
295
280
|
|
296
281
|
# Integer types.
|
@@ -359,6 +344,9 @@ module ActiveRecord
|
|
359
344
|
register_class_with_precision map, %r{\Adatetime2\(\d+\)}i, MSSQL::Type::DateTime2
|
360
345
|
map.register_type 'datetime2(7)', MSSQL::Type::DateTime2.new
|
361
346
|
|
347
|
+
# TODO: we should have identity separated from the sql_type
|
348
|
+
# let's say in another attribute (this will help to pass more AR tests),
|
349
|
+
# also we add collation attribute per column.
|
362
350
|
# aliases
|
363
351
|
map.alias_type 'int identity', 'int'
|
364
352
|
map.alias_type 'bigint identity', 'bigint'
|
@@ -52,8 +52,6 @@ ArJdbc::ConnectionMethods.module_eval do
|
|
52
52
|
|
53
53
|
# @note Assumes SQLServer SQL-JDBC driver on the class-path.
|
54
54
|
def sqlserver_connection(config)
|
55
|
-
config = config.deep_dup
|
56
|
-
|
57
55
|
config[:adapter_spec] ||= ::ArJdbc::MSSQL
|
58
56
|
config[:adapter_class] = ActiveRecord::ConnectionAdapters::MSSQLAdapter unless config.key?(:adapter_class)
|
59
57
|
|
@@ -62,15 +60,13 @@ ArJdbc::ConnectionMethods.module_eval do
|
|
62
60
|
config[:host] ||= 'localhost'
|
63
61
|
config[:driver] ||= 'com.microsoft.sqlserver.jdbc.SQLServerDriver'
|
64
62
|
config[:connection_alive_sql] ||= 'SELECT 1'
|
65
|
-
config[:lock_timeout] ||= 5000
|
66
63
|
|
67
64
|
config[:url] ||= begin
|
68
65
|
url = "jdbc:sqlserver://#{config[:host]}"
|
69
66
|
url << ( config[:port] ? ":#{config[:port]};" : ';' )
|
70
67
|
url << "databaseName=#{config[:database]};" if config[:database]
|
71
68
|
url << "instanceName=#{config[:instance]};" if config[:instance]
|
72
|
-
url << "
|
73
|
-
url << "lockTimeout=#{config[:lock_timeout].to_i};"
|
69
|
+
url << "sendTimeAsDatetime=#{config[:send_time_as_datetime] || false};"
|
74
70
|
app = config[:appname] || config[:application]
|
75
71
|
url << "applicationName=#{app};" if app
|
76
72
|
isc = config[:integrated_security] # Win only - needs sqljdbc_auth.dll
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
module MSSQL
|
4
|
+
module DatabaseLimits
|
5
|
+
|
6
|
+
# Returns the maximum number of elements in an IN (x,y,z) clause.
|
7
|
+
# NOTE: Could not find a limit for IN in mssql but 10000 seems to work
|
8
|
+
# with the active record tests
|
9
|
+
def in_clause_length
|
10
|
+
10_000
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
# the max bind params is 2100 but it seems
|
16
|
+
# the jdbc uses 2 for something
|
17
|
+
def bind_params_length
|
18
|
+
2_098
|
19
|
+
end
|
20
|
+
|
21
|
+
# max number of insert rows in mssql
|
22
|
+
def insert_rows_length
|
23
|
+
1_000
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -71,8 +71,48 @@ module ActiveRecord
|
|
71
71
|
@connection.get_transaction_isolation
|
72
72
|
end
|
73
73
|
|
74
|
+
def insert_fixtures_set(fixture_set, tables_to_delete = [])
|
75
|
+
fixture_inserts = []
|
76
|
+
|
77
|
+
fixture_set.each do |table_name, fixtures|
|
78
|
+
fixtures.each_slice(insert_rows_length) do |batch|
|
79
|
+
fixture_inserts << build_fixture_sql(batch, table_name)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
table_deletes = tables_to_delete.map do |table|
|
84
|
+
"DELETE FROM #{quote_table_name(table)}".dup
|
85
|
+
end
|
86
|
+
total_sql = Array.wrap(combine_multi_statements(table_deletes + fixture_inserts))
|
87
|
+
|
88
|
+
disable_referential_integrity do
|
89
|
+
transaction(requires_new: true) do
|
90
|
+
total_sql.each do |sql|
|
91
|
+
execute sql, 'Fixtures Load'
|
92
|
+
yield if block_given?
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
74
98
|
private
|
75
99
|
|
100
|
+
# Overrides method in abstract class, combining the sqls with semicolon
|
101
|
+
# affects disable_referential_integrity in mssql specially when multiple
|
102
|
+
# tables are involved.
|
103
|
+
def combine_multi_statements(total_sql)
|
104
|
+
total_sql
|
105
|
+
end
|
106
|
+
|
107
|
+
def default_insert_value(column)
|
108
|
+
if column.identity?
|
109
|
+
table_name = quote(quote_table_name(column.table_name))
|
110
|
+
Arel.sql("IDENT_CURRENT(#{table_name}) + IDENT_INCR(#{table_name})")
|
111
|
+
else
|
112
|
+
super
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
76
116
|
def insert_sql?(sql)
|
77
117
|
!(sql =~ /^\s*(INSERT|EXEC sp_executesql N'INSERT)/i).nil?
|
78
118
|
end
|
@@ -87,7 +127,7 @@ module ActiveRecord
|
|
87
127
|
end
|
88
128
|
|
89
129
|
def identity_column_name(table_name)
|
90
|
-
for column in
|
130
|
+
for column in columns(table_name)
|
91
131
|
return column.name if column.identity?
|
92
132
|
end
|
93
133
|
nil
|
@@ -18,9 +18,14 @@ module ActiveRecord
|
|
18
18
|
def explain(arel, binds = [])
|
19
19
|
return if DISABLED
|
20
20
|
|
21
|
+
if arel.respond_to?(:to_sql)
|
22
|
+
raw_sql, raw_binds = to_sql_and_binds(arel, binds)
|
23
|
+
else
|
24
|
+
raw_sql, raw_binds = arel, binds
|
25
|
+
end
|
21
26
|
# sql = to_sql(arel, binds)
|
22
27
|
# result = with_showplan_on { exec_query(sql, 'EXPLAIN', binds) }
|
23
|
-
sql = interpolate_sql_statement(
|
28
|
+
sql = interpolate_sql_statement(raw_sql, raw_binds)
|
24
29
|
result = with_showplan_on do
|
25
30
|
exec_query(sql, 'EXPLAIN', [])
|
26
31
|
end
|
data/lib/arjdbc/mssql/quoting.rb
CHANGED
@@ -2,6 +2,9 @@ module ActiveRecord
|
|
2
2
|
module ConnectionAdapters
|
3
3
|
module MSSQL
|
4
4
|
module Quoting
|
5
|
+
QUOTED_TRUE = '1'.freeze
|
6
|
+
QUOTED_FALSE = '0'.freeze
|
7
|
+
|
5
8
|
# Quote date/time values for use in SQL input, includes microseconds
|
6
9
|
# with three digits only if the value is a Time responding to usec.
|
7
10
|
# The JDBC drivers does not work with 6 digits microseconds
|
@@ -29,17 +32,21 @@ module ActiveRecord
|
|
29
32
|
cast_type = lookup_cast_type(column.sql_type)
|
30
33
|
if cast_type.type == :uuid && value =~ /\(\)/
|
31
34
|
value
|
35
|
+
elsif column.type == :datetime_basic && value.is_a?(String)
|
36
|
+
# let's trust the user to set a right default value for this
|
37
|
+
# legacy type something like: '2017-02-28 01:59:19.789'
|
38
|
+
quote(value)
|
32
39
|
else
|
33
40
|
super
|
34
41
|
end
|
35
42
|
end
|
36
43
|
|
37
44
|
def quoted_true
|
38
|
-
|
45
|
+
QUOTED_TRUE
|
39
46
|
end
|
40
47
|
|
41
48
|
def quoted_false
|
42
|
-
|
49
|
+
QUOTED_FALSE
|
43
50
|
end
|
44
51
|
|
45
52
|
# @override
|
@@ -7,7 +7,8 @@ module ActiveRecord
|
|
7
7
|
def visit_TableDefinition(o)
|
8
8
|
if o.as
|
9
9
|
table_name = quote_table_name(o.temporary ? "##{o.name}" : o.name)
|
10
|
-
|
10
|
+
query = o.as.respond_to?(:to_sql) ? o.as.to_sql : o.as
|
11
|
+
projections, source = query.match(%r{SELECT\s+(.*)?\s+FROM\s+(.*)?}).captures
|
11
12
|
select_into = "SELECT #{projections} INTO #{table_name} FROM #{source}"
|
12
13
|
else
|
13
14
|
o.instance_variable_set :@as, nil
|
@@ -46,9 +46,13 @@ module ActiveRecord
|
|
46
46
|
# NOTE: This is ready, all implemented in the java part of adapter,
|
47
47
|
# it uses MSSQLColumn, SqlTypeMetadata, etc.
|
48
48
|
def columns(table_name)
|
49
|
-
|
49
|
+
@connection.columns(table_name)
|
50
50
|
rescue => e
|
51
|
-
raise translate_exception_class(e, nil)
|
51
|
+
# raise translate_exception_class(e, nil)
|
52
|
+
# FIXME: this breaks one arjdbc test but fixes activerecord tests
|
53
|
+
# (table name alias). Also it behaves similarly to the CRuby adapter
|
54
|
+
# which returns an empty array too. (postgres throws a exception)
|
55
|
+
[]
|
52
56
|
end
|
53
57
|
|
54
58
|
# Returns an array of indexes for the given table.
|
@@ -213,7 +217,11 @@ module ActiveRecord
|
|
213
217
|
.gsub(/\s+NULLS\s+(?:FIRST|LAST)\b/i, '')
|
214
218
|
}.reject(&:blank?).map.with_index { |column, i| "#{column} AS alias_#{i}" }
|
215
219
|
|
216
|
-
|
220
|
+
(order_columns << super).join(', ')
|
221
|
+
end
|
222
|
+
|
223
|
+
def create_schema_dumper(options)
|
224
|
+
MSSQL::SchemaDumper.create(self, options)
|
217
225
|
end
|
218
226
|
|
219
227
|
def rename_column(table_name, column_name, new_column_name)
|
@@ -25,7 +25,7 @@ module ActiveRecord
|
|
25
25
|
module RealTransactionExt
|
26
26
|
attr_reader :initial_transaction_isolation
|
27
27
|
|
28
|
-
def initialize(connection, options,
|
28
|
+
def initialize(connection, options, *args)
|
29
29
|
@connection = connection
|
30
30
|
|
31
31
|
if options[:isolation]
|
@@ -58,11 +58,11 @@ module ActiveRecord
|
|
58
58
|
end
|
59
59
|
|
60
60
|
class Transaction
|
61
|
-
|
61
|
+
prepend MSSQL::TransactionExt
|
62
62
|
end
|
63
63
|
|
64
64
|
class RealTransaction
|
65
|
-
|
65
|
+
prepend MSSQL::RealTransactionExt
|
66
66
|
end
|
67
67
|
|
68
68
|
end
|
data/lib/arjdbc/mssql.rb
CHANGED
data/lib/arjdbc/mysql/adapter.rb
CHANGED
@@ -65,6 +65,10 @@ module ActiveRecord
|
|
65
65
|
true
|
66
66
|
end
|
67
67
|
|
68
|
+
def supports_set_server_option?
|
69
|
+
false
|
70
|
+
end
|
71
|
+
|
68
72
|
# HELPER METHODS ===========================================
|
69
73
|
|
70
74
|
# Reloading the type map in abstract/statement_cache.rb blows up postgres
|
@@ -90,10 +94,6 @@ module ActiveRecord
|
|
90
94
|
exception.error_code if exception.is_a?(JDBCError)
|
91
95
|
end
|
92
96
|
|
93
|
-
def create_table(table_name, **options) #:nodoc:
|
94
|
-
super(table_name, options: "ENGINE=InnoDB", **options)
|
95
|
-
end
|
96
|
-
|
97
97
|
#--
|
98
98
|
# QUOTING ==================================================
|
99
99
|
#+
|
@@ -146,6 +146,22 @@ module ActiveRecord
|
|
146
146
|
::ActiveRecord::ConnectionAdapters::MySQL::Column
|
147
147
|
end
|
148
148
|
|
149
|
+
# defined in MySQL::DatabaseStatements which is not included
|
150
|
+
def default_insert_value(column)
|
151
|
+
Arel.sql("DEFAULT") unless column.auto_increment?
|
152
|
+
end
|
153
|
+
|
154
|
+
# FIXME: optimize insert_fixtures_set by using JDBC Statement.addBatch()/executeBatch()
|
155
|
+
def combine_multi_statements(total_sql)
|
156
|
+
total_sql
|
157
|
+
end
|
158
|
+
|
159
|
+
def with_multi_statements
|
160
|
+
yield
|
161
|
+
end
|
162
|
+
|
163
|
+
def discard_remaining_results
|
164
|
+
end
|
149
165
|
end
|
150
166
|
end
|
151
167
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
ArJdbc::ConnectionMethods.module_eval do
|
3
3
|
def mysql_connection(config)
|
4
|
-
config = config.deep_dup
|
5
4
|
# NOTE: this isn't "really" necessary but Rails (in tests) assumes being able to :
|
6
5
|
# ActiveRecord::Base.mysql2_connection ActiveRecord::Base.configurations['arunit'].merge(database: ...)
|
7
6
|
config = symbolize_keys_if_necessary(config)
|
@@ -11,9 +10,11 @@ ArJdbc::ConnectionMethods.module_eval do
|
|
11
10
|
|
12
11
|
return jndi_connection(config) if jndi_config?(config)
|
13
12
|
|
14
|
-
driver = config[:driver]
|
15
|
-
|
16
|
-
|
13
|
+
driver = config[:driver] ||=
|
14
|
+
defined?(::Jdbc::MySQL.driver_name) ? ::Jdbc::MySQL.driver_name : 'com.mysql.jdbc.Driver'
|
15
|
+
|
16
|
+
mysql_driver = driver.start_with?('com.mysql.')
|
17
|
+
mariadb_driver = ! mysql_driver && driver.start_with?('org.mariadb.')
|
17
18
|
|
18
19
|
begin
|
19
20
|
require 'jdbc/mysql'
|
@@ -21,11 +22,6 @@ ArJdbc::ConnectionMethods.module_eval do
|
|
21
22
|
rescue LoadError # assuming driver.jar is on the class-path
|
22
23
|
end if mysql_driver
|
23
24
|
|
24
|
-
if driver.nil?
|
25
|
-
config[:driver] ||=
|
26
|
-
defined?(::Jdbc::MySQL.driver_name) ? ::Jdbc::MySQL.driver_name : 'com.mysql.jdbc.Driver'
|
27
|
-
end
|
28
|
-
|
29
25
|
config[:username] = 'root' unless config.key?(:username)
|
30
26
|
# jdbc:mysql://[host][,failoverhost...][:port]/[database]
|
31
27
|
# - if the host name is not specified, it defaults to 127.0.0.1
|
@@ -40,8 +36,7 @@ ArJdbc::ConnectionMethods.module_eval do
|
|
40
36
|
|
41
37
|
properties = ( config[:properties] ||= {} )
|
42
38
|
if mysql_driver
|
43
|
-
properties['zeroDateTimeBehavior'] ||=
|
44
|
-
config[:driver].to_s.start_with?('com.mysql.cj.') ? 'CONVERT_TO_NULL' : 'convertToNull'
|
39
|
+
properties['zeroDateTimeBehavior'] ||= 'convertToNull'
|
45
40
|
properties['jdbcCompliantTruncation'] ||= false
|
46
41
|
# NOTE: this is "better" than passing what users are used to set on MRI
|
47
42
|
# e.g. 'utf8mb4' will fail cause the driver will check for a Java charset
|
@@ -113,8 +108,7 @@ ArJdbc::ConnectionMethods.module_eval do
|
|
113
108
|
rescue LoadError # assuming driver.jar is on the class-path
|
114
109
|
end
|
115
110
|
|
116
|
-
config[:driver] ||=
|
117
|
-
defined?(::Jdbc::MariaDB.driver_name) ? ::Jdbc::MariaDB.driver_name : 'org.mariadb.jdbc.Driver'
|
111
|
+
config[:driver] ||= 'org.mariadb.jdbc.Driver'
|
118
112
|
|
119
113
|
mysql_connection(config)
|
120
114
|
end
|
@@ -8,6 +8,7 @@ require 'active_record/connection_adapters/postgresql/explain_pretty_printer'
|
|
8
8
|
require 'active_record/connection_adapters/postgresql/quoting'
|
9
9
|
require 'active_record/connection_adapters/postgresql/referential_integrity'
|
10
10
|
require 'active_record/connection_adapters/postgresql/schema_creation'
|
11
|
+
require 'active_record/connection_adapters/postgresql/schema_definitions'
|
11
12
|
require 'active_record/connection_adapters/postgresql/schema_dumper'
|
12
13
|
require 'active_record/connection_adapters/postgresql/schema_statements'
|
13
14
|
require 'active_record/connection_adapters/postgresql/type_metadata'
|
@@ -30,9 +31,6 @@ module ArJdbc
|
|
30
31
|
# @private
|
31
32
|
IndexDefinition = ::ActiveRecord::ConnectionAdapters::IndexDefinition
|
32
33
|
|
33
|
-
# @private
|
34
|
-
ForeignKeyDefinition = ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition
|
35
|
-
|
36
34
|
# @private
|
37
35
|
Type = ::ActiveRecord::Type
|
38
36
|
|
@@ -50,7 +48,6 @@ module ArJdbc
|
|
50
48
|
ADAPTER_NAME
|
51
49
|
end
|
52
50
|
|
53
|
-
# TODO: Update this to pull info from the DatabaseMetaData object?
|
54
51
|
def postgresql_version
|
55
52
|
@postgresql_version ||=
|
56
53
|
begin
|
@@ -247,6 +244,8 @@ module ArJdbc
|
|
247
244
|
|
248
245
|
def supports_foreign_keys?; true end
|
249
246
|
|
247
|
+
def supports_validate_constraints?; true end
|
248
|
+
|
250
249
|
def supports_index_sort_order?; true end
|
251
250
|
|
252
251
|
def supports_partial_index?; true end
|
@@ -257,6 +256,8 @@ module ArJdbc
|
|
257
256
|
|
258
257
|
def supports_views?; true end
|
259
258
|
|
259
|
+
def supports_bulk_alter?; true end
|
260
|
+
|
260
261
|
def supports_datetime_with_precision?; true end
|
261
262
|
|
262
263
|
def supports_comments?; true end
|
@@ -267,6 +268,10 @@ module ArJdbc
|
|
267
268
|
@standard_conforming_strings != :unsupported
|
268
269
|
end
|
269
270
|
|
271
|
+
def supports_foreign_tables? # we don't really support this yet, its a reminder :)
|
272
|
+
postgresql_version >= 90300
|
273
|
+
end
|
274
|
+
|
270
275
|
def supports_hex_escaped_bytea?
|
271
276
|
postgresql_version >= 90000
|
272
277
|
end
|
@@ -374,8 +379,8 @@ module ArJdbc
|
|
374
379
|
end
|
375
380
|
|
376
381
|
def explain(arel, binds = [])
|
377
|
-
sql =
|
378
|
-
ActiveRecord::ConnectionAdapters::PostgreSQL::ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', binds))
|
382
|
+
sql, binds = to_sql_and_binds(arel, binds)
|
383
|
+
ActiveRecord::ConnectionAdapters::PostgreSQL::ExplainPrettyPrinter.new.pp(exec_query("EXPLAIN #{sql}", 'EXPLAIN', binds))
|
379
384
|
end
|
380
385
|
|
381
386
|
# @note Only for "better" AR 4.0 compatibility.
|
@@ -435,10 +440,8 @@ module ArJdbc
|
|
435
440
|
|
436
441
|
# Set the client message level.
|
437
442
|
def client_min_messages=(level)
|
438
|
-
#
|
439
|
-
|
440
|
-
return nil if redshift? # not supported on Redshift
|
441
|
-
execute("SET client_min_messages TO '#{level}'", 'SCHEMA')
|
443
|
+
# Not supported on Redshift
|
444
|
+
redshift? ? nil : super
|
442
445
|
end
|
443
446
|
|
444
447
|
# ORDER BY clause for the passed order option.
|
@@ -580,6 +583,10 @@ module ArJdbc
|
|
580
583
|
::ActiveRecord::SerializationFailure.new(message)
|
581
584
|
when /deadlock detected/
|
582
585
|
::ActiveRecord::Deadlocked.new(message)
|
586
|
+
when /lock timeout/
|
587
|
+
::ActiveRecord::LockWaitTimeout.new(message)
|
588
|
+
when /canceling statement/ # This needs to come after lock timeout because the lock timeout message also contains "canceling statement"
|
589
|
+
::ActiveRecord::QueryCanceled.new(message)
|
583
590
|
else
|
584
591
|
super
|
585
592
|
end
|
@@ -612,6 +619,10 @@ module ArJdbc
|
|
612
619
|
@local_tz ||= execute('SHOW TIME ZONE', 'SCHEMA').first["TimeZone"]
|
613
620
|
end
|
614
621
|
|
622
|
+
def bind_params_length
|
623
|
+
32767
|
624
|
+
end
|
625
|
+
|
615
626
|
end
|
616
627
|
end
|
617
628
|
|
@@ -627,7 +638,6 @@ module ActiveRecord::ConnectionAdapters
|
|
627
638
|
|
628
639
|
# Try to use as much of the built in postgres logic as possible
|
629
640
|
# maybe someday we can extend the actual adapter
|
630
|
-
include ActiveRecord::ConnectionAdapters::PostgreSQL::ColumnDumper
|
631
641
|
include ActiveRecord::ConnectionAdapters::PostgreSQL::ReferentialIntegrity
|
632
642
|
include ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements
|
633
643
|
include ActiveRecord::ConnectionAdapters::PostgreSQL::Quoting
|
@@ -658,7 +668,8 @@ module ActiveRecord::ConnectionAdapters
|
|
658
668
|
|
659
669
|
super(connection, logger, config) # configure_connection happens in super
|
660
670
|
|
661
|
-
|
671
|
+
@type_map = Type::HashLookupTypeMap.new
|
672
|
+
initialize_type_map
|
662
673
|
|
663
674
|
@use_insert_returning = @config.key?(:insert_returning) ?
|
664
675
|
self.class.type_cast_config_to_boolean(@config[:insert_returning]) : nil
|
@@ -680,14 +691,6 @@ module ActiveRecord::ConnectionAdapters
|
|
680
691
|
|
681
692
|
public :sql_for_insert
|
682
693
|
|
683
|
-
def schema_creation # :nodoc:
|
684
|
-
PostgreSQL::SchemaCreation.new self
|
685
|
-
end
|
686
|
-
|
687
|
-
def update_table_definition(table_name, base)
|
688
|
-
Table.new(table_name, base)
|
689
|
-
end
|
690
|
-
|
691
694
|
def jdbc_connection_class(spec)
|
692
695
|
::ArJdbc::PostgreSQL.jdbc_connection_class
|
693
696
|
end
|
@@ -15,7 +15,7 @@ module ArJdbc
|
|
15
15
|
end
|
16
16
|
|
17
17
|
# Extracts the value from a PostgreSQL column default definition.
|
18
|
-
def extract_value_from_default(default)
|
18
|
+
def extract_value_from_default(default) # :nodoc:
|
19
19
|
case default
|
20
20
|
# Quoted types
|
21
21
|
when /\A[\(B]?'(.*)'.*::"?([\w. ]+)"?(?:\[\])?\z/m
|
@@ -41,13 +41,10 @@ module ArJdbc
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
def extract_default_function(default_value, default)
|
45
|
-
default if
|
44
|
+
def extract_default_function(default_value, default) # :nodoc:
|
45
|
+
default if ! default_value && ( %r{\w+\(.*\)|\(.*\)::\w+} === default )
|
46
46
|
end
|
47
47
|
|
48
|
-
def has_default_function?(default_value, default)
|
49
|
-
!default_value && %r{\w+\(.*\)|\(.*\)::\w+|CURRENT_DATE|CURRENT_TIMESTAMP} === default
|
50
|
-
end
|
51
48
|
end
|
52
49
|
|
53
50
|
end
|