eco-helpers 2.6.3 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +95 -0
- data/CHANGELOG.md +135 -2
- data/Rakefile +13 -7
- data/eco-helpers.gemspec +3 -3
- data/lib/eco/api/common/loaders/base.rb +2 -2
- data/lib/eco/api/common/loaders/case_base.rb +1 -1
- data/lib/eco/api/common/loaders/config/workflow/mailer.rb +5 -5
- data/lib/eco/api/common/loaders/error_handler.rb +8 -5
- data/lib/eco/api/common/loaders/parser.rb +44 -22
- data/lib/eco/api/common/loaders/policy.rb +6 -4
- data/lib/eco/api/common/loaders/use_case.rb +13 -7
- data/lib/eco/api/common/people/base_parser.rb +0 -2
- data/lib/eco/api/common/people/default_parsers/boolean_parser.rb +0 -1
- data/lib/eco/api/common/people/default_parsers/csv_parser.rb +1 -1
- data/lib/eco/api/common/people/default_parsers/date_parser.rb +64 -12
- data/lib/eco/api/common/people/default_parsers/freemium_parser.rb +0 -1
- data/lib/eco/api/common/people/default_parsers/login_providers_parser.rb +13 -5
- data/lib/eco/api/common/people/default_parsers/multi_parser.rb +0 -1
- data/lib/eco/api/common/people/default_parsers/numeric_parser.rb +18 -5
- data/lib/eco/api/common/people/default_parsers/policy_groups_parser.rb +8 -8
- data/lib/eco/api/common/people/default_parsers/select_parser.rb +50 -26
- data/lib/eco/api/common/people/default_parsers/send_invites_parser.rb +6 -6
- data/lib/eco/api/common/people/default_parsers/xls_parser.rb +9 -12
- data/lib/eco/api/common/people/default_parsers.rb +1 -12
- data/lib/eco/api/common/people/entries.rb +13 -13
- data/lib/eco/api/common/people/entry_factory.rb +76 -45
- data/lib/eco/api/common/people/person_attribute_parser.rb +8 -12
- data/lib/eco/api/common/people/person_entry.rb +86 -75
- data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +60 -44
- data/lib/eco/api/common/people/person_factory.rb +30 -22
- data/lib/eco/api/common/people/person_modifier.rb +11 -13
- data/lib/eco/api/common/people/person_parser.rb +101 -39
- data/lib/eco/api/common/people/supervisor_helpers.rb +25 -26
- data/lib/eco/api/common/session/base_session.rb +9 -9
- data/lib/eco/api/common/session/environment.rb +7 -5
- data/lib/eco/api/common/session/sftp.rb +59 -32
- data/lib/eco/api/common/version_patches/ecoportal_api/external_person.rb +10 -6
- data/lib/eco/api/common/version_patches/exception.rb +11 -13
- data/lib/eco/api/error.rb +32 -20
- data/lib/eco/api/microcases/set_supervisor.rb +0 -3
- data/lib/eco/api/organization/node_classifications.rb +82 -0
- data/lib/eco/api/organization/policy_groups.rb +4 -6
- data/lib/eco/api/organization/tag_tree.rb +169 -93
- data/lib/eco/api/organization.rb +1 -0
- data/lib/eco/api/session/batch/job.rb +1 -1
- data/lib/eco/api/session/config/tagtree.rb +41 -23
- data/lib/eco/api/session/config/workflow.rb +113 -88
- data/lib/eco/api/session/config.rb +6 -0
- data/lib/eco/api/session.rb +51 -29
- data/lib/eco/api/usecases/base_io.rb +28 -25
- data/lib/eco/api/usecases/default/locations/cli/tagtree_extract_cli.rb +7 -2
- data/lib/eco/api/usecases/default/locations/cli/tagtree_upload_cli.rb +21 -0
- data/lib/eco/api/usecases/default/locations/csv_to_tree_case.rb +3 -3
- data/lib/eco/api/usecases/default/locations/tagtree_extract_case.rb +54 -23
- data/lib/eco/api/usecases/default/locations/tagtree_upload_case.rb +87 -0
- data/lib/eco/api/usecases/default/locations.rb +1 -0
- data/lib/eco/api/usecases/default/people/analyse_people_case.rb +60 -56
- data/lib/eco/api/usecases/default/people/change_email_case.rb +8 -9
- data/lib/eco/api/usecases/default/people/clean_unknown_tags_case.rb +13 -11
- data/lib/eco/api/usecases/default/people/clear_abilities_case.rb +2 -2
- data/lib/eco/api/usecases/default/people/org_data_convert_case.rb +25 -27
- data/lib/eco/api/usecases/default/people/refresh_case.rb +2 -2
- data/lib/eco/api/usecases/default/people/reinvite_trans_case.rb +1 -1
- data/lib/eco/api/usecases/default/people/reinvite_trans_cli.rb +0 -1
- data/lib/eco/api/usecases/default/people/restore_db_case.rb +39 -34
- data/lib/eco/api/usecases/default/people/set_default_tag_case.rb +19 -15
- data/lib/eco/api/usecases/default/people/supers_cyclic_identify_case.rb +16 -12
- data/lib/eco/api/usecases/default_cases/hris_case.rb +17 -15
- data/lib/eco/api/usecases/default_cases/samples/sftp_case.rb +30 -16
- data/lib/eco/api/usecases/default_cases/to_csv_detailed_case.rb +0 -2
- data/lib/eco/api/usecases/graphql/base.rb +5 -3
- data/lib/eco/api/usecases/graphql/helpers/base/case_env.rb +4 -1
- data/lib/eco/api/usecases/graphql/helpers/base/graphql_env.rb +14 -0
- data/lib/eco/api/usecases/graphql/helpers/base.rb +5 -4
- data/lib/eco/api/usecases/graphql/helpers/location/base/classifications_parser.rb +60 -0
- data/lib/eco/api/usecases/graphql/helpers/location/base/tree_tracking.rb +72 -0
- data/lib/eco/api/usecases/graphql/helpers/location/base.rb +25 -59
- data/lib/eco/api/usecases/graphql/helpers/location/command/diff/as_update.rb +59 -0
- data/lib/eco/api/usecases/graphql/helpers/location/command/diff/compare.rb +49 -0
- data/lib/eco/api/usecases/graphql/helpers/location/command/diff.rb +11 -0
- data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/commandable.rb +46 -0
- data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/diff_sortable/for_archive.rb +23 -0
- data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/diff_sortable/for_unarchive.rb +65 -0
- data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/diff_sortable.rb +49 -0
- data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/sortable/relation_safe_sort.rb +119 -0
- data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/sortable.rb +59 -0
- data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages.rb +82 -0
- data/lib/eco/api/usecases/graphql/helpers/location/command/diffs.rb +20 -0
- data/lib/eco/api/usecases/graphql/helpers/location/command/optimizations.rb +84 -0
- data/lib/eco/api/usecases/graphql/helpers/location/command/result.rb +4 -4
- data/lib/eco/api/usecases/graphql/helpers/location/command/results.rb +24 -12
- data/lib/eco/api/usecases/graphql/helpers/location/command.rb +21 -24
- data/lib/eco/api/usecases/graphql/helpers/location/tags_remap/tags_map.rb +1 -1
- data/lib/eco/api/usecases/graphql/helpers/location/tags_remap/tags_set.rb +10 -11
- data/lib/eco/api/usecases/graphql/helpers/location/tags_remap.rb +8 -9
- data/lib/eco/api/usecases/graphql/samples/location/command/dsl.rb +41 -12
- data/lib/eco/api/usecases/graphql/samples/location/command/results.rb +11 -80
- data/lib/eco/api/usecases/graphql/samples/location/command/service/tree_update.rb +89 -0
- data/lib/eco/api/usecases/graphql/samples/location/command/service.rb +6 -0
- data/lib/eco/api/usecases/graphql/samples/location/command/track_changed_ids.rb +89 -0
- data/lib/eco/api/usecases/graphql/samples/location/command.rb +3 -0
- data/lib/eco/api/usecases/graphql/samples/location/service/base.rb +9 -0
- data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible/heading.rb +18 -0
- data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible/inputable.rb +53 -0
- data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible/parsing/classifications.rb +34 -0
- data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible/parsing/helpers.rb +28 -0
- data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible/parsing.rb +46 -0
- data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff/convertible.rb +38 -0
- data/lib/eco/api/usecases/graphql/samples/location/service/tree_diff.rb +105 -0
- data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter/discarded.rb +16 -0
- data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter/input.rb +15 -0
- data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter/node_attr_maps.rb +22 -0
- data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter/parser.rb +45 -0
- data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/converter.rb +36 -0
- data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list/output.rb +56 -0
- data/lib/eco/api/usecases/graphql/samples/location/service/tree_to_list.rb +41 -0
- data/lib/eco/api/usecases/graphql/samples/location/service.rb +8 -0
- data/lib/eco/api/usecases/graphql/samples/location.rb +1 -0
- data/lib/eco/api/usecases/graphql/utils/sftp.rb +96 -36
- data/lib/eco/api/usecases/ooze_cases/export_register_case.rb +8 -6
- data/lib/eco/api/usecases/ooze_samples/helpers/creatable.rb +4 -3
- data/lib/eco/api/usecases/ooze_samples/helpers/exportable_ooze.rb +39 -25
- data/lib/eco/api/usecases/ooze_samples/helpers/exportable_register.rb +13 -15
- data/lib/eco/api/usecases/ooze_samples/helpers/filters.rb +50 -21
- data/lib/eco/api/usecases/ooze_samples/helpers/ooze_handlers.rb +21 -11
- data/lib/eco/api/usecases/ooze_samples/helpers/rescuable.rb +2 -0
- data/lib/eco/api/usecases/ooze_samples/helpers/shortcuts.rb +49 -43
- data/lib/eco/api/usecases/ooze_samples/ooze_base_case.rb +17 -19
- data/lib/eco/api/usecases/ooze_samples/register_export_case.rb +48 -43
- data/lib/eco/api/usecases/ooze_samples/register_update_case.rb +34 -34
- data/lib/eco/api/usecases/ooze_samples/target_oozes_update_case.rb +8 -10
- data/lib/eco/api/usecases.rb +0 -1
- data/lib/eco/cli/config/use_cases.rb +31 -29
- data/lib/eco/cli_default/input_filters.rb +0 -5
- data/lib/eco/cli_default/people_filters.rb +4 -4
- data/lib/eco/cli_default/workflow.rb +13 -14
- data/lib/eco/csv/table.rb +34 -25
- data/lib/eco/data/hashes/array_diff.rb +24 -35
- data/lib/eco/data/hashes/diff_result/meta.rb +131 -0
- data/lib/eco/data/hashes/diff_result.rb +65 -57
- data/lib/eco/data/hashes/sanke_camel_indifferent_access.rb +278 -0
- data/lib/eco/data/hashes.rb +1 -1
- data/lib/eco/data/locations/convert.rb +1 -1
- data/lib/eco/data/locations/node_base/csv_convert.rb +19 -9
- data/lib/eco/data/locations/node_base/parsing.rb +4 -2
- data/lib/eco/data/locations/node_base/treeify.rb +149 -132
- data/lib/eco/data/locations/node_base.rb +15 -4
- data/lib/eco/data/locations/node_diff/accessors.rb +13 -5
- data/lib/eco/data/locations/node_diff/nodes_diff/clustered_treeify.rb +101 -0
- data/lib/eco/data/locations/node_diff/nodes_diff/diffs_tree.rb +99 -0
- data/lib/eco/data/locations/node_diff/{selectors.rb → nodes_diff/selectors.rb} +1 -1
- data/lib/eco/data/locations/node_diff/nodes_diff.rb +50 -35
- data/lib/eco/data/locations/node_diff.rb +45 -17
- data/lib/eco/data/locations/node_level/parsing.rb +15 -21
- data/lib/eco/data/locations/node_level.rb +66 -22
- data/lib/eco/data/locations/node_plain/parsing.rb +1 -1
- data/lib/eco/data/locations/node_plain.rb +60 -7
- data/lib/eco/data/strings/camel_case.rb +35 -0
- data/lib/eco/data/strings/snake_case.rb +18 -0
- data/lib/eco/data/strings.rb +8 -0
- data/lib/eco/data.rb +1 -0
- data/lib/eco/language/methods/call_detector.rb +11 -0
- data/lib/eco/language/methods/dsl_able.rb +7 -1
- data/lib/eco/language/methods.rb +2 -1
- data/lib/eco/language/models/collection.rb +23 -25
- data/lib/eco/language/models/parser_serializer.rb +24 -5
- data/lib/eco/version.rb +1 -1
- data/lib/eco-helpers.rb +0 -1
- metadata +54 -9
- data/lib/eco/data/hashes/diff_meta.rb +0 -52
@@ -8,17 +8,16 @@ module Eco
|
|
8
8
|
|
9
9
|
include Eco::Language::AuxiliarLogger
|
10
10
|
|
11
|
-
attr_reader :
|
12
|
-
attr_reader :
|
13
|
-
|
14
|
-
def initialize(
|
15
|
-
@logger
|
16
|
-
@
|
17
|
-
@
|
18
|
-
|
19
|
-
@
|
20
|
-
raise "Missing
|
21
|
-
raise "Missing source2" unless !!self.src_h2
|
11
|
+
attr_reader :source_1, :source_2
|
12
|
+
attr_reader :src_h_1, :src_h_2
|
13
|
+
|
14
|
+
def initialize(source_1, source_2, logger: nil)
|
15
|
+
@logger = logger if logger
|
16
|
+
@source_1 = source_1
|
17
|
+
@source_2 = source_2
|
18
|
+
|
19
|
+
raise "Missing source_1" unless (@src_h_1 = by_key(source_1))
|
20
|
+
raise "Missing source_2" unless (@src_h_2 = by_key(source_2))
|
22
21
|
end
|
23
22
|
|
24
23
|
# @note
|
@@ -26,35 +25,31 @@ module Eco
|
|
26
25
|
# - It also allows to know the original value
|
27
26
|
# @return [Hash] where `key` is the key of the record, and `value` a `DiffResult` object
|
28
27
|
def diffs
|
29
|
-
@diffs ||= source_results.select
|
30
|
-
res.diff?
|
31
|
-
end
|
28
|
+
@diffs ||= source_results.select(&:diff?)
|
32
29
|
end
|
33
30
|
|
34
31
|
# @return [Boolean] wheter or not there are differences.
|
35
32
|
def diffs?
|
36
|
-
|
33
|
+
diffs.any?
|
37
34
|
end
|
38
35
|
|
39
36
|
# All the items that contain the diff of a node.
|
40
37
|
# @return [Array<Eco::Data::Hash::DiffResult>]
|
41
38
|
def source_results
|
42
|
-
@source_results ||= paired_sources.each_with_object([]) do |(
|
43
|
-
res << diff_result_class.new(
|
39
|
+
@source_results ||= paired_sources.each_with_object([]) do |(src_1, src_2), res|
|
40
|
+
res << diff_result_class.new(src_1, src_2)
|
44
41
|
end
|
45
42
|
end
|
46
43
|
|
47
44
|
protected
|
48
45
|
|
49
|
-
# It pairs the hashes of `
|
46
|
+
# It pairs the hashes of `source_1` and `source_2`
|
50
47
|
# @note
|
51
48
|
# - It also ensures they are in their Hash form (with string keys)
|
52
49
|
# - This will merge entries of the same source that hold the same `key` attr value (latest wins)
|
53
50
|
def paired_sources
|
54
|
-
|
55
|
-
|
56
|
-
all_keys = keys1 | keys2
|
57
|
-
all_keys.map {|key| [src_h1[key], src_h2[key]]}
|
51
|
+
all_keys = src_h_1.keys | src_h_2.keys
|
52
|
+
all_keys.map {|key| [src_h_1[key], src_h_2[key]]}
|
58
53
|
end
|
59
54
|
|
60
55
|
# @return [String] the `key` attribute of `diff_result_class`
|
@@ -68,22 +63,14 @@ module Eco
|
|
68
63
|
diff_result_class.case_sensitive?
|
69
64
|
end
|
70
65
|
|
71
|
-
def compared_attrs
|
72
|
-
diff_result_class.compared_attrs.map(&:to_s)
|
73
|
-
end
|
74
|
-
|
75
66
|
private
|
76
67
|
|
77
68
|
def symbolize_keys(hash)
|
78
|
-
hash.
|
79
|
-
h[k.to_sym] = v
|
80
|
-
end
|
69
|
+
hash.transform_keys(&:to_sym)
|
81
70
|
end
|
82
71
|
|
83
72
|
def stringify_keys(hash)
|
84
|
-
hash.
|
85
|
-
h[k.to_s] = v
|
86
|
-
end
|
73
|
+
hash.transform_keys(&:to_s)
|
87
74
|
end
|
88
75
|
|
89
76
|
def by_key(content)
|
@@ -95,7 +82,9 @@ module Eco
|
|
95
82
|
def to_array_of_hashes(content)
|
96
83
|
case content
|
97
84
|
when Hash
|
98
|
-
|
85
|
+
log(:error) {
|
86
|
+
"(ArrayDiff) Input data as 'Hash' not supported. Expecting 'Enumerable' or 'String'"
|
87
|
+
}
|
99
88
|
exit(1)
|
100
89
|
when String
|
101
90
|
to_array_of_hashes(Eco::CSV.parse(content))
|
@@ -106,13 +95,13 @@ module Eco
|
|
106
95
|
Eco::CSV::Table.new(content).to_array_of_hashes
|
107
96
|
else
|
108
97
|
log(:error) {
|
109
|
-
"Input content 'Array' of '#{sample.class}' is not supported."
|
98
|
+
"(ArrayDiff) Input content 'Array' of '#{sample.class}' is not supported."
|
110
99
|
}
|
111
100
|
exit(1)
|
112
101
|
end
|
113
102
|
else
|
114
103
|
log(:error) {
|
115
|
-
"Could not obtain any data out content: '#{content.class}'"
|
104
|
+
"(ArrayDiff) Could not obtain any data out content: '#{content.class}'"
|
116
105
|
}
|
117
106
|
exit(1)
|
118
107
|
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
module Eco
|
2
|
+
module Data
|
3
|
+
module Hashes
|
4
|
+
class DiffResult
|
5
|
+
module Meta
|
6
|
+
class << self
|
7
|
+
def included(base)
|
8
|
+
super(base)
|
9
|
+
base.extend Eco::Language::Models::ClassHelpers
|
10
|
+
base.extend ClassMethods
|
11
|
+
base.inheritable_class_vars :key, :compared_attrs, :case_sensitive
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
# @param value [String, NilClass]
|
17
|
+
# @return [String] the attribute that is key of the node diff elements.
|
18
|
+
def key(value = nil)
|
19
|
+
return @key unless value
|
20
|
+
@key = value.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [Boolean] is there a `key` attribute defined?
|
24
|
+
def key?
|
25
|
+
!!@key
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param attrs [Array<Symbol>, Array<String>]
|
29
|
+
# @return [Array<String>] the comparable attributes
|
30
|
+
def compare(*attrs, when_present: false)
|
31
|
+
if when_present
|
32
|
+
compared_attrs_when_present.push(*attrs.map(&:to_s)).uniq!
|
33
|
+
compared_attrs_when_present
|
34
|
+
else
|
35
|
+
compared_attrs.push(*attrs.map(&:to_s)).uniq!
|
36
|
+
compared_attrs
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Whether or not the diff calc of a node should be done case sensitive or insensitive.
|
41
|
+
def case_sensitive(value = nil)
|
42
|
+
@case_sensitive = false unless instance_variable_defined?(:@case_sensitive)
|
43
|
+
return @case_sensitive unless value
|
44
|
+
@case_sensitive = !!value
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Boolean] are comparisons of values done case sensitive?
|
48
|
+
def case_sensitive?
|
49
|
+
!!@case_sensitive
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Array<String>] the comparable attributes
|
53
|
+
def compared_attrs
|
54
|
+
@compared_attrs ||= []
|
55
|
+
end
|
56
|
+
|
57
|
+
# Same as `compared_attrs` but they only get compared when present
|
58
|
+
# in both data sources
|
59
|
+
# @note if present in one source but not in another,
|
60
|
+
# that attribute will NOT generate a diff.
|
61
|
+
def compared_attrs_when_present
|
62
|
+
@compared_attrs_when_present ||= []
|
63
|
+
end
|
64
|
+
|
65
|
+
def all_compared_attrs
|
66
|
+
compared_attrs | compared_attrs_when_present
|
67
|
+
end
|
68
|
+
|
69
|
+
def compared_attr_when_present?(attr)
|
70
|
+
compared_attrs_when_present.include?(attr)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def key
|
75
|
+
self.class.key.dup
|
76
|
+
end
|
77
|
+
|
78
|
+
def case_sensitive?
|
79
|
+
self.class.case_sensitive?
|
80
|
+
end
|
81
|
+
|
82
|
+
def all_compared_attrs
|
83
|
+
self.class.all_compared_attrs.dup.compact.map(&:to_s)
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
# @return [Boolean] whether `val1` is equal to `val2`
|
89
|
+
def eq?(val_1, val_2)
|
90
|
+
return eq_ary?(val_1, val_2) if [val_1, val_2].any? {|v| v.is_a?(Array)}
|
91
|
+
return true if val_1 == val_2
|
92
|
+
return false if case_sensitive?
|
93
|
+
return false unless val_2 && val_1
|
94
|
+
val_1.upcase == val_2.upcase
|
95
|
+
end
|
96
|
+
|
97
|
+
# Compares two arrays
|
98
|
+
# @note
|
99
|
+
# 1. Order does NOT matter
|
100
|
+
# 2. Repeated elements are treated as one
|
101
|
+
def eq_ary?(val_1, val_2)
|
102
|
+
return false unless [val_1, val_2].all? {|v| v.is_a?(Array)}
|
103
|
+
return true if val_1 == val_2
|
104
|
+
v_1 = case_sensitive?? val_1 : val_1.map {|v| v&.upcase}
|
105
|
+
v_2 = case_sensitive?? val_2 : val_2.map {|v| v&.upcase}
|
106
|
+
joined = (v_1 | v_2)
|
107
|
+
(joined & v_1) == (joined & v_2)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Hash access
|
111
|
+
# @note DSL to be able to modify behaviour
|
112
|
+
# (i.e. indifferent access for camel and snake case keys)
|
113
|
+
def get_attr(src, key)
|
114
|
+
return nil unless src
|
115
|
+
src[key.to_s]
|
116
|
+
end
|
117
|
+
|
118
|
+
def slice_attrs(src, *keys)
|
119
|
+
return nil unless src
|
120
|
+
src.slice(*keys)
|
121
|
+
end
|
122
|
+
|
123
|
+
def key_present?(src, key)
|
124
|
+
return false unless src
|
125
|
+
src.key?(key)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -1,53 +1,68 @@
|
|
1
|
+
require_relative 'diff_result/meta'
|
2
|
+
|
1
3
|
module Eco
|
2
4
|
module Data
|
3
5
|
module Hashes
|
4
6
|
class DiffResult
|
5
|
-
|
6
|
-
include Eco::Data::Hashes::DiffMeta
|
7
|
-
|
8
|
-
inheritable_class_vars :key, :compared_attrs, :case_sensitive
|
7
|
+
include Eco::Data::Hashes::DiffResult::Meta
|
9
8
|
|
10
|
-
attr_reader :
|
9
|
+
attr_reader :src_1, :src_2
|
11
10
|
|
12
|
-
def initialize(
|
13
|
-
@
|
14
|
-
@
|
11
|
+
def initialize(src_1, src_2)
|
12
|
+
@src_1 = src_1
|
13
|
+
@src_2 = src_2
|
15
14
|
end
|
16
15
|
|
17
|
-
|
18
|
-
|
16
|
+
# @return [Value] the current value of `attr` (in `src_2`)
|
17
|
+
def attr(attr)
|
18
|
+
get_attr(src_2, attr)
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
# @return [Value] the previous value of `attr` (in `src_1`)
|
22
|
+
def attr_prev(attr)
|
23
|
+
get_attr(src_1, attr)
|
23
24
|
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
self.
|
26
|
+
# Deduplication to prevent mutability when manipulation is required.
|
27
|
+
def dup(src_1: nil, src_2: nil)
|
28
|
+
src_1 ||= self.src_1
|
29
|
+
src_2 ||= self.src_2
|
30
|
+
self.class.new(src_1.dup, src_2.dup)
|
29
31
|
end
|
30
32
|
|
31
33
|
def new?
|
32
|
-
|
34
|
+
src_2 && !src_1
|
33
35
|
end
|
34
36
|
|
35
37
|
def del?
|
36
|
-
|
38
|
+
src_1 && !src_2
|
37
39
|
end
|
38
40
|
|
39
41
|
def update?
|
40
42
|
!new? && !del? && diff?
|
41
43
|
end
|
42
44
|
|
45
|
+
# Uniq access point to identify attrs that have changed.
|
46
|
+
# @note when is `new?` or to be deleted (`del?`), there's nothing to compare.
|
47
|
+
# @return [Array<Symbol>] hash with the list of attrs that are different
|
48
|
+
# between `src_1` and `src_2`.
|
49
|
+
def diff_attrs
|
50
|
+
return (@diff_attrs = []) if new? || del?
|
51
|
+
@diff_attrs ||= all_compared_attrs.each_with_object([]) do |kattr, out|
|
52
|
+
next unless comparable_attr?(kattr)
|
53
|
+
out << kattr unless eq?(attr_prev(kattr), attr(kattr))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
43
57
|
# @note `diff_attrs` may not include the `key` attribute
|
44
58
|
# This is always included via `new?` (new key value) and `del?` (missing key value)
|
45
59
|
# @return [Boolean] was there any change?
|
46
60
|
def diff?
|
47
|
-
new? || del? ||
|
61
|
+
new? || del? || diff_attrs.any?
|
48
62
|
end
|
49
63
|
|
50
|
-
# Is the `key` attr value
|
64
|
+
# Is the `key` attr value updated?
|
65
|
+
# @note that `new?` and `del?` won't be considered as key's change
|
51
66
|
def key?
|
52
67
|
!(new? || del?) && diff_attr?(key)
|
53
68
|
end
|
@@ -59,54 +74,47 @@ module Eco
|
|
59
74
|
diff_attrs.include?(attr.to_s)
|
60
75
|
end
|
61
76
|
|
62
|
-
# @return [Value] the current value of `attr` (in `src2`)
|
63
|
-
def attr(attr)
|
64
|
-
return nil unless src2
|
65
|
-
src2[attr.to_s]
|
66
|
-
end
|
67
|
-
|
68
|
-
# @return [Value] the previous value of `attr` (in `src1`)
|
69
|
-
def attr_prev(attr)
|
70
|
-
return nil unless src1
|
71
|
-
src1[attr.to_s]
|
72
|
-
end
|
73
|
-
|
74
77
|
# @note the `key` attribute will always be added (even if there's no change)
|
75
|
-
# @return [Hash] hash with the differences as per `
|
78
|
+
# @return [Hash] hash with the differences as per `src_2`
|
76
79
|
def diff_hash
|
77
|
-
target_attrs = [key] |
|
78
|
-
return
|
79
|
-
return
|
80
|
-
|
80
|
+
target_attrs = [key] | all_compared_attrs
|
81
|
+
return slice_attrs(src_2, *target_attrs) if new?
|
82
|
+
return slice_attrs(src_1, key) if del?
|
83
|
+
slice_attrs(src_2, key, *diff_attrs)
|
81
84
|
end
|
82
85
|
|
83
|
-
#
|
84
|
-
|
85
|
-
|
86
|
-
|
86
|
+
# Uniq access point to scope if an `attr` is in the scope of the diff compare.
|
87
|
+
# Set of attributes that are general target to identify differences
|
88
|
+
# between both sources.
|
89
|
+
# @note When the class `all_compared_attrs` has not been deefined,
|
90
|
+
# it uses `all_source_keys`
|
91
|
+
# @return [Array<String>] the set of attributes that are comparable in this class.
|
92
|
+
def all_compared_attrs
|
93
|
+
super().map(&:to_s).uniq.tap do |attrs|
|
94
|
+
return all_source_keys unless attrs.any?
|
87
95
|
end
|
88
96
|
end
|
89
97
|
|
90
|
-
#
|
91
|
-
def
|
92
|
-
|
93
|
-
return false if case_sensitive?
|
94
|
-
return false if !val2 || !val1
|
95
|
-
val1.upcase == val2.upcase
|
98
|
+
# All the keys that the data comes with
|
99
|
+
def all_source_keys
|
100
|
+
(src_1&.keys || []) & (src_2&.keys || [])
|
96
101
|
end
|
97
102
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
+
private
|
104
|
+
|
105
|
+
# Refinement over `all_compared_attrs`, provided that those that must
|
106
|
+
# be comparable only **when present** in both, are filtered out when
|
107
|
+
# that is not the case.
|
108
|
+
def comparable_attr?(attr)
|
109
|
+
attr = attr.to_s
|
110
|
+
return false unless all_compared_attrs.include?(attr)
|
111
|
+
return true unless self.class.compared_attr_when_present?(attr)
|
112
|
+
key_present_in_both?(attr)
|
103
113
|
end
|
104
114
|
|
105
|
-
#
|
106
|
-
def
|
107
|
-
|
108
|
-
return comp_attrs unless comp_attrs.empty?
|
109
|
-
(src1&.keys || []) & (src2&.keys || [])
|
115
|
+
# Is the key `attr` present in both sources?
|
116
|
+
def key_present_in_both?(attr)
|
117
|
+
key_present?(src_1, attr) && key_present?(src_2, attr)
|
110
118
|
end
|
111
119
|
end
|
112
120
|
end
|