beetle_etl 0.0.1 → 0.0.2
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/.travis.yml +1 -1
- data/beetle_etl.gemspec +1 -2
- data/lib/beetle_etl/import.rb +5 -5
- data/lib/beetle_etl/steps/assign_ids.rb +4 -2
- data/lib/beetle_etl/steps/load.rb +14 -3
- data/lib/beetle_etl/steps/table_diff.rb +3 -3
- data/lib/beetle_etl/task_runner/dependency_resolver.rb +1 -1
- data/lib/beetle_etl/task_runner/task_runner.rb +45 -38
- data/lib/beetle_etl/version.rb +1 -1
- data/spec/steps/load_spec.rb +17 -1
- data/spec/steps/step_spec.rb +0 -1
- metadata +23 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b08e51fe6819079c6b8317636030d5d678b102cc
|
4
|
+
data.tar.gz: 6afa19db3171f105fa275f99c82c07306aa9c568
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a915efc65e4450aa4ba7cec71a75b89082d6b65be4cd2e6db88ee8e540f9bc0d1db96afd18c787ac504309460447bfdbb20ab462e012ac503e8fe8cdecb65880
|
7
|
+
data.tar.gz: afc74720f9875d7a447030bb14fbc4da90c1004b5c725fb55b0630bbc073d3d15560e6c5e2b7002951e1989eb4b63b956508411811c146986820aee2679a6462
|
data/.travis.yml
CHANGED
@@ -5,7 +5,7 @@ rvm:
|
|
5
5
|
addons:
|
6
6
|
postgresql: "9.3"
|
7
7
|
code_climate:
|
8
|
-
repo_token:
|
8
|
+
repo_token: fcd6d8c28da900609a2cf903716d858621b8ce68152edbcebe6908a9a3f5d3d5
|
9
9
|
|
10
10
|
before_script:
|
11
11
|
- psql -c 'create database travis_ci_test;' -U postgres
|
data/beetle_etl.gemspec
CHANGED
@@ -19,11 +19,10 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
21
|
spec.add_runtime_dependency 'sequel', '>= 4.13.0'
|
22
|
-
spec.add_runtime_dependency 'celluloid', '>= 0.15.2'
|
23
22
|
|
24
23
|
spec.add_development_dependency 'bundler', '~> 1.6'
|
25
24
|
spec.add_development_dependency 'rake'
|
26
|
-
spec.add_development_dependency 'rspec', '~> 3.
|
25
|
+
spec.add_development_dependency 'rspec', '~> 3.1.0'
|
27
26
|
spec.add_development_dependency 'pg'
|
28
27
|
spec.add_development_dependency 'codeclimate-test-reporter'
|
29
28
|
spec.add_development_dependency 'activesupport'
|
data/lib/beetle_etl/import.rb
CHANGED
@@ -4,28 +4,28 @@ module BeetleETL
|
|
4
4
|
extend self
|
5
5
|
|
6
6
|
def run
|
7
|
-
TaskRunner.
|
7
|
+
TaskRunner.new(data_steps).run
|
8
8
|
BeetleETL.database.transaction do
|
9
|
-
load_steps.
|
9
|
+
TaskRunner.new(load_steps).run
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
13
|
private
|
14
14
|
|
15
15
|
def data_steps
|
16
|
-
transformations.
|
16
|
+
transformations.flat_map do |t|
|
17
17
|
[
|
18
18
|
Transform.new(t.table_name, t.dependencies, t.query),
|
19
19
|
MapRelations.new(t.table_name, t.relations),
|
20
20
|
TableDiff.new(t.table_name),
|
21
21
|
AssignIds.new(t.table_name),
|
22
22
|
]
|
23
|
-
end
|
23
|
+
end
|
24
24
|
end
|
25
25
|
|
26
26
|
def load_steps
|
27
27
|
transformations.map do |t|
|
28
|
-
Load.new(t.table_name)
|
28
|
+
Load.new(t.table_name, t.relations)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -7,10 +7,21 @@ module BeetleETL
|
|
7
7
|
transition
|
8
8
|
]
|
9
9
|
|
10
|
+
attr_reader :relations
|
11
|
+
|
12
|
+
def initialize(table_name, relations)
|
13
|
+
super(table_name)
|
14
|
+
@relations = relations
|
15
|
+
end
|
16
|
+
|
10
17
|
def run
|
11
|
-
%w(create update delete undelete).
|
12
|
-
public_send(:"load_#{transition}")
|
13
|
-
end
|
18
|
+
%w(create update delete undelete).map do |transition|
|
19
|
+
Thread.new { public_send(:"load_#{transition}") }
|
20
|
+
end.each(&:join)
|
21
|
+
end
|
22
|
+
|
23
|
+
def dependencies
|
24
|
+
relations.values.map { |d| Load.step_name(d) }.to_set
|
14
25
|
end
|
15
26
|
|
16
27
|
def load_create
|
@@ -12,9 +12,9 @@ module BeetleETL
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def run
|
15
|
-
%w(create keep update delete undelete).
|
16
|
-
public_send(:"transition_#{transition}")
|
17
|
-
end
|
15
|
+
%w(create keep update delete undelete).map do |transition|
|
16
|
+
Thread.new { public_send(:"transition_#{transition}") }
|
17
|
+
end.each(&:join)
|
18
18
|
end
|
19
19
|
|
20
20
|
def transition_create
|
@@ -1,63 +1,70 @@
|
|
1
|
-
require 'celluloid/autostart'
|
2
|
-
|
3
1
|
module BeetleETL
|
4
2
|
class TaskRunner
|
5
3
|
|
6
|
-
|
4
|
+
def initialize(tasks)
|
5
|
+
@dependency_resolver = DependencyResolver.new(tasks)
|
6
|
+
@tasks = tasks
|
7
7
|
|
8
|
-
|
9
|
-
@runnables = runnables
|
8
|
+
@queue = Queue.new
|
10
9
|
@completed = Set.new
|
11
10
|
@running = Set.new
|
12
|
-
@dependency_resolver = DependencyResolver.new(runnables)
|
13
|
-
|
14
|
-
run_next
|
15
11
|
end
|
16
12
|
|
17
|
-
def
|
18
|
-
|
19
|
-
@completed << runnable_name
|
20
|
-
|
21
|
-
run_next
|
22
|
-
end
|
13
|
+
def run
|
14
|
+
results = {}
|
23
15
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
resolvables.each do |runnable|
|
29
|
-
unless @running.include?(runnable.name)
|
30
|
-
Task.new(Actor.current, runnable).async.run_task
|
31
|
-
@running << runnable.name
|
32
|
-
end
|
16
|
+
until all_tasks_complete?
|
17
|
+
runnables.each do |task|
|
18
|
+
run_task_async(task)
|
19
|
+
mark_task_running(task.name)
|
33
20
|
end
|
21
|
+
|
22
|
+
task_name, task_data = @queue.pop
|
23
|
+
results[task_name] = task_data
|
24
|
+
mark_task_completed(task_name)
|
34
25
|
end
|
26
|
+
|
27
|
+
results
|
35
28
|
end
|
36
29
|
|
37
30
|
private
|
38
31
|
|
39
|
-
|
40
|
-
|
32
|
+
attr_reader :running, :completed
|
33
|
+
|
34
|
+
def run_task_async(task)
|
35
|
+
Thread.new do
|
36
|
+
started_at = now
|
37
|
+
result = task.run
|
38
|
+
finished_at = now
|
39
|
+
|
40
|
+
@queue.push [task.name, {
|
41
|
+
started_at: started_at,
|
42
|
+
finished_at: finished_at,
|
43
|
+
result: result,
|
44
|
+
}]
|
45
|
+
end
|
41
46
|
end
|
42
47
|
|
43
|
-
def
|
44
|
-
|
48
|
+
def mark_task_running(task_name)
|
49
|
+
running.add(task_name)
|
45
50
|
end
|
46
51
|
|
47
|
-
|
52
|
+
def mark_task_completed(task_name)
|
53
|
+
runnables.delete(task_name)
|
54
|
+
completed.add(task_name)
|
55
|
+
end
|
48
56
|
|
49
|
-
|
57
|
+
def runnables
|
58
|
+
resolvables = @dependency_resolver.resolvables(completed)
|
59
|
+
resolvables.reject { |r| running.include? r.name }
|
60
|
+
end
|
50
61
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
62
|
+
def all_tasks_complete?
|
63
|
+
@tasks.map(&:name).to_set == completed.to_set
|
64
|
+
end
|
55
65
|
|
56
|
-
|
57
|
-
|
58
|
-
@runner.async.completed(@task.name)
|
59
|
-
terminate
|
60
|
-
end
|
66
|
+
def now
|
67
|
+
Time.now
|
61
68
|
end
|
62
69
|
|
63
70
|
end
|
data/lib/beetle_etl/version.rb
CHANGED
data/spec/steps/load_spec.rb
CHANGED
@@ -13,7 +13,7 @@ module BeetleETL
|
|
13
13
|
let(:now) { Time.now.beginning_of_day }
|
14
14
|
let(:yesterday) { 1.day.ago.beginning_of_day }
|
15
15
|
|
16
|
-
subject { Load.new(:example_table) }
|
16
|
+
subject { Load.new(:example_table, []) }
|
17
17
|
|
18
18
|
before do
|
19
19
|
BeetleETL.configure do |config|
|
@@ -52,6 +52,22 @@ module BeetleETL
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
describe '#depenencies' do
|
56
|
+
it 'depends on Transform of the same table and AssignIds of its dependees' do
|
57
|
+
relations = {
|
58
|
+
dependee_a_id: :dependee_a,
|
59
|
+
dependee_b_id: :dependee_b,
|
60
|
+
}
|
61
|
+
|
62
|
+
expect(Load.new(:depender, relations).dependencies).to eql(
|
63
|
+
[
|
64
|
+
'dependee_a: Load',
|
65
|
+
'dependee_b: Load',
|
66
|
+
].to_set
|
67
|
+
)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
55
71
|
describe '#run' do
|
56
72
|
it 'runs all load steps' do
|
57
73
|
%w(create update delete undelete).each do |transition|
|
data/spec/steps/step_spec.rb
CHANGED
metadata
CHANGED
@@ -1,125 +1,111 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beetle_etl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luciano Maiwald
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 4.13.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 4.13.0
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: celluloid
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - '>='
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.15.2
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - '>='
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 0.15.2
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: bundler
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
|
-
- - ~>
|
31
|
+
- - "~>"
|
46
32
|
- !ruby/object:Gem::Version
|
47
33
|
version: '1.6'
|
48
34
|
type: :development
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
|
-
- - ~>
|
38
|
+
- - "~>"
|
53
39
|
- !ruby/object:Gem::Version
|
54
40
|
version: '1.6'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: rake
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
|
-
- -
|
45
|
+
- - ">="
|
60
46
|
- !ruby/object:Gem::Version
|
61
47
|
version: '0'
|
62
48
|
type: :development
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
|
-
- -
|
52
|
+
- - ">="
|
67
53
|
- !ruby/object:Gem::Version
|
68
54
|
version: '0'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: rspec
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
|
-
- - ~>
|
59
|
+
- - "~>"
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: 3.
|
61
|
+
version: 3.1.0
|
76
62
|
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
|
-
- - ~>
|
66
|
+
- - "~>"
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: 3.
|
68
|
+
version: 3.1.0
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: pg
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
|
-
- -
|
73
|
+
- - ">="
|
88
74
|
- !ruby/object:Gem::Version
|
89
75
|
version: '0'
|
90
76
|
type: :development
|
91
77
|
prerelease: false
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
93
79
|
requirements:
|
94
|
-
- -
|
80
|
+
- - ">="
|
95
81
|
- !ruby/object:Gem::Version
|
96
82
|
version: '0'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: codeclimate-test-reporter
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
|
-
- -
|
87
|
+
- - ">="
|
102
88
|
- !ruby/object:Gem::Version
|
103
89
|
version: '0'
|
104
90
|
type: :development
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
|
-
- -
|
94
|
+
- - ">="
|
109
95
|
- !ruby/object:Gem::Version
|
110
96
|
version: '0'
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
98
|
name: activesupport
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
114
100
|
requirements:
|
115
|
-
- -
|
101
|
+
- - ">="
|
116
102
|
- !ruby/object:Gem::Version
|
117
103
|
version: '0'
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
107
|
requirements:
|
122
|
-
- -
|
108
|
+
- - ">="
|
123
109
|
- !ruby/object:Gem::Version
|
124
110
|
version: '0'
|
125
111
|
description: Taking care of synchronizing external data with referential data in your
|
@@ -130,8 +116,8 @@ executables: []
|
|
130
116
|
extensions: []
|
131
117
|
extra_rdoc_files: []
|
132
118
|
files:
|
133
|
-
- .gitignore
|
134
|
-
- .travis.yml
|
119
|
+
- ".gitignore"
|
120
|
+
- ".travis.yml"
|
135
121
|
- Gemfile
|
136
122
|
- LICENSE.txt
|
137
123
|
- README.md
|
@@ -183,17 +169,17 @@ require_paths:
|
|
183
169
|
- lib
|
184
170
|
required_ruby_version: !ruby/object:Gem::Requirement
|
185
171
|
requirements:
|
186
|
-
- -
|
172
|
+
- - ">="
|
187
173
|
- !ruby/object:Gem::Version
|
188
174
|
version: '0'
|
189
175
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
190
176
|
requirements:
|
191
|
-
- -
|
177
|
+
- - ">="
|
192
178
|
- !ruby/object:Gem::Version
|
193
179
|
version: '0'
|
194
180
|
requirements: []
|
195
181
|
rubyforge_project:
|
196
|
-
rubygems_version: 2.
|
182
|
+
rubygems_version: 2.4.5
|
197
183
|
signing_key:
|
198
184
|
specification_version: 4
|
199
185
|
summary: BeetleETL helps you with your recurring ETL imports.
|