exwiw 0.9.24 → 1.1.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/CHANGELOG.md +32 -0
- data/README.md +34 -29
- data/docs/mongodb.md +1 -1
- data/lib/exwiw/adapter/identifier_quoting.rb +2 -2
- data/lib/exwiw/adapter/mongodb_adapter.rb +0 -8
- data/lib/exwiw/adapter/mysql_adapter.rb +17 -94
- data/lib/exwiw/adapter/postgresql_adapter.rb +48 -70
- data/lib/exwiw/adapter/sqlite_adapter.rb +0 -58
- data/lib/exwiw/adapter.rb +0 -11
- data/lib/exwiw/cli.rb +55 -13
- data/lib/exwiw/ddl_postprocessor.rb +44 -4
- data/lib/exwiw/query_ast_builder.rb +129 -31
- data/lib/exwiw/runner.rb +2 -19
- data/lib/exwiw/schema_check.rb +41 -2
- data/lib/exwiw/version.rb +1 -1
- metadata +1 -1
data/lib/exwiw/schema_check.rb
CHANGED
|
@@ -21,6 +21,15 @@ module Exwiw
|
|
|
21
21
|
added_tables added_columns removed_tables removed_columns changed_tables needs_mask_decision
|
|
22
22
|
].freeze
|
|
23
23
|
|
|
24
|
+
# The subset of the removals that would break an `export` run: a non-ignored
|
|
25
|
+
# config still referencing a table or column the schema no longer has, i.e.
|
|
26
|
+
# the extraction SELECT would name something that does not exist. Removals of
|
|
27
|
+
# `ignore: true` entries stay out (nothing selects them), as do additions.
|
|
28
|
+
# `--fail-on=stale` keys the exit code to these. Deliberate over-approximation:
|
|
29
|
+
# a hand-written config naming a database VIEW lands here too (tidy's stance),
|
|
30
|
+
# though a SELECT against it would succeed.
|
|
31
|
+
STALE_CATEGORIES = %w[stale_tables stale_columns].freeze
|
|
32
|
+
|
|
24
33
|
def self.from_rails_application(schema_dir:)
|
|
25
34
|
Rails.application.eager_load!
|
|
26
35
|
new(models: ActiveRecord::Base.descendants, schema_dir: schema_dir)
|
|
@@ -81,6 +90,12 @@ module Exwiw
|
|
|
81
90
|
CATEGORIES.all? { |category| report.fetch(category, []).empty? }
|
|
82
91
|
end
|
|
83
92
|
|
|
93
|
+
# Whether the report contains drift that would break an extraction run
|
|
94
|
+
# (see STALE_CATEGORIES). Always a subset of what makes clean? false.
|
|
95
|
+
def self.stale?(report)
|
|
96
|
+
STALE_CATEGORIES.any? { |category| !report.fetch(category, []).empty? }
|
|
97
|
+
end
|
|
98
|
+
|
|
84
99
|
private def regenerate_into(tmp_dir)
|
|
85
100
|
FileUtils.cp_r(File.join(@schema_dir, "."), tmp_dir) if Dir.exist?(@schema_dir)
|
|
86
101
|
@regenerator.call(tmp_dir)
|
|
@@ -111,7 +126,7 @@ module Exwiw
|
|
|
111
126
|
end
|
|
112
127
|
|
|
113
128
|
private def diff(committed, regenerated)
|
|
114
|
-
report = CATEGORIES.to_h { |category| [category, []] }
|
|
129
|
+
report = (CATEGORIES + STALE_CATEGORIES).to_h { |category| [category, []] }
|
|
115
130
|
|
|
116
131
|
(committed.keys | regenerated.keys).sort.each do |key|
|
|
117
132
|
before = committed[key]
|
|
@@ -122,7 +137,11 @@ module Exwiw
|
|
|
122
137
|
next
|
|
123
138
|
end
|
|
124
139
|
if after.nil?
|
|
125
|
-
|
|
140
|
+
label = table_label(key, before)
|
|
141
|
+
report["removed_tables"] << label
|
|
142
|
+
# A rails-managed table is dumped whole, so its disappearance breaks
|
|
143
|
+
# the export too; only `ignore: true` keeps a removed table out.
|
|
144
|
+
report["stale_tables"] << label unless before["ignore"]
|
|
126
145
|
next
|
|
127
146
|
end
|
|
128
147
|
next if before == after
|
|
@@ -132,6 +151,10 @@ module Exwiw
|
|
|
132
151
|
added, removed = column_diff(before, after)
|
|
133
152
|
report["added_columns"] += added.sort.map { |column| "#{label}.#{column}" }
|
|
134
153
|
report["removed_columns"] += removed.sort.map { |column| "#{label}.#{column}" }
|
|
154
|
+
if extracted?(before)
|
|
155
|
+
stale = removed & extracted_column_names(before)
|
|
156
|
+
report["stale_columns"] += stale.sort.map { |column| "#{label}.#{column}" }
|
|
157
|
+
end
|
|
135
158
|
end
|
|
136
159
|
|
|
137
160
|
report
|
|
@@ -148,6 +171,22 @@ module Exwiw
|
|
|
148
171
|
(config["columns"] || config["fields"] || []).map { |column| column["name"] }
|
|
149
172
|
end
|
|
150
173
|
|
|
174
|
+
# Whether the extraction SELECT names this table's columns: an `ignore: true`
|
|
175
|
+
# config only contributes DDL, and a rails-managed one is dumped as
|
|
176
|
+
# `SELECT *` — so a removed column cannot break either. (A removed
|
|
177
|
+
# rails-managed table still can; #diff handles that separately.)
|
|
178
|
+
private def extracted?(config)
|
|
179
|
+
!config["ignore"] && !TableConfig::RAILS_MANAGED_TYPES.include?(config["type"])
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# The columns the extraction SELECT actually names: `ignore: true` columns
|
|
183
|
+
# are dropped when the config loads, so their staleness breaks nothing.
|
|
184
|
+
private def extracted_column_names(config)
|
|
185
|
+
(config["columns"] || config["fields"] || [])
|
|
186
|
+
.reject { |column| column["ignore"] }
|
|
187
|
+
.map { |column| column["name"] }
|
|
188
|
+
end
|
|
189
|
+
|
|
151
190
|
# How a table is named in the report. The database is part of the label, or
|
|
152
191
|
# the same table name in two of them collides (each has `schema_migrations`).
|
|
153
192
|
private def table_label(key, config)
|
data/lib/exwiw/version.rb
CHANGED