table_saw 2.9.0 → 3.0.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.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- table_saw (2.9.0)
4
+ table_saw (3.0.0)
5
5
  activerecord (>= 5.2)
6
6
  pg
7
7
  thor
@@ -9,127 +9,139 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- actionpack (6.1.0)
13
- actionview (= 6.1.0)
14
- activesupport (= 6.1.0)
12
+ actionpack (6.1.7.3)
13
+ actionview (= 6.1.7.3)
14
+ activesupport (= 6.1.7.3)
15
15
  rack (~> 2.0, >= 2.0.9)
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.1.0)
20
- activesupport (= 6.1.0)
19
+ actionview (6.1.7.3)
20
+ activesupport (= 6.1.7.3)
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.1.0)
26
- activesupport (= 6.1.0)
27
- activerecord (6.1.0)
28
- activemodel (= 6.1.0)
29
- activesupport (= 6.1.0)
30
- activesupport (6.1.0)
25
+ activemodel (6.1.7.3)
26
+ activesupport (= 6.1.7.3)
27
+ activerecord (6.1.7.3)
28
+ activemodel (= 6.1.7.3)
29
+ activesupport (= 6.1.7.3)
30
+ activesupport (6.1.7.3)
31
31
  concurrent-ruby (~> 1.0, >= 1.0.2)
32
32
  i18n (>= 1.6, < 2)
33
33
  minitest (>= 5.1)
34
34
  tzinfo (~> 2.0)
35
35
  zeitwerk (~> 2.3)
36
- appraisal (2.3.0)
36
+ appraisal (2.4.1)
37
37
  bundler
38
38
  rake
39
39
  thor (>= 0.14.0)
40
- ast (2.4.1)
40
+ ast (2.4.2)
41
41
  builder (3.2.4)
42
42
  coderay (1.1.3)
43
- combustion (1.3.1)
43
+ combustion (1.3.7)
44
44
  activesupport (>= 3.0.0)
45
45
  railties (>= 3.0.0)
46
46
  thor (>= 0.14.6)
47
- concurrent-ruby (1.1.7)
47
+ concurrent-ruby (1.2.2)
48
48
  crass (1.0.6)
49
- database_cleaner (1.8.5)
50
- diff-lcs (1.4.4)
51
- docile (1.3.4)
52
- erubi (1.10.0)
53
- i18n (1.8.5)
49
+ database_cleaner (2.0.2)
50
+ database_cleaner-active_record (>= 2, < 3)
51
+ database_cleaner-active_record (2.1.0)
52
+ activerecord (>= 5.a)
53
+ database_cleaner-core (~> 2.0.0)
54
+ database_cleaner-core (2.0.1)
55
+ diff-lcs (1.5.0)
56
+ docile (1.4.0)
57
+ erubi (1.12.0)
58
+ i18n (1.13.0)
54
59
  concurrent-ruby (~> 1.0)
55
- loofah (2.8.0)
60
+ json (2.6.3)
61
+ loofah (2.21.3)
56
62
  crass (~> 1.0.2)
57
- nokogiri (>= 1.5.9)
63
+ nokogiri (>= 1.12.0)
58
64
  method_source (1.0.0)
59
- mini_portile2 (2.4.0)
60
- minitest (5.14.2)
61
- nokogiri (1.10.10)
62
- mini_portile2 (~> 2.4.0)
63
- parallel (1.20.1)
64
- parser (3.0.0.0)
65
+ minitest (5.18.0)
66
+ nokogiri (1.15.2-x86_64-darwin)
67
+ racc (~> 1.4)
68
+ parallel (1.23.0)
69
+ parser (3.2.2.1)
65
70
  ast (~> 2.4.1)
66
- pg (1.2.3)
67
- pry (0.13.1)
71
+ pg (1.5.3)
72
+ pry (0.14.2)
68
73
  coderay (~> 1.1)
69
74
  method_source (~> 1.0)
70
- rack (2.2.3)
71
- rack-test (1.1.0)
72
- rack (>= 1.0, < 3)
75
+ racc (1.6.2)
76
+ rack (2.2.7)
77
+ rack-test (2.1.0)
78
+ rack (>= 1.3)
73
79
  rails-dom-testing (2.0.3)
