mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fix to correctly schema dump the tinyblob
Currently `tinyblob` is dumped to `t.binary "tiny_blob", limit: 255`. But `t.binary ... limit: 255` is generating SQL to `varchar(255)`. It is incorrect. This commit fixes this problem.
This commit is contained in:
parent
de732e0015
commit
f8438ae336
8 changed files with 36 additions and 16 deletions
|
@ -134,6 +134,7 @@ module ActiveRecord
|
|||
time: { name: "time" },
|
||||
date: { name: "date" },
|
||||
binary: { name: "blob" },
|
||||
blob: { name: "blob" },
|
||||
boolean: { name: "tinyint", limit: 1 },
|
||||
bigint: { name: "bigint" },
|
||||
json: { name: "json" },
|
||||
|
@ -679,12 +680,18 @@ module ActiveRecord
|
|||
# Maps logical Rails types to MySQL-specific data types.
|
||||
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'
|
||||
integer_to_sql(limit)
|
||||
when 'text'
|
||||
text_to_sql(limit)
|
||||
when 'blob'
|
||||
binary_to_sql(limit)
|
||||
when 'binary'
|
||||
if (0..0xfff) === limit
|
||||
"varbinary(#{limit})"
|
||||
else
|
||||
binary_to_sql(limit)
|
||||
end
|
||||
else
|
||||
super(type, limit, precision, scale)
|
||||
end
|
||||
|
@ -997,15 +1004,6 @@ module ActiveRecord
|
|||
MySQL::TableDefinition.new(native_database_types, name, temporary, options, as)
|
||||
end
|
||||
|
||||
def binary_to_sql(limit) # :nodoc:
|
||||
case limit
|
||||
when 0..0xfff; "varbinary(#{limit})"
|
||||
when nil; "blob"
|
||||
when 0x1000..0xffffffff; "blob(#{limit})"
|
||||
else raise(ActiveRecordError, "No binary type has byte length #{limit}")
|
||||
end
|
||||
end
|
||||
|
||||
def integer_to_sql(limit) # :nodoc:
|
||||
case limit
|
||||
when 1; 'tinyint'
|
||||
|
@ -1028,6 +1026,16 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def binary_to_sql(limit) # :nodoc:
|
||||
case limit
|
||||
when 0..0xff; 'tinyblob'
|
||||
when nil, 0x100..0xffff; 'blob'
|
||||
when 0x10000..0xffffff; 'mediumblob'
|
||||
when 0x1000000..0xffffffff; 'longblob'
|
||||
else raise(ActiveRecordError, "No binary type has byte length #{limit}")
|
||||
end
|
||||
end
|
||||
|
||||
class MysqlJson < Type::Internal::AbstractJson # :nodoc:
|
||||
def changed_in_place?(raw_old_value, new_value)
|
||||
# Normalization is required because MySQL JSON data format includes
|
||||
|
|
|
@ -7,6 +7,10 @@ module ActiveRecord
|
|||
super
|
||||
end
|
||||
|
||||
def blob(*args, **options)
|
||||
args.each { |name| column(name, :blob, options) }
|
||||
end
|
||||
|
||||
def json(*args, **options)
|
||||
args.each { |name| column(name, :json, options) }
|
||||
end
|
||||
|
|
|
@ -27,6 +27,14 @@ module ActiveRecord
|
|||
|
||||
private
|
||||
|
||||
def schema_type(column)
|
||||
if column.sql_type == 'tinyblob'
|
||||
'blob'
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def schema_limit(column)
|
||||
super unless column.type == :boolean
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ class MysqlSqlTypesTest < ActiveRecord::MysqlTestCase
|
|||
def test_binary_types
|
||||
assert_equal 'varbinary(64)', type_to_sql(:binary, 64)
|
||||
assert_equal 'varbinary(4095)', type_to_sql(:binary, 4095)
|
||||
assert_equal 'blob(4096)', type_to_sql(:binary, 4096)
|
||||
assert_equal 'blob', type_to_sql(:binary, 4096)
|
||||
assert_equal 'blob', type_to_sql(:binary)
|
||||
end
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ class Mysql2SqlTypesTest < ActiveRecord::Mysql2TestCase
|
|||
def test_binary_types
|
||||
assert_equal 'varbinary(64)', type_to_sql(:binary, 64)
|
||||
assert_equal 'varbinary(4095)', type_to_sql(:binary, 4095)
|
||||
assert_equal 'blob(4096)', type_to_sql(:binary, 4096)
|
||||
assert_equal 'blob', type_to_sql(:binary, 4096)
|
||||
assert_equal 'blob', type_to_sql(:binary)
|
||||
end
|
||||
|
||||
|
|
|
@ -215,7 +215,7 @@ class SchemaDumperTest < ActiveRecord::TestCase
|
|||
|
||||
def test_schema_dump_includes_length_for_mysql_blob_and_text_fields
|
||||
output = standard_dump
|
||||
assert_match %r{t\.binary\s+"tiny_blob",\s+limit: 255$}, output
|
||||
assert_match %r{t\.blob\s+"tiny_blob",\s+limit: 255$}, output
|
||||
assert_match %r{t\.binary\s+"normal_blob",\s+limit: 65535$}, output
|
||||
assert_match %r{t\.binary\s+"medium_blob",\s+limit: 16777215$}, output
|
||||
assert_match %r{t\.binary\s+"long_blob",\s+limit: 4294967295$}, output
|
||||
|
|
|
@ -2,7 +2,7 @@ ActiveRecord::Schema.define do
|
|||
create_table :binary_fields, force: true do |t|
|
||||
t.binary :var_binary, limit: 255
|
||||
t.binary :var_binary_large, limit: 4095
|
||||
t.column :tiny_blob, 'tinyblob', limit: 255
|
||||
t.blob :tiny_blob, limit: 255
|
||||
t.binary :normal_blob, limit: 65535
|
||||
t.binary :medium_blob, limit: 16777215
|
||||
t.binary :long_blob, limit: 2147483647
|
||||
|
|
|
@ -2,7 +2,7 @@ ActiveRecord::Schema.define do
|
|||
create_table :binary_fields, force: true do |t|
|
||||
t.binary :var_binary, limit: 255
|
||||
t.binary :var_binary_large, limit: 4095
|
||||
t.column :tiny_blob, 'tinyblob', limit: 255
|
||||
t.blob :tiny_blob, limit: 255
|
||||
t.binary :normal_blob, limit: 65535
|
||||
t.binary :medium_blob, limit: 16777215
|
||||
t.binary :long_blob, limit: 2147483647
|
||||
|
|
Loading…
Reference in a new issue