mimi-db 0.2.3 → 0.2.4
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/lib/mimi/db/dictate/migrator.rb +12 -8
- data/lib/mimi/db/dictate/schema_diff.rb +24 -47
- data/lib/mimi/db/dictate.rb +25 -0
- data/lib/mimi/db/helpers.rb +28 -0
- data/lib/mimi/db/version.rb +1 -1
- data/lib/tasks/db.rake +8 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d8e5f05648963455f22f4495aeed73bbab8edd4
|
4
|
+
data.tar.gz: b519848493d926249f1be91a586e80aaceff153e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f61958bb7e08cbf6d2ed28e8ed566a983f38365894257eb84b5ed579da21b248cfbd6898a964d267b22e1d22a6b806c6c0add014afa245a143c997a0a784fbf
|
7
|
+
data.tar.gz: 5256b301a6bd6891cf3cf47698ae34608b9b68858b7d39c1854da2bfc041779b2dfacd101c6b7306b569d91e95c28298beae2aadbec97c3f3ba872a273783ff0
|
@@ -83,24 +83,28 @@ module Mimi
|
|
83
83
|
|
84
84
|
def run_change_table!
|
85
85
|
diff = Mimi::DB::Dictate::SchemaDiff.diff(from_schema, to_schema)
|
86
|
-
if diff.empty?
|
86
|
+
if diff[:columns].empty? && diff[:indexes].empty?
|
87
87
|
logger.info "- no changes: #{table_name}"
|
88
88
|
return
|
89
89
|
end
|
90
90
|
logger.info "- ALTER TABLE: #{table_name}"
|
91
|
-
run_change_table_columns!(diff[:columns])
|
92
|
-
run_change_table_indexes!(diff[:indexes])
|
91
|
+
run_change_table_columns!(diff[:columns]) unless diff[:columns].empty?
|
92
|
+
run_change_table_indexes!(diff[:indexes]) unless diff[:indexes].empty?
|
93
93
|
end
|
94
94
|
|
95
95
|
def run_change_table_columns!(diff_columns)
|
96
|
-
diff_columns
|
97
|
-
|
98
|
-
|
96
|
+
diff_columns.each do |c, diff|
|
97
|
+
drop_column!(table_name, c) if diff[:from] && diff[:to].nil?
|
98
|
+
change_column!(table_name, diff[:to]) if diff[:from] && diff[:to]
|
99
|
+
add_column!(table_name, diff[:to]) if diff[:from].nil? && diff[:to]
|
100
|
+
end
|
99
101
|
end
|
100
102
|
|
101
103
|
def run_change_table_indexes!(diff_indexes)
|
102
|
-
diff_indexes
|
103
|
-
|
104
|
+
diff_indexes.each do |i, diff|
|
105
|
+
drop_index!(table_name, diff[:from]) if diff[:from] && diff[:to].nil?
|
106
|
+
add_index!(table_name, diff[:to]) if diff[:from].nil? && diff[:to]
|
107
|
+
end
|
104
108
|
end
|
105
109
|
|
106
110
|
def run_create_table!
|
@@ -15,58 +15,35 @@ module Mimi
|
|
15
15
|
#
|
16
16
|
# Compares two schema definitions
|
17
17
|
#
|
18
|
-
# @return [Hash] :columns, :indexes => :
|
18
|
+
# @return [Hash] :columns, :indexes => :from, :to
|
19
19
|
#
|
20
20
|
def self.diff(from, to, opts = {})
|
21
21
|
options = DEFAULT_OPTIONS.merge(opts)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
result = { table_name: from.table_name, columns: {}, indexes: {} }
|
23
|
+
all_column_names = (from.columns.values.map(&:name) + to.columns.values.map(&:name)).uniq
|
24
|
+
all_column_names.each do |c|
|
25
|
+
if from.columns[c] && to.columns[c].nil?
|
26
|
+
result[:columns][c] = { from: from.columns[c], to: nil }
|
27
|
+
elsif from.columns[c] && to.columns[c] && !(from.columns[c] == to.columns[c])
|
28
|
+
result[:columns][c] = { from: from.columns[c], to: to.columns[c] }
|
29
|
+
elsif from.columns[c].nil? && to.columns[c]
|
30
|
+
result[:columns][c] = { from: nil, to: to.columns[c] }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
from_indexes = from.indexes.map { |i| [i.columns, i] }.to_h
|
34
|
+
to_indexes = to.indexes.map { |i| [i.columns, i] }.to_h
|
35
|
+
all_index_cols = (from_indexes.keys + to_indexes.keys).uniq
|
36
|
+
all_index_cols.each do |cc|
|
37
|
+
if from_indexes[cc] && to_indexes[cc].nil?
|
38
|
+
result[:indexes][cc] = { from: from_indexes[cc], to: nil }
|
39
|
+
elsif from_indexes[cc] && to_indexes[cc]
|
40
|
+
# index diff is not supported
|
41
|
+
elsif from_indexes[cc].nil? && to_indexes[cc]
|
42
|
+
result[:indexes][cc] = { from: nil, to: to_indexes[cc]}
|
43
|
+
end
|
28
44
|
end
|
29
|
-
columns_change = to.columns.values.reject do |c|
|
30
|
-
res = from.columns[c.name].nil? || from.columns[c.name] == c
|
31
|
-
res ||= c.type == :primary_key unless options[:force_primary_key]
|
32
|
-
end
|
33
|
-
from_indexes_c = from.indexes.map(&:columns).uniq
|
34
|
-
to_indexes_c = to.indexes.map(&:columns).uniq
|
35
|
-
# ignore primary key indexes
|
36
|
-
from_indexes_c -= [[from.primary_key&.name]]
|
37
|
-
to_indexes_c -= [[to.primary_key&.name]]
|
38
45
|
|
39
|
-
|
40
|
-
indexes_c_add = to_indexes_c - from_indexes_c
|
41
|
-
indexes_remove = from.indexes.select do |idx|
|
42
|
-
indexes_c_remove.include?(idx.columns)
|
43
|
-
end
|
44
|
-
indexes_add = to.indexes.select do |idx|
|
45
|
-
indexes_c_add.include?(idx.columns)
|
46
|
-
end
|
47
|
-
|
48
|
-
diff = {}
|
49
|
-
unless columns_names_remove.empty?
|
50
|
-
diff[:columns] ||= {}
|
51
|
-
diff[:columns][:remove] = columns_names_remove
|
52
|
-
end
|
53
|
-
unless columns_change.empty?
|
54
|
-
diff[:columns] ||= {}
|
55
|
-
diff[:columns][:change] = columns_change
|
56
|
-
end
|
57
|
-
unless columns_add.empty?
|
58
|
-
diff[:columns] ||= {}
|
59
|
-
diff[:columns][:add] = columns_add
|
60
|
-
end
|
61
|
-
unless indexes_remove.empty?
|
62
|
-
diff[:indexes] ||= {}
|
63
|
-
diff[:indexes][:remove] = indexes_remove
|
64
|
-
end
|
65
|
-
unless indexes_add.empty?
|
66
|
-
diff[:indexes] ||= {}
|
67
|
-
diff[:indexes][:add] = indexes_add
|
68
|
-
end
|
69
|
-
diff
|
46
|
+
result
|
70
47
|
end
|
71
48
|
end # module SchemaDiff
|
72
49
|
end # module Dictate
|
data/lib/mimi/db/dictate.rb
CHANGED
@@ -85,6 +85,31 @@ module Mimi
|
|
85
85
|
logger.error "DB::Dictate failed to update DB schema: #{e}"
|
86
86
|
raise
|
87
87
|
end
|
88
|
+
|
89
|
+
# Diff existing DB schema and the target schema
|
90
|
+
#
|
91
|
+
# @param opts [Hash]
|
92
|
+
# @return [Hash]
|
93
|
+
#
|
94
|
+
def self.diff_schema!(opts = {})
|
95
|
+
logger = opts[:logger] || ActiveRecord::Base.logger
|
96
|
+
diff = { add_tables: [], change_tables: [], drop_tables: []}
|
97
|
+
Mimi::DB.all_table_names.each do |t|
|
98
|
+
m = Mimi::DB::Dictate::Migrator.new(t, opts)
|
99
|
+
if m.from_schema && m.to_schema.nil?
|
100
|
+
diff[:drop_tables] << t
|
101
|
+
elsif m.from_schema && m.to_schema
|
102
|
+
t_diff = Mimi::DB::Dictate::SchemaDiff.diff(m.from_schema, m.to_schema)
|
103
|
+
diff[:change_tables] << t_diff unless t_diff[:columns].empty? && t_diff[:indexes].empty?
|
104
|
+
elsif m.from_schema.nil? && m.to_schema
|
105
|
+
diff[:add_tables] << m.to_schema
|
106
|
+
end
|
107
|
+
end
|
108
|
+
diff
|
109
|
+
rescue StandardError => e
|
110
|
+
logger.error "DB::Dictate failed to update DB schema: #{e}"
|
111
|
+
raise
|
112
|
+
end
|
88
113
|
end # module Dictate
|
89
114
|
end # module DB
|
90
115
|
end # module Mimi
|
data/lib/mimi/db/helpers.rb
CHANGED
@@ -60,6 +60,34 @@ module Mimi
|
|
60
60
|
Mimi::DB::Dictate.update_schema!(opts)
|
61
61
|
end
|
62
62
|
|
63
|
+
# Discovers differences between existing DB schema and target schema
|
64
|
+
# defined in models.
|
65
|
+
#
|
66
|
+
# @example
|
67
|
+
# Mimi::DB.diff_schema
|
68
|
+
#
|
69
|
+
# # =>
|
70
|
+
# # {
|
71
|
+
# # add_tables: [<table_schema1>, <table_schema2> ...],
|
72
|
+
# # change_tables: [
|
73
|
+
# # { table_name: ...,
|
74
|
+
# # columns: {
|
75
|
+
# # "<column_name1>" => {
|
76
|
+
# # from: { <column_definition or nil> },
|
77
|
+
# # to: { <column_definition or nil> }
|
78
|
+
# # }
|
79
|
+
# # }
|
80
|
+
# # }, ...
|
81
|
+
# # ],
|
82
|
+
# # drop_tables: [<table_name1>, ...]
|
83
|
+
# # }
|
84
|
+
# @return [Hash]
|
85
|
+
#
|
86
|
+
def diff_schema!(opts = {})
|
87
|
+
opts[:logger] ||= Mimi::DB.logger
|
88
|
+
Mimi::DB::Dictate.diff_schema(opts)
|
89
|
+
end
|
90
|
+
|
63
91
|
# Creates the database specified in the current configuration.
|
64
92
|
#
|
65
93
|
def create!
|
data/lib/mimi/db/version.rb
CHANGED
data/lib/tasks/db.rake
CHANGED
@@ -59,6 +59,14 @@ namespace :db do
|
|
59
59
|
logger.info "* Updating database schema (DRY RUN): #{Mimi::DB.module_options[:db_database]}"
|
60
60
|
Mimi::DB.update_schema!(destructive: true, dry_run: true)
|
61
61
|
end
|
62
|
+
|
63
|
+
desc 'Display differences between existing DB schema and target schema'
|
64
|
+
task diff: :"db:start" do
|
65
|
+
logger.info "* Diff database schema: #{Mimi::DB.module_options[:db_database]}"
|
66
|
+
diff = Mimi::DB.diff_schema(destructive: true, dry_run: true)
|
67
|
+
require 'pp'
|
68
|
+
pp diff
|
69
|
+
end
|
62
70
|
end
|
63
71
|
end
|
64
72
|
end
|