74
80
  activesupport (>= 4.2.0)
75
81
  nokogiri (>= 1.6)
76
- rails-html-sanitizer (1.3.0)
77
- loofah (~> 2.3)
78
- railties (6.1.0)
79
- actionpack (= 6.1.0)
80
- activesupport (= 6.1.0)
82
+ rails-html-sanitizer (1.5.0)
83
+ loofah (~> 2.19, >= 2.19.1)
84
+ railties (6.1.7.3)
85
+ actionpack (= 6.1.7.3)
86
+ activesupport (= 6.1.7.3)
81
87
  method_source
82
- rake (>= 0.8.7)
88
+ rake (>= 12.2)
83
89
  thor (~> 1.0)
84
- rainbow (3.0.0)
90
+ rainbow (3.1.1)
85
91
  rake (13.0.3)
86
- regexp_parser (2.0.3)
87
- rexml (3.2.4)
88
- rspec (3.10.0)
89
- rspec-core (~> 3.10.0)
90
- rspec-expectations (~> 3.10.0)
91
- rspec-mocks (~> 3.10.0)
92
- rspec-core (3.10.1)
93
- rspec-support (~> 3.10.0)
94
- rspec-expectations (3.10.1)
92
+ regexp_parser (2.8.0)
93
+ rexml (3.2.5)
94
+ rspec (3.12.0)
95
+ rspec-core (~> 3.12.0)
96
+ rspec-expectations (~> 3.12.0)
97
+ rspec-mocks (~> 3.12.0)
98
+ rspec-core (3.12.2)
99
+ rspec-support (~> 3.12.0)
100
+ rspec-expectations (3.12.3)
95
101
  diff-lcs (>= 1.2.0, < 2.0)
96
- rspec-support (~> 3.10.0)
97
- rspec-mocks (3.10.1)
102
+ rspec-support (~> 3.12.0)
103
+ rspec-mocks (3.12.5)
98
104
  diff-lcs (>= 1.2.0, < 2.0)
99
- rspec-support (~> 3.10.0)
100
- rspec-support (3.10.1)
101
- rubocop (0.93.1)
105
+ rspec-support (~> 3.12.0)
106
+ rspec-support (3.12.0)
107
+ rubocop (1.51.0)
108
+ json (~> 2.3)
102
109
  parallel (~> 1.10)
103
- parser (>= 2.7.1.5)
110
+ parser (>= 3.2.0.0)
104
111
  rainbow (>= 2.2.2, < 4.0)
105
- regexp_parser (>= 1.8)
106
- rexml
107
- rubocop-ast (>= 0.6.0)
112
+ regexp_parser (>= 1.8, < 3.0)
113
+ rexml (>= 3.2.5, < 4.0)
114
+ rubocop-ast (>= 1.28.0, < 2.0)
108
115
  ruby-progressbar (~> 1.7)
109
- unicode-display_width (>= 1.4.0, < 2.0)
110
- rubocop-ast (1.3.0)
111
- parser (>= 2.7.1.5)
112
- rubocop-rspec (1.44.1)
113
- rubocop (~> 0.87)
114
- rubocop-ast (>= 0.7.1)
115
- ruby-progressbar (1.11.0)
116
- scenic (1.5.4)
116
+ unicode-display_width (>= 2.4.0, < 3.0)
117
+ rubocop-ast (1.28.1)
118
+ parser (>= 3.2.1.0)
119
+ rubocop-capybara (2.18.0)
120
+ rubocop (~> 1.41)
121
+ rubocop-factory_bot (2.23.1)
122
+ rubocop (~> 1.33)
123
+ rubocop-rspec (2.22.0)
124
+ rubocop (~> 1.33)
125
+ rubocop-capybara (~> 2.17)
126
+ rubocop-factory_bot (~> 2.22)
127
+ ruby-progressbar (1.13.0)
128
+ scenic (1.7.0)
117
129
  activerecord (>= 4.0.0)
118
130
  railties (>= 4.0.0)
119
- simplecov (0.20.0)
131
+ simplecov (0.22.0)
120
132
  docile (~> 1.1)
