├── .editorconfig
├── .github
└── workflows
│ └── build.yml
├── .gitignore
├── LICENSE
├── README.md
├── assets
├── database.png
├── diagram.png
├── docker_config.png
├── docker_login.png
├── empty_database.png
├── migration_finished.png
└── success.png
├── build.gradle
├── docker-compose.yaml
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── lombok.config
├── settings.gradle
└── src
├── main
├── java
│ └── altium
│ │ └── migrator
│ │ ├── AltiumMigratorApplication.java
│ │ └── service
│ │ ├── GitRepositoryService.java
│ │ ├── LiquibaseMigrationService.java
│ │ └── MigrationCommandRunner.java
└── resources
│ ├── application-dev.yaml
│ ├── application-docker-dev.yaml
│ ├── application-prod.yaml
│ ├── application.yaml
│ └── logging
│ ├── log4j-dev.yaml
│ └── log4j-prod.yaml
└── test
├── groovy
└── altium
│ └── migrator
│ ├── DatabaseSpecTemplate.groovy
│ └── PostgresContainerITSpec.groovy
└── resources
├── application-it-test.yaml
└── db
└── migrations
├── 25-12-2022
└── BatteryManagement.sql
└── db.changelog-master.xml
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 4
6 | tab_width = 4
7 | charset = utf-8
8 | trim_trailing_whitespace = false
9 | insert_final_newline = false
10 | max_line_length = off
11 | ij_visual_guides = 140
12 | ij_continuation_indent_size = 8
13 | ij_formatter_off_tag = @formatter:off
14 | ij_formatter_on_tag = @formatter:on
15 | ij_formatter_tags_enabled = false
16 | ij_smart_tabs = true
17 | ij_wrap_on_typing = false
18 |
19 | [*.java]
20 | ij_java_align_consecutive_assignments = false
21 | ij_java_align_consecutive_variable_declarations = false
22 | ij_java_align_group_field_declarations = false
23 | ij_java_align_multiline_annotation_parameters = false
24 | ij_java_align_multiline_array_initializer_expression = false
25 | ij_java_align_multiline_assignment = false
26 | ij_java_align_multiline_binary_operation = false
27 | ij_java_align_multiline_chained_methods = false
28 | ij_java_align_multiline_extends_list = false
29 | ij_java_align_multiline_for = true
30 | ij_java_align_multiline_method_parentheses = false
31 | ij_java_align_multiline_parameters = true
32 | ij_java_align_multiline_parameters_in_calls = false
33 | ij_java_align_multiline_parenthesized_expression = false
34 | ij_java_align_multiline_records = true
35 | ij_java_align_multiline_resources = true
36 | ij_java_align_multiline_ternary_operation = false
37 | ij_java_align_multiline_text_blocks = false
38 | ij_java_align_multiline_throws_list = false
39 | ij_java_align_subsequent_simple_methods = false
40 | ij_java_align_throws_keyword = false
41 | ij_java_annotation_parameter_wrap = off
42 | ij_java_array_initializer_new_line_after_left_brace = false
43 | ij_java_array_initializer_right_brace_on_new_line = false
44 | ij_java_array_initializer_wrap = off
45 | ij_java_assert_statement_colon_on_next_line = false
46 | ij_java_assert_statement_wrap = off
47 | ij_java_assignment_wrap = off
48 | ij_java_binary_operation_sign_on_next_line = false
49 | ij_java_binary_operation_wrap = off
50 | ij_java_blank_lines_after_anonymous_class_header = 0
51 | ij_java_blank_lines_after_class_header = 1
52 | ij_java_blank_lines_after_imports = 1
53 | ij_java_blank_lines_after_package = 1
54 | ij_java_blank_lines_around_class = 1
55 | ij_java_blank_lines_around_field = 0
56 | ij_java_blank_lines_around_field_in_interface = 0
57 | ij_java_blank_lines_around_initializer = 1
58 | ij_java_blank_lines_around_method = 1
59 | ij_java_blank_lines_around_method_in_interface = 1
60 | ij_java_blank_lines_before_class_end = 0
61 | ij_java_blank_lines_before_imports = 1
62 | ij_java_blank_lines_before_method_body = 0
63 | ij_java_blank_lines_before_package = 0
64 | ij_java_block_brace_style = end_of_line
65 | ij_java_block_comment_at_first_column = true
66 | ij_java_call_parameters_new_line_after_left_paren = false
67 | ij_java_call_parameters_right_paren_on_new_line = false
68 | ij_java_call_parameters_wrap = off
69 | ij_java_case_statement_on_separate_line = true
70 | ij_java_catch_on_new_line = false
71 | ij_java_class_annotation_wrap = split_into_lines
72 | ij_java_class_brace_style = end_of_line
73 | ij_java_class_count_to_use_import_on_demand = 8
74 | ij_java_class_names_in_javadoc = 1
75 | ij_java_do_not_indent_top_level_class_members = false
76 | ij_java_do_not_wrap_after_single_annotation = false
77 | ij_java_do_while_brace_force = never
78 | ij_java_doc_add_blank_line_after_description = true
79 | ij_java_doc_add_blank_line_after_param_comments = false
80 | ij_java_doc_add_blank_line_after_return = false
81 | ij_java_doc_add_p_tag_on_empty_lines = true
82 | ij_java_doc_align_exception_comments = true
83 | ij_java_doc_align_param_comments = true
84 | ij_java_doc_do_not_wrap_if_one_line = false
85 | ij_java_doc_enable_formatting = true
86 | ij_java_doc_enable_leading_asterisks = true
87 | ij_java_doc_indent_on_continuation = false
88 | ij_java_doc_keep_empty_lines = true
89 | ij_java_doc_keep_empty_parameter_tag = true
90 | ij_java_doc_keep_empty_return_tag = true
91 | ij_java_doc_keep_empty_throws_tag = true
92 | ij_java_doc_keep_invalid_tags = true
93 | ij_java_doc_param_description_on_new_line = false
94 | ij_java_doc_preserve_line_breaks = false
95 | ij_java_doc_use_throws_not_exception_tag = true
96 | ij_java_else_on_new_line = false
97 | ij_java_entity_dd_suffix = EJB
98 | ij_java_entity_eb_suffix = Bean
99 | ij_java_entity_hi_suffix = Home
100 | ij_java_entity_lhi_prefix = Local
101 | ij_java_entity_lhi_suffix = Home
102 | ij_java_entity_li_prefix = Local
103 | ij_java_entity_pk_class = java.lang.String
104 | ij_java_entity_vo_suffix = VO
105 | ij_java_enum_constants_wrap = off
106 | ij_java_extends_keyword_wrap = off
107 | ij_java_extends_list_wrap = off
108 | ij_java_field_annotation_wrap = split_into_lines
109 | ij_java_finally_on_new_line = false
110 | ij_java_for_brace_force = never
111 | ij_java_for_statement_new_line_after_left_paren = false
112 | ij_java_for_statement_right_paren_on_new_line = false
113 | ij_java_for_statement_wrap = off
114 | ij_java_generate_final_locals = false
115 | ij_java_generate_final_parameters = false
116 | ij_java_if_brace_force = never
117 | ij_java_imports_layout = *,|,javax.**,java.**,|,me.bill.**,com.ecp.**,|,$*
118 | ij_java_indent_case_from_switch = true
119 | ij_java_insert_inner_class_imports = false
120 | ij_java_insert_override_annotation = true
121 | ij_java_keep_blank_lines_before_right_brace = 2
122 | ij_java_keep_blank_lines_between_package_declaration_and_header = 2
123 | ij_java_keep_blank_lines_in_code = 2
124 | ij_java_keep_blank_lines_in_declarations = 2
125 | ij_java_keep_control_statement_in_one_line = true
126 | ij_java_keep_first_column_comment = true
127 | ij_java_keep_indents_on_empty_lines = false
128 | ij_java_keep_line_breaks = true
129 | ij_java_keep_multiple_expressions_in_one_line = false
130 | ij_java_keep_simple_blocks_in_one_line = false
131 | ij_java_keep_simple_classes_in_one_line = false
132 | ij_java_keep_simple_lambdas_in_one_line = false
133 | ij_java_keep_simple_methods_in_one_line = false
134 | ij_java_label_indent_absolute = false
135 | ij_java_label_indent_size = 0
136 | ij_java_lambda_brace_style = end_of_line
137 | ij_java_layout_static_imports_separately = true
138 | ij_java_line_comment_add_space = false
139 | ij_java_line_comment_at_first_column = false
140 | ij_java_message_dd_suffix = EJB
141 | ij_java_message_eb_suffix = Bean
142 | ij_java_method_annotation_wrap = split_into_lines
143 | ij_java_method_brace_style = end_of_line
144 | ij_java_method_call_chain_wrap = off
145 | ij_java_method_parameters_new_line_after_left_paren = false
146 | ij_java_method_parameters_right_paren_on_new_line = false
147 | ij_java_method_parameters_wrap = off
148 | ij_java_modifier_list_wrap = false
149 | ij_java_names_count_to_use_import_on_demand = 50
150 | ij_java_new_line_after_lparen_in_record_header = false
151 | ij_java_packages_to_use_import_on_demand = java.awt.*,javax.swing.*
152 | ij_java_parameter_annotation_wrap = off
153 | ij_java_parentheses_expression_new_line_after_left_paren = false
154 | ij_java_parentheses_expression_right_paren_on_new_line = false
155 | ij_java_place_assignment_sign_on_next_line = false
156 | ij_java_prefer_longer_names = true
157 | ij_java_prefer_parameters_wrap = false
158 | ij_java_record_components_wrap = normal
159 | ij_java_repeat_synchronized = true
160 | ij_java_replace_instanceof_and_cast = false
161 | ij_java_replace_null_check = true
162 | ij_java_replace_sum_lambda_with_method_ref = true
163 | ij_java_resource_list_new_line_after_left_paren = false
164 | ij_java_resource_list_right_paren_on_new_line = false
165 | ij_java_resource_list_wrap = off
166 | ij_java_rparen_on_new_line_in_record_header = false
167 | ij_java_session_dd_suffix = EJB
168 | ij_java_session_eb_suffix = Bean
169 | ij_java_session_hi_suffix = Home
170 | ij_java_session_lhi_prefix = Local
171 | ij_java_session_lhi_suffix = Home
172 | ij_java_session_li_prefix = Local
173 | ij_java_session_si_suffix = Service
174 | ij_java_space_after_closing_angle_bracket_in_type_argument = false
175 | ij_java_space_after_colon = true
176 | ij_java_space_after_comma = true
177 | ij_java_space_after_comma_in_type_arguments = true
178 | ij_java_space_after_for_semicolon = true
179 | ij_java_space_after_quest = true
180 | ij_java_space_after_type_cast = true
181 | ij_java_space_before_annotation_array_initializer_left_brace = false
182 | ij_java_space_before_annotation_parameter_list = false
183 | ij_java_space_before_array_initializer_left_brace = false
184 | ij_java_space_before_catch_keyword = true
185 | ij_java_space_before_catch_left_brace = true
186 | ij_java_space_before_catch_parentheses = true
187 | ij_java_space_before_class_left_brace = true
188 | ij_java_space_before_colon = true
189 | ij_java_space_before_colon_in_foreach = true
190 | ij_java_space_before_comma = false
191 | ij_java_space_before_do_left_brace = true
192 | ij_java_space_before_else_keyword = true
193 | ij_java_space_before_else_left_brace = true
194 | ij_java_space_before_finally_keyword = true
195 | ij_java_space_before_finally_left_brace = true
196 | ij_java_space_before_for_left_brace = true
197 | ij_java_space_before_for_parentheses = true
198 | ij_java_space_before_for_semicolon = false
199 | ij_java_space_before_if_left_brace = true
200 | ij_java_space_before_if_parentheses = true
201 | ij_java_space_before_method_call_parentheses = false
202 | ij_java_space_before_method_left_brace = true
203 | ij_java_space_before_method_parentheses = false
204 | ij_java_space_before_opening_angle_bracket_in_type_parameter = false
205 | ij_java_space_before_quest = true
206 | ij_java_space_before_switch_left_brace = true
207 | ij_java_space_before_switch_parentheses = true
208 | ij_java_space_before_synchronized_left_brace = true
209 | ij_java_space_before_synchronized_parentheses = true
210 | ij_java_space_before_try_left_brace = true
211 | ij_java_space_before_try_parentheses = true
212 | ij_java_space_before_type_parameter_list = false
213 | ij_java_space_before_while_keyword = true
214 | ij_java_space_before_while_left_brace = true
215 | ij_java_space_before_while_parentheses = true
216 | ij_java_space_inside_one_line_enum_braces = false
217 | ij_java_space_within_empty_array_initializer_braces = false
218 | ij_java_space_within_empty_method_call_parentheses = false
219 | ij_java_space_within_empty_method_parentheses = false
220 | ij_java_spaces_around_additive_operators = true
221 | ij_java_spaces_around_assignment_operators = true
222 | ij_java_spaces_around_bitwise_operators = true
223 | ij_java_spaces_around_equality_operators = true
224 | ij_java_spaces_around_lambda_arrow = true
225 | ij_java_spaces_around_logical_operators = true
226 | ij_java_spaces_around_method_ref_dbl_colon = false
227 | ij_java_spaces_around_multiplicative_operators = true
228 | ij_java_spaces_around_relational_operators = true
229 | ij_java_spaces_around_shift_operators = true
230 | ij_java_spaces_around_type_bounds_in_type_parameters = true
231 | ij_java_spaces_around_unary_operator = false
232 | ij_java_spaces_within_angle_brackets = false
233 | ij_java_spaces_within_annotation_parentheses = false
234 | ij_java_spaces_within_array_initializer_braces = false
235 | ij_java_spaces_within_braces = false
236 | ij_java_spaces_within_brackets = false
237 | ij_java_spaces_within_cast_parentheses = false
238 | ij_java_spaces_within_catch_parentheses = false
239 | ij_java_spaces_within_for_parentheses = false
240 | ij_java_spaces_within_if_parentheses = false
241 | ij_java_spaces_within_method_call_parentheses = false
242 | ij_java_spaces_within_method_parentheses = false
243 | ij_java_spaces_within_parentheses = false
244 | ij_java_spaces_within_switch_parentheses = false
245 | ij_java_spaces_within_synchronized_parentheses = false
246 | ij_java_spaces_within_try_parentheses = false
247 | ij_java_spaces_within_while_parentheses = false
248 | ij_java_special_else_if_treatment = true
249 | ij_java_subclass_name_suffix = Impl
250 | ij_java_ternary_operation_signs_on_next_line = false
251 | ij_java_ternary_operation_wrap = off
252 | ij_java_test_name_suffix = Test
253 | ij_java_throws_keyword_wrap = off
254 | ij_java_throws_list_wrap = off
255 | ij_java_use_external_annotations = false
256 | ij_java_use_fq_class_names = false
257 | ij_java_use_relative_indents = false
258 | ij_java_use_single_class_imports = true
259 | ij_java_variable_annotation_wrap = off
260 | ij_java_visibility = public
261 | ij_java_while_brace_force = never
262 | ij_java_while_on_new_line = false
263 | ij_java_wrap_comments = false
264 | ij_java_wrap_first_method_in_call_chain = false
265 | ij_java_wrap_long_lines = false
266 |
267 | [{*.gant,*.gradle,*.groovy,*.gson,*.gy}]
268 | ij_groovy_align_group_field_declarations = false
269 | ij_groovy_align_multiline_array_initializer_expression = false
270 | ij_groovy_align_multiline_assignment = false
271 | ij_groovy_align_multiline_binary_operation = false
272 | ij_groovy_align_multiline_chained_methods = false
273 | ij_groovy_align_multiline_extends_list = false
274 | ij_groovy_align_multiline_for = true
275 | ij_groovy_align_multiline_list_or_map = true
276 | ij_groovy_align_multiline_method_parentheses = false
277 | ij_groovy_align_multiline_parameters = true
278 | ij_groovy_align_multiline_parameters_in_calls = false
279 | ij_groovy_align_multiline_resources = true
280 | ij_groovy_align_multiline_ternary_operation = false
281 | ij_groovy_align_multiline_throws_list = false
282 | ij_groovy_align_named_args_in_map = true
283 | ij_groovy_align_throws_keyword = false
284 | ij_groovy_array_initializer_new_line_after_left_brace = false
285 | ij_groovy_array_initializer_right_brace_on_new_line = false
286 | ij_groovy_array_initializer_wrap = off
287 | ij_groovy_assert_statement_wrap = off
288 | ij_groovy_assignment_wrap = off
289 | ij_groovy_binary_operation_wrap = off
290 | ij_groovy_blank_lines_after_class_header = 1
291 | ij_groovy_blank_lines_after_imports = 1
292 | ij_groovy_blank_lines_after_package = 1
293 | ij_groovy_blank_lines_around_class = 1
294 | ij_groovy_blank_lines_around_field = 0
295 | ij_groovy_blank_lines_around_field_in_interface = 0
296 | ij_groovy_blank_lines_around_method = 1
297 | ij_groovy_blank_lines_around_method_in_interface = 1
298 | ij_groovy_blank_lines_before_imports = 1
299 | ij_groovy_blank_lines_before_method_body = 0
300 | ij_groovy_blank_lines_before_package = 0
301 | ij_groovy_block_brace_style = end_of_line
302 | ij_groovy_block_comment_at_first_column = false
303 | ij_groovy_call_parameters_new_line_after_left_paren = false
304 | ij_groovy_call_parameters_right_paren_on_new_line = false
305 | ij_groovy_call_parameters_wrap = off
306 | ij_groovy_catch_on_new_line = false
307 | ij_groovy_class_annotation_wrap = split_into_lines
308 | ij_groovy_class_brace_style = end_of_line
309 | ij_groovy_class_count_to_use_import_on_demand = 50
310 | ij_groovy_do_while_brace_force = never
311 | ij_groovy_else_on_new_line = false
312 | ij_groovy_enum_constants_wrap = off
313 | ij_groovy_extends_keyword_wrap = off
314 | ij_groovy_extends_list_wrap = off
315 | ij_groovy_field_annotation_wrap = split_into_lines
316 | ij_groovy_finally_on_new_line = false
317 | ij_groovy_for_brace_force = never
318 | ij_groovy_for_statement_new_line_after_left_paren = false
319 | ij_groovy_for_statement_right_paren_on_new_line = false
320 | ij_groovy_for_statement_wrap = off
321 | ij_groovy_if_brace_force = never
322 | ij_groovy_import_annotation_wrap = 2
323 | ij_groovy_indent_case_from_switch = true
324 | ij_groovy_indent_label_blocks = true
325 | ij_groovy_insert_inner_class_imports = false
326 | ij_groovy_keep_blank_lines_before_right_brace = 2
327 | ij_groovy_keep_blank_lines_in_code = 2
328 | ij_groovy_keep_blank_lines_in_declarations = 2
329 | ij_groovy_keep_control_statement_in_one_line = true
330 | ij_groovy_keep_first_column_comment = true
331 | ij_groovy_keep_indents_on_empty_lines = false
332 | ij_groovy_keep_line_breaks = true
333 | ij_groovy_keep_multiple_expressions_in_one_line = false
334 | ij_groovy_keep_simple_blocks_in_one_line = false
335 | ij_groovy_keep_simple_classes_in_one_line = true
336 | ij_groovy_keep_simple_lambdas_in_one_line = true
337 | ij_groovy_keep_simple_methods_in_one_line = true
338 | ij_groovy_label_indent_absolute = false
339 | ij_groovy_label_indent_size = 0
340 | ij_groovy_lambda_brace_style = end_of_line
341 | ij_groovy_layout_static_imports_separately = true
342 | ij_groovy_line_comment_add_space = false
343 | ij_groovy_line_comment_at_first_column = true
344 | ij_groovy_method_annotation_wrap = split_into_lines
345 | ij_groovy_method_brace_style = end_of_line
346 | ij_groovy_method_call_chain_wrap = off
347 | ij_groovy_method_parameters_new_line_after_left_paren = false
348 | ij_groovy_method_parameters_right_paren_on_new_line = false
349 | ij_groovy_method_parameters_wrap = off
350 | ij_groovy_modifier_list_wrap = false
351 | ij_groovy_names_count_to_use_import_on_demand = 10
352 | ij_groovy_parameter_annotation_wrap = off
353 | ij_groovy_parentheses_expression_new_line_after_left_paren = false
354 | ij_groovy_parentheses_expression_right_paren_on_new_line = false
355 | ij_groovy_prefer_parameters_wrap = false
356 | ij_groovy_resource_list_new_line_after_left_paren = false
357 | ij_groovy_resource_list_right_paren_on_new_line = false
358 | ij_groovy_resource_list_wrap = off
359 | ij_groovy_space_after_assert_separator = true
360 | ij_groovy_space_after_colon = true
361 | ij_groovy_space_after_comma = true
362 | ij_groovy_space_after_comma_in_type_arguments = true
363 | ij_groovy_space_after_for_semicolon = true
364 | ij_groovy_space_after_quest = true
365 | ij_groovy_space_after_type_cast = true
366 | ij_groovy_space_before_annotation_parameter_list = false
367 | ij_groovy_space_before_array_initializer_left_brace = false
368 | ij_groovy_space_before_assert_separator = false
369 | ij_groovy_space_before_catch_keyword = true
370 | ij_groovy_space_before_catch_left_brace = true
371 | ij_groovy_space_before_catch_parentheses = true
372 | ij_groovy_space_before_class_left_brace = true
373 | ij_groovy_space_before_closure_left_brace = true
374 | ij_groovy_space_before_colon = true
375 | ij_groovy_space_before_comma = false
376 | ij_groovy_space_before_do_left_brace = true
377 | ij_groovy_space_before_else_keyword = true
378 | ij_groovy_space_before_else_left_brace = true
379 | ij_groovy_space_before_finally_keyword = true
380 | ij_groovy_space_before_finally_left_brace = true
381 | ij_groovy_space_before_for_left_brace = true
382 | ij_groovy_space_before_for_parentheses = true
383 | ij_groovy_space_before_for_semicolon = false
384 | ij_groovy_space_before_if_left_brace = true
385 | ij_groovy_space_before_if_parentheses = true
386 | ij_groovy_space_before_method_call_parentheses = false
387 | ij_groovy_space_before_method_left_brace = true
388 | ij_groovy_space_before_method_parentheses = false
389 | ij_groovy_space_before_quest = true
390 | ij_groovy_space_before_switch_left_brace = true
391 | ij_groovy_space_before_switch_parentheses = true
392 | ij_groovy_space_before_synchronized_left_brace = true
393 | ij_groovy_space_before_synchronized_parentheses = true
394 | ij_groovy_space_before_try_left_brace = true
395 | ij_groovy_space_before_try_parentheses = true
396 | ij_groovy_space_before_while_keyword = true
397 | ij_groovy_space_before_while_left_brace = true
398 | ij_groovy_space_before_while_parentheses = true
399 | ij_groovy_space_in_named_argument = true
400 | ij_groovy_space_in_named_argument_before_colon = false
401 | ij_groovy_space_within_empty_array_initializer_braces = false
402 | ij_groovy_space_within_empty_method_call_parentheses = false
403 | ij_groovy_spaces_around_additive_operators = true
404 | ij_groovy_spaces_around_assignment_operators = true
405 | ij_groovy_spaces_around_bitwise_operators = true
406 | ij_groovy_spaces_around_equality_operators = true
407 | ij_groovy_spaces_around_lambda_arrow = true
408 | ij_groovy_spaces_around_logical_operators = true
409 | ij_groovy_spaces_around_multiplicative_operators = true
410 | ij_groovy_spaces_around_regex_operators = true
411 | ij_groovy_spaces_around_relational_operators = true
412 | ij_groovy_spaces_around_shift_operators = true
413 | ij_groovy_spaces_within_annotation_parentheses = false
414 | ij_groovy_spaces_within_array_initializer_braces = false
415 | ij_groovy_spaces_within_braces = true
416 | ij_groovy_spaces_within_brackets = false
417 | ij_groovy_spaces_within_cast_parentheses = false
418 | ij_groovy_spaces_within_catch_parentheses = false
419 | ij_groovy_spaces_within_for_parentheses = false
420 | ij_groovy_spaces_within_gstring_injection_braces = false
421 | ij_groovy_spaces_within_if_parentheses = false
422 | ij_groovy_spaces_within_list_or_map = false
423 | ij_groovy_spaces_within_method_call_parentheses = false
424 | ij_groovy_spaces_within_method_parentheses = false
425 | ij_groovy_spaces_within_parentheses = false
426 | ij_groovy_spaces_within_switch_parentheses = false
427 | ij_groovy_spaces_within_synchronized_parentheses = false
428 | ij_groovy_spaces_within_try_parentheses = false
429 | ij_groovy_spaces_within_tuple_expression = false
430 | ij_groovy_spaces_within_while_parentheses = false
431 | ij_groovy_special_else_if_treatment = true
432 | ij_groovy_ternary_operation_wrap = off
433 | ij_groovy_throws_keyword_wrap = off
434 | ij_groovy_throws_list_wrap = off
435 | ij_groovy_use_flying_geese_braces = false
436 | ij_groovy_use_fq_class_names = false
437 | ij_groovy_use_fq_class_names_in_javadoc = true
438 | ij_groovy_use_relative_indents = false
439 | ij_groovy_use_single_class_imports = true
440 | ij_groovy_variable_annotation_wrap = off
441 | ij_groovy_while_brace_force = never
442 | ij_groovy_while_on_new_line = false
443 | ij_groovy_wrap_long_lines = false
444 |
445 | [{*.yaml,*.yml,skaffold.yaml}]
446 | indent_size = 2
447 | ij_yaml_keep_indents_on_empty_lines = false
448 | ij_yaml_keep_line_breaks = true
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: build
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 |
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - uses: actions/checkout@v3
16 |
17 | - name: Set up JDK
18 | uses: actions/setup-java@v4
19 | with:
20 | distribution: 'zulu'
21 | java-version: '21'
22 | cache: 'gradle'
23 |
24 | - name: Run Integration Tests
25 | run: gradle clean build --info
26 |
27 | - name: Login to Docker Hub
28 | uses: docker/login-action@v3
29 | with:
30 | username: ${{ secrets.DOCKERHUB_USERNAME }}
31 | password: ${{ secrets.DOCKERHUB_TOKEN }}
32 |
33 | - name: Build docker image
34 | run: gradle bootBuildImage --info
35 |
36 | - name: Tag docker image
37 | run: docker tag altium-migrator ${{ secrets.DOCKERHUB_USERNAME }}/altium-migrator:latest
38 |
39 | - name: Push docker image
40 | run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/altium-migrator:latest
41 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | build/
3 | !gradle/wrapper/gradle-wrapper.jar
4 | !**/src/main/**/build/
5 | !**/src/test/**/build/
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 | bin/
16 | !**/src/main/**/bin/
17 | !**/src/test/**/bin/
18 |
19 | ### IntelliJ IDEA ###
20 | .idea
21 | *.iws
22 | *.iml
23 | *.ipr
24 | out/
25 | !**/src/main/**/out/
26 | !**/src/test/**/out/
27 |
28 | ### NetBeans ###
29 | /nbproject/private/
30 | /nbbuild/
31 | /dist/
32 | /nbdist/
33 | /.nb-gradle/
34 |
35 | ### VS Code ###
36 | .vscode/
37 | /src/main/resources/db/
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Stanislav Vodolagin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Altium database migration tool
2 |
3 | [](https://github.com/ximtech/altium-migrator/actions/workflows/build.yml)
4 |
5 | The Altium database migration tool is a Spring boot application that helps handle changes from
6 | [Git component repository](https://github.com/ximtech/altium-library) to local database for offline development
7 | or any other hosted Postgres database by data source.
8 |
9 |
10 | ### How it works
11 |
12 | 
13 |
14 | 1. User run docker command, then if application image is not in local storage it will be downloaded from public docker hub
15 | 2. The container will start with user provided DB connection or default for local development
16 | 3. After the start, application will fetch from repository migration scripts(database sql dump)
17 | 4. Then liquibase migration tool will check database state and update it if needed
18 | 5. Application can be run as many times as needed, it won't overwrite data or duplicate them.
19 |
20 |
21 | ### How to use it
22 |
23 | 1. First, download and install Docker here: [Download Docker Desktop for Windows](https://www.docker.com/products/docker-desktop/)
24 | 2. After Docker has been installed, check it with: `docker ps` in command prompt
25 | 3. Then need to signup/sign-in for Docker hub. Open Docker desktop and then `Sign in`:
26 |
27 | 
28 |
29 | 4. Check login with command: `docker login`
30 |
31 | 
32 |
33 | 5. Now when Docker has configured. Need to install PostgresDB for local environment
34 | - ***First option.*** Run Database in container see [here](https://hub.docker.com/_/postgres)
35 | - Run in command line: `docker pull postgres`, it will pull the latest Postgres image
36 | - Run Database image:
37 | ```
38 | docker run -d -p 5432:5432\
39 | --name dev-postgres \
40 | -e POSTGRES_PASSWORD=postgres \
41 | -e POSTGRES_USER=postgres \
42 | -e POSTGRES_DB=altium-components \
43 | postgres
44 | ```
45 | - ***Second option.*** Download and install Postgres for local development [here](https://www.postgresql.org/download/windows/) -> `Download the installer`
46 | - Download and install PgAdmin tool from [here](https://www.pgadmin.org/)
47 | - Create empty Database:
48 | - 
49 | - In `Database` field write: `altium-components` -> `Save`
50 | - Check that empty database has been created:
51 | - 
52 |
53 | 6. ***Optionally:*** Create DB schema, or `altium` will be created as default schema. It will be used for all migrations
54 | 7. When all has been configured and empty Database created. Then run application
55 |
56 | ***Local development***
57 | ``` text
58 | docker run -p 5432:5432 -e PROFILE=docker-dev ximtech/altium-migrator
59 | ```
60 |
61 | ***Custom Database Hosting***
62 |
63 | ***Note:*** For custom datasource do not change `PROFILE` variable
64 |
65 | ```text
66 | docker run -p 5432:5432 \
67 | -e PROFILE=prod \
68 | -e ALTIUM_DB_DATASOURCE='jdbc:postgresql://host.docker.internal:5432/altium-components' \
69 | -e ALTIUM_DB_USERNAME='postgres' \
70 | -e ALTIUM_DB_PASSWORD='postgres' \
71 | -e LIQUIBASE_SCHEMA_NAME=altium \
72 | ximtech/altium-migrator:latest
73 | ```
74 |
75 | 7. At the end check that all data has been transferred:
76 | - 
77 |
78 | ***Database Structure***
79 | - 
80 |
--------------------------------------------------------------------------------
/assets/database.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ximtech/altium-migrator/07c97b5282f33c38c8b7835c3770da426deb500f/assets/database.png
--------------------------------------------------------------------------------
/assets/diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ximtech/altium-migrator/07c97b5282f33c38c8b7835c3770da426deb500f/assets/diagram.png
--------------------------------------------------------------------------------
/assets/docker_config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ximtech/altium-migrator/07c97b5282f33c38c8b7835c3770da426deb500f/assets/docker_config.png
--------------------------------------------------------------------------------
/assets/docker_login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ximtech/altium-migrator/07c97b5282f33c38c8b7835c3770da426deb500f/assets/docker_login.png
--------------------------------------------------------------------------------
/assets/empty_database.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ximtech/altium-migrator/07c97b5282f33c38c8b7835c3770da426deb500f/assets/empty_database.png
--------------------------------------------------------------------------------
/assets/migration_finished.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ximtech/altium-migrator/07c97b5282f33c38c8b7835c3770da426deb500f/assets/migration_finished.png
--------------------------------------------------------------------------------
/assets/success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ximtech/altium-migrator/07c97b5282f33c38c8b7835c3770da426deb500f/assets/success.png
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'idea'
3 | id 'java'
4 | id 'groovy'
5 | id 'org.springframework.boot' version '3.2.6'
6 | id 'io.spring.dependency-management' version '1.1.4'
7 | }
8 |
9 | group = 'com.altium.migrator'
10 | version = '1.1.0'
11 |
12 | java {
13 | sourceCompatibility = JavaVersion.VERSION_21
14 | targetCompatibility = JavaVersion.VERSION_21
15 | }
16 |
17 | configurations {
18 | compileOnly {
19 | extendsFrom annotationProcessor
20 | }
21 | }
22 |
23 | repositories {
24 | mavenCentral()
25 | }
26 |
27 | jar {
28 | enabled = false
29 | }
30 |
31 | bootJar {
32 | archivesBaseName = 'altium-migrator'
33 | }
34 |
35 | bootBuildImage {
36 | builder = 'paketobuildpacks/builder-jammy-tiny'
37 | imageName = 'altium-migrator'
38 | publish = false
39 | }
40 |
41 | ext {
42 | jgitVersion = '6.4.0.202211300538-r'
43 | testContainersVersion = '1.17.6'
44 | commonsIOVersion = '2.11.0'
45 | spockVersion = '2.3-groovy-3.0'
46 | }
47 |
48 | sourceSets {
49 | test {
50 | groovy {
51 | srcDirs = ['src/test/groovy']
52 | }
53 | resources {
54 | srcDirs = ['src/test/resources']
55 | }
56 | }
57 | }
58 |
59 | dependencies {
60 | implementation "org.springframework.boot:spring-boot-starter-data-jdbc"
61 | implementation 'org.springframework.boot:spring-boot-starter-log4j2'
62 | implementation "org.liquibase:liquibase-core"
63 | implementation "org.eclipse.jgit:org.eclipse.jgit:$jgitVersion"
64 | implementation "org.eclipse.jgit:org.eclipse.jgit.ssh.apache:$jgitVersion"
65 | implementation "org.eclipse.jgit:org.eclipse.jgit.gpg.bc:$jgitVersion"
66 | implementation "commons-io:commons-io:$commonsIOVersion"
67 | implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml'
68 |
69 | compileOnly "org.projectlombok:lombok"
70 | runtimeOnly "org.postgresql:postgresql"
71 |
72 | // Testing, Spock, Groovy
73 | testImplementation "org.codehaus.groovy:groovy-all:3.0.20"
74 | testImplementation "org.spockframework:spock-core:$spockVersion"
75 | testImplementation "org.spockframework:spock-spring:$spockVersion"
76 |
77 | testImplementation "org.springframework.boot:spring-boot-starter-test"
78 | testImplementation "org.testcontainers:spock:$testContainersVersion"
79 | implementation platform("org.testcontainers:testcontainers-bom:$testContainersVersion")
80 | testImplementation "org.testcontainers:postgresql"
81 |
82 | annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
83 | annotationProcessor "org.projectlombok:lombok"
84 | }
85 |
86 | configurations {
87 | all*.exclude module: 'spring-boot-starter-logging'
88 | }
89 |
90 | idea {
91 | module {
92 | downloadJavadoc = true
93 | downloadSources = true
94 | }
95 | }
96 |
97 | test {
98 | useJUnitPlatform()
99 | systemProperties System.properties
100 |
101 | testLogging {
102 | events "passed", "skipped", "failed"
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/docker-compose.yaml:
--------------------------------------------------------------------------------
1 | version: '2.4'
2 |
3 | services:
4 | server:
5 | image: altium-migrator:latest
6 | ports:
7 | - 5432:5432
8 | command: --spring.profiles.active=docker-dev
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ximtech/altium-migrator/07c97b5282f33c38c8b7835c3770da426deb500f/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
84 |
85 | APP_NAME="Gradle"
86 | APP_BASE_NAME=${0##*/}
87 |
88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
90 |
91 | # Use the maximum available, or set MAX_FD != -1 to use that value.
92 | MAX_FD=maximum
93 |
94 | warn () {
95 | echo "$*"
96 | } >&2
97 |
98 | die () {
99 | echo
100 | echo "$*"
101 | echo
102 | exit 1
103 | } >&2
104 |
105 | # OS specific support (must be 'true' or 'false').
106 | cygwin=false
107 | msys=false
108 | darwin=false
109 | nonstop=false
110 | case "$( uname )" in #(
111 | CYGWIN* ) cygwin=true ;; #(
112 | Darwin* ) darwin=true ;; #(
113 | MSYS* | MINGW* ) msys=true ;; #(
114 | NONSTOP* ) nonstop=true ;;
115 | esac
116 |
117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
118 |
119 |
120 | # Determine the Java command to use to start the JVM.
121 | if [ -n "$JAVA_HOME" ] ; then
122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
123 | # IBM's JDK on AIX uses strange locations for the executables
124 | JAVACMD=$JAVA_HOME/jre/sh/java
125 | else
126 | JAVACMD=$JAVA_HOME/bin/java
127 | fi
128 | if [ ! -x "$JAVACMD" ] ; then
129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
130 |
131 | Please set the JAVA_HOME variable in your environment to match the
132 | location of your Java installation."
133 | fi
134 | else
135 | JAVACMD=java
136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 |
142 | # Increase the maximum file descriptors if we can.
143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
144 | case $MAX_FD in #(
145 | max*)
146 | MAX_FD=$( ulimit -H -n ) ||
147 | warn "Could not query maximum file descriptor limit"
148 | esac
149 | case $MAX_FD in #(
150 | '' | soft) :;; #(
151 | *)
152 | ulimit -n "$MAX_FD" ||
153 | warn "Could not set maximum file descriptor limit to $MAX_FD"
154 | esac
155 | fi
156 |
157 | # Collect all arguments for the java command, stacking in reverse order:
158 | # * args from the command line
159 | # * the main class name
160 | # * -classpath
161 | # * -D...appname settings
162 | # * --module-path (only if needed)
163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
164 |
165 | # For Cygwin or MSYS, switch paths to Windows format before running java
166 | if "$cygwin" || "$msys" ; then
167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
169 |
170 | JAVACMD=$( cygpath --unix "$JAVACMD" )
171 |
172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
173 | for arg do
174 | if
175 | case $arg in #(
176 | -*) false ;; # don't mess with options #(
177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
178 | [ -e "$t" ] ;; #(
179 | *) false ;;
180 | esac
181 | then
182 | arg=$( cygpath --path --ignore --mixed "$arg" )
183 | fi
184 | # Roll the args list around exactly as many times as the number of
185 | # args, so each arg winds up back in the position where it started, but
186 | # possibly modified.
187 | #
188 | # NB: a `for` loop captures its iteration list before it begins, so
189 | # changing the positional parameters here affects neither the number of
190 | # iterations, nor the values presented in `arg`.
191 | shift # remove old arg
192 | set -- "$@" "$arg" # push replacement arg
193 | done
194 | fi
195 |
196 | # Collect all arguments for the java command;
197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
198 | # shell script including quotes and variable substitutions, so put them in
199 | # double quotes to make sure that they get re-expanded; and
200 | # * put everything else in single quotes, so that it's not re-expanded.
201 |
202 | set -- \
203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
204 | -classpath "$CLASSPATH" \
205 | org.gradle.wrapper.GradleWrapperMain \
206 | "$@"
207 |
208 | # Stop when "xargs" is not available.
209 | if ! command -v xargs >/dev/null 2>&1
210 | then
211 | die "xargs is not available"
212 | fi
213 |
214 | # Use "xargs" to parse quoted args.
215 | #
216 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
217 | #
218 | # In Bash we could simply go:
219 | #
220 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
221 | # set -- "${ARGS[@]}" "$@"
222 | #
223 | # but POSIX shell has neither arrays nor command substitution, so instead we
224 | # post-process each arg (as a line of input to sed) to backslash-escape any
225 | # character that might be a shell metacharacter, then use eval to reverse
226 | # that process (while maintaining the separation between arguments), and wrap
227 | # the whole thing up as a single "set" statement.
228 | #
229 | # This will of course break if any of these variables contains a newline or
230 | # an unmatched quote.
231 | #
232 |
233 | eval "set -- $(
234 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
235 | xargs -n1 |
236 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
237 | tr '\n' ' '
238 | )" '"$@"'
239 |
240 | exec "$JAVACMD" "$@"
241 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if %ERRORLEVEL% equ 0 goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if %ERRORLEVEL% equ 0 goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | set EXIT_CODE=%ERRORLEVEL%
84 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
85 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
86 | exit /b %EXIT_CODE%
87 |
88 | :mainEnd
89 | if "%OS%"=="Windows_NT" endlocal
90 |
91 | :omega
92 |
--------------------------------------------------------------------------------
/lombok.config:
--------------------------------------------------------------------------------
1 | lombok.anyConstructor.addConstructorProperties = true
2 | lombok.fieldDefaults.defaultPrivate = true
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'altium-migrator'
2 |
--------------------------------------------------------------------------------
/src/main/java/altium/migrator/AltiumMigratorApplication.java:
--------------------------------------------------------------------------------
1 | package altium.migrator;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class AltiumMigratorApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(AltiumMigratorApplication.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/altium/migrator/service/GitRepositoryService.java:
--------------------------------------------------------------------------------
1 | package altium.migrator.service;
2 |
3 | import lombok.SneakyThrows;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.apache.commons.io.FileUtils;
6 | import org.eclipse.jgit.api.Git;
7 | import org.springframework.beans.factory.annotation.Value;
8 | import org.springframework.stereotype.Service;
9 |
10 | import java.io.File;
11 |
12 | @Slf4j
13 | @Service
14 | public class GitRepositoryService {
15 |
16 | @Value("${git.repository.url}")
17 | private String gitRepositoryUrl;
18 |
19 | @Value("${git.repository.directory.name}")
20 | private String gitDirectoryName;
21 |
22 | @Value("${migration.root.folder}")
23 | private String destinationPath;
24 |
25 | @SneakyThrows
26 | public void cloneRepositoryWithChangelog() {
27 | File destinationDirectory = new File(destinationPath);
28 | if (!FileUtils.isEmptyDirectory(destinationDirectory)) {
29 | log.info("Destination directory {} not empty. Skipping repository clone", destinationPath);
30 | return;
31 | }
32 |
33 | log.info("Accessing git repository: {}", gitRepositoryUrl);
34 | Git.cloneRepository()
35 | .setURI(gitRepositoryUrl)
36 | .setDirectory(destinationDirectory)
37 | .setBranch("refs/heads/main")
38 | .setCloneAllBranches(false)
39 | .setCloneSubmodules(true)
40 | .setNoCheckout(true)
41 | .call()
42 | .checkout()
43 | .setStartPoint("origin/main")
44 | .addPath(gitDirectoryName)
45 | .call();
46 |
47 | log.info("Git repository successfully cloned to path: {}", destinationDirectory.getPath());
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/altium/migrator/service/LiquibaseMigrationService.java:
--------------------------------------------------------------------------------
1 | package altium.migrator.service;
2 |
3 | import liquibase.Contexts;
4 | import liquibase.Liquibase;
5 | import liquibase.database.core.PostgresDatabase;
6 | import liquibase.database.jvm.JdbcConnection;
7 | import liquibase.exception.LiquibaseException;
8 | import liquibase.resource.DirectoryResourceAccessor;
9 | import lombok.RequiredArgsConstructor;
10 | import lombok.SneakyThrows;
11 | import lombok.extern.slf4j.Slf4j;
12 | import org.springframework.beans.factory.annotation.Value;
13 | import org.springframework.stereotype.Service;
14 |
15 | import javax.sql.DataSource;
16 | import java.io.File;
17 | import java.sql.Connection;
18 | import java.sql.SQLException;
19 | import java.sql.Statement;
20 |
21 | @Slf4j
22 | @Service
23 | @RequiredArgsConstructor
24 | public class LiquibaseMigrationService {
25 |
26 | @Value("${db.changelog.file.name}")
27 | private String dbChangelogFileName;
28 |
29 | @Value("${migration.root.folder}/${git.repository.directory.name}")
30 | private String migrationRootFolder;
31 |
32 | @Value("${db.schema.name}")
33 | private String defaultSchemaName;
34 |
35 | private final DataSource dataSource;
36 |
37 | @SneakyThrows
38 | public void processDataMigration() {
39 | Liquibase liquibase = null;
40 | log.info("Started database migration");
41 | File changelogDirectory = new File(migrationRootFolder);
42 | try (Connection connection = this.dataSource.getConnection()) {
43 | DirectoryResourceAccessor resourceAccessor = new DirectoryResourceAccessor(changelogDirectory);
44 | PostgresDatabase postgresDatabase = new PostgresDatabase();
45 | postgresDatabase.setConnection(new JdbcConnection(connection));
46 | Statement statement = connection.createStatement();
47 | statement.execute("CREATE SCHEMA IF NOT EXISTS %1$s; SET SEARCH_PATH TO %1$s;".formatted(defaultSchemaName));
48 | postgresDatabase.setDefaultSchemaName(defaultSchemaName);
49 | liquibase = new Liquibase(dbChangelogFileName, resourceAccessor, postgresDatabase);
50 | Contexts contexts = new Contexts();
51 | liquibase.update(contexts);
52 | connection.commit();
53 |
54 | } catch (SQLException | LiquibaseException e) {
55 | log.error("Error during liquibase execution: [{}]", e.getMessage());
56 | if (liquibase != null) {
57 | try {
58 | liquibase.forceReleaseLocks();
59 | } catch (LiquibaseException ignore) {}
60 | }
61 | throw new RuntimeException(e);
62 | }
63 | log.info("Migration successfully finished");
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/altium/migrator/service/MigrationCommandRunner.java:
--------------------------------------------------------------------------------
1 | package altium.migrator.service;
2 |
3 | import lombok.RequiredArgsConstructor;
4 | import lombok.SneakyThrows;
5 | import lombok.extern.slf4j.Slf4j;
6 | import org.apache.commons.io.FileUtils;
7 | import org.springframework.beans.factory.annotation.Value;
8 | import org.springframework.boot.CommandLineRunner;
9 | import org.springframework.stereotype.Service;
10 |
11 | import java.io.File;
12 |
13 | @Slf4j
14 | @Service
15 | @RequiredArgsConstructor
16 | public class MigrationCommandRunner implements CommandLineRunner {
17 |
18 | private final GitRepositoryService gitRepositoryService;
19 | private final LiquibaseMigrationService migrationService;
20 |
21 | @Value("${migration.root.folder}")
22 | private String destinationPath;
23 |
24 | @Override
25 | public void run(String... args) {
26 | checkDestinationFolder();
27 | gitRepositoryService.cloneRepositoryWithChangelog();
28 | migrationService.processDataMigration();
29 | }
30 |
31 | @SneakyThrows
32 | private void checkDestinationFolder() {
33 | File destinationFolder = new File(destinationPath);
34 | if (!destinationFolder.exists()) {
35 | log.info("Database migration directory not found: {}. Creating new one.", destinationPath);
36 | FileUtils.forceMkdir(destinationFolder);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/resources/application-dev.yaml:
--------------------------------------------------------------------------------
1 | server:
2 | error:
3 | include-stacktrace: always
4 |
5 | spring:
6 | datasource:
7 | url: jdbc:postgresql://localhost:5432/altium-components
8 | username: postgres
9 | password: postgres
10 |
11 | logging:
12 | config: classpath:logging/log4j-dev.yaml
13 |
--------------------------------------------------------------------------------
/src/main/resources/application-docker-dev.yaml:
--------------------------------------------------------------------------------
1 | server:
2 | error:
3 | include-stacktrace: always
4 |
5 | spring:
6 | datasource:
7 | url: jdbc:postgresql://host.docker.internal:5432/altium-components
8 | username: postgres
9 | password: postgres
10 |
11 | logging:
12 | config: classpath:logging/log4j-dev.yaml
--------------------------------------------------------------------------------
/src/main/resources/application-prod.yaml:
--------------------------------------------------------------------------------
1 | spring:
2 | datasource:
3 | url: ${ALTIUM_DB_DATASOURCE}
4 | username: ${ALTIUM_DB_USERNAME}
5 | password: ${ALTIUM_DB_PASSWORD}
6 |
7 | logging:
8 | config: classpath:logging/log4j-prod.yaml
9 |
--------------------------------------------------------------------------------
/src/main/resources/application.yaml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8093
3 | error:
4 | whitelabel:
5 | enabled: false
6 |
7 | spring:
8 | liquibase:
9 | enabled: false # migration scripts has been stored in separate git repository
10 | profiles:
11 | active: ${PROFILE:dev}
12 | main:
13 | allow-bean-definition-overriding: false
14 |
15 | datasource:
16 | hikari:
17 | minimum-idle: 1
18 | idle-timeout: 10000
19 | maximumPoolSize: 2
20 |
21 | sql:
22 | init:
23 | platform: postgres
24 | continue-on-error: false
25 |
26 | git.repository.url: "https://github.com/ximtech/altium-library"
27 | git.repository.directory.name: "migrations"
28 |
29 | migration.root.folder: "/tmp/src/main/resources/db"
30 | db.changelog.file.name: "db.changelog-master.xml"
31 | db.schema.name: ${LIQUIBASE_SCHEMA_NAME:altium}
--------------------------------------------------------------------------------
/src/main/resources/logging/log4j-dev.yaml:
--------------------------------------------------------------------------------
1 | Configuration:
2 | Appenders:
3 | Console:
4 | name: Console
5 | target: SYSTEM_OUT
6 | PatternLayout:
7 | pattern: '%d{dd MMM yyyy HH:mm:ss,SSS} %highlight{%-5level}{STYLE=Logback} %clr{[%t]}{magenta} %clr{(%F:%L)}{cyan} - %m%n'
8 | disableAnsi: false
9 |
10 | Loggers:
11 | Root:
12 | level: INFO
13 | AppenderRef:
14 | - ref: Console
15 |
16 | Logger:
17 | - name: altium.migrator.debug
18 | level: DEBUG
19 | additivity: false
20 | AppenderRef:
21 | - ref: Console
--------------------------------------------------------------------------------
/src/main/resources/logging/log4j-prod.yaml:
--------------------------------------------------------------------------------
1 | Configuration:
2 | Appenders:
3 | Console:
4 | name: Console
5 | target: SYSTEM_OUT
6 | PatternLayout:
7 | pattern: '%d{dd MMM yyyy HH:mm:ss,SSS} %highlight{%-5level}{STYLE=Logback} %clr{[%t]}{magenta} %clr{(%F:%L)}{cyan} - %m%n'
8 | disableAnsi: false
9 |
10 | Loggers:
11 | Root:
12 | level: INFO
13 | AppenderRef:
14 | - ref: Console
15 |
16 | Logger:
17 | - name: altium.migrator.debug
18 | level: DEBUG
19 | additivity: false
20 | AppenderRef:
21 | - ref: Console
--------------------------------------------------------------------------------
/src/test/groovy/altium/migrator/DatabaseSpecTemplate.groovy:
--------------------------------------------------------------------------------
1 | package altium.migrator
2 |
3 | import groovy.util.logging.Slf4j
4 | import org.springframework.boot.test.context.SpringBootTest
5 | import org.springframework.context.ApplicationContextInitializer
6 | import org.springframework.context.ConfigurableApplicationContext
7 | import org.springframework.test.context.ActiveProfiles
8 | import org.springframework.test.context.ContextConfiguration
9 | import org.springframework.test.context.support.TestPropertySourceUtils
10 | import org.testcontainers.containers.PostgreSQLContainer
11 | import org.testcontainers.spock.Testcontainers
12 | import spock.lang.Shared
13 | import spock.lang.Specification
14 |
15 | @Slf4j
16 | @Testcontainers
17 | @SpringBootTest
18 | @ActiveProfiles(["it-test"])
19 | @ContextConfiguration(initializers = DataSourceInitializer)
20 | class DatabaseSpecTemplate extends Specification {
21 |
22 | static final String POSTGRES_TEST_IMAGE = "postgres:12.13-alpine"
23 | static final String POSTGRES_USERNAME = "postgres"
24 | static final String POSTGRES_PASSWORD = "postgres"
25 |
26 | @Shared
27 | static final PostgreSQLContainer> POSTGRE_SQL_CONTAINER = new PostgreSQLContainer<>(POSTGRES_TEST_IMAGE)
28 | .withUsername(POSTGRES_USERNAME)
29 | .withPassword(POSTGRES_PASSWORD)
30 |
31 | static class DataSourceInitializer implements ApplicationContextInitializer {
32 |
33 | @Override
34 | void initialize(ConfigurableApplicationContext applicationContext) {
35 | POSTGRE_SQL_CONTAINER.start()
36 | log.info("Database started with url: [{}]", POSTGRE_SQL_CONTAINER.getJdbcUrl())
37 | TestPropertySourceUtils.addInlinedPropertiesToEnvironment(
38 | applicationContext,
39 | "spring.test.database.replace=none",
40 | "spring.datasource.url=" + POSTGRE_SQL_CONTAINER.getJdbcUrl(),
41 | "spring.datasource.username=" + POSTGRE_SQL_CONTAINER.getUsername(),
42 | "spring.datasource.password=" + POSTGRE_SQL_CONTAINER.getPassword()
43 | )
44 |
45 |
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/groovy/altium/migrator/PostgresContainerITSpec.groovy:
--------------------------------------------------------------------------------
1 | package altium.migrator
2 |
3 | import altium.migrator.service.GitRepositoryService
4 | import org.spockframework.spring.SpringBean
5 | import org.springframework.beans.factory.annotation.Autowired
6 | import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
7 |
8 | class PostgresContainerITSpec extends DatabaseSpecTemplate {
9 |
10 | @Autowired
11 | NamedParameterJdbcTemplate jdbcTemplate
12 |
13 | @SpringBean
14 | GitRepositoryService gitRepositoryService = Mock()
15 |
16 | def 'check that database correctly has been filled with data and it accessible'() {
17 | expect:
18 | def valueMap = jdbcTemplate.queryForMap('SELECT * FROM "BatteryManagement"', [:])
19 | def changeLogMap = jdbcTemplate.queryForMap('SELECT * FROM databasechangelog', [:])
20 |
21 | valueMap.size() == 31
22 | changeLogMap.size() == 14
23 |
24 | valueMap == ['id' : 1,
25 | 'Battery Chemistry' : 'Lithium-Ion',
26 | 'Comment' : '=Part Number',
27 | 'ComponentLink1Description': 'Datasheet',
28 | 'ComponentLink1URL' : 'http://www.ti.com/general/docs/suppproductinfo.tsp?distId=10&gotoUrl=http%3A%2F%2Fwww.ti.com%2Flit%2Fgpn%2Fbq27542-g1',
29 | 'ComponentLink2Description': 'DigiKey Link',
30 | 'ComponentLink2URL' : 'http://digikey.com/product-detail/en/texas-instruments/BQ27542DRZR-G1/296-44346-1-ND/6110619',
31 | 'Description' : 'IC BATT FUEL GAUGE LI-ION 12SON',
32 | 'Device Package' : '12-VFDFN Exposed Pad',
33 | 'Footprint Path' : 'footprints/Leadless - SON/PCB - LEADLESS - SON - TI SON-12 DRZ.PCBLIB',
34 | 'Footprint Ref' : 'TI SON-12 DRZ',
35 | 'Function' : 'Battery Monitor',
36 | 'Interface' : 'HDQ, I²C',
37 | 'LastUpdated' : '2020-03-30T16:23:26.660',
38 | 'Lifecycle Status' : 'Active',
39 | 'Manufacturer' : 'Texas Instruments',
40 | 'Part Number' : 'BQ27542DRZR-G1',
41 | 'Minimum Order' : '1',
42 | 'Mounting Type' : 'Surface Mount',
43 | 'Number of Cells' : '1',
44 | 'Operating Temperature' : '-40°C ~ 85°C (TA)',
45 | 'Package / Case' : '12-VFDFN Exposed Pad',
46 | 'Packaging' : 'TapeAndReel',
47 | 'Part Status' : 'Active',
48 | 'Price' : '1.28',
49 | 'Series' : 'Impedance Track™',
50 | 'Supplier 1' : 'DigiKey',
51 | 'Supplier Part Number 1' : '296-44346-1-ND',
52 | 'Supplier Device Package' : '12-SON (2.5x4)',
53 | 'Library Path' : 'symbols/Battery Management/SCH - BATTERY MANAGEMENT - TI BQ27542DRZR-G1.SCHLIB',
54 | 'Library Ref' : 'TI BQ27542DRZR-G1'
55 | ]
56 |
57 | changeLogMap['id'] == '1'
58 | changeLogMap['author'] == 'Stanislav_Vodolagin'
59 | changeLogMap['filename'] == '25-12-2022/BatteryManagement.sql'
60 | changeLogMap['orderexecuted'] == 1
61 | changeLogMap['exectype'] == 'EXECUTED'
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/test/resources/application-it-test.yaml:
--------------------------------------------------------------------------------
1 | migration.root.folder: "src/test/resources/db"
--------------------------------------------------------------------------------
/src/test/resources/db/migrations/25-12-2022/BatteryManagement.sql:
--------------------------------------------------------------------------------
1 | --liquibase formatted sql
2 | --changeset Stanislav_Vodolagin:1
3 |
4 | CREATE TABLE IF NOT EXISTS "BatteryManagement" (
5 | "id" bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
6 | "Description" varchar(255) NULL,
7 | "Part Number" varchar(126) NULL,
8 | "ComponentLink2URL" varchar(255) NULL,
9 | "Device Package" varchar(126) NULL,
10 | "Supplier Device Package" varchar(126) NULL,
11 | "Function" varchar(126) NULL,
12 | "Package / Case" varchar(126) NULL,
13 | "Library Ref" varchar(126) NULL,
14 | "Supplier Part Number 1" varchar(126) NULL,
15 | "Lifecycle Status" varchar(126) NULL,
16 | "Battery Chemistry" varchar(126) NULL,
17 | "Manufacturer" varchar(126) NULL,
18 | "LastUpdated" varchar(255) NULL,
19 | "Minimum Order" varchar(16) NULL,
20 | "Comment" varchar(126) NULL,
21 | "Operating Temperature" varchar(126) NULL,
22 | "ComponentLink1URL" varchar(255) NULL,
23 | "Footprint Ref" varchar(126) NULL,
24 | "Number of Cells" varchar(16) NULL,
25 | "ComponentLink1Description" varchar(126) NULL,
26 | "Supplier 1" varchar(126) NULL,
27 | "Mounting Type" varchar(126) NULL,
28 | "Series" varchar(126) NULL,
29 | "Price" varchar(64) NULL,
30 | "Library Path" varchar(255) NULL,
31 | "Packaging" varchar(126) NULL,
32 | "Part Status" varchar(126) NULL,
33 | "ComponentLink2Description" varchar(126) NULL,
34 | "Footprint Path" varchar(255) NULL,
35 | "Interface" varchar(126) NULL,
36 | PRIMARY KEY ("id")
37 | );
38 |
39 | CREATE INDEX "54f9b250-0b35-4e6e-9be4-b6e795dbc842" ON "BatteryManagement"("Mounting Type");
40 |
41 | INSERT INTO "BatteryManagement" (
42 | "Battery Chemistry",
43 | "Comment",
44 | "ComponentLink1Description",
45 | "ComponentLink1URL",
46 | "ComponentLink2Description",
47 | "ComponentLink2URL",
48 | "Description",
49 | "Device Package",
50 | "Footprint Path",
51 | "Footprint Ref",
52 | "Function",
53 | "Interface",
54 | "LastUpdated",
55 | "Lifecycle Status",
56 | "Manufacturer",
57 | "Part Number",
58 | "Minimum Order",
59 | "Mounting Type",
60 | "Number of Cells",
61 | "Operating Temperature",
62 | "Package / Case",
63 | "Packaging",
64 | "Part Status",
65 | "Price",
66 | "Series",
67 | "Supplier 1",
68 | "Supplier Part Number 1",
69 | "Supplier Device Package",
70 | "Library Path",
71 | "Library Ref"
72 | )
73 | VALUES (
74 | 'Lithium-Ion',
75 | '=Part Number',
76 | 'Datasheet',
77 | 'http://www.ti.com/general/docs/suppproductinfo.tsp?distId=10&gotoUrl=http%3A%2F%2Fwww.ti.com%2Flit%2Fgpn%2Fbq27542-g1',
78 | 'DigiKey Link',
79 | 'http://digikey.com/product-detail/en/texas-instruments/BQ27542DRZR-G1/296-44346-1-ND/6110619',
80 | 'IC BATT FUEL GAUGE LI-ION 12SON',
81 | '12-VFDFN Exposed Pad',
82 | 'footprints/Leadless - SON/PCB - LEADLESS - SON - TI SON-12 DRZ.PCBLIB',
83 | 'TI SON-12 DRZ',
84 | 'Battery Monitor',
85 | 'HDQ, I²C',
86 | '2020-03-30T16:23:26.660',
87 | 'Active',
88 | 'Texas Instruments',
89 | 'BQ27542DRZR-G1',
90 | '1',
91 | 'Surface Mount',
92 | '1',
93 | '-40°C ~ 85°C (TA)',
94 | '12-VFDFN Exposed Pad',
95 | 'TapeAndReel',
96 | 'Active',
97 | '1.28',
98 | 'Impedance Track™',
99 | 'DigiKey',
100 | '296-44346-1-ND',
101 | '12-SON (2.5x4)',
102 | 'symbols/Battery Management/SCH - BATTERY MANAGEMENT - TI BQ27542DRZR-G1.SCHLIB',
103 | 'TI BQ27542DRZR-G1'
104 | );
105 |
106 |
--------------------------------------------------------------------------------
/src/test/resources/db/migrations/db.changelog-master.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------