sneaql 0.0.13-java → 0.0.15-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/sneaql +0 -1
- data/lib/sneaql.rb +28 -8
- data/lib/sneaql_lib/base.rb +15 -2
- data/lib/sneaql_lib/core.rb +126 -1
- data/lib/sneaql_lib/database_manager.rb +8 -8
- data/lib/sneaql_lib/database_prefs/redshift.rb +5 -6
- data/lib/sneaql_lib/database_prefs/sqlite.rb +2 -2
- data/lib/sneaql_lib/database_prefs/vertica.rb +4 -4
- data/lib/sneaql_lib/docker.rb +9 -9
- data/lib/sneaql_lib/exceptions.rb +36 -16
- data/lib/sneaql_lib/expressions.rb +85 -34
- data/lib/sneaql_lib/lock_manager.rb +7 -7
- data/lib/sneaql_lib/parser.rb +10 -3
- data/lib/sneaql_lib/repo_manager.rb +2 -3
- data/lib/sneaql_lib/standard_db_objects.rb +8 -8
- data/lib/sneaql_lib/step_manager.rb +35 -21
- data/lib/sneaql_lib/tokenizer.rb +183 -0
- metadata +7 -6
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'logger'
|
2
|
+
require 'time'
|
2
3
|
|
3
4
|
module Sneaql
|
4
5
|
module Core
|
@@ -21,7 +22,7 @@ module Sneaql
|
|
21
22
|
# @param [String, Fixnum, Float] var_value value to store, expressions here will not be evaluated
|
22
23
|
def set_session_variable(var_name, var_value)
|
23
24
|
@logger.info("setting session var #{var_name} to #{var_value}")
|
24
|
-
raise "can't set
|
25
|
+
raise "can't set variable #{var_name}" unless valid_session_variable_name?(var_name)
|
25
26
|
@session_variables[var_name] = var_value
|
26
27
|
end
|
27
28
|
|
@@ -29,8 +30,8 @@ module Sneaql
|
|
29
30
|
# @param [String] var_name
|
30
31
|
# @return [Boolean]
|
31
32
|
def valid_session_variable_name?(var_name)
|
32
|
-
r =
|
33
|
-
@logger.debug
|
33
|
+
r = var_name.to_s.match(/^\w+$/) && !var_name.to_s.match(/env\_\w*/) && !var_name.to_s.match(/^\d+/) ? true : false
|
34
|
+
@logger.debug("validating #{var_name} as valid variable identifier indicates #{r}")
|
34
35
|
r
|
35
36
|
end
|
36
37
|
|
@@ -57,21 +58,25 @@ module Sneaql
|
|
57
58
|
def evaluate_expression(expression)
|
58
59
|
return expression unless expression.class == String
|
59
60
|
|
61
|
+
# first handle empty string
|
62
|
+
if expression == "''"
|
63
|
+
return ''
|
64
|
+
|
60
65
|
# reference to an environment variable
|
61
66
|
# :env_var_name or :ENV_var_name
|
62
67
|
# env variable references are case insensitive in this case
|
63
|
-
|
68
|
+
elsif expression =~ /^\:env\_\w+/i
|
64
69
|
return @environment_variables[expression.gsub(/\:env\_/i, '').strip]
|
65
70
|
|
66
71
|
# reference to a variable
|
67
72
|
# ANSI dynamic SQL :var_name
|
68
73
|
# variable names are case sensitive
|
69
|
-
elsif expression =~
|
74
|
+
elsif expression =~ /^\:\w+/
|
70
75
|
return @session_variables[expression.gsub(/\:/, '').strip]
|
71
76
|
|
72
77
|
# deprecated
|
73
|
-
elsif expression =~
|
74
|
-
@logger.warn
|
78
|
+
elsif expression =~ /^\{.*\}$/
|
79
|
+
@logger.warn('{var_name} deprecated. use dynamic SQL syntax :var_name')
|
75
80
|
return @session_variables[expression.gsub(/\{|\}/, '').strip]
|
76
81
|
|
77
82
|
# boolean
|
@@ -81,9 +86,9 @@ module Sneaql
|
|
81
86
|
return false if expression.downcase == 'false'
|
82
87
|
|
83
88
|
# string literal enclosed in single quotes
|
84
|
-
|
85
|
-
elsif expression
|
86
|
-
return expression.
|
89
|
+
|
90
|
+
elsif expression.match(/^\s*\'.*\'\s*$/)
|
91
|
+
return expression.strip[1..expression.strip.length - 2]
|
87
92
|
|
88
93
|
# else assume it is a numeric literal
|
89
94
|
# need some better thinking here
|
@@ -92,7 +97,7 @@ module Sneaql
|
|
92
97
|
end
|
93
98
|
rescue => e
|
94
99
|
@logger.error("error evaluating expression: #{e.message}")
|
95
|
-
e.backtrace.each { |b| logger.error(b.to_s) }
|
100
|
+
e.backtrace.each { |b| @logger.error(b.to_s) }
|
96
101
|
raise Sneaql::Exceptions::ExpressionEvaluationError
|
97
102
|
end
|
98
103
|
|
@@ -117,11 +122,13 @@ module Sneaql
|
|
117
122
|
# evaluates all environment variables in a given SQL statement.
|
118
123
|
# replaces...
|
119
124
|
# environment variables in the form :env_HOSTNAME
|
125
|
+
# variables are sorted and reversed before performing substitutions
|
126
|
+
# this prevents :var from partially overwriting :var_foo
|
120
127
|
# @param [String] statement SQL statement to have all environment variables evaluated
|
121
128
|
# @return [String] SQL statement with all variable references resolved
|
122
129
|
def evaluate_session_variables(statement)
|
123
130
|
# replaces :var_name in provided statement
|
124
|
-
@session_variables.keys.each do |k|
|
131
|
+
@session_variables.keys.sort.reverse.each do |k|
|
125
132
|
statement.gsub!(/\:#{k}/, @session_variables[k].to_s)
|
126
133
|
end
|
127
134
|
end
|
@@ -129,11 +136,13 @@ module Sneaql
|
|
129
136
|
# evaluates all session variables in a given SQL statement.
|
130
137
|
# replaces...
|
131
138
|
# session variables in the form :variable_name
|
139
|
+
# variables are sorted and reversed before performing substitutions
|
140
|
+
# this prevents :var from partially overwriting :var_foo
|
132
141
|
# @param [String] statement SQL statement to have all session variables evaluated
|
133
142
|
# @return [String] SQL statement with all variable references resolved
|
134
143
|
def evaluate_environment_variables(statement)
|
135
144
|
# replace env vars in the form :env_HOSTNAME
|
136
|
-
@environment_variables.keys.each do |e|
|
145
|
+
@environment_variables.keys.sort.reverse.each do |e|
|
137
146
|
statement.gsub!(/\:env\_#{e}/i, @environment_variables[e])
|
138
147
|
end
|
139
148
|
end
|
@@ -155,7 +164,7 @@ module Sneaql
|
|
155
164
|
# checks to see this is single quoted string, :variable_name, {var_name) or number (1, 1.031, etc.)
|
156
165
|
# @param [String] expr value to check
|
157
166
|
def valid_expression_reference?(expr)
|
158
|
-
|
167
|
+
expr.to_s.match(/(^\s*\'.+\'\s*$|^\:\w+$|^\{\w+\}$|^\d+$|^\d+\.\d*$|true|false)/i) ? true : false
|
159
168
|
end
|
160
169
|
|
161
170
|
# Operators valid for expression comparison
|
@@ -183,6 +192,7 @@ module Sneaql
|
|
183
192
|
exp1,
|
184
193
|
exp2
|
185
194
|
)
|
195
|
+
|
186
196
|
compare_values(operator, coerced[0], coerced[1])
|
187
197
|
end
|
188
198
|
|
@@ -195,16 +205,31 @@ module Sneaql
|
|
195
205
|
@logger.debug("coercing types #{[exp1.class, exp2.class]}")
|
196
206
|
if exp1.class == exp2.class
|
197
207
|
nil # nothing to do... continue with comparison
|
198
|
-
elsif
|
208
|
+
elsif array_has_boolean_value?([exp1, exp2])
|
209
|
+
# if one of the values is an actual Boolean object...
|
199
210
|
unless [coerce_boolean(exp1), coerce_boolean(exp2)].include?(nil)
|
200
211
|
exp1 = coerce_boolean(exp1)
|
201
212
|
exp2 = coerce_boolean(exp2)
|
202
213
|
end
|
203
|
-
elsif
|
214
|
+
elsif exp1.class == Time
|
215
|
+
tmp = coerce_datetime(exp2)
|
216
|
+
if tmp
|
217
|
+
exp2 = tmp
|
218
|
+
else
|
219
|
+
exp1, exp2 = exp1.to_s, exp2.to_s
|
220
|
+
end
|
221
|
+
elsif exp2.class == Time
|
222
|
+
tmp = coerce_datetime(exp1)
|
223
|
+
if tmp
|
224
|
+
exp1 = tmp
|
225
|
+
else
|
226
|
+
exp1, exp2 = exp1.to_s, exp2.to_s
|
227
|
+
end
|
228
|
+
elsif [exp1.class, exp2.class].include?(Float)
|
204
229
|
# if either is a float then make sure they are both floats
|
205
230
|
exp1 = exp1.to_f
|
206
231
|
exp2 = exp2.to_f
|
207
|
-
elsif [exp1.class, exp2.class].include?
|
232
|
+
elsif [exp1.class, exp2.class].include?(Fixnum)
|
208
233
|
# otherwise... if one is an integer make them both integers
|
209
234
|
exp1 = exp1.to_i
|
210
235
|
exp2 = exp2.to_i
|
@@ -213,26 +238,52 @@ module Sneaql
|
|
213
238
|
[exp1, exp2]
|
214
239
|
end
|
215
240
|
|
241
|
+
def coerce_datetime(obj)
|
242
|
+
retobj = nil
|
243
|
+
case
|
244
|
+
when obj.class == Fixnum then retobj = Time.at(obj)
|
245
|
+
when obj.class == String then retobj = Time.parse(obj)
|
246
|
+
when obj.class == Time then retobj = obj
|
247
|
+
end
|
248
|
+
retobj
|
249
|
+
end
|
250
|
+
|
251
|
+
# checks to see if any element of the array has a boolean value
|
252
|
+
# @param [Array<Object>] arr array of objects
|
253
|
+
# @return [Boolean]
|
254
|
+
def array_has_boolean_value?(arr)
|
255
|
+
tmp = arr.map { |e| e.class }
|
256
|
+
# [exp1.class, exp2.class].include?(FalseClass) || [exp1.class, exp2.class].include?(TrueClass)
|
257
|
+
tmp.include?(FalseClass) || tmp.include?(TrueClass)
|
258
|
+
end
|
259
|
+
|
216
260
|
# evaluates string or fixnum values to coerce into boolean
|
217
261
|
# @param [Object] value
|
218
262
|
# @return [Object]
|
219
263
|
def coerce_boolean(value)
|
220
264
|
retval = nil
|
221
|
-
if
|
265
|
+
if array_has_boolean_value?([value])
|
222
266
|
retval = value
|
223
267
|
elsif value.class == Fixnum
|
224
268
|
retval = true if value == 1
|
225
|
-
retval = false if value
|
269
|
+
retval = false if value.zero?
|
226
270
|
elsif value.class == String
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
271
|
+
retval = text_to_boolean(value)
|
272
|
+
end
|
273
|
+
retval
|
274
|
+
end
|
275
|
+
|
276
|
+
# converts text representation of boolean to boolean
|
277
|
+
# @param [String] value
|
278
|
+
# @return [Boolean]
|
279
|
+
def text_to_boolean(value)
|
280
|
+
case value.downcase.strip
|
281
|
+
when 'f', 'false', '0'
|
282
|
+
retval = false
|
283
|
+
when 't', 'true', '1'
|
284
|
+
retval = true
|
234
285
|
end
|
235
|
-
|
286
|
+
retval
|
236
287
|
end
|
237
288
|
|
238
289
|
# performs the actual comparison between two values
|
@@ -260,15 +311,15 @@ module Sneaql
|
|
260
311
|
# @param [String] like_right_operand this will be the like expression
|
261
312
|
# @return [Boolean]
|
262
313
|
def like_operator(left_operand, like_right_operand)
|
263
|
-
#converts to string before comparison
|
264
|
-
|
314
|
+
# converts to string before comparison
|
315
|
+
left_operand.to_s.match(wildcard_to_regex(like_right_operand.to_s)) ? true : false
|
265
316
|
end
|
266
317
|
|
267
318
|
# converts a SQL LIKE wildcard expression to a Regexp
|
268
319
|
# @param [String] wildcard like expression
|
269
320
|
# @return [Regexp] returns regexp object for use in match comparison
|
270
321
|
def wildcard_to_regex(wildcard)
|
271
|
-
Regexp.new("^#{wildcard}$".gsub('%','.*').gsub('_','.'))
|
322
|
+
Regexp.new("^#{wildcard}$".gsub('%', '.*').gsub('_', '.'))
|
272
323
|
end
|
273
324
|
|
274
325
|
# create a hash built from supplied environment variables.
|
@@ -278,14 +329,14 @@ module Sneaql
|
|
278
329
|
def filtered_environment_variables
|
279
330
|
env_vars = {}
|
280
331
|
if ENV['SNEAQL_AVAILABLE_ENV_VARS']
|
281
|
-
@logger.debug(
|
332
|
+
@logger.debug('filtering environment variables')
|
282
333
|
available = ENV['SNEAQL_AVAILABLE_ENV_VARS'].split(',')
|
283
334
|
ENV.keys.each { |k| env_vars[k] = ENV[k] if available.include?(k) }
|
284
335
|
else
|
285
|
-
@logger.debug(
|
336
|
+
@logger.debug('setting environment variables')
|
286
337
|
ENV.keys.each { |k| env_vars[k] = ENV[k] }
|
287
338
|
end
|
288
|
-
|
339
|
+
env_vars
|
289
340
|
end
|
290
341
|
|
291
342
|
# basic regex filtering to help combat sql injection
|
@@ -294,7 +345,7 @@ module Sneaql
|
|
294
345
|
# @return [Boolean] returns true if value is safe
|
295
346
|
def sql_injection_filter(value)
|
296
347
|
return false if value.to_s.match(/(\'|\;|(drop|alter).*(table|user|view|column|database|schema|function|sequence|procedure))/i)
|
297
|
-
|
348
|
+
true
|
298
349
|
end
|
299
350
|
|
300
351
|
# insures that all environment variables pass SQL injection test
|
@@ -44,7 +44,7 @@ module Sneaql
|
|
44
44
|
lock_value = false
|
45
45
|
|
46
46
|
if @database_manager.supports_transactions == true
|
47
|
-
|
47
|
+
JDBCHelpers::Execute.new(
|
48
48
|
jdbc_connection,
|
49
49
|
@database_manager.begin_statement,
|
50
50
|
@logger
|
@@ -52,7 +52,7 @@ module Sneaql
|
|
52
52
|
end
|
53
53
|
|
54
54
|
if @database_manager.supports_table_locking == true
|
55
|
-
|
55
|
+
JDBCHelpers::Execute.new(
|
56
56
|
jdbc_connection,
|
57
57
|
@database_manager.lock_table_statement(@transform_lock_table),
|
58
58
|
@logger
|
@@ -94,7 +94,7 @@ module Sneaql
|
|
94
94
|
)
|
95
95
|
|
96
96
|
if @database_manager.supports_transactions == true
|
97
|
-
|
97
|
+
JDBCHelpers::Execute.new(
|
98
98
|
jdbc_connection,
|
99
99
|
@database_manager.commit_statement,
|
100
100
|
@logger
|
@@ -104,7 +104,7 @@ module Sneaql
|
|
104
104
|
lock_value = true
|
105
105
|
else
|
106
106
|
if @database_manager.supports_transactions == true
|
107
|
-
|
107
|
+
JDBCHelpers::Execute.new(
|
108
108
|
jdbc_connection,
|
109
109
|
@database_manager.rollback_statement,
|
110
110
|
@logger
|
@@ -132,7 +132,7 @@ module Sneaql
|
|
132
132
|
jdbc_connection = create_jdbc_connection
|
133
133
|
|
134
134
|
if @database_manager.supports_transactions == true
|
135
|
-
|
135
|
+
JDBCHelpers::Execute.new(
|
136
136
|
jdbc_connection,
|
137
137
|
@database_manager.begin_statement,
|
138
138
|
@logger
|
@@ -140,7 +140,7 @@ module Sneaql
|
|
140
140
|
end
|
141
141
|
|
142
142
|
if @database_manager.supports_table_locking == true
|
143
|
-
|
143
|
+
JDBCHelpers::Execute.new(
|
144
144
|
jdbc_connection,
|
145
145
|
@database_manager.lock_table_statement(@transform_lock_table),
|
146
146
|
@logger
|
@@ -163,7 +163,7 @@ module Sneaql
|
|
163
163
|
)
|
164
164
|
ensure
|
165
165
|
jdbc_connection.close
|
166
|
-
|
166
|
+
|
167
167
|
return true
|
168
168
|
end
|
169
169
|
|
data/lib/sneaql_lib/parser.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative 'tokenizer.rb'
|
2
|
+
|
1
3
|
module Sneaql
|
2
4
|
module Core
|
3
5
|
# Parses a step file into discrete statements.
|
@@ -10,7 +12,7 @@ module Sneaql
|
|
10
12
|
# @param [String] file_path pathname to step file
|
11
13
|
# @param [Sneaql::ExpressionHandler] expression_handler
|
12
14
|
# @param [Sneaql::RecordsetManager] recordset_manager
|
13
|
-
# @param [Logger] logger optional
|
15
|
+
# @param [Logger] logger optional, if omitted default logger will be used
|
14
16
|
def initialize(file_path, expression_handler, recordset_manager, logger = nil)
|
15
17
|
@logger = logger ? logger : Logger.new(STDOUT)
|
16
18
|
@expression_handler = expression_handler
|
@@ -39,12 +41,16 @@ module Sneaql
|
|
39
41
|
raise Sneaql::Exceptions::StatementParsingError
|
40
42
|
end
|
41
43
|
|
42
|
-
# Extracts
|
44
|
+
# Extracts array of tokens from tag
|
43
45
|
# @param [String] statement_text_with_command
|
44
46
|
# @return [Array]
|
45
47
|
def tag_splitter(statement_text_with_command)
|
48
|
+
# updated to use tokenizer
|
46
49
|
# splits out all the tag elements into an array
|
47
|
-
statement_text_with_command.split('-*/')[0].gsub('/*-', '').strip.split
|
50
|
+
# statement_text_with_command.split('-*/')[0].gsub('/*-', '').strip.split
|
51
|
+
command = statement_text_with_command.split('-*/')[0].gsub('/*-', '').strip
|
52
|
+
t = Sneaql::Core::Tokenizer.new
|
53
|
+
t.tokenize(command)
|
48
54
|
end
|
49
55
|
|
50
56
|
# Returns command tag from statement at specified index. Allows for
|
@@ -78,6 +84,7 @@ module Sneaql
|
|
78
84
|
c = Sneaql::Core.find_class(:command, this_cmd[:command]).new(
|
79
85
|
nil,
|
80
86
|
@expression_handler,
|
87
|
+
nil,
|
81
88
|
@recordset_manager,
|
82
89
|
nil,
|
83
90
|
@logger
|
@@ -6,7 +6,7 @@ require_relative 'base.rb'
|
|
6
6
|
module Sneaql
|
7
7
|
# Classes to manage repositories full of SneaQL code.
|
8
8
|
module RepoManagers
|
9
|
-
|
9
|
+
|
10
10
|
# tells you the repo type based upon the url
|
11
11
|
# either git or http
|
12
12
|
# @param [String] repo_url
|
@@ -14,8 +14,7 @@ module Sneaql
|
|
14
14
|
return 'git' if repo_url.match(/\.*git.*/i)
|
15
15
|
return 'http' if repo_url.match(/\.*http.*/i)
|
16
16
|
end
|
17
|
-
|
18
|
-
|
17
|
+
|
19
18
|
# pulls a branch from a remote git repo
|
20
19
|
class GitRepoManager < Sneaql::Core::RepoDownloadManager
|
21
20
|
Sneaql::Core::RegisterMappedClass.new(
|
@@ -39,19 +39,19 @@ module Sneaql
|
|
39
39
|
)
|
40
40
|
return true
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
# Coerces a boolean to the appropriate value for the database type.
|
44
44
|
# May return a 0 or 1 in RDBMS where boolean is not supported.
|
45
45
|
# @param [Boolean] boolean_value
|
46
46
|
# @return [Boolean, Fixnum]
|
47
47
|
def coerce_boolean(boolean_value)
|
48
|
-
if @database_manager.has_boolean
|
49
|
-
boolean_value
|
50
|
-
else
|
51
|
-
boolean_value == true ? 1 : 0
|
48
|
+
if @database_manager.has_boolean
|
49
|
+
boolean_value
|
50
|
+
else
|
51
|
+
boolean_value == true ? 1 : 0
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
# Create table statement for primary transform table.
|
56
56
|
# @param [String] transform_table_name fully qualified name for this table
|
57
57
|
# @return [String]
|
@@ -68,7 +68,7 @@ module Sneaql
|
|
68
68
|
,updated_ts timestamp
|
69
69
|
);}
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
# Creates a record in the transforms table.
|
73
73
|
# @param [String] transform_table_name
|
74
74
|
# @param [Hash] params Hash of parameters with symbols matching column names
|
@@ -106,7 +106,7 @@ module Sneaql
|
|
106
106
|
,current_timestamp
|
107
107
|
);}
|
108
108
|
end
|
109
|
-
|
109
|
+
|
110
110
|
# Drops and recreates the transform steps table.
|
111
111
|
# @param [String] transform_steps_table_name fully qualified name for this table
|
112
112
|
# @return [Boolean]
|
@@ -10,14 +10,21 @@ module Sneaql
|
|
10
10
|
'local_file',
|
11
11
|
Sneaql::StepManagers::JSONFileStepManager
|
12
12
|
)
|
13
|
-
|
13
|
+
|
14
14
|
# Manages steps from a local JSON file.
|
15
15
|
def manage_steps
|
16
|
-
@steps = JSON.parse(
|
17
|
-
|
16
|
+
@steps = JSON.parse(
|
17
|
+
File.read(@params[:step_metadata_file_path])
|
18
|
+
).sort_by! { |h| h['step_number'] }
|
19
|
+
@steps.map! do |j|
|
20
|
+
{
|
21
|
+
step_number: j['step_number'],
|
22
|
+
step_file: j['step_file']
|
23
|
+
}
|
24
|
+
end
|
18
25
|
end
|
19
26
|
end
|
20
|
-
|
27
|
+
|
21
28
|
# source step metadata from a standardized table in the target database
|
22
29
|
class TransformStepTableManager < Sneaql::Core::StepMetadataManager
|
23
30
|
Sneaql::Core::RegisterMappedClass.new(
|
@@ -25,7 +32,7 @@ module Sneaql
|
|
25
32
|
'transform_steps_table',
|
26
33
|
Sneaql::StepManagers::TransformStepTableManager
|
27
34
|
)
|
28
|
-
|
35
|
+
|
29
36
|
# Manages steps based in a standardized table.
|
30
37
|
def manage_steps
|
31
38
|
jdbc_connection = JDBCHelpers::ConnectionFactory.new(
|
@@ -33,28 +40,35 @@ module Sneaql
|
|
33
40
|
@params[:db_user],
|
34
41
|
@params[:db_pass]
|
35
42
|
).connection
|
36
|
-
|
43
|
+
|
37
44
|
@steps = JDBCHelpers::QueryResultsToArray.new(
|
38
45
|
jdbc_connection,
|
39
|
-
|
40
|
-
transform_step
|
41
|
-
,sql_file_path_in_repo
|
42
|
-
from
|
43
|
-
#{@params[:transform_steps_table]}
|
44
|
-
where
|
45
|
-
transform_name='#{@params[:transform_name]}'
|
46
|
-
and
|
47
|
-
is_active=#{ if @params[:database_manager].has_boolean then 'true' else 1 end }
|
48
|
-
order by
|
49
|
-
transform_step asc;)
|
46
|
+
steps_sql
|
50
47
|
).results
|
51
|
-
|
52
|
-
@steps.map! do |s|
|
53
|
-
{
|
48
|
+
|
49
|
+
@steps.map! do |s|
|
50
|
+
{
|
51
|
+
step_number: s['transform_step'],
|
52
|
+
step_file: s['sql_file_path_in_repo']
|
53
|
+
}
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
jdbc_connection.close
|
57
57
|
end
|
58
|
+
|
59
|
+
def steps_sql
|
60
|
+
%(select
|
61
|
+
transform_step
|
62
|
+
,sql_file_path_in_repo
|
63
|
+
from
|
64
|
+
#{@params[:transform_steps_table]}
|
65
|
+
where
|
66
|
+
transform_name='#{@params[:transform_name]}'
|
67
|
+
and
|
68
|
+
is_active=#{@params[:database_manager].has_boolean ? 'true' : 1}
|
69
|
+
order by
|
70
|
+
transform_step asc;)
|
71
|
+
end
|
58
72
|
end
|
59
73
|
end
|
60
74
|
end
|