declare_schema 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|