Class: DeclareSchema::Model::FieldSpec
- Inherits:
-
Object
- Object
- DeclareSchema::Model::FieldSpec
show all
- Defined in:
- lib/declare_schema/model/field_spec.rb
Defined Under Namespace
Classes: UnknownSqlTypeError
Constant Summary
collapse
- MYSQL_TINYTEXT_LIMIT =
0xff
- MYSQL_TEXT_LIMIT =
0xffff
- MYSQL_MEDIUMTEXT_LIMIT =
0xff_ffff
- MYSQL_LONGTEXT_LIMIT =
0xffff_ffff
- MYSQL_TEXT_LIMITS_ASCENDING =
[MYSQL_TINYTEXT_LIMIT, MYSQL_TEXT_LIMIT, MYSQL_MEDIUMTEXT_LIMIT, MYSQL_LONGTEXT_LIMIT].freeze
- TYPE_SYNONYMS =
{ timestamp: :datetime }.freeze
- SQLITE_COLUMN_CLASS =
begin
ActiveRecord::ConnectionAdapters::SQLiteColumn
rescue NameError
NilClass
end
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(model, name, type, options = {}) ⇒ FieldSpec
Returns a new instance of FieldSpec.
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
# File 'lib/declare_schema/model/field_spec.rb', line 36
def initialize(model, name, type, options = {})
name == "id" and raise ArgumentError, "you cannot provide a field spec for the primary key"
@model = model
@name = name.to_sym
type.is_a?(Symbol) or raise ArgumentError, "type must be a Symbol; got #{type.inspect}"
@type = type
position_option = options.delete(:position)
@options = options
case type
when :text
@options[:default] and raise "default may not be given for :text field #{model}##{@name}"
if self.class.mysql_text_limits?
@options[:limit] = self.class.round_up_mysql_text_limit(@options[:limit] || MYSQL_LONGTEXT_LIMIT)
end
when :string
@options[:limit] or raise "limit must be given for :string field #{model}##{@name}: #{@options.inspect}; do you want `limit: 255`?"
else
@options[:collation] and raise "collation may only given for :string and :text fields"
@options[:charset] and raise "charset may only given for :string and :text fields"
end
@position = position_option || model.field_specs.length
end
|
Instance Attribute Details
#model ⇒ Object
Returns the value of attribute model.
34
35
36
|
# File 'lib/declare_schema/model/field_spec.rb', line 34
def model
@model
end
|
#name ⇒ Object
Returns the value of attribute name.
34
35
36
|
# File 'lib/declare_schema/model/field_spec.rb', line 34
def name
@name
end
|
#options ⇒ Object
Returns the value of attribute options.
34
35
36
|
# File 'lib/declare_schema/model/field_spec.rb', line 34
def options
@options
end
|
#position ⇒ Object
Returns the value of attribute position.
34
35
36
|
# File 'lib/declare_schema/model/field_spec.rb', line 34
def position
@position
end
|
#type ⇒ Object
Returns the value of attribute type.
34
35
36
|
# File 'lib/declare_schema/model/field_spec.rb', line 34
def type
@type
end
|
Class Method Details
.mysql_text_limits? ⇒ Boolean
method for easy stubbing in tests
17
18
19
20
21
22
23
|
# File 'lib/declare_schema/model/field_spec.rb', line 17
def mysql_text_limits?
if defined?(@mysql_text_limits)
@mysql_text_limits
else
@mysql_text_limits = ActiveRecord::Base.connection.class.name.match?(/mysql/i)
end
end
|
.round_up_mysql_text_limit(limit) ⇒ Object
25
26
27
28
29
30
31
|
# File 'lib/declare_schema/model/field_spec.rb', line 25
def round_up_mysql_text_limit(limit)
MYSQL_TEXT_LIMITS_ASCENDING.find do |mysql_supported_text_limit|
if limit <= mysql_supported_text_limit
mysql_supported_text_limit
end
end or raise ArgumentError, "limit of #{limit} is too large for MySQL"
end
|
Instance Method Details
#charset ⇒ Object
114
115
116
117
118
|
# File 'lib/declare_schema/model/field_spec.rb', line 114
def charset
if ActiveRecord::Base.connection.class.name.match?(/mysql/i)
(@options[:charset] || model.table_options[:charset] || Generators::DeclareSchema::Migration::Migrator.default_charset).to_s
end
end
|
#collation ⇒ Object
108
109
110
111
112
|
# File 'lib/declare_schema/model/field_spec.rb', line 108
def collation
if ActiveRecord::Base.connection.class.name.match?(/mysql/i)
(@options[:collation] || model.table_options[:collation] || Generators::DeclareSchema::Migration::Migrator.default_collation).to_s
end
end
|
#default ⇒ Object
104
105
106
|
# File 'lib/declare_schema/model/field_spec.rb', line 104
def default
@options[:default]
end
|
#different_to?(table_name, col_spec) ⇒ Boolean
127
128
129
|
# File 'lib/declare_schema/model/field_spec.rb', line 127
def different_to?(table_name, col_spec)
!same_as(table_name, col_spec)
end
|
#limit ⇒ Object
88
89
90
|
# File 'lib/declare_schema/model/field_spec.rb', line 88
def limit
@options[:limit] || native_types[sql_type][:limit]
end
|
#null ⇒ Object
100
101
102
|
# File 'lib/declare_schema/model/field_spec.rb', line 100
def null
!:null.in?(@options) || @options[:null]
end
|
#precision ⇒ Object
92
93
94
|
# File 'lib/declare_schema/model/field_spec.rb', line 92
def precision
@options[:precision]
end
|
#same_as(table_name, col_spec) ⇒ Object
131
132
133
134
135
|
# File 'lib/declare_schema/model/field_spec.rb', line 131
def same_as(table_name, col_spec)
same_type?(col_spec) &&
same_attributes?(col_spec) &&
(!type.in?([:text, :string]) || same_charset_and_collation?(table_name, col_spec))
end
|
#same_type?(col_spec) ⇒ Boolean
120
121
122
123
124
125
|
# File 'lib/declare_schema/model/field_spec.rb', line 120
def same_type?(col_spec)
type = sql_type
normalized_type = TYPE_SYNONYMS[type] || type
normalized_col_spec_type = TYPE_SYNONYMS[col_spec.type] || col_spec.type
normalized_type == normalized_col_spec_type
end
|
#scale ⇒ Object
96
97
98
|
# File 'lib/declare_schema/model/field_spec.rb', line 96
def scale
@options[:scale]
end
|
#sql_options ⇒ Object
84
85
86
|
# File 'lib/declare_schema/model/field_spec.rb', line 84
def sql_options
@options.except(:ruby_default, :validates)
end
|
#sql_type ⇒ Object
73
74
75
76
77
78
79
80
81
82
|
# File 'lib/declare_schema/model/field_spec.rb', line 73
def sql_type
@options[:sql_type] || begin
if native_type?(type)
type
else
field_class = DeclareSchema.to_class(type)
field_class && field_class::COLUMN_TYPE or raise UnknownSqlTypeError, "#{type.inspect} for #{model}##{@name}"
end
end
end
|