table_saw 2.9.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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