master_data_tool 0.18.0 → 0.19.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/README.md +11 -11
- data/lib/master_data_tool/import/executor.rb +12 -1
- data/lib/master_data_tool/master_data.rb +5 -1
- data/lib/master_data_tool/master_data_status.rb +12 -7
- data/lib/master_data_tool/report/default_printer.rb +1 -0
- data/lib/master_data_tool/version.rb +1 -1
- data/lib/master_data_tool.rb +6 -1
- data/scripts/drop_db.sh +11 -0
- data/sig/master_data_tool.rbs +227 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d77c4691ca7880f5b1ab73c4d0e5d424e743cb2973e88cb2fc45e7d15cf7acf
|
4
|
+
data.tar.gz: a18d5f0ec46051a0c45db4e369270a5387a827cafa6b17760ead426152a1fd3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 644b4a2322932c327a75d1cd955458689e4e08151301cbb1f5782a7465a62bfc80ba823774b0d77b2a525ce9cbd68dd28e6a14b354473608c4a7b61ef4cbf9b1
|
7
|
+
data.tar.gz: 91eb8811ca518eb91311c2d4a50dea7bb778edfa7f106e0d6d09e6bc5b866d4e12c6375936aa31f02f918c73979e9b81fa1038531f1ca9281e6a80d246516aa7
|
data/README.md
CHANGED
@@ -35,18 +35,18 @@ Or install it yourself as:
|
|
35
35
|
|
36
36
|
### マスタデータの投入
|
37
37
|
|
38
|
-
| option
|
39
|
-
|
40
|
-
| --dry-run
|
41
|
-
| --verify
|
42
|
-
| --only-import-tables
|
43
|
-
| --except-import-tables
|
44
|
-
| --only-verify-tables
|
45
|
-
| --except-verify-tables
|
46
|
-
| --skip-no-change
|
47
|
-
| --silent
|
38
|
+
| option | default | 内容 |
|
39
|
+
|---------------------------------| --- |-----------------------------------------------------------------|
|
40
|
+
| --dry-run | true | dry-runモードで実行する(データ変更は行わない) |
|
41
|
+
| --verify | true | データ投入後に全テーブル・全レコードのバリデーションチェックを行う |
|
42
|
+
| --only-import-tables | [] | 指定したテーブルのみデータ投入を行う |
|
43
|
+
| --except-import-tables | [] | 指定したテーブルのデータ投入を行わない |
|
44
|
+
| --only-verify-tables | [] | 指定したテーブルのみ投入後のバリデーションチェックを行う |
|
45
|
+
| --except-verify-tables | [] | 指定したテーブルのバリデーションチェックを行わない |
|
46
|
+
| --skip-no-change | true | CSVファイルに更新がないテーブルをスキップする |
|
47
|
+
| --silent | false | 結果の出力をやめる |
|
48
48
|
| --delete-all-ignore-foreign-key | false | 外部キー制約を無視してレコードを消すかどうか |
|
49
|
-
| --
|
49
|
+
| --override-identifier | nil | fixtures/#{override_identifier} のディレクトリにある内容でfixturesを上書きして投入する |
|
50
50
|
|
51
51
|
```bash
|
52
52
|
bundle exec master_data_tool import
|
@@ -27,11 +27,13 @@ module MasterDataTool
|
|
27
27
|
@override_identifier = override_identifier
|
28
28
|
@report_printer = report_printer
|
29
29
|
@report_printer.silent = silent
|
30
|
+
@master_data_statuses = []
|
30
31
|
end
|
31
32
|
|
32
33
|
def execute
|
33
34
|
ApplicationRecord.transaction do
|
34
35
|
print_execute_options
|
36
|
+
load_master_data_statuses
|
35
37
|
|
36
38
|
master_data_collection = build_master_data_collection
|
37
39
|
|
@@ -51,6 +53,8 @@ module MasterDataTool
|
|
51
53
|
|
52
54
|
private
|
53
55
|
|
56
|
+
attr_reader :master_data_statuses
|
57
|
+
|
54
58
|
def print_execute_options
|
55
59
|
return if @silent
|
56
60
|
|
@@ -115,7 +119,10 @@ module MasterDataTool
|
|
115
119
|
return true if import_skip_table?(master_data_file.table_name)
|
116
120
|
return false unless @skip_no_change
|
117
121
|
|
118
|
-
|
122
|
+
master_data_status = master_data_statuses.dig(master_data_file.table_name)
|
123
|
+
return false unless master_data_status
|
124
|
+
|
125
|
+
!master_data_status.will_change?(master_data_file)
|
119
126
|
end
|
120
127
|
|
121
128
|
def import_skip_table?(table_name)
|
@@ -152,6 +159,10 @@ module MasterDataTool
|
|
152
159
|
pattern = Pathname.new(MasterDataTool.config.master_data_dir).join(@override_identifier).join('*.csv').to_s
|
153
160
|
Pathname.glob(pattern).select(&:file?)
|
154
161
|
end
|
162
|
+
|
163
|
+
def load_master_data_statuses
|
164
|
+
@master_data_statuses = MasterDataTool::MasterDataStatus.fetch_all
|
165
|
+
end
|
155
166
|
end
|
156
167
|
end
|
157
168
|
end
|
@@ -142,9 +142,13 @@ module MasterDataTool
|
|
142
142
|
scoped.find_each do |record|
|
143
143
|
valid = record.valid?
|
144
144
|
report.append(MasterDataTool::Report::VerifyReport.build_verify_record_report(self, record, valid))
|
145
|
+
next if valid
|
145
146
|
next if ignore_fail
|
146
147
|
|
147
|
-
|
148
|
+
e = MasterDataTool::VerifyFailed.new("[#{table_name}] id = #{record.id} is invalid")
|
149
|
+
e.errors = record.errors
|
150
|
+
|
151
|
+
raise e
|
148
152
|
end
|
149
153
|
end
|
150
154
|
end
|
@@ -14,7 +14,17 @@ module MasterDataTool
|
|
14
14
|
validates :version,
|
15
15
|
presence: true
|
16
16
|
|
17
|
+
def will_change?(master_data_file)
|
18
|
+
raise unless name == master_data_file.table_name
|
19
|
+
|
20
|
+
version != self.class.decide_version(master_data_file.path)
|
21
|
+
end
|
22
|
+
|
17
23
|
class << self
|
24
|
+
def fetch_all
|
25
|
+
all.index_by(&:name)
|
26
|
+
end
|
27
|
+
|
18
28
|
def build(master_data_file)
|
19
29
|
version = decide_version(master_data_file.path)
|
20
30
|
new(name: MasterDataTool.resolve_table_name(master_data_file.path, master_data_file.override_identifier), version: version)
|
@@ -23,15 +33,10 @@ module MasterDataTool
|
|
23
33
|
def import_records!(records, dry_run: true)
|
24
34
|
if dry_run
|
25
35
|
pp records
|
26
|
-
|
27
|
-
import!(records, validate: true, on_duplicate_key_update: %w[name version], timestamps: true)
|
36
|
+
return
|
28
37
|
end
|
29
|
-
end
|
30
38
|
|
31
|
-
|
32
|
-
def master_data_will_change?(master_data_file)
|
33
|
-
new_version = decide_version(master_data_file.path)
|
34
|
-
!where(name: master_data_file.table_name, version: new_version).exists?
|
39
|
+
import!(records, validate: true, on_duplicate_key_update: %w[name version], timestamps: true)
|
35
40
|
end
|
36
41
|
|
37
42
|
def decide_version(csv_path)
|
data/lib/master_data_tool.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'csv'
|
4
|
+
require 'socket'
|
4
5
|
require_relative "master_data_tool/version"
|
5
6
|
require_relative "master_data_tool/config"
|
6
7
|
require_relative "master_data_tool/master_data_status"
|
@@ -15,9 +16,13 @@ require_relative "master_data_tool/import"
|
|
15
16
|
module MasterDataTool
|
16
17
|
class Error < StandardError; end
|
17
18
|
class DryRunError < StandardError; end
|
18
|
-
class VerifyFailed < StandardError; end
|
19
19
|
class NotLoadedError < StandardError; end
|
20
20
|
|
21
|
+
class VerifyFailed < StandardError
|
22
|
+
attr_accessor :errors
|
23
|
+
delegate :full_messages, to: :errors
|
24
|
+
end
|
25
|
+
|
21
26
|
class << self
|
22
27
|
def config
|
23
28
|
@config ||= Config.new
|
data/scripts/drop_db.sh
ADDED
data/sig/master_data_tool.rbs
CHANGED
@@ -1,4 +1,230 @@
|
|
1
|
+
# TypeProf 0.21.3
|
2
|
+
|
3
|
+
# Classes
|
1
4
|
module MasterDataTool
|
2
5
|
VERSION: String
|
3
|
-
|
6
|
+
self.@config: Config
|
7
|
+
|
8
|
+
def self.config: -> Config
|
9
|
+
def self.configure: -> untyped
|
10
|
+
def self.resolve_table_name: (Pathname csv_path, String? override_identifier) -> String
|
11
|
+
|
12
|
+
class Config
|
13
|
+
def initialize: -> void
|
14
|
+
end
|
15
|
+
|
16
|
+
class MasterDataStatus
|
17
|
+
def will_change?: (MasterDataFile master_data_file) -> bool
|
18
|
+
def self.fetch_all: -> Hash[String,MasterDataStatus]
|
19
|
+
def self.build: (MasterDataFile master_data_file) -> MasterDataStatus
|
20
|
+
def self.import_records!: (Array[MasterDataStatus] records, dry_run: bool) -> Array[MasterDataStatus]
|
21
|
+
def self.master_data_will_change?: (MasterDataFile master_data_file) -> bool
|
22
|
+
def self.decide_version: (Pathname csv_path) -> String
|
23
|
+
end
|
24
|
+
|
25
|
+
class MasterDataFile
|
26
|
+
attr_reader table_name: String
|
27
|
+
attr_reader path: Pathname
|
28
|
+
attr_reader override_identifier: String?
|
29
|
+
def initialize: (String table_name, Pathname path, String? override_identifier) -> void
|
30
|
+
def self.build: (Pathname path, String? override_identifier) -> MasterDataFile
|
31
|
+
def basename: -> Pathname
|
32
|
+
def ==: (untyped other) -> bool
|
33
|
+
alias eql? ==
|
34
|
+
def hash: -> Integer
|
35
|
+
end
|
36
|
+
|
37
|
+
class MasterDataFileCollection
|
38
|
+
@override_identifier: String?
|
39
|
+
@collection: Array[MasterDataFile]
|
40
|
+
|
41
|
+
def initialize: (override_identifier: String?) -> void
|
42
|
+
def each: ?{ -> Array[MasterDataFile] } -> Enumerator[bot, untyped]
|
43
|
+
def to_a: -> Array[MasterDataFile]
|
44
|
+
|
45
|
+
private
|
46
|
+
def build: -> Array[MasterDataFile]
|
47
|
+
def extract_master_data_csv_paths: -> Array[MasterDataFile]
|
48
|
+
def overridden_master_data_csv_paths: -> Array[MasterDataFile]
|
49
|
+
end
|
50
|
+
|
51
|
+
class MasterData
|
52
|
+
@loaded: bool
|
53
|
+
@affected: bool
|
54
|
+
@preload_associations: Array[untyped]
|
55
|
+
@eager_load_associations: Array[untyped]
|
56
|
+
|
57
|
+
attr_reader master_data_file: MasterDataFile
|
58
|
+
attr_reader model_klass: untyped
|
59
|
+
attr_reader columns: Array[String]
|
60
|
+
attr_reader new_records: Array[untyped]
|
61
|
+
def new_records: -> Array[untyped]
|
62
|
+
attr_reader updated_records: Array[untyped]
|
63
|
+
def updated_records: -> Array[untyped]
|
64
|
+
attr_reader no_change_records: Array[untyped]
|
65
|
+
def no_change_records: -> Array[untyped]
|
66
|
+
attr_reader deleted_records: Array[untyped]
|
67
|
+
def deleted_records: -> Array[untyped]
|
68
|
+
attr_reader before_count: Integer
|
69
|
+
def before_count: -> Integer
|
70
|
+
attr_reader after_count: Integer
|
71
|
+
def after_count: -> Integer
|
72
|
+
def initialize: (MasterDataFile master_data_file, untyped model_klass) -> void
|
73
|
+
def self.build: (MasterDataFile master_data_file, ?load: bool) -> MasterData
|
74
|
+
def basename: -> Pathname
|
75
|
+
def load: -> true
|
76
|
+
def import_records: -> Array[untyped]
|
77
|
+
def affected_records: -> Array[untyped]
|
78
|
+
def loaded?: -> bool
|
79
|
+
def affected?: -> bool?
|
80
|
+
def table_name: -> String
|
81
|
+
def import!: (?dry_run: true, ?delete_all_ignore_foreign_key: false) -> Report::ImportReport
|
82
|
+
def verify!: (?ignore_fail: bool) -> Report::VerifyReport
|
83
|
+
def print_affected_table: -> Report::PrintAffectedTableReport?
|
84
|
+
|
85
|
+
private
|
86
|
+
def preload_associations: -> Array[untyped]
|
87
|
+
def eager_load_associations: -> Array[untyped]
|
88
|
+
def build_records_from_csv: (Array[Array[String?]] csv, Hash[Integer, untyped] old_records_by_id) -> Hash[Integer, untyped]
|
89
|
+
def enable_foreign_key_checks: -> untyped
|
90
|
+
def disable_foreign_key_checks: -> untyped
|
91
|
+
end
|
92
|
+
|
93
|
+
class MasterDataCollection
|
94
|
+
@collection: Array[MasterData]
|
95
|
+
|
96
|
+
def initialize: -> void
|
97
|
+
def append: (MasterData master_data) -> Array[MasterData]
|
98
|
+
def each: ?{ (MasterData) -> (Array[MasterDataStatus | {operation: :verify, table_name: untyped, valid: untyped, id: untyped}]?) } -> (Array[MasterData] | Enumerator[MasterData, untyped] | Enumerator[untyped, untyped])
|
99
|
+
def to_a: -> Array[MasterData]
|
100
|
+
end
|
101
|
+
|
102
|
+
module Report
|
103
|
+
module Printer
|
104
|
+
attr_accessor silent: false
|
105
|
+
def initialize: (?silent: false) -> void
|
106
|
+
def print: (String message) -> nil
|
107
|
+
end
|
108
|
+
|
109
|
+
class DefaultPrinter
|
110
|
+
include Printer
|
111
|
+
|
112
|
+
def print: (String message) -> nil
|
113
|
+
end
|
114
|
+
|
115
|
+
module Core
|
116
|
+
def initialize: (MasterData master_data) -> void
|
117
|
+
def print: (Printer printer) -> untyped
|
118
|
+
|
119
|
+
private
|
120
|
+
def convert_to_ltsv: ({operation: :affected_table | :verify, table_name: untyped, valid: untyped, id: untyped} items) -> String
|
121
|
+
end
|
122
|
+
|
123
|
+
class ImportReport
|
124
|
+
include Core
|
125
|
+
@master_data: MasterData
|
126
|
+
|
127
|
+
attr_reader reports: Array[untyped]
|
128
|
+
def reports: -> Array[untyped]
|
129
|
+
def print: (Printer printer) -> untyped
|
130
|
+
|
131
|
+
private
|
132
|
+
def count_report: -> Hash[Symbol, Array[Hash[Symbol, untyped]]]
|
133
|
+
def new_records_report: -> Hash[Symbol, Array[Hash[Symbol, untyped]]]
|
134
|
+
def updated_records_report: -> Hash[Symbol, Array[Hash[Symbol, untyped]]]
|
135
|
+
def no_change_records_report: -> Hash[Symbol, Array[Hash[Symbol, untyped]]]
|
136
|
+
def deleted_records_report: -> Hash[Symbol, Array[Hash[Symbol, untyped]]]
|
137
|
+
end
|
138
|
+
|
139
|
+
class VerifyReport
|
140
|
+
include Core
|
141
|
+
@master_data: MasterData
|
142
|
+
|
143
|
+
attr_reader reports: Array[{operation: :verify, table_name: untyped, valid: untyped, id: untyped}]
|
144
|
+
def initialize: (MasterData master_data) -> void
|
145
|
+
def append: ({operation: :verify, table_name: untyped, valid: untyped, id: untyped} verify_record_report) -> Array[{operation: :verify, table_name: untyped, valid: untyped, id: untyped}]
|
146
|
+
def print: (Printer printer) -> Array[{operation: :verify, table_name: untyped, valid: untyped, id: untyped}]
|
147
|
+
def self.build_verify_record_report: (MasterData master_data, untyped record, untyped valid) -> {operation: :verify, table_name: untyped, valid: untyped, id: untyped}
|
148
|
+
end
|
149
|
+
|
150
|
+
class PrintAffectedTableReport
|
151
|
+
include Core
|
152
|
+
@master_data: MasterData
|
153
|
+
|
154
|
+
def print: (Printer printer) -> nil
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
module Dump
|
159
|
+
class Executor
|
160
|
+
DEFAULT_IGNORE_TABLES: [String, String, String]
|
161
|
+
DEFAULT_IGNORE_COLUMNS: [String, String]
|
162
|
+
@ignore_empty_table: bool
|
163
|
+
@ignore_tables: Array[String]
|
164
|
+
@ignore_column_names: Array[String]
|
165
|
+
@only_tables: Array[String]
|
166
|
+
@verbose: bool
|
167
|
+
|
168
|
+
def initialize: (ignore_empty_table: bool, ignore_tables: Array[String], ignore_column_names: Array[String], only_tables: Array[String], verbose: bool) -> void
|
169
|
+
def execute: -> Array[untyped]
|
170
|
+
|
171
|
+
private
|
172
|
+
def print_message: (String message) -> nil
|
173
|
+
def dump_to_csv: (untyped table) -> nil
|
174
|
+
def ignore?: (untyped model_klass) -> false
|
175
|
+
|
176
|
+
class Error < Struct[untyped]
|
177
|
+
attr_accessor table(): untyped
|
178
|
+
attr_accessor exception(): nil
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
module Import
|
184
|
+
class Executor
|
185
|
+
@dry_run: bool
|
186
|
+
@verify: bool
|
187
|
+
@only_import_tables: Array[String]
|
188
|
+
@except_import_tables: Array[String]
|
189
|
+
@only_verify_tables: Array[String]
|
190
|
+
@except_verify_tables: Array[String]
|
191
|
+
@skip_no_change: bool
|
192
|
+
@silent: bool
|
193
|
+
@delete_all_ignore_foreign_key: bool
|
194
|
+
@override_identifier: String?
|
195
|
+
@report_printer: Report::DefaultPrinter
|
196
|
+
@master_data_statuses: [MasterDataStatus]
|
197
|
+
|
198
|
+
def initialize: (dry_run: bool, verify: bool, only_import_tables: Array[String], except_import_tables: Array[String], only_verify_tables: Array[String], except_verify_tables: Array[String], skip_no_change: bool, silent: bool, delete_all_ignore_foreign_key: bool, override_identifier: String?, report_printer: Report::Printer) -> void
|
199
|
+
def execute: -> nil
|
200
|
+
|
201
|
+
private
|
202
|
+
def print_execute_options: -> nil
|
203
|
+
def build_master_data_collection: -> MasterDataCollection
|
204
|
+
def import_all!: (MasterDataCollection master_data_collection) -> (Array[MasterData] | Enumerator[MasterData, untyped] | Enumerator[untyped, untyped])
|
205
|
+
def verify_all!: (MasterDataCollection master_data_collection) -> (Array[MasterData] | Enumerator[MasterData, untyped] | Enumerator[untyped, untyped])
|
206
|
+
def save_master_data_statuses!: (MasterDataCollection master_data_collection) -> Array[MasterDataStatus]
|
207
|
+
def print_affected_tables: (MasterDataCollection master_data_collection) -> (Array[MasterData] | Enumerator[MasterData, untyped] | Enumerator[untyped, untyped])
|
208
|
+
def load_skip_table?: (untyped master_data_file) -> bool
|
209
|
+
def import_skip_table?: (untyped table_name) -> bool
|
210
|
+
def verify_skip_table?: (untyped table_name) -> bool
|
211
|
+
def need_skip_table?: (untyped table_name, Array[untyped] only, Array[untyped] except) -> bool
|
212
|
+
def extract_master_data_csv_paths: -> Array[Pathname]
|
213
|
+
def overridden_master_data_csv_paths: -> Array[Pathname]
|
214
|
+
def master_data_statuses: -> untyped
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
class Error < StandardError
|
219
|
+
end
|
220
|
+
|
221
|
+
class DryRunError < StandardError
|
222
|
+
end
|
223
|
+
|
224
|
+
class NotLoadedError < StandardError
|
225
|
+
end
|
226
|
+
|
227
|
+
class VerifyFailed < StandardError
|
228
|
+
attr_accessor errors: untyped
|
229
|
+
end
|
4
230
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: master_data_tool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.19.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takahiro Ooishi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-07-
|
11
|
+
date: 2022-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -209,6 +209,7 @@ files:
|
|
209
209
|
- lib/master_data_tool/version.rb
|
210
210
|
- log/test.log
|
211
211
|
- master_data_tool.gemspec
|
212
|
+
- scripts/drop_db.sh
|
212
213
|
- scripts/setup.sh
|
213
214
|
- sig/master_data_tool.rbs
|
214
215
|
homepage: https://github.com/taka0125/master_data_tool
|
@@ -231,7 +232,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
231
232
|
- !ruby/object:Gem::Version
|
232
233
|
version: '0'
|
233
234
|
requirements: []
|
234
|
-
rubygems_version: 3.
|
235
|
+
rubygems_version: 3.3.7
|
235
236
|
signing_key:
|
236
237
|
specification_version: 4
|
237
238
|
summary: マスタデータの管理ツール
|