Module: ActiveRecord::DatabaseValidations::MySQL

Defined in:
lib/active_record/database_validations/mysql.rb

Constant Summary collapse

TYPE_LIMITS =
{
  char:       { type: :characters },
  varchar:    { type: :characters },
  varbinary:  { type: :bytes },

  tinytext:   { type: :bytes, maximum: 2 **  8 - 1 },
  text:       { type: :bytes, maximum: 2 ** 16 - 1 },
  mediumtext: { type: :bytes, maximum: 2 ** 24 - 1 },
  longtext:   { type: :bytes, maximum: 2 ** 32 - 1 },

  tinyblob:   { type: :bytes, maximum: 2 **  8 - 1 },
  blob:       { type: :bytes, maximum: 2 ** 16 - 1 },
  mediumblob: { type: :bytes, maximum: 2 ** 24 - 1 },
  longblob:   { type: :bytes, maximum: 2 ** 32 - 1 },
}

Class Method Summary collapse

Class Method Details

.column_range(column) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/active_record/database_validations/mysql.rb', line 31

def self.column_range(column)
  args = {}
  unsigned = column.sql_type =~ / unsigned\z/
  case column.type
  when :decimal
    args[:less_than] = maximum = 10 ** (column.precision - column.scale)
    if unsigned
      args[:greater_than_or_equal_to] = 0
    else
      args[:greater_than] = 0 - maximum
    end

  when :integer
    args[:only_integer] = true
    args[:less_than] = unsigned ? 1 << (column.limit * 8) : 1 << (column.limit * 8 - 1)
    args[:greater_than_or_equal_to] = unsigned ? 0 : 0 - args[:less_than]
  end

  args
end

.column_size_limit(column) ⇒ Object



20
21
22
23
24
25
26
27
28
29
# File 'lib/active_record/database_validations/mysql.rb', line 20

def self.column_size_limit(column)
  column_type = column.sql_type.sub(/\(.*\z/, '').gsub(/\s/, '_').to_sym
  type_limit  = TYPE_LIMITS.fetch(column_type, {})

  [
    column.limit || type_limit[:maximum],
    type_limit[:type],
    determine_encoding(column),
  ]
end

.determine_encoding(column) ⇒ Object



52
53
54
55
56
57
58
59
# File 'lib/active_record/database_validations/mysql.rb', line 52

def self.determine_encoding(column)
  column = ActiveRecord::Validations::TypedColumn.new(column)
  return nil unless column.text?
  case column.collation
    when /\Autf8/; Encoding::UTF_8
    else raise NotImplementedError, "Don't know how to determine the Ruby encoding for MySQL's #{column.collation} collation."
  end
end

.requires_transcoding?(value, column_encoding = nil) ⇒ Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/active_record/database_validations/mysql.rb', line 61

def self.requires_transcoding?(value, column_encoding = nil)
  column_encoding.present? && column_encoding != value.encoding
end

.value_for_column(value, column_encoding = nil) ⇒ Object



65
66
67
68
69
70
71
72
73
# File 'lib/active_record/database_validations/mysql.rb', line 65

def self.value_for_column(value, column_encoding = nil)
  value = value.to_s unless value.is_a?(String)

  if requires_transcoding?(value, column_encoding)
    return value.encode(Encoding::UTF_8)
  end

  value
end