activerecord-jdbc-adapter 1.3.0.beta2 → 1.3.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +14 -8
- data/.travis.yml +40 -31
- data/.yardopts +4 -0
- data/Appraisals +2 -5
- data/CONTRIBUTING.md +46 -0
- data/Gemfile +21 -4
- data/Gemfile.lock +42 -17
- data/{History.txt → History.md} +142 -75
- data/README.md +102 -104
- data/RUNNING_TESTS.md +76 -0
- data/Rakefile.jdbc +20 -0
- data/activerecord-jdbc-adapter.gemspec +35 -18
- data/gemfiles/rails23.gemfile +4 -3
- data/gemfiles/rails23.gemfile.lock +9 -6
- data/gemfiles/rails30.gemfile +4 -3
- data/gemfiles/rails30.gemfile.lock +9 -6
- data/gemfiles/rails31.gemfile +4 -3
- data/gemfiles/rails31.gemfile.lock +9 -6
- data/gemfiles/rails32.gemfile +4 -3
- data/gemfiles/rails32.gemfile.lock +17 -14
- data/gemfiles/rails40.gemfile +5 -5
- data/gemfiles/rails40.gemfile.lock +17 -69
- data/lib/active_record/connection_adapters/firebird_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
- data/lib/arel/visitors/compat.rb +22 -3
- data/lib/arel/visitors/db2.rb +8 -4
- data/lib/arel/visitors/derby.rb +14 -13
- data/lib/arel/visitors/firebird.rb +5 -4
- data/lib/arel/visitors/hsqldb.rb +11 -9
- data/lib/arel/visitors/sql_server.rb +89 -61
- data/lib/arjdbc.rb +1 -1
- data/lib/arjdbc/db2/adapter.rb +181 -212
- data/lib/arjdbc/db2/as400.rb +31 -18
- data/lib/arjdbc/db2/column.rb +167 -0
- data/lib/arjdbc/db2/connection_methods.rb +2 -0
- data/lib/arjdbc/derby/adapter.rb +206 -107
- data/lib/arjdbc/derby/connection_methods.rb +4 -9
- data/lib/arjdbc/firebird.rb +1 -0
- data/lib/arjdbc/firebird/adapter.rb +202 -64
- data/lib/arjdbc/firebird/connection_methods.rb +20 -0
- data/lib/arjdbc/h2/adapter.rb +56 -36
- data/lib/arjdbc/hsqldb/adapter.rb +99 -68
- data/lib/arjdbc/jdbc/adapter.rb +474 -265
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/adapter_require.rb +8 -7
- data/lib/arjdbc/jdbc/arel_support.rb +132 -0
- data/lib/arjdbc/jdbc/base_ext.rb +8 -7
- data/lib/arjdbc/jdbc/callbacks.rb +16 -10
- data/lib/arjdbc/jdbc/column.rb +25 -3
- data/lib/arjdbc/jdbc/connection.rb +28 -55
- data/lib/arjdbc/jdbc/extension.rb +14 -14
- data/lib/arjdbc/jdbc/java.rb +6 -3
- data/lib/arjdbc/jdbc/jdbc.rake +1 -1
- data/lib/arjdbc/jdbc/quoted_primary_key.rb +2 -2
- data/lib/arjdbc/jdbc/rake_tasks.rb +1 -1
- data/lib/arjdbc/jdbc/type_converter.rb +5 -2
- data/lib/arjdbc/mssql/adapter.rb +160 -280
- data/lib/arjdbc/mssql/column.rb +182 -0
- data/lib/arjdbc/mssql/connection_methods.rb +37 -4
- data/lib/arjdbc/mssql/explain_support.rb +13 -21
- data/lib/arjdbc/mssql/limit_helpers.rb +79 -42
- data/lib/arjdbc/mssql/lock_methods.rb +77 -0
- data/lib/arjdbc/mssql/utils.rb +11 -11
- data/lib/arjdbc/mysql/adapter.rb +165 -247
- data/lib/arjdbc/mysql/column.rb +123 -0
- data/lib/arjdbc/mysql/connection_methods.rb +3 -6
- data/lib/arjdbc/oracle/adapter.rb +282 -288
- data/lib/arjdbc/oracle/column.rb +122 -0
- data/lib/arjdbc/oracle/connection_methods.rb +3 -0
- data/lib/arjdbc/postgresql/adapter.rb +336 -574
- data/lib/arjdbc/postgresql/column.rb +458 -0
- data/lib/arjdbc/postgresql/connection_methods.rb +1 -2
- data/lib/arjdbc/postgresql/schema_creation.rb +38 -0
- data/lib/arjdbc/sqlite3/adapter.rb +189 -145
- data/lib/arjdbc/sqlite3/explain_support.rb +1 -1
- data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +8 -8
- data/lib/arjdbc/util/quoted_cache.rb +60 -0
- data/lib/arjdbc/util/table_copier.rb +110 -0
- data/lib/arjdbc/version.rb +6 -7
- data/pom.xml +56 -2
- data/rakelib/02-test.rake +72 -83
- data/rakelib/db.rake +29 -17
- data/src/java/arjdbc/ArJdbcModule.java +21 -18
- data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +84 -12
- data/src/java/arjdbc/derby/DerbyModule.java +140 -143
- data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +58 -7
- data/src/java/arjdbc/h2/H2Module.java +43 -0
- data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +7 -6
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +1223 -648
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +24 -23
- data/src/java/arjdbc/mysql/MySQLModule.java +33 -32
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +147 -30
- data/src/java/arjdbc/oracle/OracleModule.java +13 -13
- data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +114 -6
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +166 -36
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +101 -19
- data/src/java/arjdbc/util/QuotingUtils.java +19 -19
- metadata +240 -394
- data/bench/bench_attributes.rb +0 -13
- data/bench/bench_attributes_new.rb +0 -14
- data/bench/bench_create.rb +0 -12
- data/bench/bench_find_all.rb +0 -12
- data/bench/bench_find_all_mt.rb +0 -25
- data/bench/bench_model.rb +0 -85
- data/bench/bench_new.rb +0 -12
- data/bench/bench_new_valid.rb +0 -12
- data/bench/bench_valid.rb +0 -13
- data/lib/arel/engines/sql/compilers/db2_compiler.rb +0 -9
- data/lib/arel/engines/sql/compilers/derby_compiler.rb +0 -6
- data/lib/arel/engines/sql/compilers/h2_compiler.rb +0 -6
- data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +0 -15
- data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +0 -6
- data/lib/arel/engines/sql/compilers/mssql_compiler.rb +0 -46
- data/lib/arjdbc/jdbc/missing_functionality_helper.rb +0 -98
- data/lib/arjdbc/mssql/lock_helpers.rb +0 -76
- data/lib/arjdbc/mssql/tsql_methods.rb +0 -58
- data/lib/arjdbc/postgresql/column_cast.rb +0 -134
- data/test/activerecord/connections/native_jdbc_mysql/connection.rb +0 -25
- data/test/activerecord/jall.sh +0 -7
- data/test/activerecord/jtest.sh +0 -3
- data/test/assets/flowers.jpg +0 -0
- data/test/binary.rb +0 -67
- data/test/db/db2.rb +0 -43
- data/test/db/db2/binary_test.rb +0 -6
- data/test/db/db2/has_many_through_test.rb +0 -6
- data/test/db/db2/rake_test.rb +0 -82
- data/test/db/db2/rake_test_data.sql +0 -35
- data/test/db/db2/reset_column_information_test.rb +0 -5
- data/test/db/db2/serialize_test.rb +0 -6
- data/test/db/db2/simple_test.rb +0 -81
- data/test/db/db2/test_helper.rb +0 -6
- data/test/db/db2/unit_test.rb +0 -73
- data/test/db/derby.rb +0 -12
- data/test/db/derby/binary_test.rb +0 -6
- data/test/db/derby/migration_test.rb +0 -74
- data/test/db/derby/rake_test.rb +0 -96
- data/test/db/derby/reset_column_information_test.rb +0 -6
- data/test/db/derby/row_locking_test.rb +0 -20
- data/test/db/derby/schema_dump_test.rb +0 -5
- data/test/db/derby/serialize_test.rb +0 -6
- data/test/db/derby/simple_test.rb +0 -173
- data/test/db/derby/test_helper.rb +0 -6
- data/test/db/derby/unit_test.rb +0 -32
- data/test/db/derby/xml_column_test.rb +0 -17
- data/test/db/h2.rb +0 -11
- data/test/db/h2/binary_test.rb +0 -6
- data/test/db/h2/change_column_test.rb +0 -68
- data/test/db/h2/identity_column_test.rb +0 -35
- data/test/db/h2/offset_test.rb +0 -49
- data/test/db/h2/rake_test.rb +0 -98
- data/test/db/h2/schema_dump_test.rb +0 -29
- data/test/db/h2/serialize_test.rb +0 -6
- data/test/db/h2/simple_test.rb +0 -56
- data/test/db/hsqldb.rb +0 -11
- data/test/db/hsqldb/binary_test.rb +0 -6
- data/test/db/hsqldb/rake_test.rb +0 -101
- data/test/db/hsqldb/schema_dump_test.rb +0 -19
- data/test/db/hsqldb/serialize_test.rb +0 -6
- data/test/db/hsqldb/simple_test.rb +0 -17
- data/test/db/informix.rb +0 -13
- data/test/db/jdbc.rb +0 -16
- data/test/db/jdbc_derby.rb +0 -14
- data/test/db/jdbc_h2.rb +0 -17
- data/test/db/jdbc_mysql.rb +0 -13
- data/test/db/jdbc_postgres.rb +0 -23
- data/test/db/jndi_config.rb +0 -32
- data/test/db/jndi_pooled_config.rb +0 -32
- data/test/db/mssql.rb +0 -11
- data/test/db/mssql/binary_test.rb +0 -6
- data/test/db/mssql/exec_proc_test.rb +0 -46
- data/test/db/mssql/identity_insert_test.rb +0 -18
- data/test/db/mssql/ignore_system_views_test.rb +0 -40
- data/test/db/mssql/limit_offset_test.rb +0 -190
- data/test/db/mssql/multibyte_test.rb +0 -16
- data/test/db/mssql/multiple_connections_test.rb +0 -71
- data/test/db/mssql/rake_test.rb +0 -143
- data/test/db/mssql/reset_column_information_test.rb +0 -6
- data/test/db/mssql/row_locking_test.rb +0 -7
- data/test/db/mssql/serialize_test.rb +0 -6
- data/test/db/mssql/simple_test.rb +0 -140
- data/test/db/mssql/transaction_test.rb +0 -6
- data/test/db/mssql/types_test.rb +0 -205
- data/test/db/mssql/unit_test.rb +0 -249
- data/test/db/mysql.rb +0 -4
- data/test/db/mysql/_rails_test_mysql.32.out +0 -6585
- data/test/db/mysql/binary_test.rb +0 -6
- data/test/db/mysql/connection_test.rb +0 -51
- data/test/db/mysql/index_length_test.rb +0 -58
- data/test/db/mysql/multibyte_test.rb +0 -10
- data/test/db/mysql/nonstandard_primary_key_test.rb +0 -39
- data/test/db/mysql/rake_test.rb +0 -97
- data/test/db/mysql/reset_column_information_test.rb +0 -6
- data/test/db/mysql/schema_dump_test.rb +0 -228
- data/test/db/mysql/serialize_test.rb +0 -6
- data/test/db/mysql/simple_test.rb +0 -187
- data/test/db/mysql/statement_escaping_test.rb +0 -46
- data/test/db/mysql/transaction_test.rb +0 -6
- data/test/db/mysql/types_test.rb +0 -30
- data/test/db/mysql/unit_test.rb +0 -93
- data/test/db/mysql_config.rb +0 -7
- data/test/db/oracle.rb +0 -27
- data/test/db/oracle/binary_test.rb +0 -6
- data/test/db/oracle/limit_test.rb +0 -24
- data/test/db/oracle/multibyte_test.rb +0 -22
- data/test/db/oracle/rake_test.rb +0 -100
- data/test/db/oracle/reset_column_information_test.rb +0 -6
- data/test/db/oracle/serialize_test.rb +0 -6
- data/test/db/oracle/simple_test.rb +0 -140
- data/test/db/oracle/specific_test.rb +0 -180
- data/test/db/oracle/transaction_test.rb +0 -31
- data/test/db/oracle/unit_test.rb +0 -31
- data/test/db/postgres.rb +0 -11
- data/test/db/postgres/_rails_test_postgres.32.out +0 -6405
- data/test/db/postgres/a_custom_primary_key_test.rb +0 -50
- data/test/db/postgres/active_schema_unit_test.rb +0 -68
- data/test/db/postgres/array_type_test.rb +0 -101
- data/test/db/postgres/binary_test.rb +0 -6
- data/test/db/postgres/connection_test.rb +0 -63
- data/test/db/postgres/data_types_test.rb +0 -703
- data/test/db/postgres/hstore_test.rb +0 -200
- data/test/db/postgres/information_schema_leak_test.rb +0 -30
- data/test/db/postgres/json_test.rb +0 -86
- data/test/db/postgres/ltree_test.rb +0 -51
- data/test/db/postgres/mixed_case_test.rb +0 -29
- data/test/db/postgres/native_types_test.rb +0 -124
- data/test/db/postgres/rake_test.rb +0 -117
- data/test/db/postgres/reserved_test.rb +0 -22
- data/test/db/postgres/reset_column_information_test.rb +0 -6
- data/test/db/postgres/row_locking_test.rb +0 -21
- data/test/db/postgres/schema_dump_test.rb +0 -95
- data/test/db/postgres/schema_test.rb +0 -115
- data/test/db/postgres/simple_test.rb +0 -260
- data/test/db/postgres/table_alias_length_test.rb +0 -16
- data/test/db/postgres/transaction_test.rb +0 -6
- data/test/db/postgres/unit_test.rb +0 -31
- data/test/db/postgres_config.rb +0 -10
- data/test/db/sqlite3.rb +0 -6
- data/test/db/sqlite3/_rails_test_sqlite3.32.out +0 -6274
- data/test/db/sqlite3/has_many_though_test.rb +0 -6
- data/test/db/sqlite3/rake_test.rb +0 -71
- data/test/db/sqlite3/reset_column_information_test.rb +0 -6
- data/test/db/sqlite3/schema_dump_test.rb +0 -6
- data/test/db/sqlite3/serialize_test.rb +0 -6
- data/test/db/sqlite3/simple_test.rb +0 -268
- data/test/db/sqlite3/transaction_test.rb +0 -32
- data/test/db/sqlite3/type_conversion_test.rb +0 -104
- data/test/has_many_through.rb +0 -61
- data/test/informix_simple_test.rb +0 -48
- data/test/jdbc/db2.rb +0 -36
- data/test/jdbc/oracle.rb +0 -34
- data/test/jdbc_column_test.rb +0 -23
- data/test/jdbc_common.rb +0 -16
- data/test/jdbc_connection_test.rb +0 -196
- data/test/jndi_callbacks_test.rb +0 -33
- data/test/jndi_test.rb +0 -55
- data/test/manualTestDatabase.rb +0 -191
- data/test/models/add_not_null_column_to_table.rb +0 -9
- data/test/models/auto_id.rb +0 -15
- data/test/models/binary.rb +0 -18
- data/test/models/custom_pk_name.rb +0 -15
- data/test/models/data_types.rb +0 -40
- data/test/models/entry.rb +0 -41
- data/test/models/mixed_case.rb +0 -22
- data/test/models/reserved_word.rb +0 -15
- data/test/models/rights_and_roles.rb +0 -57
- data/test/models/string_id.rb +0 -17
- data/test/models/thing.rb +0 -17
- data/test/models/topic.rb +0 -32
- data/test/models/validates_uniqueness_of_string.rb +0 -19
- data/test/rails/mysql.rb +0 -13
- data/test/rails/sqlite3/version.rb +0 -6
- data/test/rails_stub.rb +0 -31
- data/test/rake_test_support.rb +0 -298
- data/test/row_locking.rb +0 -102
- data/test/schema_dump.rb +0 -182
- data/test/serialize.rb +0 -275
- data/test/shared_helper.rb +0 -35
- data/test/simple.rb +0 -1317
- data/test/sybase_jtds_simple_test.rb +0 -28
- data/test/sybase_reset_column_information_test.rb +0 -6
- data/test/test_helper.rb +0 -304
- data/test/transaction.rb +0 -109
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
|
3
|
+
module ArJdbc
|
4
|
+
module MSSQL
|
5
|
+
module LockMethods
|
6
|
+
|
7
|
+
# @private
|
8
|
+
SELECT_FROM_WHERE_RE = /\A(\s*SELECT\s.*?)(\sFROM\s)(.*?)(\sWHERE\s.*|)\Z/mi
|
9
|
+
|
10
|
+
# Microsoft SQL Server uses its own syntax for SELECT .. FOR UPDATE:
|
11
|
+
# SELECT .. FROM table1 WITH(ROWLOCK,UPDLOCK), table2 WITH(ROWLOCK,UPDLOCK) WHERE ..
|
12
|
+
#
|
13
|
+
# This does in-place modification of the passed-in string.
|
14
|
+
def add_lock!(sql, options)
|
15
|
+
if (lock = options[:lock]) && sql =~ /\A\s*SELECT/mi
|
16
|
+
# Check for and extract the :limit/:offset sub-query
|
17
|
+
if sql =~ /\A(\s*SELECT t\.\* FROM \()(.*)(\) AS t WHERE t._row_num BETWEEN \d+ AND \d+\s*)\Z/m
|
18
|
+
prefix, subselect, suffix = [$1, $2, $3]
|
19
|
+
add_lock!(subselect, options)
|
20
|
+
return sql.replace(prefix + subselect + suffix)
|
21
|
+
end
|
22
|
+
unless sql =~ SELECT_FROM_WHERE_RE
|
23
|
+
# If you get this error, this driver probably needs to be fixed.
|
24
|
+
raise NotImplementedError, "Don't know how to add_lock! to SQL statement: #{sql.inspect}"
|
25
|
+
end
|
26
|
+
select_clause, from_word, from_tables, where_clause = $1, $2, $3, $4
|
27
|
+
with_clause = lock.is_a?(String) ? " #{lock} " : " WITH(ROWLOCK,UPDLOCK) "
|
28
|
+
|
29
|
+
# Split the FROM clause into its constituent tables, and add the with clause after each one.
|
30
|
+
new_from_tables = []
|
31
|
+
scanner = StringScanner.new(from_tables)
|
32
|
+
until scanner.eos?
|
33
|
+
prev_pos = scanner.pos
|
34
|
+
if scanner.scan_until(/,|(INNER\s+JOIN|CROSS\s+JOIN|(LEFT|RIGHT|FULL)(\s+OUTER)?\s+JOIN)\s+/mi)
|
35
|
+
join_operand = scanner.pre_match[prev_pos..-1]
|
36
|
+
join_operator = scanner.matched
|
37
|
+
else
|
38
|
+
join_operand = scanner.rest
|
39
|
+
join_operator = ""
|
40
|
+
scanner.terminate
|
41
|
+
end
|
42
|
+
|
43
|
+
# At this point, we have something like:
|
44
|
+
# join_operand == "appointments "
|
45
|
+
# join_operator == "INNER JOIN "
|
46
|
+
# or:
|
47
|
+
# join_operand == "appointment_details AS d1 ON appointments.[id] = d1.[appointment_id]"
|
48
|
+
# join_operator == ""
|
49
|
+
if join_operand =~ /\A(.*)(\s+ON\s+.*)\Z/mi
|
50
|
+
table_spec, on_clause = $1, $2
|
51
|
+
else
|
52
|
+
table_spec = join_operand
|
53
|
+
on_clause = ""
|
54
|
+
end
|
55
|
+
|
56
|
+
# Add the "WITH(ROWLOCK,UPDLOCK)" option to the table specification
|
57
|
+
table_spec << with_clause unless table_spec =~ /\A\(\s*SELECT\s+/mi # HACK - this parser isn't so great
|
58
|
+
join_operand = table_spec + on_clause
|
59
|
+
|
60
|
+
# So now we have something like:
|
61
|
+
# join_operand == "appointments WITH(ROWLOCK,UPDLOCK) "
|
62
|
+
# join_operator == "INNER JOIN "
|
63
|
+
# or:
|
64
|
+
# join_operand == "appointment_details AS d1 WITH(ROWLOCK,UPDLOCK) ON appointments.[id] = d1.[appointment_id]"
|
65
|
+
# join_operator == ""
|
66
|
+
|
67
|
+
new_from_tables << join_operand
|
68
|
+
new_from_tables << join_operator
|
69
|
+
end
|
70
|
+
sql.replace( select_clause.to_s << from_word.to_s << new_from_tables.join << where_clause.to_s )
|
71
|
+
end
|
72
|
+
sql
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/arjdbc/mssql/utils.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
# NOTE: lot of code kindly borrowed from __activerecord-sqlserver-adapter__
|
2
1
|
module ArJdbc
|
3
2
|
module MSSQL
|
3
|
+
# @note Lot of code kindly borrowed from **activerecord-sqlserver-adapter**.
|
4
4
|
module Utils
|
5
|
-
|
5
|
+
|
6
6
|
module_function
|
7
|
-
|
8
|
-
GET_TABLE_NAME_INSERT_UPDATE_RE =
|
7
|
+
|
8
|
+
GET_TABLE_NAME_INSERT_UPDATE_RE =
|
9
9
|
/^\s*(INSERT|EXEC sp_executesql N'INSERT)\s+INTO\s+([^\(\s,]+)\s*|^\s*update\s+([^\(\s,]+)\s*/i
|
10
|
-
|
10
|
+
|
11
11
|
GET_TABLE_NAME_FROM_RE = /\bFROM\s+([^\(\)\s,]+)\s*/i
|
12
|
-
|
12
|
+
|
13
13
|
def get_table_name(sql, qualified = nil)
|
14
14
|
if sql =~ GET_TABLE_NAME_INSERT_UPDATE_RE
|
15
15
|
tn = $2 || $3
|
@@ -20,21 +20,21 @@ module ArJdbc
|
|
20
20
|
nil
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
# protected
|
25
25
|
|
26
26
|
def unquote_table_name(table_name)
|
27
27
|
unquote_column_name(table_name)
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
def unquote_column_name(column_name)
|
31
31
|
column_name.to_s.tr('[]', '')
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def unquote_string(string)
|
35
35
|
string.to_s.gsub("''", "'")
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
def unqualify_table_name(table_name)
|
39
39
|
table_name.to_s.split('.').last.tr('[]', '')
|
40
40
|
end
|
@@ -47,7 +47,7 @@ module ArJdbc
|
|
47
47
|
table_names = table_name.to_s.split('.')
|
48
48
|
table_names.length == 3 ? table_names.first.tr('[]', '') : nil
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
data/lib/arjdbc/mysql/adapter.rb
CHANGED
@@ -2,11 +2,31 @@ ArJdbc.load_java_part :MySQL
|
|
2
2
|
|
3
3
|
require 'bigdecimal'
|
4
4
|
require 'active_record/connection_adapters/abstract/schema_definitions'
|
5
|
+
require 'arjdbc/mysql/column'
|
5
6
|
require 'arjdbc/mysql/explain_support'
|
6
7
|
|
7
8
|
module ArJdbc
|
8
9
|
module MySQL
|
9
|
-
|
10
|
+
|
11
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
|
12
|
+
def self.jdbc_connection_class
|
13
|
+
::ActiveRecord::ConnectionAdapters::MySQLJdbcConnection
|
14
|
+
end
|
15
|
+
|
16
|
+
# @private
|
17
|
+
def init_connection(jdbc_connection)
|
18
|
+
meta = jdbc_connection.meta_data
|
19
|
+
if meta.driver_major_version < 5
|
20
|
+
raise ::ActiveRecord::ConnectionFailed,
|
21
|
+
"MySQL adapter requires driver >= 5.0 got: '#{meta.driver_version}'"
|
22
|
+
elsif meta.driver_major_version == 5 && meta.driver_minor_version < 1
|
23
|
+
config[:connection_alive_sql] ||= 'SELECT 1' # need 5.1 for JDBC 4.0
|
24
|
+
else
|
25
|
+
# NOTE: since the loaded Java driver class can't change :
|
26
|
+
MySQL.send(:remove_method, :init_connection) rescue nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
10
30
|
def configure_connection
|
11
31
|
variables = config[:variables] || {}
|
12
32
|
# By default, MySQL 'where id is null' selects the last inserted id. Turn this off.
|
@@ -42,161 +62,68 @@ module ArJdbc
|
|
42
62
|
# ...and send them all in one query
|
43
63
|
execute("SET #{encoding} #{variable_assignments}", :skip_logging)
|
44
64
|
end
|
45
|
-
|
46
|
-
def self.column_selector
|
47
|
-
[ /mysql/i, lambda { |_,column| column.extend(::ArJdbc::MySQL::Column) } ]
|
48
|
-
end
|
49
|
-
|
50
|
-
def self.jdbc_connection_class
|
51
|
-
::ActiveRecord::ConnectionAdapters::MySQLJdbcConnection
|
52
|
-
end
|
53
65
|
|
54
66
|
def strict_mode? # strict_mode is default since AR 4.0
|
55
67
|
config.key?(:strict) ? config[:strict] : ::ActiveRecord::VERSION::MAJOR > 3
|
56
68
|
end
|
57
|
-
|
69
|
+
|
70
|
+
# @private
|
58
71
|
@@emulate_booleans = true
|
59
|
-
|
72
|
+
|
60
73
|
# Boolean emulation can be disabled using (or using the adapter method) :
|
61
|
-
#
|
74
|
+
#
|
62
75
|
# ArJdbc::MySQL.emulate_booleans = false
|
63
|
-
#
|
76
|
+
#
|
64
77
|
# @see ActiveRecord::ConnectionAdapters::MysqlAdapter#emulate_booleans
|
65
78
|
def self.emulate_booleans; @@emulate_booleans; end
|
66
79
|
def self.emulate_booleans=(emulate); @@emulate_booleans = emulate; end
|
67
|
-
|
68
|
-
module Column
|
69
|
-
|
70
|
-
def extract_default(default)
|
71
|
-
if sql_type =~ /blob/i || type == :text
|
72
|
-
if default.blank?
|
73
|
-
return null ? nil : ''
|
74
|
-
else
|
75
|
-
raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}"
|
76
|
-
end
|
77
|
-
elsif missing_default_forged_as_empty_string?(default)
|
78
|
-
nil
|
79
|
-
else
|
80
|
-
super
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def has_default?
|
85
|
-
return false if sql_type =~ /blob/i || type == :text #mysql forbids defaults on blob and text columns
|
86
|
-
super
|
87
|
-
end
|
88
|
-
|
89
|
-
def simplified_type(field_type)
|
90
|
-
if adapter.respond_to?(:emulate_booleans) && adapter.emulate_booleans
|
91
|
-
return :boolean if field_type.downcase.index('tinyint(1)')
|
92
|
-
end
|
93
|
-
|
94
|
-
case field_type
|
95
|
-
when /enum/i, /set/i then :string
|
96
|
-
when /year/i then :integer
|
97
|
-
when /bit/i then :binary
|
98
|
-
else
|
99
|
-
super
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def extract_limit(sql_type)
|
104
|
-
case sql_type
|
105
|
-
when /blob|text/i
|
106
|
-
case sql_type
|
107
|
-
when /tiny/i
|
108
|
-
255
|
109
|
-
when /medium/i
|
110
|
-
16777215
|
111
|
-
when /long/i
|
112
|
-
2147483647 # mysql only allows 2^31-1, not 2^32-1, somewhat inconsistently with the tiny/medium/normal cases
|
113
|
-
else
|
114
|
-
super # we could return 65535 here, but we leave it undecorated by default
|
115
|
-
end
|
116
|
-
when /^bigint/i; 8
|
117
|
-
when /^int/i; 4
|
118
|
-
when /^mediumint/i; 3
|
119
|
-
when /^smallint/i; 2
|
120
|
-
when /^tinyint/i; 1
|
121
|
-
when /^enum\((.+)\)/i # 255
|
122
|
-
$1.split(',').map{ |enum| enum.strip.length - 2 }.max
|
123
|
-
when /^(bool|date|float|int|time)/i
|
124
|
-
nil
|
125
|
-
else
|
126
|
-
super
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
# MySQL misreports NOT NULL column default when none is given.
|
131
|
-
# We can't detect this for columns which may have a legitimate ''
|
132
|
-
# default (string) but we can for others (integer, datetime, boolean,
|
133
|
-
# and the rest).
|
134
|
-
#
|
135
|
-
# Test whether the column has default '', is not null, and is not
|
136
|
-
# a type allowing default ''.
|
137
|
-
def missing_default_forged_as_empty_string?(default)
|
138
|
-
type != :string && !null && default == ''
|
139
|
-
end
|
140
|
-
|
141
|
-
def adapter; end
|
142
|
-
private :adapter
|
143
|
-
|
144
|
-
end
|
145
80
|
|
146
|
-
ColumnExtensions = Column # :nodoc: backwards-compatibility
|
147
|
-
|
148
81
|
NATIVE_DATABASE_TYPES = {
|
149
82
|
:primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY",
|
150
83
|
:string => { :name => "varchar", :limit => 255 },
|
151
84
|
:text => { :name => "text" },
|
152
85
|
:integer => { :name => "int", :limit => 4 },
|
153
86
|
:float => { :name => "float" },
|
154
|
-
:
|
87
|
+
# :double => { :name=>"double", :limit=>17 }
|
88
|
+
# :real => { :name=>"real", :limit=>17 }
|
89
|
+
:numeric => { :name => "numeric" }, # :limit => 65
|
90
|
+
:decimal => { :name => "decimal" }, # :limit => 65
|
155
91
|
:datetime => { :name => "datetime" },
|
92
|
+
# TIMESTAMP has varying properties depending on MySQL version (SQL mode)
|
156
93
|
:timestamp => { :name => "datetime" },
|
157
94
|
:time => { :name => "time" },
|
158
95
|
:date => { :name => "date" },
|
159
96
|
:binary => { :name => "blob" },
|
160
|
-
:boolean => { :name => "tinyint", :limit => 1 }
|
97
|
+
:boolean => { :name => "tinyint", :limit => 1 },
|
98
|
+
# AR-JDBC added :
|
99
|
+
:bit => { :name => "bit" }, # :limit => 1
|
100
|
+
:enum => { :name => "enum" },
|
101
|
+
:set => { :name => "set" }, # :limit => 64
|
102
|
+
:char => { :name => "char" }, # :limit => 255
|
161
103
|
}
|
162
104
|
|
105
|
+
# @override
|
163
106
|
def native_database_types
|
164
107
|
NATIVE_DATABASE_TYPES
|
165
108
|
end
|
166
|
-
|
167
|
-
def modify_types(types)
|
168
|
-
types[:primary_key] = "int(11) DEFAULT NULL auto_increment PRIMARY KEY"
|
169
|
-
types[:integer] = { :name => 'int', :limit => 4 }
|
170
|
-
types[:decimal] = { :name => "decimal" }
|
171
|
-
types[:timestamp] = { :name => "datetime" }
|
172
|
-
types[:datetime][:limit] = nil
|
173
|
-
types
|
174
|
-
end
|
175
109
|
|
176
110
|
ADAPTER_NAME = 'MySQL'.freeze
|
177
|
-
|
178
|
-
|
111
|
+
|
112
|
+
# @override
|
113
|
+
def adapter_name
|
179
114
|
ADAPTER_NAME
|
180
115
|
end
|
181
116
|
|
182
|
-
def self.
|
183
|
-
|
184
|
-
'mysql' => ::Arel::Visitors::MySQL,
|
185
|
-
'mysql2' => ::Arel::Visitors::MySQL,
|
186
|
-
'jdbcmysql' => ::Arel::Visitors::MySQL
|
187
|
-
}
|
117
|
+
def self.arel_visitor_type(config = nil)
|
118
|
+
::Arel::Visitors::MySQL
|
188
119
|
end
|
189
120
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
end if defined? ::Arel::Visitors::MySQL
|
194
|
-
|
195
|
-
# @see #bind_substitution
|
196
|
-
class BindSubstitution < Arel::Visitors::MySQL # :nodoc:
|
121
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcAdapter#bind_substitution
|
122
|
+
# @private
|
123
|
+
class BindSubstitution < Arel::Visitors::MySQL
|
197
124
|
include Arel::Visitors::BindVisitor
|
198
125
|
end if defined? Arel::Visitors::BindVisitor
|
199
|
-
|
126
|
+
|
200
127
|
def case_sensitive_equality_operator
|
201
128
|
"= BINARY"
|
202
129
|
end
|
@@ -211,10 +138,11 @@ module ArJdbc
|
|
211
138
|
|
212
139
|
# QUOTING ==================================================
|
213
140
|
|
141
|
+
# @override
|
214
142
|
def quote(value, column = nil)
|
215
143
|
return value.quoted_id if value.respond_to?(:quoted_id)
|
216
144
|
return value.to_s if column && column.type == :primary_key
|
217
|
-
|
145
|
+
|
218
146
|
if value.kind_of?(String) && column && column.type == :binary && column.class.respond_to?(:string_to_binary)
|
219
147
|
"x'#{column.class.string_to_binary(value).unpack("H*")[0]}'"
|
220
148
|
elsif value.kind_of?(BigDecimal)
|
@@ -223,67 +151,80 @@ module ArJdbc
|
|
223
151
|
super
|
224
152
|
end
|
225
153
|
end
|
226
|
-
|
227
|
-
|
154
|
+
|
155
|
+
# @override
|
156
|
+
def quote_column_name(name)
|
228
157
|
"`#{name.to_s.gsub('`', '``')}`"
|
229
158
|
end
|
230
|
-
|
231
|
-
|
159
|
+
|
160
|
+
# @override
|
161
|
+
def quote_table_name(name)
|
232
162
|
quote_column_name(name).gsub('.', '`.`')
|
233
163
|
end
|
234
|
-
|
235
|
-
#
|
164
|
+
|
165
|
+
# @override
|
236
166
|
def supports_migrations?
|
237
167
|
true
|
238
168
|
end
|
239
169
|
|
240
|
-
|
170
|
+
# @override
|
171
|
+
def supports_primary_key?
|
241
172
|
true
|
242
173
|
end
|
243
174
|
|
244
|
-
|
175
|
+
# @override
|
176
|
+
def supports_bulk_alter?
|
245
177
|
true
|
246
178
|
end
|
247
179
|
|
248
|
-
#
|
249
|
-
|
250
|
-
|
180
|
+
# @override
|
181
|
+
def supports_index_sort_order?
|
182
|
+
# Technically MySQL allows to create indexes with the sort order syntax
|
183
|
+
# but at the moment (5.5) it doesn't yet implement them.
|
251
184
|
true
|
252
185
|
end
|
253
186
|
|
254
|
-
#
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
187
|
+
# @override
|
188
|
+
def supports_transaction_isolation?
|
189
|
+
# MySQL 4 technically support transaction isolation, but it is affected by
|
190
|
+
# a bug where the transaction level gets persisted for the whole session:
|
191
|
+
# http://bugs.mysql.com/bug.php?id=39170
|
259
192
|
version[0] && version[0] >= 5
|
260
193
|
end
|
261
|
-
|
262
|
-
|
194
|
+
|
195
|
+
# @override
|
196
|
+
def supports_views?
|
263
197
|
version[0] && version[0] >= 5
|
264
198
|
end
|
265
|
-
|
266
|
-
def supports_savepoints? # :nodoc:
|
267
|
-
true
|
268
|
-
end
|
269
199
|
|
200
|
+
# @override
|
270
201
|
def supports_transaction_isolation?(level = nil)
|
271
202
|
version[0] >= 5 # MySQL 5+
|
272
203
|
end
|
273
|
-
|
274
|
-
|
275
|
-
|
204
|
+
|
205
|
+
# NOTE: handled by JdbcAdapter we override only to have save-point in logs :
|
206
|
+
|
207
|
+
# @override
|
208
|
+
def supports_savepoints?
|
209
|
+
true
|
210
|
+
end
|
211
|
+
|
212
|
+
# @override
|
213
|
+
def create_savepoint(name = current_savepoint_name(true))
|
214
|
+
log("SAVEPOINT #{name}", 'Savepoint') { super }
|
276
215
|
end
|
277
216
|
|
278
|
-
|
279
|
-
|
217
|
+
# @override
|
218
|
+
def rollback_to_savepoint(name = current_savepoint_name)
|
219
|
+
log("ROLLBACK TO SAVEPOINT #{name}", 'Savepoint') { super }
|
280
220
|
end
|
281
221
|
|
282
|
-
|
283
|
-
|
222
|
+
# @override
|
223
|
+
def release_savepoint(name = current_savepoint_name)
|
224
|
+
log("RELEASE SAVEPOINT #{name}", 'Savepoint') { super }
|
284
225
|
end
|
285
226
|
|
286
|
-
def disable_referential_integrity
|
227
|
+
def disable_referential_integrity
|
287
228
|
fk_checks = select_value("SELECT @@FOREIGN_KEY_CHECKS")
|
288
229
|
begin
|
289
230
|
update("SET FOREIGN_KEY_CHECKS = 0")
|
@@ -293,56 +234,44 @@ module ArJdbc
|
|
293
234
|
end
|
294
235
|
end
|
295
236
|
|
296
|
-
#
|
297
|
-
|
298
|
-
def exec_insert(sql, name, binds, pk = nil, sequence_name = nil) # :nodoc:
|
299
|
-
execute sql, name, binds
|
300
|
-
end
|
301
|
-
|
302
|
-
def exec_update(sql, name, binds) # :nodoc:
|
303
|
-
execute sql, name, binds
|
304
|
-
end
|
305
|
-
|
306
|
-
def exec_delete(sql, name, binds) # :nodoc:
|
307
|
-
execute sql, name, binds
|
308
|
-
end
|
309
|
-
|
310
|
-
# Make it public just like native MySQL adapter does.
|
311
|
-
def update_sql(sql, name = nil) # :nodoc:
|
237
|
+
# @override make it public just like native MySQL adapter does
|
238
|
+
def update_sql(sql, name = nil)
|
312
239
|
super
|
313
240
|
end
|
314
|
-
|
241
|
+
|
315
242
|
# SCHEMA STATEMENTS ========================================
|
316
|
-
|
317
|
-
|
243
|
+
|
244
|
+
# @deprecated no longer used - handled with (AR built-in) Rake tasks
|
245
|
+
def structure_dump
|
246
|
+
# NOTE: due AR (2.3-3.2) compatibility views are not included
|
318
247
|
if supports_views?
|
319
248
|
sql = "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'"
|
320
249
|
else
|
321
250
|
sql = "SHOW TABLES"
|
322
251
|
end
|
323
252
|
|
324
|
-
|
253
|
+
@connection.execute_query_raw(sql).map do |table|
|
254
|
+
# e.g. { "Tables_in_arjdbc_test"=>"big_fields", "Table_type"=>"BASE TABLE" }
|
325
255
|
table.delete('Table_type')
|
256
|
+
table_name = table.to_a.first.last
|
326
257
|
|
327
|
-
|
258
|
+
create_table = select_one("SHOW CREATE TABLE #{quote_table_name(table_name)}")
|
328
259
|
|
329
|
-
|
330
|
-
|
331
|
-
elsif(view = hash["Create View"])
|
332
|
-
structure += view + ";\n\n"
|
333
|
-
end
|
334
|
-
end
|
260
|
+
"#{create_table['Create Table']};\n\n"
|
261
|
+
end.join
|
335
262
|
end
|
336
263
|
|
337
|
-
# Returns just a table's primary key
|
264
|
+
# Returns just a table's primary key.
|
265
|
+
# @override
|
338
266
|
def primary_key(table)
|
339
267
|
#pk_and_sequence = pk_and_sequence_for(table)
|
340
268
|
#pk_and_sequence && pk_and_sequence.first
|
341
269
|
@connection.primary_keys(table).first
|
342
270
|
end
|
343
|
-
|
271
|
+
|
344
272
|
# Returns a table's primary key and belonging sequence.
|
345
|
-
# @note
|
273
|
+
# @note Not used, only here for potential compatibility with native adapter.
|
274
|
+
# @override
|
346
275
|
def pk_and_sequence_for(table)
|
347
276
|
result = execute("SHOW CREATE TABLE #{quote_table_name(table)}", 'SCHEMA').first
|
348
277
|
if result['Create Table'].to_s =~ /PRIMARY KEY\s+(?:USING\s+\w+\s+)?\((.+)\)/
|
@@ -352,18 +281,20 @@ module ArJdbc
|
|
352
281
|
return nil
|
353
282
|
end
|
354
283
|
end
|
355
|
-
|
284
|
+
|
285
|
+
# @private
|
356
286
|
IndexDefinition = ::ActiveRecord::ConnectionAdapters::IndexDefinition
|
357
|
-
|
287
|
+
|
358
288
|
if ::ActiveRecord::VERSION::MAJOR > 3
|
359
|
-
|
289
|
+
|
360
290
|
INDEX_TYPES = [ :fulltext, :spatial ]
|
361
291
|
INDEX_USINGS = [ :btree, :hash ]
|
362
|
-
|
292
|
+
|
363
293
|
end
|
364
|
-
|
294
|
+
|
365
295
|
# Returns an array of indexes for the given table.
|
366
|
-
|
296
|
+
# @override
|
297
|
+
def indexes(table_name, name = nil)
|
367
298
|
indexes = []
|
368
299
|
current_index = nil
|
369
300
|
result = execute("SHOW KEYS FROM #{quote_table_name(table_name)}", name || 'SCHEMA')
|
@@ -372,7 +303,7 @@ module ArJdbc
|
|
372
303
|
if current_index != key_name
|
373
304
|
next if key_name == 'PRIMARY' # skip the primary key
|
374
305
|
current_index = key_name
|
375
|
-
indexes <<
|
306
|
+
indexes <<
|
376
307
|
if self.class.const_defined?(:INDEX_TYPES) # AR 4.0
|
377
308
|
mysql_index_type = row['Index_type'].downcase.to_sym
|
378
309
|
index_type = INDEX_TYPES.include?(mysql_index_type) ? mysql_index_type : nil
|
@@ -388,8 +319,9 @@ module ArJdbc
|
|
388
319
|
end
|
389
320
|
indexes
|
390
321
|
end
|
391
|
-
|
392
|
-
|
322
|
+
|
323
|
+
# @override
|
324
|
+
def columns(table_name, name = nil)
|
393
325
|
sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}"
|
394
326
|
column = ::ActiveRecord::ConnectionAdapters::MysqlAdapter::Column
|
395
327
|
result = execute(sql, name || 'SCHEMA')
|
@@ -399,12 +331,14 @@ module ArJdbc
|
|
399
331
|
result
|
400
332
|
end
|
401
333
|
|
402
|
-
|
334
|
+
# @private
|
335
|
+
def recreate_database(name, options = {})
|
403
336
|
drop_database(name)
|
404
337
|
create_database(name, options)
|
405
338
|
end
|
406
339
|
|
407
|
-
|
340
|
+
# @override
|
341
|
+
def create_database(name, options = {})
|
408
342
|
if options[:collation]
|
409
343
|
execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}` COLLATE `#{options[:collation]}`"
|
410
344
|
else
|
@@ -412,7 +346,8 @@ module ArJdbc
|
|
412
346
|
end
|
413
347
|
end
|
414
348
|
|
415
|
-
|
349
|
+
# @override
|
350
|
+
def drop_database(name)
|
416
351
|
execute "DROP DATABASE IF EXISTS `#{name}`"
|
417
352
|
end
|
418
353
|
|
@@ -420,20 +355,24 @@ module ArJdbc
|
|
420
355
|
select_one("SELECT DATABASE() as db")["db"]
|
421
356
|
end
|
422
357
|
|
423
|
-
|
358
|
+
# @override
|
359
|
+
def create_table(name, options = {})
|
424
360
|
super(name, {:options => "ENGINE=InnoDB DEFAULT CHARSET=utf8"}.merge(options))
|
425
361
|
end
|
426
362
|
|
363
|
+
# @override
|
427
364
|
def rename_table(table_name, new_name)
|
428
365
|
execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}"
|
429
366
|
rename_table_indexes(table_name, new_name) if respond_to?(:rename_table_indexes) # AR-4.0 SchemaStatements
|
430
367
|
end
|
431
|
-
|
432
|
-
|
368
|
+
|
369
|
+
# @override
|
370
|
+
def remove_index!(table_name, index_name)
|
433
371
|
# missing table_name quoting in AR-2.3
|
434
372
|
execute "DROP INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}"
|
435
373
|
end
|
436
|
-
|
374
|
+
|
375
|
+
# @override
|
437
376
|
def add_column(table_name, column_name, type, options = {})
|
438
377
|
add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
|
439
378
|
add_column_options!(add_column_sql, options)
|
@@ -441,7 +380,7 @@ module ArJdbc
|
|
441
380
|
execute(add_column_sql)
|
442
381
|
end
|
443
382
|
|
444
|
-
def change_column_default(table_name, column_name, default)
|
383
|
+
def change_column_default(table_name, column_name, default)
|
445
384
|
column = column_for(table_name, column_name)
|
446
385
|
change_column table_name, column_name, column.sql_type, :default => default
|
447
386
|
end
|
@@ -456,7 +395,8 @@ module ArJdbc
|
|
456
395
|
change_column table_name, column_name, column.sql_type, :null => null
|
457
396
|
end
|
458
397
|
|
459
|
-
|
398
|
+
# @override
|
399
|
+
def change_column(table_name, column_name, type, options = {})
|
460
400
|
column = column_for(table_name, column_name)
|
461
401
|
|
462
402
|
unless options_include_default?(options)
|
@@ -473,7 +413,8 @@ module ArJdbc
|
|
473
413
|
execute(change_column_sql)
|
474
414
|
end
|
475
415
|
|
476
|
-
|
416
|
+
# @override
|
417
|
+
def rename_column(table_name, column_name, new_column_name)
|
477
418
|
options = {}
|
478
419
|
if column = columns(table_name).find { |c| c.name == column_name.to_s }
|
479
420
|
options[:default] = column.default; options[:null] = column.null
|
@@ -486,8 +427,10 @@ module ArJdbc
|
|
486
427
|
execute(rename_column_sql)
|
487
428
|
rename_column_indexes(table_name, column_name, new_column_name) if respond_to?(:rename_column_indexes) # AR-4.0 SchemaStatements
|
488
429
|
end
|
489
|
-
|
490
|
-
|
430
|
+
|
431
|
+
# @note Only used with (non-AREL) ActiveRecord **2.3**.
|
432
|
+
# @see Arel::Visitors::MySQL
|
433
|
+
def add_limit_offset!(sql, options)
|
491
434
|
limit, offset = options[:limit], options[:offset]
|
492
435
|
if limit && offset
|
493
436
|
sql << " LIMIT #{offset.to_i}, #{sanitize_limit(limit)}"
|
@@ -497,16 +440,15 @@ module ArJdbc
|
|
497
440
|
sql << " OFFSET #{offset.to_i}"
|
498
441
|
end
|
499
442
|
sql
|
500
|
-
end
|
443
|
+
end if ::ActiveRecord::VERSION::MAJOR < 3
|
501
444
|
|
502
|
-
# Taken from: https://github.com/gfmurphy/rails/blob/3-1-stable/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb#L540
|
503
|
-
#
|
504
445
|
# In the simple case, MySQL allows us to place JOINs directly into the UPDATE
|
505
446
|
# query. However, this does not allow for LIMIT, OFFSET and ORDER. To support
|
506
447
|
# these, we must use a subquery. However, MySQL is too stupid to create a
|
507
448
|
# temporary table for this automatically, so we have to give it some prompting
|
508
449
|
# in the form of a subsubquery. Ugh!
|
509
|
-
|
450
|
+
# @private based on mysql_adapter.rb from 3.1-stable
|
451
|
+
def join_to_update(update, select)
|
510
452
|
if select.limit || select.offset || select.orders.any?
|
511
453
|
subsubselect = select.clone
|
512
454
|
subsubselect.projections = [update.key]
|
@@ -575,10 +517,11 @@ module ArJdbc
|
|
575
517
|
end
|
576
518
|
end
|
577
519
|
|
520
|
+
# @override
|
578
521
|
def empty_insert_statement_value
|
579
522
|
"VALUES ()"
|
580
523
|
end
|
581
|
-
|
524
|
+
|
582
525
|
protected
|
583
526
|
def quoted_columns_for_index(column_names, options = {})
|
584
527
|
length = options[:length] if options.is_a?(Hash)
|
@@ -593,6 +536,7 @@ module ArJdbc
|
|
593
536
|
end
|
594
537
|
end
|
595
538
|
|
539
|
+
# @override
|
596
540
|
def translate_exception(exception, message)
|
597
541
|
return super unless exception.respond_to?(:errno)
|
598
542
|
|
@@ -607,18 +551,14 @@ module ArJdbc
|
|
607
551
|
end
|
608
552
|
|
609
553
|
private
|
610
|
-
|
554
|
+
|
611
555
|
def column_for(table_name, column_name)
|
612
556
|
unless column = columns(table_name).find { |c| c.name == column_name.to_s }
|
613
557
|
raise "No such column: #{table_name}.#{column_name}"
|
614
558
|
end
|
615
559
|
column
|
616
560
|
end
|
617
|
-
|
618
|
-
def show_create_table(table)
|
619
|
-
select_one("SHOW CREATE TABLE #{quote_table_name(table)}")
|
620
|
-
end
|
621
|
-
|
561
|
+
|
622
562
|
def version
|
623
563
|
return @version ||= begin
|
624
564
|
version = []
|
@@ -633,7 +573,7 @@ module ArJdbc
|
|
633
573
|
version
|
634
574
|
end
|
635
575
|
end
|
636
|
-
|
576
|
+
|
637
577
|
end
|
638
578
|
end
|
639
579
|
|
@@ -641,19 +581,19 @@ module ActiveRecord
|
|
641
581
|
module ConnectionAdapters
|
642
582
|
# Remove any vestiges of core/Ruby MySQL adapter
|
643
583
|
remove_const(:MysqlAdapter) if const_defined?(:MysqlAdapter)
|
644
|
-
|
584
|
+
|
645
585
|
class MysqlAdapter < JdbcAdapter
|
646
586
|
include ::ArJdbc::MySQL
|
647
587
|
include ::ArJdbc::MySQL::ExplainSupport
|
648
|
-
|
649
|
-
# By default, the MysqlAdapter will consider all columns of type
|
650
|
-
#
|
651
|
-
#
|
588
|
+
|
589
|
+
# By default, the MysqlAdapter will consider all columns of type
|
590
|
+
# __tinyint(1)__ as boolean. If you wish to disable this :
|
591
|
+
# ```
|
652
592
|
# ActiveRecord::ConnectionAdapters::Mysql[2]Adapter.emulate_booleans = false
|
653
|
-
#
|
593
|
+
# ```
|
654
594
|
def self.emulate_booleans; ::ArJdbc::MySQL.emulate_booleans; end
|
655
595
|
def self.emulate_booleans=(emulate); ::ArJdbc::MySQL.emulate_booleans = emulate; end
|
656
|
-
|
596
|
+
|
657
597
|
class Column < JdbcColumn
|
658
598
|
include ::ArJdbc::MySQL::Column
|
659
599
|
|
@@ -669,9 +609,9 @@ module ActiveRecord
|
|
669
609
|
def adapter
|
670
610
|
MysqlAdapter
|
671
611
|
end
|
672
|
-
|
612
|
+
|
673
613
|
end
|
674
|
-
|
614
|
+
|
675
615
|
def initialize(*args)
|
676
616
|
super
|
677
617
|
# configure_connection happens in super
|
@@ -685,30 +625,8 @@ module ActiveRecord
|
|
685
625
|
Column
|
686
626
|
end
|
687
627
|
|
688
|
-
# some QUOTING caching :
|
689
|
-
|
690
|
-
@@quoted_table_names = {}
|
691
|
-
|
692
|
-
def quote_table_name(name)
|
693
|
-
unless quoted = @@quoted_table_names[name]
|
694
|
-
quoted = super
|
695
|
-
@@quoted_table_names[name] = quoted.freeze
|
696
|
-
end
|
697
|
-
quoted
|
698
|
-
end
|
699
|
-
|
700
|
-
@@quoted_column_names = {}
|
701
|
-
|
702
|
-
def quote_column_name(name)
|
703
|
-
unless quoted = @@quoted_column_names[name]
|
704
|
-
quoted = super
|
705
|
-
@@quoted_column_names[name] = quoted.freeze
|
706
|
-
end
|
707
|
-
quoted
|
708
|
-
end
|
709
|
-
|
710
628
|
end
|
711
|
-
|
629
|
+
|
712
630
|
if ActiveRecord::VERSION::MAJOR < 3 ||
|
713
631
|
( ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR <= 1 )
|
714
632
|
remove_const(:MysqlColumn) if const_defined?(:MysqlColumn)
|
@@ -724,6 +642,6 @@ module ActiveRecord
|
|
724
642
|
Mysql2Column = MysqlAdapter::Column
|
725
643
|
end
|
726
644
|
end
|
727
|
-
|
645
|
+
|
728
646
|
end
|
729
647
|
end
|