From f3772f729c72d098156b35eb105d3ffdd928c5eb Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Wed, 26 Nov 2014 18:54:07 +0900 Subject: Add `unsigned` support for numeric data types in MySQL Example: create_table :foos do |t| t.integer :unsigned_integer, unsigned: true t.bigint :unsigned_bigint, unsigned: true t.float :unsigned_float, unsigned: true t.decimal :unsigned_decimal, unsigned: true, precision: 10, scale: 2 end --- .../connection_adapters/abstract_mysql_adapter.rb | 32 +++++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) (limited to 'activerecord/lib/active_record/connection_adapters') 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 597f0d0597..55de098f70 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -17,7 +17,7 @@ module ActiveRecord end class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition - attr_accessor :charset + attr_accessor :charset, :unsigned end class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition @@ -30,6 +30,7 @@ module ActiveRecord column.type = :integer column.auto_increment = true end + column.unsigned ||= options[:unsigned] column.charset = options[:charset] column end @@ -65,6 +66,11 @@ module ActiveRecord create_sql end + def visit_ColumnDefinition(o) + o.sql_type = type_to_sql(o.type, o.limit, o.precision, o.scale, o.unsigned) + super + end + def visit_AddColumnDefinition(o) add_column_position!(super, column_options(o.column)) end @@ -117,6 +123,7 @@ module ActiveRecord spec = {} if column.auto_increment? spec[:id] = ':bigint' if column.bigint? + spec[:unsigned] = 'true' if column.unsigned? return if spec.empty? else spec[:id] = column.type.inspect @@ -125,6 +132,16 @@ module ActiveRecord spec end + def prepare_column_options(column) + spec = super + spec[:unsigned] = 'true' if column.unsigned? + spec + end + + def migration_keys + super + [:unsigned] + end + private def schema_limit(column) @@ -171,6 +188,10 @@ module ActiveRecord sql_type =~ /blob/i || type == :text end + def unsigned? + /unsigned/ === sql_type + end + def case_sensitive? collation && !collation.match(/_ci$/) end @@ -712,8 +733,8 @@ module ActiveRecord end # Maps logical Rails types to MySQL-specific data types. - def type_to_sql(type, limit = nil, precision = nil, scale = nil) - case type.to_s + def type_to_sql(type, limit = nil, precision = nil, scale = nil, unsigned = nil) + sql = case type.to_s when 'binary' binary_to_sql(limit) when 'integer' @@ -721,8 +742,11 @@ module ActiveRecord when 'text' text_to_sql(limit) else - super + super(type, limit, precision, scale) end + + sql << ' unsigned' if unsigned && type != :primary_key + sql end # SHOW VARIABLES LIKE 'name' -- cgit v1.2.3