diff options
author | Sean Griffin <sean@seantheprogrammer.com> | 2016-01-10 19:03:07 -0700 |
---|---|---|
committer | Sean Griffin <sean@seantheprogrammer.com> | 2016-01-10 19:03:07 -0700 |
commit | 5465224892281a088422df438e4fc0ce7f6c8f5e (patch) | |
tree | 60d3260a104dd16a3ba005d079d9f809a5ccb10c | |
parent | 0cffe1b316b010b53dd5b5c6a63e4082d23e216d (diff) | |
parent | 560bf1c939d6928bc4debaf32178ed811d46c052 (diff) | |
download | rails-5465224892281a088422df438e4fc0ce7f6c8f5e.tar.gz rails-5465224892281a088422df438e4fc0ce7f6c8f5e.tar.bz2 rails-5465224892281a088422df438e4fc0ce7f6c8f5e.zip |
Merge pull request #22998 from kamipo/extract_mysql_column_class
Extract `MySQL::{Column|TypeMetadata}` classes to the appropriate files
4 files changed, 97 insertions, 85 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb index 828e46637d..d435d91102 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -1,7 +1,9 @@ require 'active_record/connection_adapters/abstract_adapter' +require 'active_record/connection_adapters/mysql/column' require 'active_record/connection_adapters/mysql/schema_creation' require 'active_record/connection_adapters/mysql/schema_definitions' require 'active_record/connection_adapters/mysql/schema_dumper' +require 'active_record/connection_adapters/mysql/type_metadata' require 'active_support/core_ext/string/strip' @@ -19,78 +21,6 @@ module ActiveRecord MySQL::SchemaCreation.new(self) end - class Column < ConnectionAdapters::Column # :nodoc: - delegate :strict, :extra, to: :sql_type_metadata, allow_nil: true - - def initialize(*) - super - assert_valid_default(default) - extract_default - end - - def extract_default - if blob_or_text_column? - @default = null || strict ? nil : '' - end - end - - def has_default? - return false if blob_or_text_column? # MySQL forbids defaults on blob and text columns - super - end - - def blob_or_text_column? - /\A(?:tiny|medium|long)?blob\b/ === sql_type || type == :text - end - - def unsigned? - /\bunsigned\z/ === sql_type - end - - def case_sensitive? - collation && !collation.match(/_ci$/) - end - - def auto_increment? - extra == 'auto_increment' - end - - private - - def assert_valid_default(default) - if blob_or_text_column? && default.present? - raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}" - end - end - end - - class MysqlTypeMetadata < DelegateClass(SqlTypeMetadata) # :nodoc: - attr_reader :extra, :strict - - def initialize(type_metadata, extra: "", strict: false) - super(type_metadata) - @type_metadata = type_metadata - @extra = extra - @strict = strict - end - - def ==(other) - other.is_a?(MysqlTypeMetadata) && - attributes_for_hash == other.attributes_for_hash - end - alias eql? == - - def hash - attributes_for_hash.hash - end - - protected - - def attributes_for_hash - [self.class, @type_metadata, extra, strict] - end - end - ## # :singleton-method: # By default, the Mysql2Adapter will consider all columns of type <tt>tinyint(1)</tt> @@ -234,7 +164,7 @@ module ActiveRecord end def new_column(field, default, sql_type_metadata = nil, null = true, default_function = nil, collation = nil) # :nodoc: - Column.new(field, default, sql_type_metadata, null, default_function, collation) + MySQL::Column.new(field, default, sql_type_metadata, null, default_function, collation) end # Must return the MySQL error number from the exception, if the exception has an @@ -848,7 +778,7 @@ module ActiveRecord end def fetch_type_metadata(sql_type, extra = "") - MysqlTypeMetadata.new(super(sql_type), extra: extra, strict: strict_mode?) + MySQL::TypeMetadata.new(super(sql_type), extra: extra, strict: strict_mode?) end def add_index_length(option_strings, column_names, options = {}) diff --git a/activerecord/lib/active_record/connection_adapters/mysql/column.rb b/activerecord/lib/active_record/connection_adapters/mysql/column.rb new file mode 100644 index 0000000000..9c45fdd44a --- /dev/null +++ b/activerecord/lib/active_record/connection_adapters/mysql/column.rb @@ -0,0 +1,50 @@ +module ActiveRecord + module ConnectionAdapters + module MySQL + class Column < ConnectionAdapters::Column # :nodoc: + delegate :strict, :extra, to: :sql_type_metadata, allow_nil: true + + def initialize(*) + super + assert_valid_default + extract_default + end + + def has_default? + return false if blob_or_text_column? # MySQL forbids defaults on blob and text columns + super + end + + def blob_or_text_column? + /\A(?:tiny|medium|long)?blob\b/ === sql_type || type == :text + end + + def unsigned? + /\bunsigned\z/ === sql_type + end + + def case_sensitive? + collation && collation !~ /_ci\z/ + end + + def auto_increment? + extra == 'auto_increment' + end + + private + + def extract_default + if blob_or_text_column? + @default = null || strict ? nil : '' + end + end + + def assert_valid_default + if blob_or_text_column? && default.present? + raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}" + end + end + end + end + end +end diff --git a/activerecord/lib/active_record/connection_adapters/mysql/type_metadata.rb b/activerecord/lib/active_record/connection_adapters/mysql/type_metadata.rb new file mode 100644 index 0000000000..e1e3f7b472 --- /dev/null +++ b/activerecord/lib/active_record/connection_adapters/mysql/type_metadata.rb @@ -0,0 +1,32 @@ +module ActiveRecord + module ConnectionAdapters + module MySQL + class TypeMetadata < DelegateClass(SqlTypeMetadata) # :nodoc: + attr_reader :extra, :strict + + def initialize(type_metadata, extra: "", strict: false) + super(type_metadata) + @type_metadata = type_metadata + @extra = extra + @strict = strict + end + + def ==(other) + other.is_a?(MySQL::TypeMetadata) && + attributes_for_hash == other.attributes_for_hash + end + alias eql? == + + def hash + attributes_for_hash.hash + end + + protected + + def attributes_for_hash + [self.class, @type_metadata, extra, strict] + end + end + end + end +end diff --git a/activerecord/test/cases/column_definition_test.rb b/activerecord/test/cases/column_definition_test.rb index 783a374116..81162b7e98 100644 --- a/activerecord/test/cases/column_definition_test.rb +++ b/activerecord/test/cases/column_definition_test.rb @@ -41,49 +41,49 @@ module ActiveRecord if current_adapter?(:Mysql2Adapter) def test_should_set_default_for_mysql_binary_data_types type = SqlTypeMetadata.new(type: :binary, sql_type: "binary(1)") - binary_column = AbstractMysqlAdapter::Column.new("title", "a", type) + binary_column = MySQL::Column.new("title", "a", type) assert_equal "a", binary_column.default type = SqlTypeMetadata.new(type: :binary, sql_type: "varbinary") - varbinary_column = AbstractMysqlAdapter::Column.new("title", "a", type) + varbinary_column = MySQL::Column.new("title", "a", type) assert_equal "a", varbinary_column.default end def test_should_be_empty_string_default_for_mysql_binary_data_types type = SqlTypeMetadata.new(type: :binary, sql_type: "binary(1)") - binary_column = AbstractMysqlAdapter::Column.new("title", "", type, false) + binary_column = MySQL::Column.new("title", "", type, false) assert_equal "", binary_column.default type = SqlTypeMetadata.new(type: :binary, sql_type: "varbinary") - varbinary_column = AbstractMysqlAdapter::Column.new("title", "", type, false) + varbinary_column = MySQL::Column.new("title", "", type, false) assert_equal "", varbinary_column.default end def test_should_not_set_default_for_blob_and_text_data_types assert_raise ArgumentError do - AbstractMysqlAdapter::Column.new("title", "a", SqlTypeMetadata.new(sql_type: "blob")) + MySQL::Column.new("title", "a", SqlTypeMetadata.new(sql_type: "blob")) end - text_type = AbstractMysqlAdapter::MysqlTypeMetadata.new( + text_type = MySQL::TypeMetadata.new( SqlTypeMetadata.new(type: :text)) assert_raise ArgumentError do - AbstractMysqlAdapter::Column.new("title", "Hello", text_type) + MySQL::Column.new("title", "Hello", text_type) end - text_column = AbstractMysqlAdapter::Column.new("title", nil, text_type) + text_column = MySQL::Column.new("title", nil, text_type) assert_equal nil, text_column.default - not_null_text_column = AbstractMysqlAdapter::Column.new("title", nil, text_type, false) + not_null_text_column = MySQL::Column.new("title", nil, text_type, false) assert_equal "", not_null_text_column.default end def test_has_default_should_return_false_for_blob_and_text_data_types binary_type = SqlTypeMetadata.new(sql_type: "blob") - blob_column = AbstractMysqlAdapter::Column.new("title", nil, binary_type) + blob_column = MySQL::Column.new("title", nil, binary_type) assert !blob_column.has_default? text_type = SqlTypeMetadata.new(type: :text) - text_column = AbstractMysqlAdapter::Column.new("title", nil, text_type) + text_column = MySQL::Column.new("title", nil, text_type) assert !text_column.has_default? end end |