chronicle-etl 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/chronicle/etl.rb +1 -0
- data/lib/chronicle/etl/catalog.rb +41 -1
- data/lib/chronicle/etl/cli/jobs.rb +0 -1
- data/lib/chronicle/etl/exceptions.rb +17 -0
- data/lib/chronicle/etl/runner.rb +25 -38
- data/lib/chronicle/etl/transformers/null_transformer.rb +2 -2
- data/lib/chronicle/etl/transformers/transformer.rb +3 -2
- data/lib/chronicle/etl/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e1c08bc4f71c807525090abbf1701be19ab72cce08a99cc3bbec9b0db7150a02
|
4
|
+
data.tar.gz: 172a5d7e7ba7a9424ef7b5ab4da2b8c44defdb4e0a34c833248ff1b63f40407e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f671c00928b15f9c0f6fa159ac106ff9c4f65a8bd16048e5d0cab82d680945317f7680e7796e98c665bb5cc757e0657f1a36d773d89e3e1587d9eebc12abdd8
|
7
|
+
data.tar.gz: 449d1368e0054f39006c7903218300b9b97ca839d6eff43b6b7bd659e5146d443a31c53325c4769ae7a56db9d42417020ccde17362ae024c01aca2ed63029044
|
data/Gemfile.lock
CHANGED
data/lib/chronicle/etl.rb
CHANGED
@@ -4,6 +4,11 @@ module Chronicle
|
|
4
4
|
# Loader connector classes are available to chronicle-etl
|
5
5
|
module Catalog
|
6
6
|
PLUGINS = ['email', 'bash']
|
7
|
+
BUILTIN = {
|
8
|
+
extractor: ['stdin', 'json', 'csv', 'file'],
|
9
|
+
transformer: ['null'],
|
10
|
+
loader: ['stdout', 'csv', 'table', 'rest']
|
11
|
+
}.freeze
|
7
12
|
|
8
13
|
# Return which ETL connectors are available, both built in and externally-defined
|
9
14
|
def self.available_classes
|
@@ -15,7 +20,7 @@ module Chronicle
|
|
15
20
|
PLUGINS.each do |plugin|
|
16
21
|
require "chronicle/#{plugin}"
|
17
22
|
rescue LoadError
|
18
|
-
# this will happen if the gem isn't available globally
|
23
|
+
# this will happen if the gem isn't available globally
|
19
24
|
end
|
20
25
|
|
21
26
|
parent_klasses = [
|
@@ -38,6 +43,18 @@ module Chronicle
|
|
38
43
|
end
|
39
44
|
end
|
40
45
|
|
46
|
+
# For a given connector identifier, return the class (either builtin, or from a
|
47
|
+
# external chronicle gem)
|
48
|
+
def self.identifier_to_klass(identifier:, phase:)
|
49
|
+
if BUILTIN[phase].include? identifier
|
50
|
+
load_builtin_klass(name: identifier, phase: phase)
|
51
|
+
else
|
52
|
+
provider, name = identifier.split(':')
|
53
|
+
name ||= ''
|
54
|
+
load_provider_klass(provider: provider, name: name, phase: phase)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
41
58
|
# Returns whether a class is an Extractor, Transformer, or Loader
|
42
59
|
def phase
|
43
60
|
ancestors = self.ancestors
|
@@ -57,6 +74,29 @@ module Chronicle
|
|
57
74
|
def built_in?
|
58
75
|
to_s.include? 'Chronicle::ETL'
|
59
76
|
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def self.load_builtin_klass(name:, phase:)
|
81
|
+
klass_str = "Chronicle::ETL::#{name.capitalize}#{phase.capitalize}"
|
82
|
+
begin
|
83
|
+
Object.const_get(klass_str)
|
84
|
+
rescue NameError => e
|
85
|
+
raise ConnectorNotAvailableError.new("Connector not found", name: name)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.load_provider_klass(name: '', phase:, provider:)
|
90
|
+
begin
|
91
|
+
require "chronicle/#{provider}"
|
92
|
+
klass_str = "Chronicle::#{provider.capitalize}::#{name.capitalize}#{phase.capitalize}"
|
93
|
+
Object.const_get(klass_str)
|
94
|
+
rescue LoadError => e
|
95
|
+
raise ProviderNotAvailableError.new("Provider '#{provider.capitalize}' could not be loaded", provider: provider)
|
96
|
+
rescue NameError => e
|
97
|
+
raise ProviderConnectorNotAvailableError.new("Connector '#{name}' in '#{provider}' could not be found", provider: provider, name: name)
|
98
|
+
end
|
99
|
+
end
|
60
100
|
end
|
61
101
|
end
|
62
102
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Chronicle
|
2
|
+
module ETL
|
3
|
+
class Error < StandardError; end;
|
4
|
+
|
5
|
+
class ConnectorNotAvailableError < Error
|
6
|
+
def initialize(message, provider: nil, name: nil)
|
7
|
+
super(message)
|
8
|
+
@provider = provider
|
9
|
+
@name = name
|
10
|
+
end
|
11
|
+
attr_reader :name, :provider
|
12
|
+
end
|
13
|
+
|
14
|
+
class ProviderNotAvailableError < ConnectorNotAvailableError; end
|
15
|
+
class ProviderConnectorNotAvailableError < ConnectorNotAvailableError; end
|
16
|
+
end
|
17
|
+
end
|
data/lib/chronicle/etl/runner.rb
CHANGED
@@ -1,59 +1,46 @@
|
|
1
|
-
|
2
|
-
BUILTIN = {
|
3
|
-
extractor: ['stdin', 'json', 'csv', 'file'],
|
4
|
-
transformer: ['null'],
|
5
|
-
loader: ['stdout', 'csv', 'table']
|
6
|
-
}.freeze
|
1
|
+
require 'colorize'
|
7
2
|
|
8
|
-
|
3
|
+
class Chronicle::ETL::Runner
|
4
|
+
def initialize(options = {})
|
9
5
|
@options = options
|
10
|
-
|
11
|
-
instantiate_etl_classes
|
12
6
|
end
|
13
7
|
|
14
8
|
def run!
|
15
|
-
|
9
|
+
extractor = instantiate_klass(:extractor)
|
10
|
+
loader = instantiate_klass(:loader)
|
11
|
+
|
12
|
+
total = extractor.results_count
|
16
13
|
progress_bar = Chronicle::ETL::Utils::ProgressBar.new(title: 'Running job', total: total)
|
17
|
-
count = 0
|
18
14
|
|
19
|
-
|
15
|
+
loader.start
|
20
16
|
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
extractor.extract do |data, metadata|
|
18
|
+
transformer = instantiate_klass(:transformer, data)
|
19
|
+
transformed_data = transformer.transform
|
24
20
|
|
21
|
+
loader.load(transformed_data)
|
25
22
|
progress_bar.increment
|
26
|
-
count += 1
|
27
23
|
end
|
28
24
|
|
29
25
|
progress_bar.finish
|
30
|
-
|
26
|
+
loader.finish
|
31
27
|
end
|
32
28
|
|
33
29
|
private
|
34
30
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
@loader = load_etl_class(:loader, @options[:loader][:name]).new(@options[:loader][:options])
|
31
|
+
def instantiate_klass(phase, *args)
|
32
|
+
klass = load_etl_class(phase, @options[phase][:name])
|
33
|
+
klass.new(@options[phase][:options], *args)
|
39
34
|
end
|
40
35
|
|
41
|
-
def load_etl_class(phase,
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
rescue LoadError => e
|
51
|
-
warn("Error loading #{phase} '#{provider}'".red)
|
52
|
-
warn(" Perhaps you haven't installed it yet: `$ gem install chronicle-#{provider}`")
|
53
|
-
exit(false)
|
54
|
-
end
|
55
|
-
klass_name = "Chronicle::#{provider.capitalize}::#{name&.capitalize}#{phase.capitalize}"
|
56
|
-
end
|
57
|
-
Object.const_get(klass_name)
|
36
|
+
def load_etl_class(phase, identifier)
|
37
|
+
Chronicle::ETL::Catalog.identifier_to_klass(phase: phase, identifier: identifier)
|
38
|
+
rescue Chronicle::ETL::ProviderNotAvailableError => e
|
39
|
+
warn(e.message.red)
|
40
|
+
warn(" Perhaps you haven't installed it yet: `$ gem install chronicle-#{e.provider}`")
|
41
|
+
exit(false)
|
42
|
+
rescue Chronicle::ETL::ConnectorNotAvailableError => e
|
43
|
+
warn(e.message.red)
|
44
|
+
exit(false)
|
58
45
|
end
|
59
46
|
end
|
@@ -8,12 +8,13 @@ module Chronicle
|
|
8
8
|
# == Paramters:
|
9
9
|
# options::
|
10
10
|
# Options for configuring this Transformer
|
11
|
-
def initialize(options = {})
|
11
|
+
def initialize(options = {}, data)
|
12
12
|
@options = options
|
13
|
+
@data = data
|
13
14
|
end
|
14
15
|
|
15
16
|
# The main entrypoint for transforming a record. Called by a Runner on each extracted record
|
16
|
-
def transform
|
17
|
+
def transform
|
17
18
|
raise NotImplementedError
|
18
19
|
end
|
19
20
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chronicle-etl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Louis
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-08-
|
11
|
+
date: 2020-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -183,6 +183,7 @@ files:
|
|
183
183
|
- lib/chronicle/etl/cli/main.rb
|
184
184
|
- lib/chronicle/etl/cli/subcommand_base.rb
|
185
185
|
- lib/chronicle/etl/config.rb
|
186
|
+
- lib/chronicle/etl/exceptions.rb
|
186
187
|
- lib/chronicle/etl/extractors/csv_extractor.rb
|
187
188
|
- lib/chronicle/etl/extractors/extractor.rb
|
188
189
|
- lib/chronicle/etl/extractors/file_extractor.rb
|