cure 0.1.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +13 -3
- data/.tool-versions +1 -0
- data/Dockerfile +1 -1
- data/Gemfile +1 -0
- data/Gemfile.lock +25 -6
- data/README.md +61 -93
- data/docs/README.md +33 -0
- data/docs/about.md +219 -0
- data/docs/builder/add.md +52 -0
- data/docs/builder/black_white_list.md +83 -0
- data/docs/builder/copy.md +48 -0
- data/docs/builder/explode.md +70 -0
- data/docs/builder/main.md +43 -0
- data/docs/builder/remove.md +46 -0
- data/docs/examples/examples.md +164 -0
- data/docs/export/main.md +37 -0
- data/docs/extract/main.md +89 -0
- data/docs/metadata/main.md +29 -0
- data/docs/query/main.md +45 -0
- data/docs/sources/main.md +36 -0
- data/docs/transform/main.md +53 -0
- data/docs/validate/main.md +42 -0
- data/exe/cure +12 -41
- data/exe/cure.old +59 -0
- data/lib/cure/builder/base_builder.rb +151 -0
- data/lib/cure/builder/candidate.rb +56 -0
- data/lib/cure/cli/command.rb +105 -0
- data/lib/cure/cli/generate_command.rb +54 -0
- data/lib/cure/cli/new_command.rb +52 -0
- data/lib/cure/cli/run_command.rb +19 -0
- data/lib/cure/cli/templates/README.md.erb +1 -0
- data/lib/cure/cli/templates/gemfile.erb +5 -0
- data/lib/cure/cli/templates/gitignore.erb +181 -0
- data/lib/cure/cli/templates/new_template.rb.erb +31 -0
- data/lib/cure/cli/templates/tool-versions.erb +1 -0
- data/lib/cure/config.rb +142 -18
- data/lib/cure/coordinator.rb +61 -25
- data/lib/cure/database.rb +191 -0
- data/lib/cure/dsl/builder.rb +26 -0
- data/lib/cure/dsl/exporters.rb +45 -0
- data/lib/cure/dsl/extraction.rb +60 -0
- data/lib/cure/dsl/metadata.rb +33 -0
- data/lib/cure/dsl/queries.rb +36 -0
- data/lib/cure/dsl/source_files.rb +36 -0
- data/lib/cure/dsl/template.rb +131 -0
- data/lib/cure/dsl/transformations.rb +95 -0
- data/lib/cure/dsl/validator.rb +22 -0
- data/lib/cure/export/base_processor.rb +194 -0
- data/lib/cure/export/manager.rb +24 -0
- data/lib/cure/extract/base_processor.rb +47 -0
- data/lib/cure/extract/csv_lookup.rb +14 -3
- data/lib/cure/extract/extractor.rb +41 -84
- data/lib/cure/extract/filter.rb +118 -0
- data/lib/cure/extract/named_range.rb +94 -0
- data/lib/cure/extract/named_range_processor.rb +128 -0
- data/lib/cure/extract/variable.rb +25 -0
- data/lib/cure/extract/variable_processor.rb +57 -0
- data/lib/cure/generator/base_generator.rb +14 -4
- data/lib/cure/generator/case_generator.rb +10 -3
- data/lib/cure/generator/character_generator.rb +9 -3
- data/lib/cure/generator/erb_generator.rb +21 -0
- data/lib/cure/generator/eval_generator.rb +34 -0
- data/lib/cure/generator/faker_generator.rb +7 -1
- data/lib/cure/generator/guid_generator.rb +7 -2
- data/lib/cure/generator/hex_generator.rb +6 -1
- data/lib/cure/generator/imports.rb +4 -0
- data/lib/cure/generator/number_generator.rb +6 -1
- data/lib/cure/generator/placeholder_generator.rb +7 -1
- data/lib/cure/generator/proc_generator.rb +21 -0
- data/lib/cure/generator/redact_generator.rb +9 -3
- data/lib/cure/generator/static_generator.rb +21 -0
- data/lib/cure/generator/variable_generator.rb +11 -5
- data/lib/cure/helpers/file_helpers.rb +12 -2
- data/lib/cure/helpers/object_helpers.rb +5 -17
- data/lib/cure/helpers/perf_helpers.rb +30 -0
- data/lib/cure/helpers/string.rb +54 -0
- data/lib/cure/launcher.rb +125 -0
- data/lib/cure/log.rb +7 -0
- data/lib/cure/planner.rb +136 -0
- data/lib/cure/strategy/append_strategy.rb +4 -0
- data/lib/cure/strategy/base_strategy.rb +19 -44
- data/lib/cure/strategy/contain_strategy.rb +51 -0
- data/lib/cure/strategy/end_with_strategy.rb +7 -1
- data/lib/cure/strategy/full_strategy.rb +4 -0
- data/lib/cure/strategy/history/history_cache.rb +82 -0
- data/lib/cure/strategy/imports.rb +2 -0
- data/lib/cure/strategy/match_strategy.rb +7 -2
- data/lib/cure/strategy/prepend_strategy.rb +28 -0
- data/lib/cure/strategy/regex_strategy.rb +7 -1
- data/lib/cure/strategy/split_strategy.rb +8 -3
- data/lib/cure/strategy/start_with_strategy.rb +7 -1
- data/lib/cure/transformation/candidate.rb +32 -35
- data/lib/cure/transformation/transform.rb +22 -56
- data/lib/cure/validator/base_rule.rb +78 -0
- data/lib/cure/validator/candidate.rb +54 -0
- data/lib/cure/validator/manager.rb +21 -0
- data/lib/cure/validators.rb +3 -3
- data/lib/cure/version.rb +1 -1
- data/lib/cure.rb +19 -11
- data/templates/dsl_example.rb +48 -0
- data/templates/empty_template.rb +31 -0
- metadata +132 -21
- data/lib/cure/export/exporter.rb +0 -74
- data/lib/cure/extract/builder.rb +0 -27
- data/lib/cure/main.rb +0 -72
- data/lib/cure/template/dispatch.rb +0 -30
- data/lib/cure/template/extraction.rb +0 -38
- data/lib/cure/template/template.rb +0 -28
- data/lib/cure/template/transformations.rb +0 -26
- data/templates/aws_cur_template.json +0 -145
- data/templates/example_template.json +0 -54
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cure/log"
|
4
|
+
require "cure/config"
|
5
|
+
require "cure/extract/csv_lookup"
|
6
|
+
require "cure/extract/base_processor"
|
7
|
+
|
8
|
+
require "csv"
|
9
|
+
|
10
|
+
module Cure
|
11
|
+
module Extract
|
12
|
+
class NamedRangeProcessor < BaseProcessor
|
13
|
+
|
14
|
+
# @return [Array<Extraction::NamedRange>] named_ranges
|
15
|
+
attr_reader :candidate_nrs
|
16
|
+
|
17
|
+
def initialize(database_service, candidate_nrs)
|
18
|
+
@candidate_nrs = candidate_nrs
|
19
|
+
@cache = init_cache
|
20
|
+
|
21
|
+
@tables_created = []
|
22
|
+
super database_service
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param [Integer] row_idx
|
26
|
+
# @param [Array] csv_row
|
27
|
+
def process_row(row_idx, csv_row) # rubocop:disable all
|
28
|
+
# Return if row is not in any named range
|
29
|
+
return unless row_bounds.cover?(row_idx)
|
30
|
+
|
31
|
+
# Iterate over the NR's, if its inside those bounds, add it
|
32
|
+
@candidate_nrs.each do |nr|
|
33
|
+
next unless nr.row_in_bounds?(row_idx)
|
34
|
+
|
35
|
+
if nr.filter.row_handler.has_content?
|
36
|
+
unless nr.filter.row_handler.including_proc[:where].call(csv_row)
|
37
|
+
nr.row_count += 1
|
38
|
+
next
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Row is inbounds - we need to do two things, filter the content, create the table, insert the row
|
43
|
+
if nr.header_in_bounds?(nr.active_row_count(row_idx))
|
44
|
+
column_headers = csv_row[nr.section[0]..nr.section[1]]
|
45
|
+
|
46
|
+
if nr.filter.col_handler.has_content?
|
47
|
+
nr.filter.col_handler.set_col_positions(column_headers)
|
48
|
+
column_headers = nr.filter.col_handler.translate_headers(column_headers)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Create table, flush cache
|
52
|
+
create_table(nr.name, column_headers)
|
53
|
+
@tables_created << nr.name
|
54
|
+
|
55
|
+
@cache[nr.name].each do |row|
|
56
|
+
insert_record(
|
57
|
+
nr.name,
|
58
|
+
nr.filter.col_handler.filter_row(row)
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
@cache[nr.name] = [] # Evict cache
|
63
|
+
|
64
|
+
next
|
65
|
+
end
|
66
|
+
|
67
|
+
next unless nr.content_in_bounds?(row_idx)
|
68
|
+
|
69
|
+
# 0. Remove unnecessary columns
|
70
|
+
|
71
|
+
|
72
|
+
# 2. If cache is over n records and if the table exists,
|
73
|
+
# add it to the database.
|
74
|
+
|
75
|
+
filtered_row = nr.filter.col_handler.filter_row(
|
76
|
+
csv_row[nr.section[0]..nr.section[1]]
|
77
|
+
)
|
78
|
+
|
79
|
+
if @tables_created.include?(nr.name)
|
80
|
+
@cache[nr.name] << filtered_row.unshift(row_idx)
|
81
|
+
|
82
|
+
if @cache[nr.name].size >= 10
|
83
|
+
insert_cache(nr.name)
|
84
|
+
next
|
85
|
+
end
|
86
|
+
else
|
87
|
+
# If the table doesnt exist, cache it for now.
|
88
|
+
@cache[nr.name] << filtered_row.unshift(row_idx)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def after_process
|
94
|
+
@cache.each do |named_range, cache|
|
95
|
+
insert_cache(named_range) if cache.size.positive?
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# @return [Range]
|
100
|
+
# This covers the max size of all named ranges
|
101
|
+
def row_bounds
|
102
|
+
@row_bounds ||= calculate_row_bounds
|
103
|
+
end
|
104
|
+
|
105
|
+
# @return [Range]
|
106
|
+
def calculate_row_bounds
|
107
|
+
positions = @candidate_nrs.map(&:row_bounds).flatten.sort
|
108
|
+
(positions.first..positions.last)
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def init_cache
|
114
|
+
cache = {}
|
115
|
+
@candidate_nrs.each do |nr|
|
116
|
+
cache[nr.name] = []
|
117
|
+
end
|
118
|
+
|
119
|
+
cache
|
120
|
+
end
|
121
|
+
|
122
|
+
def insert_cache(named_range)
|
123
|
+
insert_batched_rows(named_range, @cache[named_range])
|
124
|
+
@cache[named_range] = []
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cure
|
4
|
+
module Extract
|
5
|
+
class Variable
|
6
|
+
attr_reader :name, :location, :ref_name
|
7
|
+
|
8
|
+
def initialize(name, location, ref_name: "_default")
|
9
|
+
@name = name
|
10
|
+
@location = [Extract::CsvLookup.position_for_letter(location),
|
11
|
+
Extract::CsvLookup.position_for_digit(location)]
|
12
|
+
@ref_name = ref_name
|
13
|
+
end
|
14
|
+
|
15
|
+
def row_in_bounds?(row_idx)
|
16
|
+
row_bounds_range.cover?(row_idx)
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [Range]
|
20
|
+
def row_bounds_range
|
21
|
+
@row_bounds_range ||= (@location&.last..@location&.last)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cure/log"
|
4
|
+
require "cure/config"
|
5
|
+
require "cure/extract/base_processor"
|
6
|
+
|
7
|
+
require "csv"
|
8
|
+
|
9
|
+
module Cure
|
10
|
+
module Extract
|
11
|
+
class VariableProcessor < BaseProcessor
|
12
|
+
|
13
|
+
# @return [Array<Extraction::Variable>] variables
|
14
|
+
attr_reader :candidate_variables
|
15
|
+
|
16
|
+
def initialize(database_service, candidate_variables)
|
17
|
+
super(database_service)
|
18
|
+
|
19
|
+
@candidate_variables = candidate_variables
|
20
|
+
@candidate_count = candidate_variables.length
|
21
|
+
@processed = 0
|
22
|
+
|
23
|
+
init_db
|
24
|
+
end
|
25
|
+
|
26
|
+
# @param [Integer] row_idx
|
27
|
+
# @param [Array] csv_row
|
28
|
+
def process_row(row_idx, csv_row)
|
29
|
+
# Return if row is not in any variable OR if all candidates are processed.
|
30
|
+
|
31
|
+
return if @candidate_count == @processed
|
32
|
+
return unless candidate_rows.include?(row_idx)
|
33
|
+
|
34
|
+
# Iterate over the NR's, if its inside those bounds, add it
|
35
|
+
@candidate_variables.each do |cv|
|
36
|
+
next unless cv.row_in_bounds?(row_idx)
|
37
|
+
|
38
|
+
insert_record(:variables, [nil, cv.name, csv_row[cv.location.first]])
|
39
|
+
@processed += 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [Array]
|
44
|
+
def candidate_rows
|
45
|
+
@candidate_rows ||= @candidate_variables.map { |v| v.location.last }
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def init_db
|
51
|
+
return if @database_service.table_exist?(:variables)
|
52
|
+
|
53
|
+
create_table(:variables, %w[name value])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -11,19 +11,29 @@ module Cure
|
|
11
11
|
end
|
12
12
|
|
13
13
|
# @param [Object/Nil] source_value
|
14
|
+
# @param [RowCtx/Nil] row_ctx
|
14
15
|
# @return [String]
|
15
|
-
def generate(source_value
|
16
|
-
translated = _generate(source_value)
|
16
|
+
def generate(source_value, row_ctx)
|
17
|
+
translated = _generate(source_value, row_ctx)
|
17
18
|
translated = "#{prefix}#{translated}" if prefix
|
18
19
|
translated = "#{translated}#{suffix}" if suffix
|
19
20
|
translated
|
20
21
|
end
|
21
22
|
|
23
|
+
def describe
|
24
|
+
_describe
|
25
|
+
end
|
26
|
+
|
22
27
|
private
|
23
28
|
|
29
|
+
# @param [RowCtx] _row_ctx
|
24
30
|
# @param [Object/Nil] _source_value
|
25
31
|
# @return [String]
|
26
|
-
def _generate(_source_value)
|
32
|
+
def _generate(_source_value, _row_ctx)
|
33
|
+
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
|
34
|
+
end
|
35
|
+
|
36
|
+
def _describe
|
27
37
|
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
|
28
38
|
end
|
29
39
|
|
@@ -44,7 +54,7 @@ module Cure
|
|
44
54
|
end
|
45
55
|
|
46
56
|
def extract_property(property, default_val)
|
47
|
-
@options.fetch(property, default_val)
|
57
|
+
@options.fetch(property.to_sym, @options.fetch(property, default_val))
|
48
58
|
end
|
49
59
|
end
|
50
60
|
end
|
@@ -8,18 +8,25 @@ module Cure
|
|
8
8
|
private
|
9
9
|
|
10
10
|
# @param [Object] source_value
|
11
|
-
|
12
|
-
|
11
|
+
# @param [RowCtx] _row_ctx
|
12
|
+
def _generate(source_value, _row_ctx)
|
13
|
+
result = case_options.fetch(:switch)
|
14
|
+
.find { |opts| opts[:case] == source_value }
|
15
|
+
&.fetch(:return_value, nil)
|
13
16
|
|
14
17
|
return result if result
|
15
18
|
|
16
|
-
case_options.fetch(
|
19
|
+
case_options.fetch(:else, {}).fetch(:return_value, nil)
|
17
20
|
end
|
18
21
|
|
19
22
|
# @return [Hash]
|
20
23
|
def case_options
|
21
24
|
@case_options ||= extract_property("statement", nil)
|
22
25
|
end
|
26
|
+
|
27
|
+
def _describe
|
28
|
+
"Will match source value against a value included in #{case_options}"
|
29
|
+
end
|
23
30
|
end
|
24
31
|
end
|
25
32
|
end
|
@@ -13,15 +13,16 @@ module Cure
|
|
13
13
|
private
|
14
14
|
|
15
15
|
# @param [Object] source_value
|
16
|
-
|
16
|
+
# @param [RowCtx] _row_ctx
|
17
|
+
def _generate(source_value, _row_ctx)
|
17
18
|
arr = build_options.map(&:to_a).flatten
|
18
19
|
(0...length(source_value&.length || 5)).map { arr[rand(arr.length)] }.join
|
19
20
|
end
|
20
21
|
|
21
22
|
def build_options
|
22
|
-
return [("a".."z"), ("A".."Z"), (0..9)] unless @options.key?(
|
23
|
+
return [("a".."z"), ("A".."Z"), (0..9)] unless @options.key?(:types)
|
23
24
|
|
24
|
-
type_array = @options[
|
25
|
+
type_array = @options[:types]
|
25
26
|
|
26
27
|
arr = []
|
27
28
|
arr << ("a".."z") if type_array.include? "lowercase"
|
@@ -30,6 +31,11 @@ module Cure
|
|
30
31
|
arr << ("!".."+") if type_array.include? "symbol"
|
31
32
|
arr
|
32
33
|
end
|
34
|
+
|
35
|
+
def _describe
|
36
|
+
"Will create a random list of #{@options[:types]} " \
|
37
|
+
"with as many characters as the source string."
|
38
|
+
end
|
33
39
|
end
|
34
40
|
end
|
35
41
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cure/generator/base_generator"
|
4
|
+
require "erb"
|
5
|
+
|
6
|
+
module Cure
|
7
|
+
module Generator
|
8
|
+
class ErbGenerator < BaseGenerator
|
9
|
+
private
|
10
|
+
|
11
|
+
# @param [Cure::Transformation::RowCtx] _source_value
|
12
|
+
# @param [RowCtx] row_ctx
|
13
|
+
def _generate(_source_value, row_ctx)
|
14
|
+
template = @options.fetch(:template, nil)
|
15
|
+
ERB.new(template).result_with_hash(row_ctx.row)
|
16
|
+
end
|
17
|
+
|
18
|
+
def _describe; end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cure/generator/base_generator"
|
4
|
+
|
5
|
+
module Cure
|
6
|
+
module Generator
|
7
|
+
class EvalGenerator < BaseGenerator
|
8
|
+
private
|
9
|
+
|
10
|
+
# @param [Object] _source_value
|
11
|
+
# @param [Transformation::RowCtx] _row_ctx
|
12
|
+
# This will be changed with expression evaluator
|
13
|
+
def _generate(_source_value, _row_ctx)
|
14
|
+
eval_str = extract_property("eval", nil)
|
15
|
+
result = nil
|
16
|
+
with_safe do
|
17
|
+
result = eval(eval_str) # rubocop:disable Security/Eval
|
18
|
+
end
|
19
|
+
|
20
|
+
result
|
21
|
+
rescue StandardError => e
|
22
|
+
raise "Cannot eval statement #{extract_property("eval", nil)} [#{e.message}]"
|
23
|
+
end
|
24
|
+
|
25
|
+
def with_safe(&_block)
|
26
|
+
$SAFE = 1
|
27
|
+
yield
|
28
|
+
$SAFE = 0
|
29
|
+
end
|
30
|
+
|
31
|
+
def _describe; end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -9,7 +9,8 @@ module Cure
|
|
9
9
|
private
|
10
10
|
|
11
11
|
# @param [Object] _source_value
|
12
|
-
|
12
|
+
# @param [RowCtx] _row_ctx
|
13
|
+
def _generate(_source_value, _row_ctx)
|
13
14
|
mod_code = extract_property("module", nil)
|
14
15
|
mod = Faker.const_get(mod_code)
|
15
16
|
|
@@ -20,6 +21,11 @@ module Cure
|
|
20
21
|
|
21
22
|
mod.send(meth_code)
|
22
23
|
end
|
24
|
+
|
25
|
+
def _describe
|
26
|
+
"Will create a Faker value from [#{extract_property("module", nil)}::" \
|
27
|
+
"#{extract_property("method", nil)}]"
|
28
|
+
end
|
23
29
|
end
|
24
30
|
end
|
25
31
|
end
|
@@ -8,8 +8,13 @@ module Cure
|
|
8
8
|
private
|
9
9
|
|
10
10
|
# @param [Object] _source_value
|
11
|
-
|
12
|
-
|
11
|
+
# @param [RowCtx] _row_ctx
|
12
|
+
def _generate(_source_value, _row_ctx)
|
13
|
+
SecureRandom.uuid.to_s.slice(0, @options.fetch(:length, 36))
|
14
|
+
end
|
15
|
+
|
16
|
+
def _describe
|
17
|
+
"Will create a random GUID."
|
13
18
|
end
|
14
19
|
end
|
15
20
|
end
|
@@ -8,9 +8,14 @@ module Cure
|
|
8
8
|
private
|
9
9
|
|
10
10
|
# @param [Object] _source_value
|
11
|
-
|
11
|
+
# @param [RowCtx] _row_ctx
|
12
|
+
def _generate(_source_value, _row_ctx)
|
12
13
|
1.upto(length(rand(0..9))).map { rand(0..15).to_s(16) }.join("")
|
13
14
|
end
|
15
|
+
|
16
|
+
def _describe
|
17
|
+
"Will create a random list of hex values matching the length of the source string."
|
18
|
+
end
|
14
19
|
end
|
15
20
|
end
|
16
21
|
end
|
@@ -10,3 +10,7 @@ require "cure/generator/number_generator"
|
|
10
10
|
require "cure/generator/placeholder_generator"
|
11
11
|
require "cure/generator/redact_generator"
|
12
12
|
require "cure/generator/variable_generator"
|
13
|
+
require "cure/generator/eval_generator"
|
14
|
+
require "cure/generator/erb_generator"
|
15
|
+
require "cure/generator/proc_generator"
|
16
|
+
require "cure/generator/static_generator"
|
@@ -8,9 +8,14 @@ module Cure
|
|
8
8
|
private
|
9
9
|
|
10
10
|
# @param [Object] _source_value
|
11
|
-
|
11
|
+
# @param [RowCtx] _row_ctx
|
12
|
+
def _generate(_source_value, _row_ctx)
|
12
13
|
1.upto(length(rand(0..9))).map { rand(1..9) }.join("").to_i
|
13
14
|
end
|
15
|
+
|
16
|
+
def _describe
|
17
|
+
"Will create a random list of numbers matching the length of the source string."
|
18
|
+
end
|
14
19
|
end
|
15
20
|
end
|
16
21
|
end
|
@@ -11,10 +11,16 @@ module Cure
|
|
11
11
|
private
|
12
12
|
|
13
13
|
# @param [Object] _source_value
|
14
|
-
|
14
|
+
# @param [RowCtx] _row_ctx
|
15
|
+
def _generate(_source_value, _row_ctx)
|
15
16
|
value = config.placeholders[property_name]
|
16
17
|
value || raise("Missing placeholder value. Available candidates: [#{config.placeholders.keys.join(", ")}]")
|
17
18
|
end
|
19
|
+
|
20
|
+
def _describe
|
21
|
+
"Will look up placeholders using '#{property_name}'. " \
|
22
|
+
"[Set as '#{config.placeholders[property_name]}']"
|
23
|
+
end
|
18
24
|
end
|
19
25
|
end
|
20
26
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cure/generator/base_generator"
|
4
|
+
require "erb"
|
5
|
+
|
6
|
+
module Cure
|
7
|
+
module Generator
|
8
|
+
class ProcGenerator < BaseGenerator
|
9
|
+
private
|
10
|
+
|
11
|
+
# @param [Cure::Transformation::RowCtx] source_value
|
12
|
+
# @param [RowCtx] row_ctx
|
13
|
+
def _generate(source_value, row_ctx)
|
14
|
+
proc = @options.fetch(:execute, nil)
|
15
|
+
proc.call(source_value, row_ctx)
|
16
|
+
end
|
17
|
+
|
18
|
+
def _describe; end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -7,10 +7,16 @@ module Cure
|
|
7
7
|
class RedactGenerator < BaseGenerator
|
8
8
|
private
|
9
9
|
|
10
|
-
# @param [
|
11
|
-
|
12
|
-
|
10
|
+
# @param [object] source_value
|
11
|
+
# @param [RowCtx] _row_ctx
|
12
|
+
def _generate(source_value, _row_ctx)
|
13
|
+
1.upto(length(source_value&.length || 5)).map { @options.fetch(:character, "x") }.join("")
|
13
14
|
end
|
15
|
+
|
16
|
+
def _describe
|
17
|
+
"Will replace the length of the source string with X."
|
18
|
+
end
|
19
|
+
|
14
20
|
end
|
15
21
|
end
|
16
22
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cure/generator/base_generator"
|
4
|
+
|
5
|
+
module Cure
|
6
|
+
module Generator
|
7
|
+
class StaticGenerator < BaseGenerator
|
8
|
+
private
|
9
|
+
|
10
|
+
# @param [Object] _source_value
|
11
|
+
# @param [RowCtx] _row_ctx
|
12
|
+
def _generate(_source_value, _row_ctx)
|
13
|
+
@options.fetch(:value, nil)
|
14
|
+
end
|
15
|
+
|
16
|
+
def _describe
|
17
|
+
"Will return the defined value [#{@options.fetch(:value, nil)}]"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -2,18 +2,24 @@
|
|
2
2
|
|
3
3
|
require "cure/generator/base_generator"
|
4
4
|
require "cure/config"
|
5
|
+
require "cure/database"
|
5
6
|
|
6
7
|
module Cure
|
7
8
|
module Generator
|
8
9
|
class VariableGenerator < BaseGenerator
|
9
|
-
include
|
10
|
+
include Database
|
10
11
|
|
11
12
|
private
|
12
13
|
|
13
|
-
# @param [
|
14
|
-
|
15
|
-
|
16
|
-
value
|
14
|
+
# @param [object] _source_value
|
15
|
+
# @param [RowCtx] _row_ctx
|
16
|
+
def _generate(_source_value, _row_ctx)
|
17
|
+
value = database_service.find_variable(property_name)
|
18
|
+
value || raise("Missing placeholder value [#{property_name}]. Please check you are defining it correctly.")
|
19
|
+
end
|
20
|
+
|
21
|
+
def _describe
|
22
|
+
"Will look up the variables defined using '#{property_name}'."
|
17
23
|
end
|
18
24
|
end
|
19
25
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "fileutils"
|
4
|
+
require "pathname"
|
4
5
|
|
5
6
|
module Cure
|
6
7
|
module Helpers
|
@@ -21,13 +22,22 @@ module Cure
|
|
21
22
|
end
|
22
23
|
|
23
24
|
def read_file(file_location)
|
24
|
-
result = file_location.start_with?("/") ? file_location :
|
25
|
+
result = file_location.start_with?("/") ? file_location : Pathname.new(file_location)
|
26
|
+
# result = file_location.start_with?("/") ? file_location : File.join(File.dirname(__FILE__), file_location)
|
25
27
|
|
26
|
-
raise "No file found at [#{file_location}]" unless File.exist? result
|
28
|
+
raise "No file found at [#{file_location}]" unless File.exist? result.to_s
|
27
29
|
|
28
30
|
File.read(result)
|
29
31
|
end
|
30
32
|
|
33
|
+
def open_file(file_location)
|
34
|
+
result = file_location.start_with?("/") ? file_location : Pathname.new(file_location)
|
35
|
+
|
36
|
+
raise "No file found at [#{file_location}]" unless File.exist? result.to_s
|
37
|
+
|
38
|
+
File.open(result)
|
39
|
+
end
|
40
|
+
|
31
41
|
def with_temp_dir(temp_dir, &_block)
|
32
42
|
return unless block_given?
|
33
43
|
|
@@ -6,23 +6,11 @@ require "json"
|
|
6
6
|
module Cure
|
7
7
|
module Helpers
|
8
8
|
module ObjectHelpers
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def from_json(json)
|
18
|
-
return from_hash(json) if json.is_a?(Hash) # Just a guard in case serialisation is done
|
19
|
-
|
20
|
-
from_hash(JSON.parse(json))
|
21
|
-
end
|
22
|
-
|
23
|
-
def from_hash(hash)
|
24
|
-
self.attributes = hash
|
25
|
-
self
|
9
|
+
def class_exists?(klass_name)
|
10
|
+
klass = Module.const_get(klass_name)
|
11
|
+
klass.is_a?(Class)
|
12
|
+
rescue NameError
|
13
|
+
false
|
26
14
|
end
|
27
15
|
end
|
28
16
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
require "benchmark"
|
5
|
+
|
6
|
+
module Cure
|
7
|
+
module Helpers
|
8
|
+
# This module uses some code sourced from here:
|
9
|
+
# https://torrocus.com/blog/different-ways-to-processing-large-csv-file-in-ruby/
|
10
|
+
module PerfHelpers
|
11
|
+
def print_memory_usage(process_name="default")
|
12
|
+
cmd = "ps -o rss= -p #{Process.pid}"
|
13
|
+
before_mem = `#{cmd}`.to_i
|
14
|
+
# before_gc = GC.stat(:total_allocated_objects)
|
15
|
+
|
16
|
+
yield
|
17
|
+
after_mem = `#{cmd}`.to_i
|
18
|
+
# after_gc = GC.stat(:total_allocated_objects)
|
19
|
+
|
20
|
+
log_info "Total Memory Usage [#{process_name}]: #{((after_mem - before_mem) / 1024.0).round(2)} MB"
|
21
|
+
# log_info "Total GC Objects Freed [#{process_name}]: #{after_gc - before_gc}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def print_time_spent(process_name="default", &block)
|
25
|
+
time = Benchmark.realtime(&block)
|
26
|
+
log_info "Total Processing Time [#{process_name}]: #{time.round(2)}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|