121
133
  simplecov-html (~> 0.11)
122
134
  simplecov_json_formatter (~> 0.1)
123
135
  simplecov-html (0.12.3)
124
- simplecov_json_formatter (0.1.2)
125
- thor (1.0.1)
126
- tzinfo (2.0.4)
136
+ simplecov_json_formatter (0.1.4)
137
+ thor (1.2.2)
138
+ tzinfo (2.0.6)
127
139
  concurrent-ruby (~> 1.0)
128
- unicode-display_width (1.7.0)
129
- zeitwerk (2.4.2)
140
+ unicode-display_width (2.4.2)
141
+ zeitwerk (2.6.8)
130
142
 
131
143
  PLATFORMS
132
- x86_64-darwin-20
144
+ x86_64-darwin-22
133
145
  x86_64-linux
134
146
 
135
147
  DEPENDENCIES
@@ -137,14 +149,14 @@ DEPENDENCIES
137
149
  appraisal
138
150
  bundler (~> 2.0)
139
151
  combustion (~> 1.3)
140
- database_cleaner (~> 1.7)
152
+ database_cleaner (~> 2)
141
153
  pry
142
- rake (~> 13.0)
154
+ rake (= 13.0.3)
143
155
  rspec (~> 3.0)
144
- rubocop-rspec (~> 1.33)
156
+ rubocop-rspec (~> 2.3)
145
157
  scenic (~> 1.5)
146
158
  simplecov (~> 0.16)
147
159
  table_saw!
148
160
 
149
161
  BUNDLED WITH
