diff options
Diffstat (limited to 'activerecord/test/cases/adapters/mysql2')
8 files changed, 203 insertions, 38 deletions
diff --git a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb index 4ccf568406..cefc3e3c7e 100644 --- a/activerecord/test/cases/adapters/mysql2/active_schema_test.rb +++ b/activerecord/test/cases/adapters/mysql2/active_schema_test.rb @@ -1,23 +1,23 @@ require "cases/helper" +require 'support/connection_helper' class ActiveSchemaTest < ActiveRecord::TestCase - def setup - @connection = ActiveRecord::Base.remove_connection - ActiveRecord::Base.establish_connection(@connection) + include ConnectionHelper + def setup ActiveRecord::Base.connection.singleton_class.class_eval do alias_method :execute_without_stub, :execute def execute(sql, name = nil) return sql end end end - def teardown - ActiveRecord::Base.remove_connection - ActiveRecord::Base.establish_connection(@connection) + teardown do + reset_connection end def test_add_index - # add_index calls index_name_exists? which can't work since execute is stubbed + # add_index calls table_exists? and index_name_exists? which can't work since execute is stubbed + def (ActiveRecord::Base.connection).table_exists?(*); true; end def (ActiveRecord::Base.connection).index_name_exists?(*); false; end expected = "CREATE INDEX `index_people_on_last_name` ON `people` (`last_name`) " @@ -116,6 +116,18 @@ class ActiveSchemaTest < ActiveRecord::TestCase end end + def test_indexes_in_create + ActiveRecord::Base.connection.stubs(:table_exists?).with(:temp).returns(false) + ActiveRecord::Base.connection.stubs(:index_name_exists?).with(:index_temp_on_zip).returns(false) + + expected = "CREATE TEMPORARY TABLE `temp` ( INDEX `index_temp_on_zip` (`zip`) ) ENGINE=InnoDB AS SELECT id, name, zip FROM a_really_complicated_query" + actual = ActiveRecord::Base.connection.create_table(:temp, temporary: true, as: "SELECT id, name, zip FROM a_really_complicated_query") do |t| + t.index :zip + end + + assert_equal expected, actual + end + private def with_real_execute ActiveRecord::Base.connection.singleton_class.class_eval do diff --git a/activerecord/test/cases/adapters/mysql2/boolean_test.rb b/activerecord/test/cases/adapters/mysql2/boolean_test.rb new file mode 100644 index 0000000000..267aa232d9 --- /dev/null +++ b/activerecord/test/cases/adapters/mysql2/boolean_test.rb @@ -0,0 +1,91 @@ +require "cases/helper" + +class Mysql2BooleanTest < ActiveRecord::TestCase + self.use_transactional_fixtures = false + + class BooleanType < ActiveRecord::Base + self.table_name = "mysql_booleans" + end + + setup do + @connection = ActiveRecord::Base.connection + @connection.create_table("mysql_booleans") do |t| + t.boolean "archived" + t.string "published", limit: 1 + end + BooleanType.reset_column_information + + @emulate_booleans = ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans + end + + teardown do + emulate_booleans @emulate_booleans + @connection.drop_table "mysql_booleans" + end + + test "column type with emulated booleans" do + emulate_booleans true + + assert_equal :boolean, boolean_column.type + assert_equal :string, string_column.type + end + + test "column type without emulated booleans" do + emulate_booleans false + + assert_equal :integer, boolean_column.type + assert_equal :string, string_column.type + end + + test "test type casting with emulated booleans" do + emulate_booleans true + + boolean = BooleanType.create!(archived: true, published: true) + attributes = boolean.reload.attributes_before_type_cast + + assert_equal 1, attributes["archived"] + assert_equal "1", attributes["published"] + + assert_equal 1, @connection.type_cast(true, boolean_column) + assert_equal 1, @connection.type_cast(true, string_column) + end + + test "test type casting without emulated booleans" do + emulate_booleans false + + boolean = BooleanType.create!(archived: true, published: true) + attributes = boolean.reload.attributes_before_type_cast + + assert_equal 1, attributes["archived"] + assert_equal "1", attributes["published"] + + assert_equal 1, @connection.type_cast(true, boolean_column) + assert_equal 1, @connection.type_cast(true, string_column) + end + + test "with booleans stored as 1 and 0" do + @connection.execute "INSERT INTO mysql_booleans(archived, published) VALUES(1, '1')" + boolean = BooleanType.first + assert_equal true, boolean.archived + assert_equal "1", boolean.published + end + + test "with booleans stored as t" do + @connection.execute "INSERT INTO mysql_booleans(published) VALUES('t')" + boolean = BooleanType.first + assert_equal "t", boolean.published + end + + def boolean_column + BooleanType.columns.find { |c| c.name == 'archived' } + end + + def string_column + BooleanType.columns.find { |c| c.name == 'published' } + end + + def emulate_booleans(value) + ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans = value + BooleanType.reset_column_information + end +end diff --git a/activerecord/test/cases/adapters/mysql2/case_sensitivity_test.rb b/activerecord/test/cases/adapters/mysql2/case_sensitivity_test.rb index 6bcc113482..09bebf3071 100644 --- a/activerecord/test/cases/adapters/mysql2/case_sensitivity_test.rb +++ b/activerecord/test/cases/adapters/mysql2/case_sensitivity_test.rb @@ -3,10 +3,10 @@ require 'models/person' class Mysql2CaseSensitivityTest < ActiveRecord::TestCase class CollationTest < ActiveRecord::Base - validates_uniqueness_of :string_cs_column, :case_sensitive => false - validates_uniqueness_of :string_ci_column, :case_sensitive => false end + repair_validations(CollationTest) + def test_columns_include_collation_different_from_table assert_equal 'utf8_bin', CollationTest.columns_hash['string_cs_column'].collation assert_equal 'utf8_general_ci', CollationTest.columns_hash['string_ci_column'].collation @@ -18,6 +18,7 @@ class Mysql2CaseSensitivityTest < ActiveRecord::TestCase end def test_case_insensitive_comparison_for_ci_column + CollationTest.validates_uniqueness_of(:string_ci_column, :case_sensitive => false) CollationTest.create!(:string_ci_column => 'A') invalid = CollationTest.new(:string_ci_column => 'a') queries = assert_sql { invalid.save } @@ -26,10 +27,29 @@ class Mysql2CaseSensitivityTest < ActiveRecord::TestCase end def test_case_insensitive_comparison_for_cs_column + CollationTest.validates_uniqueness_of(:string_cs_column, :case_sensitive => false) CollationTest.create!(:string_cs_column => 'A') invalid = CollationTest.new(:string_cs_column => 'a') queries = assert_sql { invalid.save } cs_uniqueness_query = queries.detect { |q| q.match(/string_cs_column/)} assert_match(/lower/i, cs_uniqueness_query) end + + def test_case_sensitive_comparison_for_ci_column + CollationTest.validates_uniqueness_of(:string_ci_column, :case_sensitive => true) + CollationTest.create!(:string_ci_column => 'A') + invalid = CollationTest.new(:string_ci_column => 'A') + queries = assert_sql { invalid.save } + ci_uniqueness_query = queries.detect { |q| q.match(/string_ci_column/) } + assert_match(/binary/i, ci_uniqueness_query) + end + + def test_case_sensitive_comparison_for_cs_column + CollationTest.validates_uniqueness_of(:string_cs_column, :case_sensitive => true) + CollationTest.create!(:string_cs_column => 'A') + invalid = CollationTest.new(:string_cs_column => 'A') + queries = assert_sql { invalid.save } + cs_uniqueness_query = queries.detect { |q| q.match(/string_cs_column/) } + assert_no_match(/binary/i, cs_uniqueness_query) + end end diff --git a/activerecord/test/cases/adapters/mysql2/connection_test.rb b/activerecord/test/cases/adapters/mysql2/connection_test.rb index fedd9f603c..65f50e77bb 100644 --- a/activerecord/test/cases/adapters/mysql2/connection_test.rb +++ b/activerecord/test/cases/adapters/mysql2/connection_test.rb @@ -1,16 +1,27 @@ require "cases/helper" +require 'support/connection_helper' class MysqlConnectionTest < ActiveRecord::TestCase + include ConnectionHelper + def setup super + @subscriber = SQLSubscriber.new + @subscription = ActiveSupport::Notifications.subscribe('sql.active_record', @subscriber) @connection = ActiveRecord::Base.connection - @connection.extend(LogIntercepter) - @connection.intercepted = true end def teardown - @connection.intercepted = false - @connection.logged = [] + ActiveSupport::Notifications.unsubscribe(@subscription) + super + end + + def test_bad_connection + assert_raise ActiveRecord::NoDatabaseError do + configuration = ActiveRecord::Base.configurations['arunit'].merge(database: 'inexistent_activerecord_unittest') + connection = ActiveRecord::Base.mysql2_connection(configuration) + connection.exec_query('drop table if exists ex') + end end def test_no_automatic_reconnection_after_timeout @@ -18,6 +29,11 @@ class MysqlConnectionTest < ActiveRecord::TestCase @connection.update('set @@wait_timeout=1') sleep 2 assert !@connection.active? + + # Repair all fixture connections so other tests won't break. + @fixture_connections.each do |c| + c.verify! + end end def test_successful_reconnection_after_timeout_with_manual_reconnect @@ -61,6 +77,14 @@ class MysqlConnectionTest < ActiveRecord::TestCase end end + def test_mysql_sql_mode_variable_overides_strict_mode + run_without_connection do |orig_connection| + ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { 'sql_mode' => 'ansi' })) + result = ActiveRecord::Base.connection.exec_query 'SELECT @@SESSION.sql_mode' + assert_not_equal [['STRICT_ALL_TABLES']], result.rows + end + end + def test_mysql_set_session_variable_to_default run_without_connection do |orig_connection| ActiveRecord::Base.establish_connection(orig_connection.deep_merge({:variables => {:default_week_format => :default}})) @@ -72,26 +96,22 @@ class MysqlConnectionTest < ActiveRecord::TestCase def test_logs_name_show_variable @connection.show_variable 'foo' - assert_equal "SCHEMA", @connection.logged[0][1] + assert_equal "SCHEMA", @subscriber.logged[0][1] end def test_logs_name_rename_column_sql @connection.execute "CREATE TABLE `bar_baz` (`foo` varchar(255))" - @connection.logged = [] + @subscriber.logged.clear @connection.send(:rename_column_sql, 'bar_baz', 'foo', 'foo2') - assert_equal "SCHEMA", @connection.logged[0][1] + assert_equal "SCHEMA", @subscriber.logged[0][1] ensure @connection.execute "DROP TABLE `bar_baz`" end - private - - def run_without_connection - original_connection = ActiveRecord::Base.remove_connection - begin - yield original_connection - ensure - ActiveRecord::Base.establish_connection(original_connection) + if mysql_56? + def test_quote_time_usec + assert_equal "'1970-01-01 00:00:00.000000'", @connection.quote(Time.at(0)) + assert_equal "'1970-01-01 00:00:00.000000'", @connection.quote(Time.at(0).to_datetime) end end end diff --git a/activerecord/test/cases/adapters/mysql2/explain_test.rb b/activerecord/test/cases/adapters/mysql2/explain_test.rb index 68ed361aeb..675703caa1 100644 --- a/activerecord/test/cases/adapters/mysql2/explain_test.rb +++ b/activerecord/test/cases/adapters/mysql2/explain_test.rb @@ -9,16 +9,16 @@ module ActiveRecord def test_explain_for_one_query explain = Developer.where(:id => 1).explain - assert_match %(EXPLAIN for: SELECT `developers`.* FROM `developers` WHERE `developers`.`id` = 1), explain - assert_match %(developers | const), explain + assert_match %(EXPLAIN for: SELECT `developers`.* FROM `developers` WHERE `developers`.`id` = 1), explain + assert_match %r(developers |.* const), explain end def test_explain_with_eager_loading explain = Developer.where(:id => 1).includes(:audit_logs).explain - assert_match %(EXPLAIN for: SELECT `developers`.* FROM `developers` WHERE `developers`.`id` = 1), explain - assert_match %(developers | const), explain - assert_match %(EXPLAIN for: SELECT `audit_logs`.* FROM `audit_logs` WHERE `audit_logs`.`developer_id` IN (1)), explain - assert_match %(audit_logs | ALL), explain + assert_match %(EXPLAIN for: SELECT `developers`.* FROM `developers` WHERE `developers`.`id` = 1), explain + assert_match %r(developers |.* const), explain + assert_match %(EXPLAIN for: SELECT `audit_logs`.* FROM `audit_logs` WHERE `audit_logs`.`developer_id` IN (1)), explain + assert_match %r(audit_logs |.* ALL), explain end end end diff --git a/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb b/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb index e76617b845..799d927ee4 100644 --- a/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb +++ b/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb @@ -2,7 +2,7 @@ require "cases/helper" class Group < ActiveRecord::Base Group.table_name = 'group' - belongs_to :select, :class_name => 'Select' + belongs_to :select has_one :values end @@ -37,7 +37,7 @@ class MysqlReservedWordTest < ActiveRecord::TestCase 'distinct_select'=>'distinct_id int, select_id int' end - def teardown + teardown do drop_tables_directly ['group', 'select', 'values', 'distinct', 'distinct_select', 'order'] end diff --git a/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb b/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb index 9ecd901eac..ec73ec35aa 100644 --- a/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb +++ b/activerecord/test/cases/adapters/mysql2/schema_migrations_test.rb @@ -4,22 +4,35 @@ module ActiveRecord module ConnectionAdapters class Mysql2Adapter class SchemaMigrationsTest < ActiveRecord::TestCase - def test_initializes_schema_migrations_for_encoding_utf8mb4 - conn = ActiveRecord::Base.connection + def test_renaming_index_on_foreign_key + connection.add_index "engines", "car_id" + connection.execute "ALTER TABLE engines ADD CONSTRAINT fk_engines_cars FOREIGN KEY (car_id) REFERENCES cars(id)" + + connection.rename_index("engines", "index_engines_on_car_id", "idx_renamed") + assert_equal ["idx_renamed"], connection.indexes("engines").map(&:name) + ensure + connection.execute "ALTER TABLE engines DROP FOREIGN KEY fk_engines_cars" + end + def test_initializes_schema_migrations_for_encoding_utf8mb4 smtn = ActiveRecord::Migrator.schema_migrations_table_name - conn.drop_table(smtn) if conn.table_exists?(smtn) + connection.drop_table(smtn) if connection.table_exists?(smtn) - config = conn.instance_variable_get(:@config) + config = connection.instance_variable_get(:@config) original_encoding = config[:encoding] config[:encoding] = 'utf8mb4' - conn.initialize_schema_migrations_table + connection.initialize_schema_migrations_table - assert conn.column_exists?(smtn, :version, :string, limit: Mysql2Adapter::MAX_INDEX_LENGTH_FOR_UTF8MB4) + assert connection.column_exists?(smtn, :version, :string, limit: Mysql2Adapter::MAX_INDEX_LENGTH_FOR_UTF8MB4) ensure config[:encoding] = original_encoding end + + private + def connection + @connection ||= ActiveRecord::Base.connection + end end end end diff --git a/activerecord/test/cases/adapters/mysql2/schema_test.rb b/activerecord/test/cases/adapters/mysql2/schema_test.rb index 5db60ff8a0..43c9116b5a 100644 --- a/activerecord/test/cases/adapters/mysql2/schema_test.rb +++ b/activerecord/test/cases/adapters/mysql2/schema_test.rb @@ -65,6 +65,15 @@ module ActiveRecord assert_nil index_c.using assert_equal :fulltext, index_c.type end + + def test_drop_temporary_table + @connection.transaction do + @connection.create_table(:temp_table, temporary: true) + # if it doesn't properly say DROP TEMPORARY TABLE, the transaction commit + # will complain that no transaction is active + @connection.drop_table(:temp_table, temporary: true) + end + end end end end |