declare_schema 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/declare_schema_build.yml +21 -5
- data/Appraisals +21 -4
- data/CHANGELOG.md +40 -0
- data/Gemfile +1 -2
- data/Gemfile.lock +7 -9
- data/README.md +3 -3
- data/Rakefile +17 -4
- data/bin/declare_schema +1 -1
- data/declare_schema.gemspec +1 -1
- data/gemfiles/rails_4_mysql.gemfile +22 -0
- data/gemfiles/{rails_4.gemfile → rails_4_sqlite.gemfile} +1 -2
- data/gemfiles/rails_5_mysql.gemfile +22 -0
- data/gemfiles/{rails_5.gemfile → rails_5_sqlite.gemfile} +1 -2
- data/gemfiles/rails_6_mysql.gemfile +22 -0
- data/gemfiles/{rails_6.gemfile → rails_6_sqlite.gemfile} +2 -3
- data/lib/declare_schema/command.rb +10 -3
- data/lib/declare_schema/model/column.rb +168 -0
- data/lib/declare_schema/model/field_spec.rb +59 -143
- data/lib/declare_schema/model/foreign_key_definition.rb +36 -25
- data/lib/declare_schema/model/table_options_definition.rb +8 -6
- data/lib/declare_schema/version.rb +1 -1
- data/lib/generators/declare_schema/migration/migration_generator.rb +1 -1
- data/lib/generators/declare_schema/migration/migrator.rb +142 -116
- data/spec/lib/declare_schema/field_declaration_dsl_spec.rb +1 -1
- data/spec/lib/declare_schema/field_spec_spec.rb +135 -38
- data/spec/lib/declare_schema/generator_spec.rb +4 -2
- data/spec/lib/declare_schema/interactive_primary_key_spec.rb +8 -2
- data/spec/lib/declare_schema/migration_generator_spec.rb +277 -171
- data/spec/lib/declare_schema/model/column_spec.rb +141 -0
- data/spec/lib/declare_schema/model/foreign_key_definition_spec.rb +93 -0
- data/spec/lib/declare_schema/model/index_definition_spec.rb +4 -5
- data/spec/lib/declare_schema/model/table_options_definition_spec.rb +19 -29
- data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +12 -26
- data/spec/support/acceptance_spec_helpers.rb +3 -3
- metadata +15 -9
@@ -26,12 +26,14 @@ module DeclareSchema
|
|
26
26
|
|
27
27
|
def mysql_table_options(connection, table_name)
|
28
28
|
database = connection.current_database
|
29
|
-
defaults = connection.select_one(<<~EOS)
|
29
|
+
defaults = connection.select_one(<<~EOS) or raise "no defaults found for table #{table_name}"
|
30
30
|
SELECT CCSA.character_set_name, CCSA.collation_name
|
31
|
-
FROM information_schema
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
FROM information_schema.TABLES as T
|
32
|
+
JOIN information_schema.COLLATION_CHARACTER_SET_APPLICABILITY as CCSA
|
33
|
+
ON CCSA.collation_name = T.table_collation
|
34
|
+
WHERE
|
35
|
+
T.table_schema = '#{connection.quote_string(database)}' AND
|
36
|
+
T.table_name = '#{connection.quote_string(table_name)}'
|
35
37
|
EOS
|
36
38
|
|
37
39
|
defaults["character_set_name"] or raise "character_set_name missing from #{defaults.inspect}"
|
@@ -75,7 +77,7 @@ module DeclareSchema
|
|
75
77
|
alias to_s settings
|
76
78
|
|
77
79
|
def alter_table_statement
|
78
|
-
statement = "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name)} #{to_s}
|
80
|
+
statement = "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name)} #{to_s}"
|
79
81
|
"execute #{statement.inspect}"
|
80
82
|
end
|
81
83
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'active_record'
|
4
|
+
require 'active_record/connection_adapters/abstract_adapter'
|
4
5
|
|
5
6
|
module Generators
|
6
7
|
module DeclareSchema
|
@@ -71,8 +72,8 @@ module Generators
|
|
71
72
|
class Migrator
|
72
73
|
class Error < RuntimeError; end
|
73
74
|
|
74
|
-
DEFAULT_CHARSET =
|
75
|
-
DEFAULT_COLLATION =
|
75
|
+
DEFAULT_CHARSET = "utf8mb4"
|
76
|
+
DEFAULT_COLLATION = "utf8mb4_bin"
|
76
77
|
|
77
78
|
@ignore_models = []
|
78
79
|
@ignore_tables = []
|
@@ -82,9 +83,18 @@ module Generators
|
|
82
83
|
@default_collation = DEFAULT_COLLATION
|
83
84
|
|
84
85
|
class << self
|
85
|
-
attr_accessor :ignore_models, :ignore_tables, :disable_indexing, :disable_constraints
|
86
|
-
|
87
|
-
|
86
|
+
attr_accessor :ignore_models, :ignore_tables, :disable_indexing, :disable_constraints
|
87
|
+
attr_reader :active_record_class, :default_charset, :default_collation, :before_generating_migration_callback
|
88
|
+
|
89
|
+
def default_charset=(charset)
|
90
|
+
charset.is_a?(String) or raise ArgumentError, "charset must be a string (got #{charset.inspect})"
|
91
|
+
@default_charset = charset
|
92
|
+
end
|
93
|
+
|
94
|
+
def default_collation=(collation)
|
95
|
+
collation.is_a?(String) or raise ArgumentError, "collation must be a string (got #{collation.inspect})"
|
96
|
+
@default_collation = collation
|
97
|
+
end
|
88
98
|
|
89
99
|
def active_record_class
|
90
100
|
@active_record_class.is_a?(Class) or @active_record_class = @active_record_class.to_s.constantize
|
@@ -107,20 +117,6 @@ module Generators
|
|
107
117
|
ActiveRecord::Base.connection
|
108
118
|
end
|
109
119
|
|
110
|
-
def fix_native_types(types)
|
111
|
-
case connection.class.name
|
112
|
-
when /mysql/i
|
113
|
-
types[:integer][:limit] ||= 11
|
114
|
-
types[:text][:limit] ||= 0xffff
|
115
|
-
types[:binary][:limit] ||= 0xffff
|
116
|
-
end
|
117
|
-
types
|
118
|
-
end
|
119
|
-
|
120
|
-
def native_types
|
121
|
-
@native_types ||= fix_native_types(connection.native_database_types)
|
122
|
-
end
|
123
|
-
|
124
120
|
def before_generating_migration(&block)
|
125
121
|
block or raise ArgumentError, 'A block is required when setting the before_generating_migration callback'
|
126
122
|
@before_generating_migration_callback = block
|
@@ -290,7 +286,7 @@ module Generators
|
|
290
286
|
"drop_table :#{t}"
|
291
287
|
end * "\n"
|
292
288
|
undo_drops = to_drop.map do |t|
|
293
|
-
|
289
|
+
add_table_back(t)
|
294
290
|
end * "\n\n"
|
295
291
|
|
296
292
|
creates = to_create.map do |t|
|
@@ -336,7 +332,7 @@ module Generators
|
|
336
332
|
disable_auto_increment = model.respond_to?(:disable_auto_increment) && model.disable_auto_increment
|
337
333
|
table_options_definition = ::DeclareSchema::Model::TableOptionsDefinition.new(model.table_name, table_options_for_model(model))
|
338
334
|
field_definitions = [
|
339
|
-
|
335
|
+
("t.integer :id, limit: 8, auto_increment: false, primary_key: true" if disable_auto_increment),
|
340
336
|
*(model.field_specs.values.sort_by(&:position).map { |f| create_field(f, longest_field_name) })
|
341
337
|
].compact
|
342
338
|
|
@@ -377,12 +373,12 @@ module Generators
|
|
377
373
|
end
|
378
374
|
|
379
375
|
def create_constraints(model)
|
380
|
-
model.constraint_specs.map { |fk| fk.to_add_statement
|
376
|
+
model.constraint_specs.map { |fk| fk.to_add_statement }
|
381
377
|
end
|
382
378
|
|
383
379
|
def create_field(field_spec, field_name_width)
|
384
|
-
options = fk_field_options(field_spec.model, field_spec.name)
|
385
|
-
args = [field_spec.name.inspect] + format_options(options
|
380
|
+
options = field_spec.sql_options.merge(fk_field_options(field_spec.model, field_spec.name))
|
381
|
+
args = [field_spec.name.inspect] + format_options(options.compact)
|
386
382
|
format("t.%-*s %s", field_name_width, field_spec.sql_type, args.join(', '))
|
387
383
|
end
|
388
384
|
|
@@ -420,12 +416,12 @@ module Generators
|
|
420
416
|
adds = to_add.map do |c|
|
421
417
|
args =
|
422
418
|
if (spec = model.field_specs[c])
|
423
|
-
options = fk_field_options(model, c)
|
424
|
-
[":#{spec.sql_type}", *format_options(options
|
419
|
+
options = spec.sql_options.merge(fk_field_options(model, c))
|
420
|
+
[":#{spec.sql_type}", *format_options(options.compact)]
|
425
421
|
else
|
426
422
|
[":integer"]
|
427
423
|
end
|
428
|
-
"add_column :#{new_table_name}, :#{c},
|
424
|
+
["add_column :#{new_table_name}, :#{c}", *args].join(', ')
|
429
425
|
end
|
430
426
|
undo_adds = to_add.map do |c|
|
431
427
|
"remove_column :#{new_table_name}, :#{c}"
|
@@ -435,36 +431,30 @@ module Generators
|
|
435
431
|
"remove_column :#{new_table_name}, :#{c}"
|
436
432
|
end
|
437
433
|
undo_removes = to_remove.map do |c|
|
438
|
-
|
434
|
+
add_column_back(model, current_table_name, c)
|
439
435
|
end
|
440
436
|
|
441
437
|
old_names = to_rename.invert
|
442
438
|
changes = []
|
443
439
|
undo_changes = []
|
444
|
-
to_change.each do |
|
445
|
-
|
446
|
-
|
447
|
-
spec
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
change_spec[:charset] = spec.charset unless spec.charset.nil?
|
459
|
-
|
460
|
-
changes << "change_column :#{new_table_name}, :#{c}, " +
|
461
|
-
([":#{spec.sql_type}"] + format_options(change_spec, spec.sql_type, changing: true)).join(", ")
|
462
|
-
back = change_column_back(current_table_name, col_name)
|
463
|
-
undo_changes << back unless back.blank?
|
440
|
+
to_change.each do |col_name_to_change|
|
441
|
+
orig_col_name = old_names[col_name_to_change] || col_name_to_change
|
442
|
+
column = db_columns[orig_col_name] or raise "failed to find column info for #{orig_col_name.inspect}"
|
443
|
+
spec = model.field_specs[col_name_to_change] or raise "failed to find field spec for #{col_name_to_change.inspect}"
|
444
|
+
spec_attrs = spec.schema_attributes(column)
|
445
|
+
column_declaration = ::DeclareSchema::Model::Column.new(model, current_table_name, column)
|
446
|
+
col_attrs = column_declaration.schema_attributes
|
447
|
+
if !::DeclareSchema::Model::Column.equivalent_schema_attributes?(spec_attrs, col_attrs)
|
448
|
+
normalized_schema_attributes = spec_attrs.merge(fk_field_options(model, col_name_to_change))
|
449
|
+
|
450
|
+
type = normalized_schema_attributes.delete(:type) or raise "no :type found in #{normalized_schema_attributes.inspect}"
|
451
|
+
changes << ["change_column #{new_table_name.to_sym.inspect}", col_name_to_change.to_sym.inspect,
|
452
|
+
type.to_sym.inspect, *format_options(normalized_schema_attributes)].join(", ")
|
453
|
+
undo_changes << change_column_back(model, current_table_name, orig_col_name)
|
464
454
|
end
|
465
|
-
end
|
455
|
+
end
|
466
456
|
|
467
|
-
index_changes, undo_index_changes = change_indexes(model, current_table_name)
|
457
|
+
index_changes, undo_index_changes = change_indexes(model, current_table_name, to_remove)
|
468
458
|
fk_changes, undo_fk_changes = if ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/)
|
469
459
|
[[], []]
|
470
460
|
else
|
@@ -476,41 +466,42 @@ module Generators
|
|
476
466
|
[[], []]
|
477
467
|
end
|
478
468
|
|
479
|
-
[(renames + adds + removes + changes)
|
469
|
+
[(renames + adds + removes + changes) * "\n",
|
480
470
|
(undo_renames + undo_adds + undo_removes + undo_changes) * "\n",
|
481
|
-
index_changes
|
482
|
-
undo_index_changes
|
483
|
-
fk_changes
|
484
|
-
undo_fk_changes
|
485
|
-
table_options_changes
|
486
|
-
undo_table_options_changes
|
471
|
+
index_changes * "\n",
|
472
|
+
undo_index_changes * "\n",
|
473
|
+
fk_changes * "\n",
|
474
|
+
undo_fk_changes * "\n",
|
475
|
+
table_options_changes * "\n",
|
476
|
+
undo_table_options_changes * "\n"]
|
487
477
|
end
|
488
478
|
|
489
|
-
def change_indexes(model, old_table_name)
|
490
|
-
return [[], []]
|
479
|
+
def change_indexes(model, old_table_name, to_remove)
|
480
|
+
Migrator.disable_constraints and return [[], []]
|
491
481
|
|
492
482
|
new_table_name = model.table_name
|
493
483
|
existing_indexes = ::DeclareSchema::Model::IndexDefinition.for_model(model, old_table_name)
|
494
484
|
model_indexes_with_equivalents = model.index_definitions_with_primary_key
|
495
485
|
model_indexes = model_indexes_with_equivalents.map do |i|
|
496
486
|
if i.explicit_name.nil?
|
497
|
-
if
|
498
|
-
i.with_name(
|
487
|
+
if (existing = existing_indexes.find { |e| i != e && e.equivalent?(i) })
|
488
|
+
i.with_name(existing.name)
|
499
489
|
end
|
500
490
|
end || i
|
501
491
|
end
|
502
|
-
existing_has_primary_key = existing_indexes.any?
|
492
|
+
existing_has_primary_key = existing_indexes.any? do |i|
|
493
|
+
i.name == ::DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME &&
|
494
|
+
!i.fields.all? { |f| to_remove.include?(f) } # if we're removing the primary key column(s), the primary key index will be removed too
|
495
|
+
end
|
503
496
|
model_has_primary_key = model_indexes.any? { |i| i.name == ::DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME }
|
504
497
|
|
505
|
-
add_indexes_init = model_indexes - existing_indexes
|
506
|
-
drop_indexes_init = existing_indexes - model_indexes
|
507
498
|
undo_add_indexes = []
|
508
|
-
|
509
|
-
add_indexes = add_indexes_init.map do |i|
|
499
|
+
add_indexes = (model_indexes - existing_indexes).map do |i|
|
510
500
|
undo_add_indexes << drop_index(old_table_name, i.name) unless i.name == ::DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME
|
511
501
|
i.to_add_statement(new_table_name, existing_has_primary_key)
|
512
502
|
end
|
513
|
-
|
503
|
+
undo_drop_indexes = []
|
504
|
+
drop_indexes = (existing_indexes - model_indexes).map do |i|
|
514
505
|
undo_drop_indexes << i.to_add_statement(old_table_name, model_has_primary_key)
|
515
506
|
drop_index(new_table_name, i.name) unless i.name == ::DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME
|
516
507
|
end.compact
|
@@ -526,59 +517,50 @@ module Generators
|
|
526
517
|
end
|
527
518
|
|
528
519
|
def change_foreign_key_constraints(model, old_table_name)
|
529
|
-
ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/) and raise 'SQLite does not support foreign keys'
|
530
|
-
return [[], []]
|
520
|
+
ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/) and raise ArgumentError, 'SQLite does not support foreign keys'
|
521
|
+
Migrator.disable_indexing and return [[], []]
|
531
522
|
|
532
523
|
new_table_name = model.table_name
|
533
524
|
existing_fks = ::DeclareSchema::Model::ForeignKeyDefinition.for_model(model, old_table_name)
|
534
525
|
model_fks = model.constraint_specs
|
535
|
-
add_fks = model_fks - existing_fks
|
536
|
-
drop_fks = existing_fks - model_fks
|
537
|
-
undo_add_fks = []
|
538
|
-
undo_drop_fks = []
|
539
526
|
|
540
|
-
|
527
|
+
undo_add_fks = []
|
528
|
+
add_fks = (model_fks - existing_fks).map do |fk|
|
541
529
|
# next if fk.parent.constantize.abstract_class || fk.parent == fk.model.class_name
|
542
|
-
undo_add_fks << remove_foreign_key(old_table_name, fk.
|
530
|
+
undo_add_fks << remove_foreign_key(old_table_name, fk.constraint_name)
|
543
531
|
fk.to_add_statement
|
544
|
-
end
|
532
|
+
end
|
545
533
|
|
546
|
-
|
534
|
+
undo_drop_fks = []
|
535
|
+
drop_fks = (existing_fks - model_fks).map do |fk|
|
547
536
|
undo_drop_fks << fk.to_add_statement
|
548
|
-
remove_foreign_key(new_table_name, fk.
|
537
|
+
remove_foreign_key(new_table_name, fk.constraint_name)
|
549
538
|
end
|
550
539
|
|
551
540
|
[drop_fks + add_fks, undo_add_fks + undo_drop_fks]
|
552
541
|
end
|
553
542
|
|
554
543
|
def remove_foreign_key(old_table_name, fk_name)
|
555
|
-
"remove_foreign_key(
|
544
|
+
"remove_foreign_key(#{old_table_name.inspect}, name: #{fk_name.to_s.inspect})"
|
556
545
|
end
|
557
546
|
|
558
|
-
def format_options(options
|
547
|
+
def format_options(options)
|
559
548
|
options.map do |k, v|
|
560
|
-
unless changing
|
561
|
-
next if k == :limit && (type == :decimal || v == native_types[type][:limit])
|
562
|
-
next if k == :null && v == true
|
563
|
-
end
|
564
|
-
|
565
|
-
next if k == :limit && type == :text && !::DeclareSchema::Model::FieldSpec.mysql_text_limits?
|
566
|
-
|
567
549
|
if k.is_a?(Symbol)
|
568
550
|
"#{k}: #{v.inspect}"
|
569
551
|
else
|
570
552
|
"#{k.inspect} => #{v.inspect}"
|
571
553
|
end
|
572
|
-
end
|
554
|
+
end
|
573
555
|
end
|
574
556
|
|
575
557
|
def fk_field_options(model, field_name)
|
576
558
|
foreign_key = model.constraint_specs.find { |fk| field_name == fk.foreign_key.to_s }
|
577
559
|
if foreign_key && (parent_table = foreign_key.parent_table_name)
|
578
560
|
parent_columns = connection.columns(parent_table) rescue []
|
579
|
-
pk_limit
|
561
|
+
pk_limit =
|
580
562
|
if (pk_column = parent_columns.find { |column| column.name.to_s == "id" }) # right now foreign keys assume id is the target
|
581
|
-
if Rails::VERSION::MAJOR
|
563
|
+
if Rails::VERSION::MAJOR < 5
|
582
564
|
pk_column.cast_type.limit
|
583
565
|
else
|
584
566
|
pk_column.limit
|
@@ -607,39 +589,83 @@ module Generators
|
|
607
589
|
end
|
608
590
|
end
|
609
591
|
|
610
|
-
def
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
592
|
+
def with_previous_model_table_name(model, table_name)
|
593
|
+
model_table_name, model.table_name = model.table_name, table_name
|
594
|
+
yield
|
595
|
+
ensure
|
596
|
+
model.table_name = model_table_name
|
597
|
+
end
|
598
|
+
|
599
|
+
def add_column_back(model, current_table_name, col_name)
|
600
|
+
with_previous_model_table_name(model, current_table_name) do
|
601
|
+
column = model.columns_hash[col_name] or raise "no columns_hash entry found for #{col_name} in #{model.inspect}"
|
602
|
+
col_spec = ::DeclareSchema::Model::Column.new(model, current_table_name, column)
|
603
|
+
schema_attributes = col_spec.schema_attributes
|
604
|
+
type = schema_attributes.delete(:type) or raise "no :type found in #{schema_attributes.inspect}"
|
605
|
+
["add_column :#{current_table_name}, :#{col_name}, #{type.inspect}", *format_options(schema_attributes)].join(', ')
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
609
|
+
def change_column_back(model, current_table_name, col_name)
|
610
|
+
with_previous_model_table_name(model, current_table_name) do
|
611
|
+
column = model.columns_hash[col_name] or raise "no columns_hash entry found for #{col_name} in #{model.inspect}"
|
612
|
+
col_spec = ::DeclareSchema::Model::Column.new(model, current_table_name, column)
|
613
|
+
schema_attributes = col_spec.schema_attributes
|
614
|
+
type = schema_attributes.delete(:type) or raise "no :type found in #{schema_attributes.inspect}"
|
615
|
+
["change_column #{current_table_name.to_sym.inspect}", col_name.to_sym.inspect, type.to_sym.inspect, *format_options(schema_attributes)].join(', ')
|
616
|
+
end
|
620
617
|
end
|
621
618
|
|
622
|
-
def
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
# Sexy migration
|
629
|
-
_, type, options = *md
|
630
|
-
type = ":#{type}"
|
619
|
+
def default_collation_from_charset(charset)
|
620
|
+
case charset
|
621
|
+
when "utf8"
|
622
|
+
"utf8_general_ci"
|
623
|
+
when "utf8mb4"
|
624
|
+
"utf8mb4_general_ci"
|
631
625
|
end
|
632
|
-
[type, options]
|
633
626
|
end
|
634
627
|
|
635
|
-
|
636
|
-
|
637
|
-
|
628
|
+
SchemaDumper = case Rails::VERSION::MAJOR
|
629
|
+
when 4
|
630
|
+
ActiveRecord::SchemaDumper
|
631
|
+
else
|
632
|
+
ActiveRecord::ConnectionAdapters::SchemaDumper
|
633
|
+
end
|
634
|
+
|
635
|
+
def add_table_back(table)
|
636
|
+
dumped_schema_stream = StringIO.new
|
637
|
+
SchemaDumper.send(:new, ActiveRecord::Base.connection).send(:table, table, dumped_schema_stream)
|
638
|
+
|
639
|
+
dumped_schema = dumped_schema_stream.string.strip.gsub!("\n ", "\n")
|
640
|
+
if connection.class.name.match?(/mysql/i)
|
641
|
+
fix_mysql_charset_and_collation(dumped_schema)
|
642
|
+
else
|
643
|
+
dumped_schema
|
644
|
+
end
|
638
645
|
end
|
639
646
|
|
640
|
-
|
641
|
-
|
642
|
-
|
647
|
+
# TODO: rewrite this method to use charset and collation variables rather than manipulating strings. -Colin
|
648
|
+
def fix_mysql_charset_and_collation(dumped_schema)
|
649
|
+
if !dumped_schema['options: ']
|
650
|
+
dumped_schema.sub!('",', "\", options: \"DEFAULT CHARSET=#{Generators::DeclareSchema::Migration::Migrator.default_charset} "+
|
651
|
+
"COLLATE=#{Generators::DeclareSchema::Migration::Migrator.default_collation}\",")
|
652
|
+
end
|
653
|
+
default_charset = dumped_schema[/CHARSET=(\w+)/, 1] or raise "unable to find charset in #{dumped_schema.inspect}"
|
654
|
+
default_collation = dumped_schema[/COLLATE=(\w+)/, 1] || default_collation_from_charset(default_charset) or
|
655
|
+
raise "unable to find collation in #{dumped_schema.inspect} or charset #{default_charset.inspect}"
|
656
|
+
dumped_schema.split("\n").map do |line|
|
657
|
+
if line['t.text'] || line['t.string']
|
658
|
+
if !line['charset: ']
|
659
|
+
if line['collation: ']
|
660
|
+
line.sub!('collation: ', "charset: #{default_charset.inspect}, collation: ")
|
661
|
+
else
|
662
|
+
line << ", charset: #{default_charset.inspect}"
|
663
|
+
end
|
664
|
+
end
|
665
|
+
line['collation: '] or line << ", collation: #{default_collation.inspect}"
|
666
|
+
end
|
667
|
+
line
|
668
|
+
end.join("\n")
|
643
669
|
end
|
644
670
|
end
|
645
671
|
end
|