150
- 2.2.3
162
+ 2.4.13
@@ -0,0 +1,17 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "bundler", "~> 2.0"
7
+ gem "combustion", "~> 1.3"
8
+ gem "database_cleaner", "~> 2"
9
+ gem "pry"
10
+ gem "rake", "13.0.3"
11
+ gem "rspec", "~> 3.0"
12
+ gem "rubocop-rspec", "~> 2.3"
13
+ gem "scenic", "~> 1.5"
14
+ gem "simplecov", "~> 0.16"
15
+ gem "activerecord", "~> 7.0", "< 7.1"
16
+
17
+ gemspec path: "../"
@@ -0,0 +1,162 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ table_saw (3.0.0)
5
+ activerecord (>= 5.2)
6
+ pg
7
+ thor
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ actionpack (7.0.5)
13
+ actionview (= 7.0.5)
14
+ activesupport (= 7.0.5)
15
+ rack (~> 2.0, >= 2.2.4)
16
+ rack-test (>= 0.6.3)
17
+ rails-dom-testing (~> 2.0)
18
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
19
+ actionview (7.0.5)
20
+ activesupport (= 7.0.5)
21
+ builder (~> 3.1)
22
+ erubi (~> 1.4)
23
+ rails-dom-testing (~> 2.0)
24
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
25
+ activemodel (7.0.5)
26
+ activesupport (= 7.0.5)
27
+ activerecord (7.0.5)
28
+ activemodel (= 7.0.5)
29
+ activesupport (= 7.0.5)
30
+ activesupport (7.0.5)
31
+ concurrent-ruby (~> 1.0, >= 1.0.2)
32
+ i18n (>= 1.6, < 2)
33
+ minitest (>= 5.1)
34
+ tzinfo (~> 2.0)
35
+ appraisal (2.4.1)
36
+ bundler
37
+ rake
38
+ thor (>= 0.14.0)
39
+ ast (2.4.2)
40
+ builder (3.2.4)
41
+ coderay (1.1.3)
42
+ combustion (1.3.7)
43
+ activesupport (>= 3.0.0)
44
+ railties (>= 3.0.0)
45
+ thor (>= 0.14.6)
46
+ concurrent-ruby (1.2.2)
47
+ crass (1.0.6)
48
+ database_cleaner (2.0.2)
49
+ database_cleaner-active_record (>= 2, < 3)
50
+ database_cleaner-active_record (2.1.0)
51
+ activerecord (>= 5.a)
52
+ database_cleaner-core (~> 2.0.0)
53
+ database_cleaner-core (2.0.1)
54
+ diff-lcs (1.5.0)
55
+ docile (1.4.0)
56
+ erubi (1.12.0)
57
+ i18n (1.13.0)
58
+ concurrent-ruby (~> 1.0)
59
+ json (2.6.3)
60
+ loofah (2.21.3)
61
+ crass (~> 1.0.2)
62
+ nokogiri (>= 1.12.0)
63
+ method_source (1.0.0)
64
+ minitest (5.18.0)
65
+ nokogiri (1.15.2-x86_64-darwin)
66
+ racc (~> 1.4)
67
+ parallel (1.23.0)
68
+ parser (3.2.2.1)
69
+ ast (~> 2.4.1)
70
+ pg (1.5.3)
71
+ pry (0.14.2)
72
+ coderay (~> 1.1)
73
+ method_source (~> 1.0)
74
+ racc (1.6.2)
75
+ rack (2.2.7)
76
+ rack-test (2.1.0)
77
+ rack (>= 1.3)
78
+ rails-dom-testing (2.0.3)
79
+ activesupport (>= 4.2.0)
80
+ nokogiri (>= 1.6)
81
+ rails-html-sanitizer (1.5.0)
82
+ loofah (~> 2.19, >= 2.19.1)
83
+ railties (7.0.5)
84
+ actionpack (= 7.0.5)
85
+ activesupport (= 7.0.5)
86
+ method_source
87
+ rake (>= 12.2)
88
+ thor (~> 1.0)
89
+ zeitwerk (~> 2.5)
90
+ rainbow (3.1.1)
91
+ rake (13.0.3)
92
+ regexp_parser (2.8.0)
93
+ rexml (3.2.5)
94
+ rspec (3.12.0)
95
+ rspec-core (~> 3.12.0)
96
+ rspec-expectations (~> 3.12.0)
97
+ rspec-mocks (~> 3.12.0)
98
+ rspec-core (3.12.2)
99
+ rspec-support (~> 3.12.0)
100
+ rspec-expectations (3.12.3)
101
+ diff-lcs (>= 1.2.0, < 2.0)
102
+ rspec-support (~> 3.12.0)
103
+ rspec-mocks (3.12.5)
104
+ diff-lcs (>= 1.2.0, < 2.0)
105
+ rspec-support (~> 3.12.0)
106
+ rspec-support (3.12.0)
107
+ rubocop (1.51.0)
108
+ json (~> 2.3)
109
+ parallel (~> 1.10)
110
+ parser (>= 3.2.0.0)
111
+ rainbow (>= 2.2.2, < 4.0)
112
+ regexp_parser (>= 1.8, < 3.0)
113
+ rexml (>= 3.2.5, < 4.0)
114
+ rubocop-ast (>= 1.28.0, < 2.0)
115
+ ruby-progressbar (~> 1.7)
116
+ unicode-display_width (>= 2.4.0, < 3.0)
117
+ rubocop-ast (1.28.1)
118
+ parser (>= 3.2.1.0)
119
+ rubocop-capybara (2.18.0)
120
+ rubocop (~> 1.41)
121
+ rubocop-factory_bot (2.23.1)
122
+ rubocop (~> 1.33)
123
+ rubocop-rspec (2.22.0)
124
+ rubocop (~> 1.33)
125
+ rubocop-capybara (~> 2.17)
126
+ rubocop-factory_bot (~> 2.22)
127
+ ruby-progressbar (1.13.0)
128
+ scenic (1.7.0)
129
+ activerecord (>= 4.0.0)
130
+ railties (>= 4.0.0)
131
+ simplecov (0.22.0)
132
+ docile (~> 1.1)
133
+ simplecov-html (~> 0.11)
134
+ simplecov_json_formatter (~> 0.1)
135
+ simplecov-html (0.12.3)
136
+ simplecov_json_formatter (0.1.4)
137
+ thor (1.2.2)
138
+ tzinfo (2.0.6)
139
+ concurrent-ruby (~> 1.0)
140
+ unicode-display_width (2.4.2)
141
+ zeitwerk (2.6.8)
142
+
143
+ PLATFORMS
144
+ x86_64-darwin-22
145
+ x86_64-linux
146
+
147
+ DEPENDENCIES
148
+ activerecord (~> 7.0, < 7.1)
149
+ appraisal
150
+ bundler (~> 2.0)
151
+ combustion (~> 1.3)
152
+ database_cleaner (~> 2)
153
+ pry
154
+ rake (= 13.0.3)
155
+ rspec (~> 3.0)
156
+ rubocop-rspec (~> 2.3)
157
+ scenic (~> 1.5)
158
+ simplecov (~> 0.16)
159
+ table_saw!
160
+
161
+ BUNDLED WITH
162
+ 2.4.13
@@ -19,7 +19,7 @@ module TableSaw
19
19
 
