Class: SchemaFerry::Converter::TypeMapper
- Inherits:
-
Object
- Object
- SchemaFerry::Converter::TypeMapper
- Defined in:
- lib/schema_ferry/converter/type_mapper.rb
Constant Summary collapse
- LIMIT_STRIPPED_TYPES =
PG has no limit concept for text/binary/bigint/float; drop the MySQL-derived limits (float's limit: 53 is DOUBLE's internal bit width, not something AR ever reads back from a PG column).
%i[text binary bigint float].freeze
- DEFAULT_PRECISION_TYPES =
PG's default timestamp precision is 6. Spelling it out makes ridgepole see a diff against the PG export (which omits it) on every run.
%i[datetime time].freeze
- PG_DEFAULT_PRECISION =
6- NO_PRECISION_TYPES =
ActiveRecord's PostgreSQL adapter never honors a precision option on :timestamptz (only :datetime/:timestamp/:time do — see ActiveRecord::ConnectionAdapters::SchemaStatements#type_to_sql). Declaring one is always a lie, so it must never be emitted.
%i[timestamptz].freeze
- DEFAULTS =
{ json: :jsonb }.freeze
- KNOWN_TYPES =
%i[ string text integer bigint float decimal datetime date time boolean binary json jsonb ].freeze
Instance Method Summary collapse
-
#call(ar_type, options = {}) ⇒ Object
Returns [pg_type_sym, adjusted_options_hash].
-
#initialize(global_overrides = {}) ⇒ TypeMapper
constructor
A new instance of TypeMapper.
Constructor Details
#initialize(global_overrides = {}) ⇒ TypeMapper
Returns a new instance of TypeMapper.
31 32 33 |
# File 'lib/schema_ferry/converter/type_mapper.rb', line 31 def initialize(global_overrides = {}) @overrides = DEFAULTS.merge(global_overrides) end |
Instance Method Details
#call(ar_type, options = {}) ⇒ Object
Returns [pg_type_sym, adjusted_options_hash]
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/schema_ferry/converter/type_mapper.rb', line 36 def call(ar_type, = {}) unless KNOWN_TYPES.include?(ar_type) raise ConversionError, "Unknown MySQL AR type: #{ar_type.inspect}. " \ "Use map_type or map_column to specify a PostgreSQL type." end pg_type = @overrides.fetch(ar_type, ar_type) adjusted = .dup pg_type, adjusted = normalize_integer(adjusted) if pg_type == :integer adjusted.delete(:limit) if LIMIT_STRIPPED_TYPES.include?(pg_type) strip_default_precision(pg_type, adjusted) if pg_type == :decimal # PG numeric(20) equals numeric(20,0) and is exported without scale. adjusted[:scale] = nil if adjusted[:scale]&.zero? # AR's schema dumper renders decimal defaults as a string (e.g. # `default: "0"`), not a numeric literal. ridgepole compares against # that dumped form, so a BigDecimal/Integer default never matches # and gets re-applied on every run. adjusted[:default] = adjusted[:default]&.to_s end [pg_type, adjusted] end |