table_saw 2.6.0 → 2.7.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/.github/workflows/ruby.yml +53 -0
- data/.rubocop.yml +24 -3
- data/.ruby-version +1 -1
- data/Gemfile.lock +43 -41
- data/README.md +1 -1
- data/lib/table_saw/associations.rb +40 -0
- data/lib/table_saw/dependency_graph/belongs_to_directives.rb +19 -15
- data/lib/table_saw/dependency_graph/dump_table.rb +1 -1
- data/lib/table_saw/dependency_graph/has_many_directives.rb +20 -15
- data/lib/table_saw/foreign_key.rb +63 -0
- data/lib/table_saw/information_schema.rb +2 -6
- data/lib/table_saw/manifest.rb +9 -0
- data/lib/table_saw/queries/foreign_key_relationships.rb +11 -12
- data/lib/table_saw/version.rb +1 -1
- data/table_saw.gemspec +1 -1
- metadata +8 -6
- data/.travis.yml +0 -24
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d7ba43df3b9906b32dc2478f41c974ee5cca5036d5ec7f95fa0ba6f04ece6812
|
|
4
|
+
data.tar.gz: d4775622ad45fc31d5a658d095807e925e4b0570a6a01eeb302546c5b5669540
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5833756a4f1746c2b54a9ddd27766f2ff3fe651455e2dcb8112938e2c0b06984a6c0c3b1d5990b1a8acfabe3e65cb2ef85807dbc2f6156f254e7c3cf794c0a17
|
|
7
|
+
data.tar.gz: c620092fcdf65362c007c38ea4bbb3e66ed016d6a29a24d11e62e0f6d23fd5e70e2aa92c9c82b5b3cf7de16a6cf00e3c8574906d4a90630ad13b3483826e15a4
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: Ruby
|
|
2
|
+
|
|
3
|
+
on: [push]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
build:
|
|
7
|
+
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
|
|
10
|
+
services:
|
|
11
|
+
postgres:
|
|
12
|
+
image: postgres:12.2
|
|
13
|
+
env:
|
|
14
|
+
POSTGRES_USER: postgres
|
|
15
|
+
POSTGRES_PASSWORD: postgres
|
|
16
|
+
POSTGRES_DB: table_saw_test
|
|
17
|
+
ports:
|
|
18
|
+
- 5432:5432
|
|
19
|
+
# needed because the postgres container does not provide a healthcheck
|
|
20
|
+
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v2
|
|
24
|
+
|
|
25
|
+
- name: Set up Ruby 2.6
|
|
26
|
+
uses: actions/setup-ruby@v1
|
|
27
|
+
with:
|
|
28
|
+
ruby-version: 2.6.x
|
|
29
|
+
|
|
30
|
+
- uses: actions/cache@v1
|
|
31
|
+
with:
|
|
32
|
+
path: vendor/bundle
|
|
33
|
+
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
|
|
34
|
+
restore-keys: |
|
|
35
|
+
${{ runner.os }}-gems-
|
|
36
|
+
|
|
37
|
+
- name: Install PostgreSQL client
|
|
38
|
+
run: |
|
|
39
|
+
sudo apt-get -yqq install libpq-dev
|
|
40
|
+
|
|
41
|
+
- name: Configure Bundler
|
|
42
|
+
run: |
|
|
43
|
+
gem install bundler -v 2.1.4 --no-document
|
|
44
|
+
bundle config path 'vendor/bundle'
|
|
45
|
+
bundle install --jobs 4 --retry 3
|
|
46
|
+
|
|
47
|
+
- name: Run tests with RSpec
|
|
48
|
+
uses: paambaati/codeclimate-action@v2.5.4
|
|
49
|
+
env:
|
|
50
|
+
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
|
51
|
+
with:
|
|
52
|
+
coverageCommand: bundle exec rspec
|
|
53
|
+
debug: false
|
data/.rubocop.yml
CHANGED
|
@@ -3,14 +3,23 @@ require: rubocop-rspec
|
|
|
3
3
|
AllCops:
|
|
4
4
|
TargetRubyVersion: 2.6
|
|
5
5
|
|
|
6
|
+
Layout/LineLength:
|
|
7
|
+
Max: 120
|
|
8
|
+
|
|
6
9
|
Layout/MultilineMethodCallIndentation:
|
|
7
10
|
EnforcedStyle: indented_relative_to_receiver
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
Layout/SpaceAroundMethodCallOperator:
|
|
13
|
+
Enabled: true
|
|
14
|
+
|
|
15
|
+
Lint/RaiseException:
|
|
16
|
+
Enabled: true
|
|
17
|
+
|
|
18
|
+
Lint/StructNewOverride:
|
|
19
|
+
Enabled: true
|
|
11
20
|
|
|
12
21
|
Naming/PredicateName:
|
|
13
|
-
|
|
22
|
+
AllowedMethods:
|
|
14
23
|
- has_many
|
|
15
24
|
|
|
16
25
|
Style/Documentation:
|
|
@@ -19,9 +28,21 @@ Style/Documentation:
|
|
|
19
28
|
Style/EmptyMethod:
|
|
20
29
|
EnforcedStyle: expanded
|
|
21
30
|
|
|
31
|
+
Style/ExponentialNotation:
|
|
32
|
+
Enabled: true
|
|
33
|
+
|
|
22
34
|
Style/FormatStringToken:
|
|
23
35
|
EnforcedStyle: template
|
|
24
36
|
|
|
37
|
+
Style/HashEachMethods:
|
|
38
|
+
Enabled: true
|
|
39
|
+
|
|
40
|
+
Style/HashTransformKeys:
|
|
41
|
+
Enabled: true
|
|
42
|
+
|
|
43
|
+
Style/HashTransformValues:
|
|
44
|
+
Enabled: true
|
|
45
|
+
|
|
25
46
|
Style/PercentLiteralDelimiters:
|
|
26
47
|
PreferredDelimiters:
|
|
27
48
|
default: ()
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.6.
|
|
1
|
+
2.6.6
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
table_saw (2.
|
|
4
|
+
table_saw (2.7.0)
|
|
5
5
|
activerecord (>= 5.2)
|
|
6
6
|
pg
|
|
7
7
|
thor
|
|
@@ -9,25 +9,25 @@ PATH
|
|
|
9
9
|
GEM
|
|
10
10
|
remote: https://rubygems.org/
|
|
11
11
|
specs:
|
|
12
|
-
actionpack (6.0.2.
|
|
13
|
-
actionview (= 6.0.2.
|
|
14
|
-
activesupport (= 6.0.2.
|
|
12
|
+
actionpack (6.0.2.2)
|
|
13
|
+
actionview (= 6.0.2.2)
|
|
14
|
+
activesupport (= 6.0.2.2)
|
|
15
15
|
rack (~> 2.0, >= 2.0.8)
|
|
16
16
|
rack-test (>= 0.6.3)
|
|
17
17
|
rails-dom-testing (~> 2.0)
|
|
18
18
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
|
19
|
-
actionview (6.0.2.
|
|
20
|
-
activesupport (= 6.0.2.
|
|
19
|
+
actionview (6.0.2.2)
|
|
20
|
+
activesupport (= 6.0.2.2)
|
|
21
21
|
builder (~> 3.1)
|
|
22
22
|
erubi (~> 1.4)
|
|
23
23
|
rails-dom-testing (~> 2.0)
|
|
24
24
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
|
25
|
-
activemodel (6.0.2.
|
|
26
|
-
activesupport (= 6.0.2.
|
|
27
|
-
activerecord (6.0.2.
|
|
28
|
-
activemodel (= 6.0.2.
|
|
29
|
-
activesupport (= 6.0.2.
|
|
30
|
-
activesupport (6.0.2.
|
|
25
|
+
activemodel (6.0.2.2)
|
|
26
|
+
activesupport (= 6.0.2.2)
|
|
27
|
+
activerecord (6.0.2.2)
|
|
28
|
+
activemodel (= 6.0.2.2)
|
|
29
|
+
activesupport (= 6.0.2.2)
|
|
30
|
+
activesupport (6.0.2.2)
|
|
31
31
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
32
32
|
i18n (>= 0.7, < 2)
|
|
33
33
|
minitest (~> 5.1)
|
|
@@ -40,7 +40,7 @@ GEM
|
|
|
40
40
|
activesupport (>= 3.0.0)
|
|
41
41
|
railties (>= 3.0.0)
|
|
42
42
|
thor (>= 0.14.6)
|
|
43
|
-
concurrent-ruby (1.1.
|
|
43
|
+
concurrent-ruby (1.1.6)
|
|
44
44
|
crass (1.0.6)
|
|
45
45
|
database_cleaner (1.7.0)
|
|
46
46
|
diff-lcs (1.3)
|
|
@@ -48,7 +48,7 @@ GEM
|
|
|
48
48
|
erubi (1.9.0)
|
|
49
49
|
i18n (1.8.2)
|
|
50
50
|
concurrent-ruby (~> 1.0)
|
|
51
|
-
jaro_winkler (1.5.
|
|
51
|
+
jaro_winkler (1.5.4)
|
|
52
52
|
json (2.2.0)
|
|
53
53
|
loofah (2.4.0)
|
|
54
54
|
crass (~> 1.0.2)
|
|
@@ -56,16 +56,16 @@ GEM
|
|
|
56
56
|
method_source (0.9.2)
|
|
57
57
|
mini_portile2 (2.4.0)
|
|
58
58
|
minitest (5.14.0)
|
|
59
|
-
nokogiri (1.10.
|
|
59
|
+
nokogiri (1.10.9)
|
|
60
60
|
mini_portile2 (~> 2.4.0)
|
|
61
|
-
parallel (1.
|
|
62
|
-
parser (2.
|
|
61
|
+
parallel (1.19.1)
|
|
62
|
+
parser (2.7.1.2)
|
|
63
63
|
ast (~> 2.4.0)
|
|
64
|
-
pg (1.2.
|
|
64
|
+
pg (1.2.3)
|
|
65
65
|
pry (0.12.2)
|
|
66
66
|
coderay (~> 1.1.0)
|
|
67
67
|
method_source (~> 0.9.0)
|
|
68
|
-
rack (2.
|
|
68
|
+
rack (2.2.2)
|
|
69
69
|
rack-test (1.1.0)
|
|
70
70
|
rack (>= 1.0, < 3)
|
|
71
71
|
rails-dom-testing (2.0.3)
|
|
@@ -73,38 +73,40 @@ GEM
|
|
|
73
73
|
nokogiri (>= 1.6)
|
|
74
74
|
rails-html-sanitizer (1.3.0)
|
|
75
75
|
loofah (~> 2.3)
|
|
76
|
-
railties (6.0.2.
|
|
77
|
-
actionpack (= 6.0.2.
|
|
78
|
-
activesupport (= 6.0.2.
|
|
76
|
+
railties (6.0.2.2)
|
|
77
|
+
actionpack (= 6.0.2.2)
|
|
78
|
+
activesupport (= 6.0.2.2)
|
|
79
79
|
method_source
|
|
80
80
|
rake (>= 0.8.7)
|
|
81
81
|
thor (>= 0.20.3, < 2.0)
|
|
82
82
|
rainbow (3.0.0)
|
|
83
|
-
rake (
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
rspec-
|
|
87
|
-
rspec-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
83
|
+
rake (13.0.1)
|
|
84
|
+
rexml (3.2.4)
|
|
85
|
+
rspec (3.9.0)
|
|
86
|
+
rspec-core (~> 3.9.0)
|
|
87
|
+
rspec-expectations (~> 3.9.0)
|
|
88
|
+
rspec-mocks (~> 3.9.0)
|
|
89
|
+
rspec-core (3.9.1)
|
|
90
|
+
rspec-support (~> 3.9.1)
|
|
91
|
+
rspec-expectations (3.9.0)
|
|
91
92
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
92
|
-
rspec-support (~> 3.
|
|
93
|
-
rspec-mocks (3.
|
|
93
|
+
rspec-support (~> 3.9.0)
|
|
94
|
+
rspec-mocks (3.9.1)
|
|
94
95
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
95
|
-
rspec-support (~> 3.
|
|
96
|
-
rspec-support (3.
|
|
97
|
-
rubocop (0.
|
|
96
|
+
rspec-support (~> 3.9.0)
|
|
97
|
+
rspec-support (3.9.2)
|
|
98
|
+
rubocop (0.82.0)
|
|
98
99
|
jaro_winkler (~> 1.5.1)
|
|
99
100
|
parallel (~> 1.10)
|
|
100
|
-
parser (>= 2.
|
|
101
|
+
parser (>= 2.7.0.1)
|
|
101
102
|
rainbow (>= 2.2.2, < 4.0)
|
|
103
|
+
rexml
|
|
102
104
|
ruby-progressbar (~> 1.7)
|
|
103
|
-
unicode-display_width (>= 1.4.0, <
|
|
105
|
+
unicode-display_width (>= 1.4.0, < 2.0)
|
|
104
106
|
rubocop-rspec (1.33.0)
|
|
105
107
|
rubocop (>= 0.60.0)
|
|
106
108
|
ruby-progressbar (1.10.1)
|
|
107
|
-
scenic (1.5.
|
|
109
|
+
scenic (1.5.2)
|
|
108
110
|
activerecord (>= 4.0.0)
|
|
109
111
|
railties (>= 4.0.0)
|
|
110
112
|
simplecov (0.16.1)
|
|
@@ -116,8 +118,8 @@ GEM
|
|
|
116
118
|
thread_safe (0.3.6)
|
|
117
119
|
tzinfo (1.2.6)
|
|
118
120
|
thread_safe (~> 0.1)
|
|
119
|
-
unicode-display_width (1.
|
|
120
|
-
zeitwerk (2.
|
|
121
|
+
unicode-display_width (1.7.0)
|
|
122
|
+
zeitwerk (2.3.0)
|
|
121
123
|
|
|
122
124
|
PLATFORMS
|
|
123
125
|
ruby
|
|
@@ -127,7 +129,7 @@ DEPENDENCIES
|
|
|
127
129
|
combustion (~> 1.1)
|
|
128
130
|
database_cleaner (~> 1.7)
|
|
129
131
|
pry
|
|
130
|
-
rake (~>
|
|
132
|
+
rake (~> 13.0)
|
|
131
133
|
rspec (~> 3.0)
|
|
132
134
|
rubocop-rspec (~> 1.33)
|
|
133
135
|
scenic (~> 1.5)
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+

|
|
2
2
|
[](https://codeclimate.com/github/hasghari/table_saw/maintainability)
|
|
3
3
|
[](https://codeclimate.com/github/hasghari/table_saw/test_coverage)
|
|
4
4
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TableSaw
|
|
4
|
+
class Associations
|
|
5
|
+
attr_reader :manifest
|
|
6
|
+
|
|
7
|
+
def initialize(manifest)
|
|
8
|
+
@manifest = manifest
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def belongs_to
|
|
12
|
+
@belongs_to ||= foreign_keys.each_with_object(Hash.new { |h, k| h[k] = Set.new }) do |fk, memo|
|
|
13
|
+
memo[fk.from_table].add(fk)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def has_many
|
|
18
|
+
@has_many ||= foreign_keys.each_with_object(Hash.new { |h, k| h[k] = Set.new }) do |fk, memo|
|
|
19
|
+
memo[fk.to_table].add(fk)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def foreign_keys
|
|
26
|
+
@foreign_keys ||= manifest_foreign_keys + schema_foreign_keys
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def manifest_foreign_keys
|
|
30
|
+
manifest.foreign_keys.map do |fk|
|
|
31
|
+
TableSaw::ForeignKey.new(from_table: fk['from_table'], from_column: fk['from_column'],
|
|
32
|
+
to_table: fk['to_table'], to_column: fk['to_column'])
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def schema_foreign_keys
|
|
37
|
+
TableSaw.information_schema.foreign_key_relationships.foreign_keys
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -3,42 +3,46 @@
|
|
|
3
3
|
module TableSaw
|
|
4
4
|
module DependencyGraph
|
|
5
5
|
class BelongsToDirectives
|
|
6
|
-
|
|
6
|
+
QUERY = <<~SQL
|
|
7
|
+
select distinct %{column} from %{table_name} where %{clause} and %{column} is not null and %{polymorphic}
|
|
8
|
+
SQL
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
attr_reader :manifest, :directive
|
|
11
|
+
|
|
12
|
+
def initialize(manifest, directive)
|
|
13
|
+
@manifest = manifest
|
|
9
14
|
@directive = directive
|
|
10
15
|
end
|
|
11
16
|
|
|
12
17
|
def call
|
|
13
|
-
associations.map do |
|
|
14
|
-
TableSaw::DependencyGraph::AddDirective.new(to_table, ids: ids[
|
|
18
|
+
associations.map do |fk|
|
|
19
|
+
TableSaw::DependencyGraph::AddDirective.new(fk.to_table, ids: ids[fk.column.primary_key],
|
|
20
|
+
partial: directive.partial?)
|
|
15
21
|
end
|
|
16
22
|
end
|
|
17
23
|
|
|
18
24
|
private
|
|
19
25
|
|
|
20
26
|
def associations
|
|
21
|
-
|
|
27
|
+
manifest.associations.belongs_to.fetch(directive.table_name, Set.new)
|
|
22
28
|
end
|
|
23
29
|
|
|
24
30
|
def ids
|
|
25
|
-
@ids ||= associations.
|
|
26
|
-
memo[column] = query_result(
|
|
31
|
+
@ids ||= associations.each_with_object({}) do |fk, memo|
|
|
32
|
+
memo[fk.column.primary_key] = query_result(fk).map { |row| row[fk.column.primary_key] }
|
|
27
33
|
end
|
|
28
34
|
end
|
|
29
35
|
|
|
30
36
|
# rubocop:disable Metrics/AbcSize
|
|
31
|
-
def query_result(
|
|
37
|
+
def query_result(foreign_key)
|
|
32
38
|
return [] unless directive.selectable?
|
|
33
39
|
|
|
34
40
|
TableSaw::Connection.exec(
|
|
35
|
-
format(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
directive.ids).call
|
|
41
|
-
)
|
|
41
|
+
format(QUERY, column: foreign_key.column.primary_key, table_name: directive.table_name,
|
|
42
|
+
clause: TableSaw::Queries::SerializeSqlInClause.new(directive.table_name,
|
|
43
|
+
directive.primary_key,
|
|
44
|
+
directive.ids).call,
|
|
45
|
+
polymorphic: foreign_key.type_condition)
|
|
42
46
|
)
|
|
43
47
|
end
|
|
44
48
|
# rubocop:enable Metrics/AbcSize
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
module TableSaw
|
|
4
4
|
module DependencyGraph
|
|
5
5
|
class HasManyDirectives
|
|
6
|
+
QUERY = <<~SQL
|
|
7
|
+
select %{primary_key} from %{table} where %{clause} and %{polymorphic}
|
|
8
|
+
SQL
|
|
9
|
+
|
|
6
10
|
attr_reader :manifest, :directive
|
|
7
11
|
|
|
8
12
|
def initialize(manifest, directive)
|
|
@@ -11,10 +15,10 @@ module TableSaw
|
|
|
11
15
|
end
|
|
12
16
|
|
|
13
17
|
def call
|
|
14
|
-
valid_associations.map do |
|
|
18
|
+
valid_associations.map do |fk|
|
|
15
19
|
TableSaw::DependencyGraph::AddDirective.new(
|
|
16
|
-
|
|
17
|
-
ids: query_result(
|
|
20
|
+
fk.from_table,
|
|
21
|
+
ids: query_result(fk).map { |r| r[TableSaw.schema_cache.primary_keys(fk.from_table)] },
|
|
18
22
|
partial: directive.partial?
|
|
19
23
|
)
|
|
20
24
|
end
|
|
@@ -23,31 +27,32 @@ module TableSaw
|
|
|
23
27
|
private
|
|
24
28
|
|
|
25
29
|
def associations
|
|
26
|
-
|
|
30
|
+
manifest.associations.has_many.fetch(directive.table_name, Set.new)
|
|
27
31
|
end
|
|
28
32
|
|
|
29
33
|
# rubocop:disable Metrics/AbcSize
|
|
30
34
|
def valid_associations
|
|
31
|
-
associations.select do |
|
|
32
|
-
next false if directive.partial? && TableSaw.schema_cache.primary_keys(
|
|
33
|
-
next true if directive.has_many.include?(
|
|
35
|
+
associations.select do |fk|
|
|
36
|
+
next false if directive.partial? && TableSaw.schema_cache.primary_keys(fk.from_table).nil?
|
|
37
|
+
next true if directive.has_many.include?(fk.from_table)
|
|
34
38
|
|
|
35
|
-
manifest.has_many.fetch(directive.table_name, []).include?(
|
|
39
|
+
manifest.has_many.fetch(directive.table_name, []).include?(fk.from_table)
|
|
36
40
|
end
|
|
37
41
|
end
|
|
38
|
-
# rubocop:enable Metrics/AbcSize
|
|
39
42
|
|
|
40
|
-
def query_result(
|
|
43
|
+
def query_result(foreign_key)
|
|
41
44
|
return [] unless directive.selectable?
|
|
42
45
|
|
|
43
46
|
TableSaw::Connection.exec(
|
|
44
|
-
format(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
format(QUERY, primary_key: TableSaw.schema_cache.primary_keys(foreign_key.from_table),
|
|
48
|
+
table: foreign_key.from_table,
|
|
49
|
+
clause: TableSaw::Queries::SerializeSqlInClause.new(foreign_key.from_table,
|
|
50
|
+
foreign_key.column.primary_key,
|
|
51
|
+
directive.ids).call,
|
|
52
|
+
polymorphic: foreign_key.type_condition)
|
|
49
53
|
)
|
|
50
54
|
end
|
|
55
|
+
# rubocop:enable Metrics/AbcSize
|
|
51
56
|
end
|
|
52
57
|
end
|
|
53
58
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TableSaw
|
|
4
|
+
class ForeignKey
|
|
5
|
+
class Column
|
|
6
|
+
REGEX = /(\w+)(?::(\w+)\((\w+)\))?/.freeze
|
|
7
|
+
|
|
8
|
+
attr_reader :value
|
|
9
|
+
|
|
10
|
+
def initialize(value)
|
|
11
|
+
@value = value
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def primary_key
|
|
15
|
+
value[REGEX, 1]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def type_condition
|
|
19
|
+
polymorphic? ? "#{type_column} = '#{type_value}'" : '1 = 1'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def type_column
|
|
25
|
+
value[REGEX, 2]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def type_value
|
|
29
|
+
value[REGEX, 3]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def polymorphic?
|
|
33
|
+
!(type_column.nil? || type_value.nil?)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
attr_reader :name, :from_table, :from_column, :to_table, :to_column
|
|
38
|
+
|
|
39
|
+
def initialize(name: nil, from_table:, from_column:, to_table:, to_column:)
|
|
40
|
+
@name = name
|
|
41
|
+
@from_table = from_table
|
|
42
|
+
@from_column = from_column
|
|
43
|
+
@to_table = to_table
|
|
44
|
+
@to_column = to_column
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def type_condition
|
|
48
|
+
@type_condition ||= column.type_condition
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def column
|
|
52
|
+
@column ||= Column.new(from_column)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def eql?(other)
|
|
56
|
+
hash == other.hash
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def hash
|
|
60
|
+
[from_table, from_column, to_table, to_column].hash
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -2,14 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
module TableSaw
|
|
4
4
|
class InformationSchema
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
foreign_key_relationships.public_send method_name
|
|
8
|
-
end
|
|
5
|
+
def constraint_names
|
|
6
|
+
foreign_key_relationships.constraint_names
|
|
9
7
|
end
|
|
10
8
|
|
|
11
|
-
private
|
|
12
|
-
|
|
13
9
|
def foreign_key_relationships
|
|
14
10
|
@foreign_key_relationships ||= TableSaw::Queries::ForeignKeyRelationships.new
|
|
15
11
|
end
|
data/lib/table_saw/manifest.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'yaml'
|
|
4
|
+
require 'table_saw/associations'
|
|
4
5
|
|
|
5
6
|
module TableSaw
|
|
6
7
|
class Manifest
|
|
@@ -58,5 +59,13 @@ module TableSaw
|
|
|
58
59
|
def has_many
|
|
59
60
|
@has_many ||= config.fetch('has_many', {})
|
|
60
61
|
end
|
|
62
|
+
|
|
63
|
+
def foreign_keys
|
|
64
|
+
@foreign_keys ||= config.fetch('foreign_keys', [])
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def associations
|
|
68
|
+
@associations ||= TableSaw::Associations.new(self)
|
|
69
|
+
end
|
|
61
70
|
end
|
|
62
71
|
end
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'table_saw/foreign_key'
|
|
4
|
+
require 'set'
|
|
5
|
+
|
|
3
6
|
module TableSaw
|
|
4
7
|
module Queries
|
|
5
8
|
class ForeignKeyRelationships
|
|
@@ -16,24 +19,20 @@ module TableSaw
|
|
|
16
19
|
where tc.constraint_type = 'FOREIGN KEY'
|
|
17
20
|
SQL
|
|
18
21
|
|
|
19
|
-
def belongs_to
|
|
20
|
-
@belongs_to ||= result.each_with_object(Hash.new { |h, k| h[k] = {} }) do |row, memo|
|
|
21
|
-
memo[row['from_table']][row['from_column']] = row['to_table']
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def has_many
|
|
26
|
-
@has_many ||= result.each_with_object(Hash.new { |h, k| h[k] = [] }) do |row, memo|
|
|
27
|
-
memo[row['to_table']].push([row['from_table'], row['from_column']])
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
22
|
def constraint_names
|
|
32
23
|
@constraint_names ||= result.each_with_object(Hash.new { |h, k| h[k] = [] }) do |row, memo|
|
|
33
24
|
memo[row['from_table']].push(row['constraint_name'])
|
|
34
25
|
end
|
|
35
26
|
end
|
|
36
27
|
|
|
28
|
+
def foreign_keys
|
|
29
|
+
@foreign_keys ||= result.map do |row|
|
|
30
|
+
TableSaw::ForeignKey.new(name: row['constraint_name'],
|
|
31
|
+
from_table: row['from_table'], from_column: row['from_column'],
|
|
32
|
+
to_table: row['to_table'], to_column: row['to_column'])
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
37
36
|
private
|
|
38
37
|
|
|
39
38
|
def result
|
data/lib/table_saw/version.rb
CHANGED
data/table_saw.gemspec
CHANGED
|
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
|
31
31
|
spec.add_development_dependency 'combustion', '~> 1.1'
|
|
32
32
|
spec.add_development_dependency 'database_cleaner', '~> 1.7'
|
|
33
33
|
spec.add_development_dependency 'pry'
|
|
34
|
-
spec.add_development_dependency 'rake', '~>
|
|
34
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
|
35
35
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
36
36
|
spec.add_development_dependency 'rubocop-rspec', '~> 1.33'
|
|
37
37
|
spec.add_development_dependency 'scenic', '~> 1.5'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: table_saw
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Hamed Asghari
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-05-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -114,14 +114,14 @@ dependencies:
|
|
|
114
114
|
requirements:
|
|
115
115
|
- - "~>"
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: '
|
|
117
|
+
version: '13.0'
|
|
118
118
|
type: :development
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
121
|
requirements:
|
|
122
122
|
- - "~>"
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: '
|
|
124
|
+
version: '13.0'
|
|
125
125
|
- !ruby/object:Gem::Dependency
|
|
126
126
|
name: rspec
|
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -186,12 +186,12 @@ executables:
|
|
|
186
186
|
extensions: []
|
|
187
187
|
extra_rdoc_files: []
|
|
188
188
|
files:
|
|
189
|
+
- ".github/workflows/ruby.yml"
|
|
189
190
|
- ".gitignore"
|
|
190
191
|
- ".rspec"
|
|
191
192
|
- ".rubocop.yml"
|
|
192
193
|
- ".ruby-gemset"
|
|
193
194
|
- ".ruby-version"
|
|
194
|
-
- ".travis.yml"
|
|
195
195
|
- CODE_OF_CONDUCT.md
|
|
196
196
|
- Gemfile
|
|
197
197
|
- Gemfile.lock
|
|
@@ -202,6 +202,7 @@ files:
|
|
|
202
202
|
- bin/setup
|
|
203
203
|
- exe/table-saw
|
|
204
204
|
- lib/table_saw.rb
|
|
205
|
+
- lib/table_saw/associations.rb
|
|
205
206
|
- lib/table_saw/configuration.rb
|
|
206
207
|
- lib/table_saw/connection.rb
|
|
207
208
|
- lib/table_saw/create_dump_file.rb
|
|
@@ -211,6 +212,7 @@ files:
|
|
|
211
212
|
- lib/table_saw/dependency_graph/build.rb
|
|
212
213
|
- lib/table_saw/dependency_graph/dump_table.rb
|
|
213
214
|
- lib/table_saw/dependency_graph/has_many_directives.rb
|
|
215
|
+
- lib/table_saw/foreign_key.rb
|
|
214
216
|
- lib/table_saw/formats.rb
|
|
215
217
|
- lib/table_saw/formats/base.rb
|
|
216
218
|
- lib/table_saw/formats/copy.rb
|
|
@@ -245,7 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
245
247
|
- !ruby/object:Gem::Version
|
|
246
248
|
version: '0'
|
|
247
249
|
requirements: []
|
|
248
|
-
rubygems_version: 3.0.
|
|
250
|
+
rubygems_version: 3.0.3
|
|
249
251
|
signing_key:
|
|
250
252
|
specification_version: 4
|
|
251
253
|
summary: Create a postgres dump file from a subset of tables
|
data/.travis.yml
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
sudo: false
|
|
3
|
-
env:
|
|
4
|
-
global:
|
|
5
|
-
- CC_TEST_REPORTER_ID=5432d4e95a7749f237cf9e659c44ba28c5c91fa65436b15c5bc849d6d9ebc049
|
|
6
|
-
language: ruby
|
|
7
|
-
cache: bundler
|
|
8
|
-
rvm:
|
|
9
|
-
- 2.5.5
|
|
10
|
-
- 2.6.5
|
|
11
|
-
- 2.7.0
|
|
12
|
-
before_install: gem install bundler -v 2.0.1
|
|
13
|
-
before_script:
|
|
14
|
-
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
|
15
|
-
- chmod +x ./cc-test-reporter
|
|
16
|
-
- ./cc-test-reporter before-build
|
|
17
|
-
script:
|
|
18
|
-
- bundle exec rspec
|
|
19
|
-
after_script:
|
|
20
|
-
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
|
21
|
-
addons:
|
|
22
|
-
postgresql: "9.6"
|
|
23
|
-
services:
|
|
24
|
-
- postgresql
|