20
20
  # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
21
21
  def call
22
- File.delete(file) if File.exist?(file)
22
+ FileUtils.rm_f(file)
23
23
  FileUtils.mkdir_p(File.dirname(file))
24
24
 
25
25
  alter_constraints_deferrability
@@ -6,7 +6,7 @@ module TableSaw
6
6
  attr_reader :table_name, :partial, :has_many
7
7
  attr_accessor :ids
8
8
 
9
- def initialize(table_name, ids: [], partial: true, has_many: [])
9
+ def initialize(table_name, ids: [], partial: true, has_many: {})
10
10
  @table_name = table_name
11
11
  @ids = ids
12
12
  @partial = partial
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableSaw
4
+ module DependencyGraph
5
+ class BuildHasManyQuery
6
+ QUERY = <<~SQL.squish
7
+ select %{primary_key} from %{table} where %{clause} and %{polymorphic}
8
+ SQL
9
+
10
+ attr_reader :manifest, :directive, :foreign_key
11
+
12
+ def initialize(manifest, directive, foreign_key)
13
+ @manifest = manifest
14
+ @directive = directive
15
+ @foreign_key = foreign_key
16
+ end
17
+
18
+ def call
19
+ build_base_query
20
+ .then { |query| append_scope(query) }
21
+ .then { |query| append_limit(query) }
22
+ end
23
+
24
+ private
25
+
26
+ # rubocop:disable Metrics/AbcSize
27
+ def build_base_query
28
+ format(QUERY, primary_key: TableSaw.schema_cache.primary_keys(foreign_key.from_table),
29
+ table: foreign_key.from_table,
30
+ clause: TableSaw::Queries::SerializeSqlInClause.new(foreign_key.from_table,
31
+ foreign_key.column.primary_key,
32
+ directive.ids).call,
33
+ polymorphic: foreign_key.type_condition)
34
+ end
35
+ # rubocop:enable Metrics/AbcSize
36
+
37
+ def append_scope(query)
38
+ return query unless has_many&.scope
39
+
40
+ [query, has_many.scope].join(' and ')
41
+ end
42
+
43
+ def append_limit(query)
44
+ return query unless has_many&.limit
45
+
46
+ [query, "limit #{has_many.limit}"].join(' ')
47
+ end
48
+
49
+ def has_many
50
+ directive.has_many[foreign_key.from_table] ||
51
+ manifest.has_many.fetch(directive.table_name, {})[foreign_key.from_table]
52
+ end
53
+ end
54
+ end
55
+ end
@@ -3,10 +3,6 @@
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
-
10
6
  attr_reader :manifest, :directive
11
7
 
12
8
  def initialize(manifest, directive)
@@ -34,25 +30,20 @@ module TableSaw
34
30
  def valid_associations
35
31
  associations.select do |fk|
36
32
  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)
33
+ next true if directive.has_many.key?(fk.from_table)
38
34
 
39
- manifest.has_many.fetch(directive.table_name, []).include?(fk.from_table)
35
+ manifest.has_many.fetch(directive.table_name, {}).key?(fk.from_table)
40
36
  end
41
37
  end
38
+ # rubocop:enable Metrics/AbcSize
42
39
 
43
40
  def query_result(foreign_key)
44
41
  return [] unless directive.selectable?
45
42
 
46
43
  TableSaw::Connection.exec(
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)
44
+ TableSaw::DependencyGraph::BuildHasManyQuery.new(manifest, directive, foreign_key).call
53
45
  )
54
46
  end
