Class: DeclareSchema::Model::Column
- Inherits:
-
Object
- Object
- DeclareSchema::Model::Column
- Defined in:
- lib/declare_schema/model/column.rb
Overview
This class is a wrapper for the ActiveRecord::…::Column class
Constant Summary collapse
- SCHEMA_KEYS =
[:type, :limit, :precision, :scale, :null, :default].freeze
Instance Attribute Summary collapse
-
#type ⇒ Object
readonly
Returns the value of attribute type.
Class Method Summary collapse
- .deserialize_default_value(column, type, default_value) ⇒ Object
- .equivalent_schema_attributes?(schema_attributes_lhs, schema_attributes_rhs) ⇒ Boolean
- .native_type?(type) ⇒ Boolean
-
.native_types ⇒ Object
MySQL example: { primary_key: “bigint auto_increment PRIMARY KEY”, string: { name: “varchar”, limit: 255 }, text: { name: “text”, limit: 65535}, integer: {name: “int”, limit: 4 }, float: {name: “float”, limit: 24 }, decimal: { name: “decimal” }, datetime: { name: “datetime” }, timestamp: { name: “timestamp” }, time: { name: “time” }, date: { name: “date” }, binary: { name>: “blob”, limit: 65535 }, boolean: { name: “tinyint”, limit: 1 }, json: { name: “json” } }.
-
.normalize_schema_attributes(schema_attributes, db_adapter_name) ⇒ Object
Normalizes schema attributes for the given database adapter name.
Instance Method Summary collapse
-
#initialize(model, current_table_name, column) ⇒ Column
constructor
A new instance of Column.
-
#schema_attributes ⇒ Object
omits keys with nil values.
Constructor Details
#initialize(model, current_table_name, column) ⇒ Column
Returns a new instance of Column.
92 93 94 95 96 97 98 |
# File 'lib/declare_schema/model/column.rb', line 92 def initialize(model, current_table_name, column) @model = model or raise ArgumentError, "must pass model" @current_table_name = current_table_name or raise ArgumentError, "must pass current_table_name" @column = column or raise ArgumentError, "must pass column" @type = @column.type self.class.native_type?(@type) or raise UnknownTypeError, "#{@type.inspect}" end |
Instance Attribute Details
#type ⇒ Object (readonly)
Returns the value of attribute type.
90 91 92 |
# File 'lib/declare_schema/model/column.rb', line 90 def type @type end |
Class Method Details
.deserialize_default_value(column, type, default_value) ⇒ Object
53 54 55 56 57 58 |
# File 'lib/declare_schema/model/column.rb', line 53 def deserialize_default_value(column, type, default_value) type or raise ArgumentError, "must pass type; got #{type.inspect}" cast_type = ActiveRecord::Base.connection.lookup_cast_type_from_column(column) or raise "cast_type not found for #{type}" cast_type.deserialize(default_value) end |
.equivalent_schema_attributes?(schema_attributes_lhs, schema_attributes_rhs) ⇒ Boolean
81 82 83 84 85 86 87 |
# File 'lib/declare_schema/model/column.rb', line 81 def equivalent_schema_attributes?(schema_attributes_lhs, schema_attributes_rhs) db_adapter_name = ActiveRecord::Base.connection.class.name normalized_lhs = normalize_schema_attributes(schema_attributes_lhs, db_adapter_name) normalized_rhs = normalize_schema_attributes(schema_attributes_rhs, db_adapter_name) normalized_lhs == normalized_rhs end |
.native_type?(type) ⇒ Boolean
10 11 12 |
# File 'lib/declare_schema/model/column.rb', line 10 def native_type?(type) type != :primary_key && (native_types.empty? || native_types[type]) # empty will happen with NullDBAdapter used in assets:precompile end |
.native_types ⇒ Object
MySQL example: { primary_key: “bigint auto_increment PRIMARY KEY”,
string: { name: "varchar", limit: 255 },
text: { name: "text", limit: 65535},
integer: {name: "int", limit: 4 },
float: {name: "float", limit: 24 },
decimal: { name: "decimal" },
datetime: { name: "datetime" },
timestamp: { name: "timestamp" },
time: { name: "time" },
date: { name: "date" },
binary: { name>: "blob", limit: 65535 },
boolean: { name: "tinyint", limit: 1 },
json: { name: "json" } }
SQLite example: { primary_key: “integer PRIMARY KEY AUTOINCREMENT NOT NULL”,
string: { name: "varchar" },
text: { name: "text"},
integer: { name: "integer" },
float: { name: "float" },
decimal: { name: "decimal" },
datetime: { name: "datetime" },
time: { name: "time" },
date: { name: "date" },
binary: { name: "blob" },
boolean: { name: "boolean" },
json: { name: "json" } }
42 43 44 45 46 47 48 49 50 51 |
# File 'lib/declare_schema/model/column.rb', line 42 def native_types @native_types ||= ActiveRecord::Base.connection.native_database_types.tap do |types| if ActiveRecord::Base.connection.class.name.match?(/mysql/i) types[:text][:limit] ||= 0xffff types[:binary][:limit] ||= 0xffff types[:varbinary] ||= { name: "varbinary" } # TODO: :varbinary is an Invoca addition to Rails; make it a configurable option end end end |
.normalize_schema_attributes(schema_attributes, db_adapter_name) ⇒ Object
Normalizes schema attributes for the given database adapter name. Note that the un-normalized attributes are still useful for generating migrations because those may be run with a different adapter. This method never mutates its argument.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/declare_schema/model/column.rb', line 64 def normalize_schema_attributes(schema_attributes, db_adapter_name) case schema_attributes[:type] when :boolean schema_attributes.reverse_merge(limit: 1) when :integer schema_attributes.reverse_merge(limit: 8) if db_adapter_name.match?(/sqlite/i) when :float schema_attributes.except(:limit) when :text schema_attributes.except(:limit) if db_adapter_name.match?(/sqlite/i) when :datetime schema_attributes.reverse_merge(precision: 0) when NilClass raise ArgumentError, ":type key not found; keys: #{schema_attributes.keys.inspect}" end || schema_attributes end |
Instance Method Details
#schema_attributes ⇒ Object
omits keys with nil values
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/declare_schema/model/column.rb', line 103 def schema_attributes SCHEMA_KEYS.each_with_object({}) do |key, result| value = case key when :default self.class.deserialize_default_value(@column, @type, @column.default) else col_value = @column.send(key) if col_value.nil? && (native_type = self.class.native_types[@column.type]) native_type[key] else col_value end end result[key] = value unless value.nil? end.tap do |result| if ActiveRecord::Base.connection.class.name.match?(/mysql/i) && @column.type.in?([:string, :text]) result.merge!(collation_and_charset_for_column(@current_table_name, @column.name)) end end end |