declare_schema 0.6.2 → 0.8.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -0
- data/Gemfile.lock +55 -53
- data/lib/declare_schema/field_declaration_dsl.rb +3 -4
- data/lib/declare_schema/model.rb +1 -2
- data/lib/declare_schema/model/column.rb +158 -0
- data/lib/declare_schema/model/field_spec.rb +59 -144
- data/lib/declare_schema/model/foreign_key_definition.rb +36 -25
- 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 +113 -135
- data/spec/lib/declare_schema/field_declaration_dsl_spec.rb +1 -1
- data/spec/lib/declare_schema/field_spec_spec.rb +142 -38
- data/spec/lib/declare_schema/migration_generator_spec.rb +73 -69
- data/spec/lib/declare_schema/model/column_spec.rb +122 -0
- data/spec/lib/declare_schema/model/foreign_key_definition_spec.rb +93 -0
- data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +2 -11
- metadata +8 -5
@@ -5,21 +5,21 @@ module DeclareSchema
|
|
5
5
|
class ForeignKeyDefinition
|
6
6
|
include Comparable
|
7
7
|
|
8
|
-
attr_reader :constraint_name, :model, :foreign_key, :options, :on_delete_cascade
|
8
|
+
attr_reader :constraint_name, :model, :foreign_key, :foreign_key_name, :options, :on_delete_cascade
|
9
9
|
|
10
10
|
def initialize(model, foreign_key, options = {})
|
11
11
|
@model = model
|
12
|
-
@foreign_key = foreign_key.presence
|
12
|
+
@foreign_key = foreign_key.to_s.presence
|
13
13
|
@options = options
|
14
14
|
|
15
15
|
@child_table = model.table_name # unless a table rename, which would happen when a class is renamed??
|
16
|
-
@parent_table_name = options[:parent_table]
|
17
|
-
@foreign_key_name = options[:foreign_key] ||
|
18
|
-
@index_name = options[:index_name] || model.connection.index_name(model.table_name, column:
|
19
|
-
@constraint_name = options[:constraint_name] || @index_name || ''
|
20
|
-
@on_delete_cascade = options[:dependent] == :delete
|
16
|
+
@parent_table_name = options[:parent_table]&.to_s
|
17
|
+
@foreign_key_name = options[:foreign_key]&.to_s || @foreign_key
|
18
|
+
@index_name = options[:index_name]&.to_s || model.connection.index_name(model.table_name, column: @foreign_key_name)
|
21
19
|
|
22
20
|
# Empty constraint lets mysql generate the name
|
21
|
+
@constraint_name = options[:constraint_name]&.to_s || @index_name&.to_s || ''
|
22
|
+
@on_delete_cascade = options[:dependent] == :delete
|
23
23
|
end
|
24
24
|
|
25
25
|
class << self
|
@@ -28,11 +28,12 @@ module DeclareSchema
|
|
28
28
|
constraints = show_create_table.split("\n").map { |line| line.strip if line['CONSTRAINT'] }.compact
|
29
29
|
|
30
30
|
constraints.map do |fkc|
|
31
|
-
options = {}
|
32
31
|
name, foreign_key, parent_table = fkc.match(/CONSTRAINT `([^`]*)` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)`/).captures
|
33
|
-
options
|
34
|
-
|
35
|
-
|
32
|
+
options = {
|
33
|
+
constraint_name: name,
|
34
|
+
parent_table: parent_table,
|
35
|
+
foreign_key: foreign_key
|
36
|
+
}
|
36
37
|
options[:dependent] = :delete if fkc['ON DELETE CASCADE']
|
37
38
|
|
38
39
|
new(model, foreign_key, options)
|
@@ -40,21 +41,37 @@ module DeclareSchema
|
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
44
|
+
# returns the parent class as a Class object
|
45
|
+
# or nil if no :class_name option given
|
46
|
+
def parent_class
|
47
|
+
if (class_name = options[:class_name])
|
48
|
+
if class_name.is_a?(Class)
|
49
|
+
class_name
|
50
|
+
else
|
51
|
+
class_name.to_s.constantize
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
43
56
|
def parent_table_name
|
44
57
|
@parent_table_name ||=
|
45
|
-
|
46
|
-
|
47
|
-
klass.try(:table_name)
|
48
|
-
end || foreign_key.sub(/_id\z/, '').camelize.constantize.table_name
|
58
|
+
parent_class&.try(:table_name) ||
|
59
|
+
foreign_key.sub(/_id\z/, '').camelize.constantize.table_name
|
49
60
|
end
|
50
61
|
|
51
|
-
|
62
|
+
def to_add_statement
|
63
|
+
"add_foreign_key(#{@child_table.inspect}, #{parent_table_name.inspect}, " +
|
64
|
+
"column: #{@foreign_key_name.inspect}, name: #{@constraint_name.inspect})"
|
65
|
+
end
|
52
66
|
|
53
|
-
def
|
54
|
-
|
55
|
-
"execute #{statement.inspect}"
|
67
|
+
def <=>(rhs)
|
68
|
+
key <=> rhs.send(:key)
|
56
69
|
end
|
57
70
|
|
71
|
+
alias eql? ==
|
72
|
+
|
73
|
+
private
|
74
|
+
|
58
75
|
def key
|
59
76
|
@key ||= [@child_table, parent_table_name, @foreign_key_name, @on_delete_cascade].map(&:to_s)
|
60
77
|
end
|
@@ -62,12 +79,6 @@ module DeclareSchema
|
|
62
79
|
def hash
|
63
80
|
key.hash
|
64
81
|
end
|
65
|
-
|
66
|
-
def <=>(rhs)
|
67
|
-
key <=> rhs.key
|
68
|
-
end
|
69
|
-
|
70
|
-
alias eql? ==
|
71
82
|
end
|
72
83
|
end
|
73
84
|
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
|
@@ -116,20 +117,6 @@ module Generators
|
|
116
117
|
ActiveRecord::Base.connection
|
117
118
|
end
|
118
119
|
|
119
|
-
def fix_native_types(types)
|
120
|
-
case connection.class.name
|
121
|
-
when /mysql/i
|
122
|
-
types[:integer][:limit] ||= 11
|
123
|
-
types[:text][:limit] ||= 0xffff
|
124
|
-
types[:binary][:limit] ||= 0xffff
|
125
|
-
end
|
126
|
-
types
|
127
|
-
end
|
128
|
-
|
129
|
-
def native_types
|
130
|
-
@native_types ||= fix_native_types(connection.native_database_types)
|
131
|
-
end
|
132
|
-
|
133
120
|
def before_generating_migration(&block)
|
134
121
|
block or raise ArgumentError, 'A block is required when setting the before_generating_migration callback'
|
135
122
|
@before_generating_migration_callback = block
|
@@ -299,7 +286,7 @@ module Generators
|
|
299
286
|
"drop_table :#{t}"
|
300
287
|
end * "\n"
|
301
288
|
undo_drops = to_drop.map do |t|
|
302
|
-
|
289
|
+
add_table_back(t)
|
303
290
|
end * "\n\n"
|
304
291
|
|
305
292
|
creates = to_create.map do |t|
|
@@ -341,11 +328,11 @@ module Generators
|
|
341
328
|
end
|
342
329
|
|
343
330
|
def create_table(model)
|
344
|
-
longest_field_name = model.field_specs.values.map { |f| f.
|
331
|
+
longest_field_name = model.field_specs.values.map { |f| f.type.to_s.length }.max
|
345
332
|
disable_auto_increment = model.respond_to?(:disable_auto_increment) && model.disable_auto_increment
|
346
333
|
table_options_definition = ::DeclareSchema::Model::TableOptionsDefinition.new(model.table_name, table_options_for_model(model))
|
347
334
|
field_definitions = [
|
348
|
-
|
335
|
+
("t.integer :id, limit: 8, auto_increment: false, primary_key: true" if disable_auto_increment),
|
349
336
|
*(model.field_specs.values.sort_by(&:position).map { |f| create_field(f, longest_field_name) })
|
350
337
|
].compact
|
351
338
|
|
@@ -386,13 +373,13 @@ module Generators
|
|
386
373
|
end
|
387
374
|
|
388
375
|
def create_constraints(model)
|
389
|
-
model.constraint_specs.map { |fk| fk.to_add_statement
|
376
|
+
model.constraint_specs.map { |fk| fk.to_add_statement }
|
390
377
|
end
|
391
378
|
|
392
379
|
def create_field(field_spec, field_name_width)
|
393
|
-
options = fk_field_options(field_spec.model, field_spec.name)
|
394
|
-
args = [field_spec.name.inspect] + format_options(options
|
395
|
-
format("t.%-*s %s", field_name_width, field_spec.
|
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)
|
382
|
+
format("t.%-*s %s", field_name_width, field_spec.type, args.join(', '))
|
396
383
|
end
|
397
384
|
|
398
385
|
def change_table(model, current_table_name)
|
@@ -429,8 +416,8 @@ module Generators
|
|
429
416
|
adds = to_add.map do |c|
|
430
417
|
args =
|
431
418
|
if (spec = model.field_specs[c])
|
432
|
-
options = fk_field_options(model, c)
|
433
|
-
[":#{spec.
|
419
|
+
options = spec.sql_options.merge(fk_field_options(model, c))
|
420
|
+
[":#{spec.type}", *format_options(options.compact)]
|
434
421
|
else
|
435
422
|
[":integer"]
|
436
423
|
end
|
@@ -444,34 +431,28 @@ module Generators
|
|
444
431
|
"remove_column :#{new_table_name}, :#{c}"
|
445
432
|
end
|
446
433
|
undo_removes = to_remove.map do |c|
|
447
|
-
|
434
|
+
add_column_back(model, current_table_name, c)
|
448
435
|
end
|
449
436
|
|
450
437
|
old_names = to_rename.invert
|
451
438
|
changes = []
|
452
439
|
undo_changes = []
|
453
|
-
to_change.each do |
|
454
|
-
|
455
|
-
|
456
|
-
spec
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
change_spec[:collation] = spec.collation unless spec.collation.nil?
|
468
|
-
|
469
|
-
changes << "change_column :#{new_table_name}, :#{c}, " +
|
470
|
-
([":#{spec.sql_type}"] + format_options(change_spec, spec.sql_type, changing: true)).join(", ")
|
471
|
-
back = change_column_back(current_table_name, col_name)
|
472
|
-
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
|
+
normalized_schema_attrs = spec_attrs.merge(fk_field_options(model, col_name_to_change))
|
448
|
+
|
449
|
+
if !::DeclareSchema::Model::Column.equivalent_schema_attributes?(normalized_schema_attrs, col_attrs)
|
450
|
+
type = normalized_schema_attrs.delete(:type) or raise "no :type found in #{normalized_schema_attrs.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_attrs)].join(", ")
|
453
|
+
undo_changes << change_column_back(model, current_table_name, orig_col_name)
|
473
454
|
end
|
474
|
-
end
|
455
|
+
end
|
475
456
|
|
476
457
|
index_changes, undo_index_changes = change_indexes(model, current_table_name, to_remove)
|
477
458
|
fk_changes, undo_fk_changes = if ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/)
|
@@ -485,26 +466,26 @@ module Generators
|
|
485
466
|
[[], []]
|
486
467
|
end
|
487
468
|
|
488
|
-
[(renames + adds + removes + changes)
|
469
|
+
[(renames + adds + removes + changes) * "\n",
|
489
470
|
(undo_renames + undo_adds + undo_removes + undo_changes) * "\n",
|
490
|
-
index_changes
|
491
|
-
undo_index_changes
|
492
|
-
fk_changes
|
493
|
-
undo_fk_changes
|
494
|
-
table_options_changes
|
495
|
-
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"]
|
496
477
|
end
|
497
478
|
|
498
479
|
def change_indexes(model, old_table_name, to_remove)
|
499
|
-
return [[], []]
|
480
|
+
Migrator.disable_constraints and return [[], []]
|
500
481
|
|
501
482
|
new_table_name = model.table_name
|
502
483
|
existing_indexes = ::DeclareSchema::Model::IndexDefinition.for_model(model, old_table_name)
|
503
484
|
model_indexes_with_equivalents = model.index_definitions_with_primary_key
|
504
485
|
model_indexes = model_indexes_with_equivalents.map do |i|
|
505
486
|
if i.explicit_name.nil?
|
506
|
-
if
|
507
|
-
i.with_name(
|
487
|
+
if (existing = existing_indexes.find { |e| i != e && e.equivalent?(i) })
|
488
|
+
i.with_name(existing.name)
|
508
489
|
end
|
509
490
|
end || i
|
510
491
|
end
|
@@ -514,15 +495,13 @@ module Generators
|
|
514
495
|
end
|
515
496
|
model_has_primary_key = model_indexes.any? { |i| i.name == ::DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME }
|
516
497
|
|
517
|
-
add_indexes_init = model_indexes - existing_indexes
|
518
|
-
drop_indexes_init = existing_indexes - model_indexes
|
519
498
|
undo_add_indexes = []
|
520
|
-
|
521
|
-
add_indexes = add_indexes_init.map do |i|
|
499
|
+
add_indexes = (model_indexes - existing_indexes).map do |i|
|
522
500
|
undo_add_indexes << drop_index(old_table_name, i.name) unless i.name == ::DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME
|
523
501
|
i.to_add_statement(new_table_name, existing_has_primary_key)
|
524
502
|
end
|
525
|
-
|
503
|
+
undo_drop_indexes = []
|
504
|
+
drop_indexes = (existing_indexes - model_indexes).map do |i|
|
526
505
|
undo_drop_indexes << i.to_add_statement(old_table_name, model_has_primary_key)
|
527
506
|
drop_index(new_table_name, i.name) unless i.name == ::DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME
|
528
507
|
end.compact
|
@@ -538,51 +517,41 @@ module Generators
|
|
538
517
|
end
|
539
518
|
|
540
519
|
def change_foreign_key_constraints(model, old_table_name)
|
541
|
-
ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/) and raise 'SQLite does not support foreign keys'
|
542
|
-
return [[], []]
|
520
|
+
ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/) and raise ArgumentError, 'SQLite does not support foreign keys'
|
521
|
+
Migrator.disable_indexing and return [[], []]
|
543
522
|
|
544
523
|
new_table_name = model.table_name
|
545
524
|
existing_fks = ::DeclareSchema::Model::ForeignKeyDefinition.for_model(model, old_table_name)
|
546
525
|
model_fks = model.constraint_specs
|
547
|
-
add_fks = model_fks - existing_fks
|
548
|
-
drop_fks = existing_fks - model_fks
|
549
|
-
undo_add_fks = []
|
550
|
-
undo_drop_fks = []
|
551
526
|
|
552
|
-
|
527
|
+
undo_add_fks = []
|
528
|
+
add_fks = (model_fks - existing_fks).map do |fk|
|
553
529
|
# next if fk.parent.constantize.abstract_class || fk.parent == fk.model.class_name
|
554
|
-
undo_add_fks << remove_foreign_key(old_table_name, fk.
|
530
|
+
undo_add_fks << remove_foreign_key(old_table_name, fk.constraint_name)
|
555
531
|
fk.to_add_statement
|
556
|
-
end
|
532
|
+
end
|
557
533
|
|
558
|
-
|
534
|
+
undo_drop_fks = []
|
535
|
+
drop_fks = (existing_fks - model_fks).map do |fk|
|
559
536
|
undo_drop_fks << fk.to_add_statement
|
560
|
-
remove_foreign_key(new_table_name, fk.
|
537
|
+
remove_foreign_key(new_table_name, fk.constraint_name)
|
561
538
|
end
|
562
539
|
|
563
540
|
[drop_fks + add_fks, undo_add_fks + undo_drop_fks]
|
564
541
|
end
|
565
542
|
|
566
543
|
def remove_foreign_key(old_table_name, fk_name)
|
567
|
-
"remove_foreign_key(
|
544
|
+
"remove_foreign_key(#{old_table_name.inspect}, name: #{fk_name.to_s.inspect})"
|
568
545
|
end
|
569
546
|
|
570
|
-
def format_options(options
|
547
|
+
def format_options(options)
|
571
548
|
options.map do |k, v|
|
572
|
-
if !changing && ((k == :limit && type == :decimal) || (k == :null && v == true))
|
573
|
-
next
|
574
|
-
end
|
575
|
-
|
576
|
-
if !::DeclareSchema::Model::FieldSpec.mysql_text_limits? && k == :limit && type == :text
|
577
|
-
next
|
578
|
-
end
|
579
|
-
|
580
549
|
if k.is_a?(Symbol)
|
581
550
|
"#{k}: #{v.inspect}"
|
582
551
|
else
|
583
552
|
"#{k.inspect} => #{v.inspect}"
|
584
553
|
end
|
585
|
-
end
|
554
|
+
end
|
586
555
|
end
|
587
556
|
|
588
557
|
def fk_field_options(model, field_name)
|
@@ -620,7 +589,33 @@ module Generators
|
|
620
589
|
end
|
621
590
|
end
|
622
591
|
|
623
|
-
|
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
|
617
|
+
end
|
618
|
+
|
624
619
|
def default_collation_from_charset(charset)
|
625
620
|
case charset
|
626
621
|
when "utf8"
|
@@ -630,64 +625,47 @@ module Generators
|
|
630
625
|
end
|
631
626
|
end
|
632
627
|
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
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)
|
642
638
|
|
643
|
-
|
639
|
+
dumped_schema = dumped_schema_stream.string.strip.gsub!("\n ", "\n")
|
644
640
|
if connection.class.name.match?(/mysql/i)
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
end
|
649
|
-
default_charset = result[/CHARSET=(\w+)/, 1] or raise "unable to find charset in #{result.inspect}"
|
650
|
-
default_collation = result[/COLLATE=(\w+)/, 1] || default_collation_from_charset(default_charset) or
|
651
|
-
raise "unable to find collation in #{result.inspect} or charset #{default_charset.inspect}"
|
652
|
-
result = result.split("\n").map do |line|
|
653
|
-
if line['t.text'] || line['t.string']
|
654
|
-
if !line['charset: ']
|
655
|
-
if line['collation: ']
|
656
|
-
line = line.sub('collation: ', "charset: #{default_charset.inspect}, collation: ")
|
657
|
-
else
|
658
|
-
line += ", charset: #{default_charset.inspect}"
|
659
|
-
end
|
660
|
-
end
|
661
|
-
line['collation: '] or line += ", collation: #{default_collation.inspect}"
|
662
|
-
end
|
663
|
-
line
|
664
|
-
end.join("\n")
|
641
|
+
fix_mysql_charset_and_collation(dumped_schema)
|
642
|
+
else
|
643
|
+
dumped_schema
|
665
644
|
end
|
666
|
-
result
|
667
645
|
end
|
668
646
|
|
669
|
-
|
670
|
-
|
671
|
-
if
|
672
|
-
|
673
|
-
|
674
|
-
elsif (md = revert.match(/\s*t\.([a-z_]+)\s+"#{column}"(?:,\s+(.*?)$)?/m))
|
675
|
-
# Sexy migration
|
676
|
-
_, string_type, options = *md
|
677
|
-
type = ":#{string_type}"
|
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}\",")
|
678
652
|
end
|
679
|
-
|
680
|
-
[
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
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")
|
691
669
|
end
|
692
670
|
end
|
693
671
|
end
|