55
- # rubocop:enable Metrics/AbcSize
56
47
  end
57
48
  end
58
49
  end
@@ -3,5 +3,6 @@
3
3
  require 'table_saw/dependency_graph/add_directive'
4
4
  require 'table_saw/dependency_graph/belongs_to_directives'
5
5
  require 'table_saw/dependency_graph/build'
6
+ require 'table_saw/dependency_graph/build_has_many_query'
6
7
  require 'table_saw/dependency_graph/dump_table'
7
8
  require 'table_saw/dependency_graph/has_many_directives'
@@ -3,7 +3,7 @@
3
3
  module TableSaw
4
4
  class ForeignKey
5
5
  class Column
6
- REGEX = /(\w+)(?::(\w+)\((\w+)\))?/.freeze
6
+ REGEX = /(\w+)(?::(\w+)\((\w+)\))?/
7
7
 
8
8
  attr_reader :value
9
9
 
@@ -5,6 +5,35 @@ require 'table_saw/associations'
5
5
 
6
6
  module TableSaw
7
7
  class Manifest
8
+ class HasManyEntry
9
+ def self.build(config)
10
+ config.each_with_object({}) do |(table, options), memo|
11
+ case table
12
+ when String
13
+ memo[table] = new(table, options)
14
+ when Hash
15
+ table, options = table.first
16
+ memo[table] = new(table, options)
17
+ end
18
+ end
19
+ end
20
+
21
+ attr_reader :table, :options
22
+
23
+ def initialize(table, options)
24
+ @table = table
25
+ @options = options || {}
26
+ end
27
+
28
+ def scope
29
+ options['scope']
30
+ end
31
+
32
+ def limit
33
+ options['limit']
34
+ end
35
+ end
36
+
8
37
  class Table
9
38
  attr_reader :variables, :config
10
39
 
@@ -30,7 +59,7 @@ module TableSaw
30
59
  end
31
60
 
32
61
  def has_many
33
- config.fetch('has_many', [])
62
+ config.fetch('has_many', {}).then { |config| HasManyEntry.build(config) }
34
63
  end
35
64
  end
36
65
 
@@ -48,7 +77,7 @@ module TableSaw
48
77
 
49
78
  def variables
50
79
  vars = config.fetch('variables', {})
51
- vars.merge(TableSaw.configuration.variables.slice(*vars.keys))
80
+ VariableInterpolation.call(vars.merge(TableSaw.configuration.variables.slice(*vars.keys)))
52
81
  end
53
82
 
54
83
  def tables
@@ -58,7 +87,9 @@ module TableSaw
58
87
  end
59
88
 
60
89
  def has_many
61
- @has_many ||= config.fetch('has_many', {})
90
+ @has_many ||= config.fetch('has_many', {}).transform_values do |value|
91
+ HasManyEntry.build(value)
92
+ end
62
93
  end
63
94
 
64
95
  def foreign_keys
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TableSaw
4
+ class VariableInterpolation
5
+ def self.call(variables)
6
+ new(variables).call
7
+ end
8
+
9
+ attr_reader :input
10
+
11
+ def initialize(input)
12
+ @input = input
13
+ end
14
+
15
+ def call
16
+ input.transform_values do |value|
17
+ next value unless value.is_a?(String)
18
+
19
+ interpolate_variables(value, input)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def interpolate_variables(string, variables)
26
+ string.gsub(/%{(\w+)}/) do |match|
27
+ variable_name = ::Regexp.last_match(1)
28
+ if variables.key?(variable_name)
29
+ nested_value = interpolate_variables(variables[variable_name], variables)
30
+ interpolate_variables(nested_value, variables)
31
+ else
32
+ match
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TableSaw
4
- VERSION = '2.9.0'
4
+ VERSION = '3.0.0'
5
5
  end
data/lib/table_saw.rb CHANGED
@@ -7,6 +7,7 @@ require 'table_saw/information_schema'
7
7
  require 'table_saw/manifest'
8
8
  require 'table_saw/queries'
9
9
  require 'table_saw/formats'
10
+ require 'table_saw/variable_interpolation'
10
11
 
11
12
  module TableSaw
12
13
  def self.configuration