activerecord-jdbc-alt-adapter 52.5.1-java → 60.2.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.nvimlog +0 -0
- data/.travis.yml +61 -37
- data/Gemfile +10 -3
- data/README.md +44 -28
- data/Rakefile +1 -1
- data/Rakefile.jdbc +8 -1
- data/activerecord-jdbc-adapter.gemspec +5 -8
- data/activerecord-jdbc-alt-adapter.gemspec +5 -8
- data/lib/arel/visitors/sqlserver.rb +33 -23
- data/lib/arjdbc/abstract/connection_management.rb +7 -0
- data/lib/arjdbc/abstract/core.rb +16 -23
- data/lib/arjdbc/abstract/database_statements.rb +24 -0
- data/lib/arjdbc/abstract/statement_cache.rb +2 -5
- data/lib/arjdbc/abstract/transaction_support.rb +5 -3
- data/lib/arjdbc/db2/column.rb +0 -39
- data/lib/arjdbc/derby/adapter.rb +1 -20
- data/lib/arjdbc/firebird/adapter.rb +0 -21
- data/lib/arjdbc/h2/adapter.rb +0 -15
- data/lib/arjdbc/hsqldb/adapter.rb +0 -14
- data/lib/arjdbc/informix/adapter.rb +0 -23
- data/lib/arjdbc/jdbc/adapter.rb +3 -1
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/adapter_require.rb +3 -1
- data/lib/arjdbc/jdbc/base_ext.rb +3 -1
- data/lib/arjdbc/jdbc/callbacks.rb +2 -0
- data/lib/arjdbc/jdbc/column.rb +2 -0
- data/lib/arjdbc/jdbc/connection.rb +2 -0
- data/lib/arjdbc/jdbc/connection_methods.rb +2 -0
- data/lib/arjdbc/jdbc/error.rb +2 -0
- data/lib/arjdbc/jdbc/extension.rb +2 -0
- data/lib/arjdbc/jdbc/java.rb +3 -1
- data/lib/arjdbc/jdbc/railtie.rb +3 -1
- data/lib/arjdbc/jdbc/rake_tasks.rb +3 -1
- data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -1
- data/lib/arjdbc/jdbc/type_cast.rb +2 -0
- data/lib/arjdbc/jdbc/type_converter.rb +2 -0
- data/lib/arjdbc/mssql/adapter.rb +105 -36
- data/lib/arjdbc/mssql/column.rb +5 -1
- data/lib/arjdbc/mssql/connection_methods.rb +8 -2
- data/lib/arjdbc/mssql/database_limits.rb +2 -0
- data/lib/arjdbc/mssql/database_statements.rb +43 -5
- data/lib/arjdbc/mssql/errors.rb +2 -0
- data/lib/arjdbc/mssql/explain_support.rb +3 -1
- data/lib/arjdbc/mssql/extensions/attribute_methods.rb +5 -1
- data/lib/arjdbc/mssql/extensions/calculations.rb +2 -0
- data/lib/arjdbc/mssql/quoting.rb +38 -0
- data/lib/arjdbc/mssql/schema_creation.rb +24 -2
- data/lib/arjdbc/mssql/schema_definitions.rb +10 -0
- data/lib/arjdbc/mssql/schema_dumper.rb +2 -0
- data/lib/arjdbc/mssql/schema_statements.rb +63 -21
- data/lib/arjdbc/mssql/transaction.rb +2 -0
- data/lib/arjdbc/mssql/types/binary_types.rb +2 -0
- data/lib/arjdbc/mssql/types/date_and_time_types.rb +2 -0
- data/lib/arjdbc/mssql/types/deprecated_types.rb +2 -0
- data/lib/arjdbc/mssql/types/numeric_types.rb +2 -0
- data/lib/arjdbc/mssql/types/string_types.rb +2 -0
- data/lib/arjdbc/mssql/types.rb +2 -0
- data/lib/arjdbc/mssql/utils.rb +2 -0
- data/lib/arjdbc/mssql.rb +3 -1
- data/lib/arjdbc/mysql/adapter.rb +47 -18
- data/lib/arjdbc/postgresql/adapter.rb +240 -214
- data/lib/arjdbc/postgresql/base/array_decoder.rb +2 -0
- data/lib/arjdbc/postgresql/base/array_encoder.rb +4 -2
- data/lib/arjdbc/postgresql/base/array_parser.rb +4 -2
- data/lib/arjdbc/postgresql/base/pgconn.rb +2 -0
- data/lib/arjdbc/postgresql/column.rb +6 -4
- data/lib/arjdbc/postgresql/name.rb +2 -0
- data/lib/arjdbc/postgresql/oid_types.rb +3 -1
- data/lib/arjdbc/sqlite3/adapter.rb +188 -180
- data/lib/arjdbc/sqlite3/connection_methods.rb +15 -4
- data/lib/arjdbc/tasks/databases.rake +13 -10
- data/lib/arjdbc/tasks/mssql_database_tasks.rb +49 -5
- data/lib/arjdbc/util/quoted_cache.rb +3 -1
- data/lib/arjdbc/util/serialized_attributes.rb +3 -1
- data/lib/arjdbc/util/table_copier.rb +3 -1
- data/lib/arjdbc/version.rb +1 -1
- data/pom.xml +4 -4
- data/rakelib/01-tomcat.rake +2 -2
- data/src/java/arjdbc/ArJdbcModule.java +5 -5
- data/src/java/arjdbc/jdbc/DriverWrapper.java +1 -9
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +406 -629
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +88 -0
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +13 -23
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +56 -30
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +94 -99
- data/src/java/arjdbc/util/DateTimeUtils.java +12 -4
- metadata +7 -16
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
module MSSQL
|
@@ -23,6 +25,15 @@ module ActiveRecord
|
|
23
25
|
end
|
24
26
|
alias_method :execute_procedure, :exec_proc # AR-SQLServer-Adapter naming
|
25
27
|
|
28
|
+
READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
|
29
|
+
:begin, :commit, :explain, :select, :set, :show, :release, :savepoint, :rollback, :with
|
30
|
+
) # :nodoc:
|
31
|
+
private_constant :READ_QUERY
|
32
|
+
|
33
|
+
def write_query?(sql) # :nodoc:
|
34
|
+
!READ_QUERY.match?(sql)
|
35
|
+
end
|
36
|
+
|
26
37
|
def execute(sql, name = nil)
|
27
38
|
# with identity insert on block
|
28
39
|
if insert_sql?(sql)
|
@@ -52,11 +63,6 @@ module ActiveRecord
|
|
52
63
|
end
|
53
64
|
end
|
54
65
|
|
55
|
-
# Implements the truncate method.
|
56
|
-
def truncate(table_name, name = nil)
|
57
|
-
execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
|
58
|
-
end
|
59
|
-
|
60
66
|
# Not a rails method, own method to test different isolation
|
61
67
|
# levels supported by the mssql adapter.
|
62
68
|
def supports_transaction_isolation_level?(level)
|
@@ -95,8 +101,40 @@ module ActiveRecord
|
|
95
101
|
end
|
96
102
|
end
|
97
103
|
|
104
|
+
# Implements the truncate method.
|
105
|
+
def truncate(table_name, name = nil)
|
106
|
+
execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
|
107
|
+
end
|
108
|
+
|
109
|
+
def truncate_tables(*table_names) # :nodoc:
|
110
|
+
return if table_names.empty?
|
111
|
+
|
112
|
+
disable_referential_integrity do
|
113
|
+
table_names.each do |table_name|
|
114
|
+
mssql_truncate(table_name)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
98
119
|
private
|
99
120
|
|
121
|
+
# It seems the truncate_tables is mostly used for testing
|
122
|
+
# this a workaround to the fact that SQL Server truncate tables
|
123
|
+
# referenced by a foreign key, it may not be required to reset
|
124
|
+
# the identity column too, more at:
|
125
|
+
# https://docs.microsoft.com/en-us/sql/t-sql/statements/truncate-table-transact-sql?view=sql-server-ver15
|
126
|
+
# TODO: improve is with pure T-SQL, use statements
|
127
|
+
# such as TRY CATCH and reset identity with DBCC CHECKIDENT
|
128
|
+
def mssql_truncate(table_name)
|
129
|
+
execute "TRUNCATE TABLE #{quote_table_name(table_name)}", 'Truncate Tables'
|
130
|
+
rescue => e
|
131
|
+
if e.message =~ /Cannot truncate table .* because it is being referenced by a FOREIGN KEY constraint/
|
132
|
+
execute "DELETE FROM #{quote_table_name(table_name)}", 'Truncate Tables with Delete'
|
133
|
+
else
|
134
|
+
raise
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
100
138
|
# Overrides method in abstract class, combining the sqls with semicolon
|
101
139
|
# affects disable_referential_integrity in mssql specially when multiple
|
102
140
|
# tables are involved.
|
data/lib/arjdbc/mssql/errors.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support/core_ext/string'
|
2
4
|
|
3
5
|
module ActiveRecord
|
@@ -108,7 +110,7 @@ module ActiveRecord
|
|
108
110
|
end
|
109
111
|
|
110
112
|
def build_separator
|
111
|
-
'+' << @widths.map {|w| '-' * (w + (cell_padding * 2))}.join('+') << '+'
|
113
|
+
'+'.dup << @widths.map {|w| '-' * (w + (cell_padding * 2))}.join('+') << '+'
|
112
114
|
end
|
113
115
|
|
114
116
|
def build_cells(items)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file contains extensions, overrides, and monkey patches to core parts
|
2
4
|
# of active record to allow SQL Server work properly.
|
3
5
|
#
|
@@ -15,7 +17,9 @@ module ActiveRecord
|
|
15
17
|
# this behaviour, even the current comments for that method says that
|
16
18
|
# it rejects primary key but it doesn't (maybe a rails bug?)
|
17
19
|
def attributes_for_update(attribute_names)
|
18
|
-
attribute_names
|
20
|
+
attribute_names &= self.class.column_names
|
21
|
+
|
22
|
+
attribute_names.delete_if do |name|
|
19
23
|
# It seems is only required to check if column in identity or not.
|
20
24
|
# This allows to update rails custom primary keys
|
21
25
|
next true if readonly_attribute?(name)
|
data/lib/arjdbc/mssql/quoting.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
module MSSQL
|
@@ -64,6 +66,42 @@ module ActiveRecord
|
|
64
66
|
# @see #quote in old adapter
|
65
67
|
BLOB_VALUE_MARKER = "''"
|
66
68
|
|
69
|
+
def column_name_matcher
|
70
|
+
COLUMN_NAME
|
71
|
+
end
|
72
|
+
|
73
|
+
def column_name_with_order_matcher
|
74
|
+
COLUMN_NAME_WITH_ORDER
|
75
|
+
end
|
76
|
+
|
77
|
+
COLUMN_NAME = /
|
78
|
+
\A
|
79
|
+
(
|
80
|
+
(?:
|
81
|
+
# \[table_name\].\[column_name\] | function(one or no argument)
|
82
|
+
((?:\w+\.|\[\w+\]\.)?(?:\w+|\[\w+\])) | \w+\((?:|\g<2>)\)
|
83
|
+
)
|
84
|
+
(?:\s+AS\s+(?:\w+|\[\w+\]))?
|
85
|
+
)
|
86
|
+
(?:\s*,\s*\g<1>)*
|
87
|
+
\z
|
88
|
+
/ix
|
89
|
+
|
90
|
+
COLUMN_NAME_WITH_ORDER = /
|
91
|
+
\A
|
92
|
+
(
|
93
|
+
(?:
|
94
|
+
# \[table_name\].\[column_name\] | function(one or no argument)
|
95
|
+
((?:\w+\.|\[\w+\]\.)?(?:\w+|\[\w+\])) | \w+\((?:|\g<2>)\)
|
96
|
+
)
|
97
|
+
(?:\s+ASC|\s+DESC)?
|
98
|
+
)
|
99
|
+
(?:\s*,\s*\g<1>)*
|
100
|
+
\z
|
101
|
+
/ix
|
102
|
+
|
103
|
+
private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
|
104
|
+
|
67
105
|
private
|
68
106
|
|
69
107
|
def time_with_db_timezone(value)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
module MSSQL
|
@@ -11,8 +13,28 @@ module ActiveRecord
|
|
11
13
|
projections, source = query.match(%r{SELECT\s+(.*)?\s+FROM\s+(.*)?}).captures
|
12
14
|
select_into = "SELECT #{projections} INTO #{table_name} FROM #{source}"
|
13
15
|
else
|
14
|
-
o.instance_variable_set :@as, nil
|
15
|
-
super
|
16
|
+
# o.instance_variable_set :@as, nil
|
17
|
+
# super
|
18
|
+
create_sql = +''
|
19
|
+
|
20
|
+
create_sql << "IF NOT EXISTS (SELECT 1 FROM sysobjects WHERE name='#{o.name}' and xtype='U') " if o.if_not_exists
|
21
|
+
create_sql << "CREATE#{table_modifier_in_create(o)} TABLE "
|
22
|
+
create_sql << "#{quote_table_name(o.name)} "
|
23
|
+
|
24
|
+
statements = o.columns.map { |c| accept c }
|
25
|
+
statements << accept(o.primary_keys) if o.primary_keys
|
26
|
+
|
27
|
+
if supports_indexes_in_create?
|
28
|
+
statements.concat(o.indexes.map { |column_name, options| index_in_create(o.name, column_name, options) })
|
29
|
+
end
|
30
|
+
|
31
|
+
if supports_foreign_keys?
|
32
|
+
statements.concat(o.foreign_keys.map { |to_table, options| foreign_key_in_create(o.name, to_table, options) })
|
33
|
+
end
|
34
|
+
|
35
|
+
create_sql << "(#{statements.join(', ')})" if statements.present?
|
36
|
+
add_table_options!(create_sql, table_options(o))
|
37
|
+
create_sql
|
16
38
|
end
|
17
39
|
end
|
18
40
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
module MSSQL
|
@@ -81,6 +83,14 @@ module ActiveRecord
|
|
81
83
|
|
82
84
|
super
|
83
85
|
end
|
86
|
+
|
87
|
+
def timestamps(**options)
|
88
|
+
if !options.key?(:precision) && @conn.supports_datetime_with_precision?
|
89
|
+
options[:precision] = 7
|
90
|
+
end
|
91
|
+
|
92
|
+
super
|
93
|
+
end
|
84
94
|
end
|
85
95
|
|
86
96
|
class Table < ActiveRecord::ConnectionAdapters::Table
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
module MSSQL
|
4
|
-
module SchemaStatements
|
6
|
+
module SchemaStatements # :nodoc:
|
5
7
|
|
6
8
|
NATIVE_DATABASE_TYPES = {
|
7
9
|
# Logical Rails types to SQL Server types
|
@@ -41,23 +43,36 @@ module ActiveRecord
|
|
41
43
|
NATIVE_DATABASE_TYPES
|
42
44
|
end
|
43
45
|
|
44
|
-
# Returns an array of Column objects for the table specified by +table_name+.
|
45
|
-
# See the concrete implementation for details on the expected parameter values.
|
46
|
-
# NOTE: This is ready, all implemented in the java part of adapter,
|
47
|
-
# it uses MSSQLColumn, SqlTypeMetadata, etc.
|
48
|
-
def columns(table_name)
|
49
|
-
log('JDBC: GETCOLUMNS', 'SCHEMA') { @connection.columns(table_name) }
|
50
|
-
rescue => e
|
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
|
-
[]
|
56
|
-
end
|
57
|
-
|
58
46
|
# Returns an array of indexes for the given table.
|
59
|
-
def indexes(table_name
|
60
|
-
|
47
|
+
def indexes(table_name)
|
48
|
+
data = select("EXEC sp_helpindex #{quote(table_name)}", "SCHEMA") rescue []
|
49
|
+
|
50
|
+
data.reduce([]) do |indexes, index|
|
51
|
+
index = index.with_indifferent_access
|
52
|
+
|
53
|
+
if index[:index_description] =~ /primary key/
|
54
|
+
indexes
|
55
|
+
else
|
56
|
+
name = index[:index_name]
|
57
|
+
unique = index[:index_description].to_s.match?(/unique/)
|
58
|
+
where = select_value("SELECT [filter_definition] FROM sys.indexes WHERE name = #{quote(name)}")
|
59
|
+
orders = {}
|
60
|
+
columns = []
|
61
|
+
|
62
|
+
index[:index_keys].split(',').each do |column|
|
63
|
+
column.strip!
|
64
|
+
|
65
|
+
if column.ends_with?('(-)')
|
66
|
+
column.gsub! '(-)', ''
|
67
|
+
orders[column] = :desc
|
68
|
+
end
|
69
|
+
|
70
|
+
columns << column
|
71
|
+
end
|
72
|
+
|
73
|
+
indexes << IndexDefinition.new(table_name, name, unique, columns, where: where, orders: orders)
|
74
|
+
end
|
75
|
+
end
|
61
76
|
end
|
62
77
|
|
63
78
|
def primary_keys(table_name)
|
@@ -124,7 +139,7 @@ module ActiveRecord
|
|
124
139
|
end
|
125
140
|
end
|
126
141
|
|
127
|
-
if options[:if_exists] &&
|
142
|
+
if options[:if_exists] && mssql_major_version < 13
|
128
143
|
# this is for sql server 2012 and 2014
|
129
144
|
execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = #{quote(table_name)}) DROP TABLE #{quote_table_name(table_name)}"
|
130
145
|
else
|
@@ -193,7 +208,7 @@ module ActiveRecord
|
|
193
208
|
column_type_sql << "(#{precision})"
|
194
209
|
else
|
195
210
|
raise(
|
196
|
-
|
211
|
+
ArgumentError,
|
197
212
|
"No #{native[:name]} type has precision of #{precision}. The " \
|
198
213
|
'allowed range of precision is from 0 to 7, even though the ' \
|
199
214
|
'sql type precision is 7 this adapter will persist up to 6 ' \
|
@@ -220,6 +235,14 @@ module ActiveRecord
|
|
220
235
|
(order_columns << super).join(', ')
|
221
236
|
end
|
222
237
|
|
238
|
+
def add_timestamps(table_name, options = {})
|
239
|
+
if !options.key?(:precision) && supports_datetime_with_precision?
|
240
|
+
options[:precision] = 7
|
241
|
+
end
|
242
|
+
|
243
|
+
super
|
244
|
+
end
|
245
|
+
|
223
246
|
def create_schema_dumper(options)
|
224
247
|
MSSQL::SchemaDumper.create(self, options)
|
225
248
|
end
|
@@ -299,13 +322,30 @@ module ActiveRecord
|
|
299
322
|
execute(sql_alter.join(' '))
|
300
323
|
end
|
301
324
|
|
325
|
+
def update_table_definition(table_name, base) #:nodoc:
|
326
|
+
MSSQL::Table.new(table_name, base)
|
327
|
+
end
|
328
|
+
|
302
329
|
private
|
303
330
|
|
331
|
+
def schema_creation
|
332
|
+
MSSQL::SchemaCreation.new(self)
|
333
|
+
end
|
334
|
+
|
335
|
+
def create_table_definition(*args)
|
336
|
+
MSSQL::TableDefinition.new(self, *args)
|
337
|
+
end
|
338
|
+
|
339
|
+
def new_column_from_field(table_name, field)
|
340
|
+
field
|
341
|
+
end
|
342
|
+
|
304
343
|
def data_source_sql(name = nil, type: nil)
|
305
344
|
scope = quoted_scope(name, type: type)
|
306
345
|
table_name = 'TABLE_NAME'
|
307
346
|
|
308
|
-
sql =
|
347
|
+
sql = ''.dup
|
348
|
+
sql << "SELECT #{table_name}"
|
309
349
|
sql << ' FROM INFORMATION_SCHEMA.TABLES'
|
310
350
|
sql << ' WHERE TABLE_CATALOG = DB_NAME()'
|
311
351
|
sql << " AND TABLE_SCHEMA = #{quote(scope[:schema])}"
|
@@ -327,7 +367,9 @@ module ActiveRecord
|
|
327
367
|
end
|
328
368
|
|
329
369
|
def change_column_type(table_name, column_name, type, options = {})
|
330
|
-
sql =
|
370
|
+
sql = ''.dup
|
371
|
+
|
372
|
+
sql << "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, limit: options[:limit], precision: options[:precision], scale: options[:scale])}"
|
331
373
|
sql << (options[:null] ? " NULL" : " NOT NULL") if options.has_key?(:null)
|
332
374
|
result = execute(sql)
|
333
375
|
result
|
data/lib/arjdbc/mssql/types.rb
CHANGED
data/lib/arjdbc/mssql/utils.rb
CHANGED
data/lib/arjdbc/mssql.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'arjdbc'
|
2
2
|
require 'arjdbc/mssql/adapter'
|
3
3
|
require 'arjdbc/mssql/connection_methods'
|
4
|
+
|
4
5
|
module ArJdbc
|
5
6
|
MsSQL = MSSQL # compatibility with 1.2
|
6
7
|
end
|
7
|
-
|
8
|
+
|
9
|
+
ArJdbc.warn_unsupported_adapter 'mssql', [6, 0] # warns on AR >= 4.2
|
data/lib/arjdbc/mysql/adapter.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
ArJdbc.load_java_part :MySQL
|
2
4
|
|
3
5
|
require 'bigdecimal'
|
@@ -19,7 +21,7 @@ module ActiveRecord
|
|
19
21
|
remove_const(:Mysql2Adapter) if const_defined?(:Mysql2Adapter)
|
20
22
|
|
21
23
|
class Mysql2Adapter < AbstractMysqlAdapter
|
22
|
-
ADAPTER_NAME = 'Mysql2'
|
24
|
+
ADAPTER_NAME = 'Mysql2'
|
23
25
|
|
24
26
|
include Jdbc::ConnectionPoolCallbacks
|
25
27
|
|
@@ -32,21 +34,30 @@ module ActiveRecord
|
|
32
34
|
include ArJdbc::MySQL
|
33
35
|
|
34
36
|
def initialize(connection, logger, connection_parameters, config)
|
35
|
-
# workaround to skip version check on JNDI to be lazy, dummy version is high enough for Rails 5.0 - 6.0
|
36
|
-
is_jndi = ::ActiveRecord::ConnectionAdapters::JdbcConnection.jndi_config?(config)
|
37
|
-
@version = '8.1.5' if is_jndi
|
38
|
-
|
39
37
|
super
|
40
38
|
|
41
|
-
# set to nil to have it lazy-load the real value when required
|
42
|
-
@version = nil if is_jndi
|
43
|
-
|
44
39
|
@prepared_statements = false unless config.key?(:prepared_statements)
|
45
40
|
# configure_connection taken care of at ArJdbc::Abstract::Core
|
46
41
|
end
|
47
42
|
|
43
|
+
def self.database_exists?(config)
|
44
|
+
conn = ActiveRecord::Base.mysql2_connection(config)
|
45
|
+
conn && conn.really_valid?
|
46
|
+
rescue ActiveRecord::NoDatabaseError
|
47
|
+
false
|
48
|
+
ensure
|
49
|
+
conn.disconnect! if conn
|
50
|
+
end
|
51
|
+
|
52
|
+
def check_version
|
53
|
+
# for JNDI, don't check version as the whole connection should be lazy
|
54
|
+
return if ::ActiveRecord::ConnectionAdapters::JdbcConnection.jndi_config?(config)
|
55
|
+
|
56
|
+
super
|
57
|
+
end
|
58
|
+
|
48
59
|
def supports_json?
|
49
|
-
!mariadb? &&
|
60
|
+
!mariadb? && database_version >= '5.7.8'
|
50
61
|
end
|
51
62
|
|
52
63
|
def supports_comments?
|
@@ -61,6 +72,10 @@ module ActiveRecord
|
|
61
72
|
true
|
62
73
|
end
|
63
74
|
|
75
|
+
def supports_lazy_transactions?
|
76
|
+
true
|
77
|
+
end
|
78
|
+
|
64
79
|
def supports_transaction_isolation?
|
65
80
|
true
|
66
81
|
end
|
@@ -71,6 +86,16 @@ module ActiveRecord
|
|
71
86
|
|
72
87
|
# HELPER METHODS ===========================================
|
73
88
|
|
89
|
+
# from MySQL::DatabaseStatements
|
90
|
+
READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
|
91
|
+
:begin, :commit, :explain, :select, :set, :show, :release, :savepoint, :rollback, :describe, :desc
|
92
|
+
) # :nodoc:
|
93
|
+
private_constant :READ_QUERY
|
94
|
+
|
95
|
+
def write_query?(sql) # :nodoc:
|
96
|
+
!READ_QUERY.match?(sql)
|
97
|
+
end
|
98
|
+
|
74
99
|
# Reloading the type map in abstract/statement_cache.rb blows up postgres
|
75
100
|
def clear_cache!
|
76
101
|
reload_type_map
|
@@ -136,7 +161,13 @@ module ActiveRecord
|
|
136
161
|
private
|
137
162
|
|
138
163
|
# e.g. "5.7.20-0ubuntu0.16.04.1"
|
139
|
-
def full_version
|
164
|
+
def full_version
|
165
|
+
schema_cache.database_version.full_version_string
|
166
|
+
end
|
167
|
+
|
168
|
+
def get_full_version
|
169
|
+
@full_version ||= @connection.full_version
|
170
|
+
end
|
140
171
|
|
141
172
|
def jdbc_connection_class(spec)
|
142
173
|
::ActiveRecord::ConnectionAdapters::MySQLJdbcConnection
|
@@ -152,15 +183,13 @@ module ActiveRecord
|
|
152
183
|
end
|
153
184
|
|
154
185
|
# 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
186
|
|
163
|
-
def
|
187
|
+
def combine_multi_statements(total_sql)
|
188
|
+
if total_sql.length == 1
|
189
|
+
total_sql.first
|
190
|
+
else
|
191
|
+
total_sql
|
192
|
+
end
|
164
193
|
end
|
165
194
|
end
|
166
195
|
end
|