slacker 1.0.17 → 1.0.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/slacker +4 -6
- data/lib/slacker/application.rb +1 -1
- data/lib/slacker/configuration.rb +3 -9
- data/lib/slacker/version.rb +1 -1
- data/lib/slacker_new/project/data/helper_method_examples/fibonacci_1.csv +32 -0
- data/lib/slacker_new/project/data/helper_method_examples/fibonacci_2.csv +34 -0
- data/lib/slacker_new/project/data/helper_method_examples/fibonacci_3.csv +46 -0
- data/lib/slacker_new/project/data/{sample_1 → template_examples}/my_table_expected_power_results.csv +0 -0
- data/lib/slacker_new/project/data/{sample_1 → template_examples}/my_table_initial_data.csv +0 -0
- data/lib/slacker_new/project/data/{sample_1 → template_examples}/numbers_expected_output.csv +0 -0
- data/lib/slacker_new/project/database.yml +6 -2
- data/lib/slacker_new/project/lib/helpers/common_helper.rb +128 -0
- data/lib/slacker_new/project/spec/helper_method_examples.rb +132 -0
- data/lib/slacker_new/project/spec/{sample_1.rb → template_examples.rb} +16 -14
- data/lib/slacker_new/project/sql/common/select_vars.sql.erb +22 -0
- data/lib/slacker_new/project/sql/common/sproc.sql.erb +52 -0
- data/lib/slacker_new/project/sql/common/t_func.sql.erb +38 -0
- data/lib/slacker_new/project/sql/helper_method_examples/create_tables.sql.erb +14 -0
- data/lib/slacker_new/project/sql/helper_method_examples/create_tf_fibonacci.sql.erb +18 -0
- data/lib/slacker_new/project/sql/{sample_1 → template_examples}/create_my_table.sql.erb +0 -0
- data/lib/slacker_new/project/sql/{sample_1 → template_examples}/my_table_on_power.sql.erb +0 -0
- data/lib/slacker_new/project/sql/{sample_1 → template_examples}/play_with_numbers.sql.erb +0 -0
- data/lib/slacker_new/project/sql/{sample_1 → template_examples}/sysobjects.sql.erb +0 -0
- data/lib/slacker_new/project/sql/{sample_1 → template_examples}/sysobjects_with_params.sql.erb +0 -0
- metadata +21 -13
- data/lib/slacker_new/project/debug/failed_examples/example_001.sql +0 -0
- data/lib/slacker_new/project/debug/passed_examples/example_001.sql +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e9e9ef75544760db4a713ba9961d6e37c152093
|
4
|
+
data.tar.gz: 9d7d6624aa848babe12e3dfc6fece001fd67affd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7a98ec5f375c332224defcbdaf529d6fad44de5e0f020ead40dc9d0b22171909ae81555a4a8ea3fc8ea514abb38e63beac07c632b7d0e09aafef1ca7e7d466c
|
7
|
+
data.tar.gz: 07c4136a04d30f9dfd3b213b99b31e3abfd884cbed0e671cabf7a9311780d8290403f9542b1b47207ede90e89d134de086358f7838fbf3127ea5a2386585e32e
|
data/bin/slacker
CHANGED
@@ -23,12 +23,10 @@ Slacker.configure do |config|
|
|
23
23
|
config.db_name = db_config["database"]
|
24
24
|
config.db_user = db_config["user"]
|
25
25
|
config.db_password = db_config["password"]
|
26
|
-
if !!db_config["port"]
|
27
|
-
|
28
|
-
|
29
|
-
if
|
30
|
-
config.db_driver = db_config["driver"]
|
31
|
-
end
|
26
|
+
config.db_port = db_config["port"] if !!db_config["port"]
|
27
|
+
config.db_driver = db_config["driver"] if !!db_config["driver"]
|
28
|
+
# Override console_enabled value with the value from configuration yaml
|
29
|
+
config.console_enabled = db_config["console_enabled"] if db_config["console_enabled"] != nil
|
32
30
|
end
|
33
31
|
|
34
32
|
if Slacker.application.run
|
data/lib/slacker/application.rb
CHANGED
@@ -247,7 +247,7 @@ EOF
|
|
247
247
|
config.output_stream = @configuration.output_stream
|
248
248
|
config.error_stream = @configuration.error_stream
|
249
249
|
|
250
|
-
config.add_formatter(Slacker::CommandLineFormatter)
|
250
|
+
config.add_formatter(Slacker::CommandLineFormatter) if @configuration.console_enabled
|
251
251
|
end
|
252
252
|
end
|
253
253
|
|
@@ -27,15 +27,9 @@ module Slacker
|
|
27
27
|
|
28
28
|
def console_enabled=(value)
|
29
29
|
@console_enabled = value
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
@rspec_args = ARGV
|
34
|
-
else
|
35
|
-
@error_stream = nil
|
36
|
-
@output_stream = nil
|
37
|
-
@rspec_args = []
|
38
|
-
end
|
30
|
+
@error_stream = $stderr
|
31
|
+
@output_stream = $stdout
|
32
|
+
@rspec_args = ARGV
|
39
33
|
end
|
40
34
|
|
41
35
|
def rspec_args
|
data/lib/slacker/version.rb
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
fibonacci
|
2
|
+
0
|
3
|
+
1
|
4
|
+
1
|
5
|
+
2
|
6
|
+
3
|
7
|
+
5
|
8
|
+
8
|
9
|
+
13
|
10
|
+
21
|
11
|
+
34
|
12
|
+
55
|
13
|
+
89
|
14
|
+
144
|
15
|
+
233
|
16
|
+
377
|
17
|
+
610
|
18
|
+
987
|
19
|
+
1597
|
20
|
+
2584
|
21
|
+
4181
|
22
|
+
6765
|
23
|
+
10946
|
24
|
+
17711
|
25
|
+
28657
|
26
|
+
46368
|
27
|
+
75025
|
28
|
+
121393
|
29
|
+
196418
|
30
|
+
317811
|
31
|
+
514229
|
32
|
+
832040
|
@@ -0,0 +1,34 @@
|
|
1
|
+
fibonacci
|
2
|
+
0
|
3
|
+
1
|
4
|
+
1
|
5
|
+
2
|
6
|
+
3
|
7
|
+
5
|
8
|
+
8
|
9
|
+
13
|
10
|
+
21
|
11
|
+
34
|
12
|
+
55
|
13
|
+
89
|
14
|
+
144
|
15
|
+
233
|
16
|
+
377
|
17
|
+
610
|
18
|
+
987
|
19
|
+
1597
|
20
|
+
2584
|
21
|
+
4181
|
22
|
+
6765
|
23
|
+
10946
|
24
|
+
17711
|
25
|
+
28657
|
26
|
+
46368
|
27
|
+
75025
|
28
|
+
121393
|
29
|
+
196418
|
30
|
+
317811
|
31
|
+
514229
|
32
|
+
832040
|
33
|
+
1346269
|
34
|
+
2178309
|
@@ -0,0 +1,46 @@
|
|
1
|
+
fibonacci
|
2
|
+
0
|
3
|
+
1
|
4
|
+
1
|
5
|
+
2
|
6
|
+
3
|
7
|
+
5
|
8
|
+
8
|
9
|
+
13
|
10
|
+
21
|
11
|
+
34
|
12
|
+
55
|
13
|
+
89
|
14
|
+
144
|
15
|
+
233
|
16
|
+
377
|
17
|
+
610
|
18
|
+
987
|
19
|
+
1597
|
20
|
+
2584
|
21
|
+
4181
|
22
|
+
6765
|
23
|
+
10946
|
24
|
+
17711
|
25
|
+
28657
|
26
|
+
46368
|
27
|
+
75025
|
28
|
+
121393
|
29
|
+
196418
|
30
|
+
317811
|
31
|
+
514229
|
32
|
+
832040
|
33
|
+
1346269
|
34
|
+
2178309
|
35
|
+
3524578
|
36
|
+
5702887
|
37
|
+
9227465
|
38
|
+
14930352
|
39
|
+
24157817
|
40
|
+
39088169
|
41
|
+
63245986
|
42
|
+
102334155
|
43
|
+
165580141
|
44
|
+
267914296
|
45
|
+
433494437
|
46
|
+
701408733
|
data/lib/slacker_new/project/data/{sample_1 → template_examples}/my_table_expected_power_results.csv
RENAMED
File without changes
|
File without changes
|
data/lib/slacker_new/project/data/{sample_1 → template_examples}/numbers_expected_output.csv
RENAMED
File without changes
|
@@ -6,14 +6,18 @@
|
|
6
6
|
driver: tiny_tds
|
7
7
|
|
8
8
|
# Full instance name when using odbc; hostname or IP when using tiny_tds.
|
9
|
-
server:
|
9
|
+
server: localhost
|
10
10
|
|
11
11
|
# Port is used by tiny_tds only. Defaults to 1433 when not set.
|
12
12
|
# Use server and port when targeting named instances with tiny_tds.
|
13
|
-
port: 1433
|
13
|
+
port: 1433
|
14
14
|
|
15
|
+
# The target database.
|
15
16
|
database: my_database
|
16
17
|
|
17
18
|
# Slacker supports only SQL Server authentication.
|
18
19
|
user: user_name
|
19
20
|
password: password
|
21
|
+
|
22
|
+
# Set this to false when using alternative formatters such as -fh and fj.
|
23
|
+
console_enabled: true
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# A helper module with methods which streamline execution of various
|
2
|
+
# programmable objects without the need to craft custom slacker *.sql templates.
|
3
|
+
|
4
|
+
module CommonHelper
|
5
|
+
# Construct a select statement with optional variable declaration.
|
6
|
+
# Inject a select statement at the end which selects all variables
|
7
|
+
def select_vars(vars, sql_script, options = {:declare_vars => true}, &block)
|
8
|
+
sql.common.select_vars({:vars => vars, :sql_script => sql_script, :options => options}, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Invoke a scalar function by name and with an arbitrary list of parameters.
|
12
|
+
def s_func(func_name, *params)
|
13
|
+
raise 's_func called with a block' if block_given?
|
14
|
+
|
15
|
+
# Extract the optional options at the end of the params array.
|
16
|
+
options = options_from_params(params)
|
17
|
+
|
18
|
+
sql_value_params = params.map{|param| sql_value(param) }
|
19
|
+
|
20
|
+
if options[:date_to_iso8601]
|
21
|
+
query("select CONVERT(NVARCHAR(MAX),#{func_name}(#{sql_value_params.join(', ')}), 101) as value;")[0][:value]
|
22
|
+
else
|
23
|
+
query("select #{func_name}(#{sql_value_params.join(', ')}) as value;")[0][:value]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Invoke a table valued function with an arbitrary list of parameters.
|
28
|
+
# Yield results to the optionally passed in lambda block.
|
29
|
+
def t_func(func_name, *params, &block)
|
30
|
+
# Extract the optional options at the end of the params array.
|
31
|
+
options = options_from_params(params)
|
32
|
+
|
33
|
+
order_by_clause = options[:order_by] != nil ? " order by #{options[:order_by]}" : ""
|
34
|
+
|
35
|
+
if params.any? {|p| p.class == TableVariable}
|
36
|
+
sql.common.t_func :func_name => func_name, :params => params, :order_by_clause => order_by_clause, &block
|
37
|
+
else
|
38
|
+
sql_value_params = params.map{|param| sql_value(param) }
|
39
|
+
query "select * from #{func_name}(#{sql_value_params.join(', ')})#{order_by_clause};", &block
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Invoke a stored procedure with an arbitrary list of input and output
|
44
|
+
# parameters passed in as hashes to allow named parameters.
|
45
|
+
def sproc(sproc_name, params = {}, out_params = {}, &block)
|
46
|
+
if out_params.count > 0 || params.any? {|p| p[1].class == TableVariable}
|
47
|
+
sql.common.sproc :sproc_name => sproc_name, :params => params, :out_params => out_params, &block
|
48
|
+
else
|
49
|
+
# Bypass the call to the template if no TableVariable parameter is present.
|
50
|
+
# This speeds up execution of a simple sproc calls up to x2.
|
51
|
+
query "exec #{sproc_name}\n#{sproc_params(params, {})};", &block
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Convert parameter values to their SQL string representation.
|
56
|
+
def sql_value(p)
|
57
|
+
if p
|
58
|
+
case p
|
59
|
+
when String then
|
60
|
+
# Do not put the %{ } escapes into quotes - this will be replaced by the Slacker's SQL preprocessor.
|
61
|
+
# Updated to also ignore hex strings for sql varbinary values, and pre-quoted values.
|
62
|
+
(p =~ /^(%{.*?}|0x[0-9a-fA-F]*|'.*')$/) != nil ? p : "'#{p}'"
|
63
|
+
when TableVariable
|
64
|
+
p.name
|
65
|
+
else p.to_s
|
66
|
+
end
|
67
|
+
else
|
68
|
+
'NULL'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Extract the last parameter if of type hash, otherwise return an empty hash.
|
73
|
+
def options_from_params(params)
|
74
|
+
options = {}
|
75
|
+
pcount = params.count
|
76
|
+
if pcount > 0 && params[pcount - 1].is_a?(Hash)
|
77
|
+
options = params[pcount - 1]
|
78
|
+
params.delete_at(pcount - 1)
|
79
|
+
end
|
80
|
+
|
81
|
+
options
|
82
|
+
end
|
83
|
+
|
84
|
+
# Generate a stored procedure parameter list.
|
85
|
+
def sproc_params(in_params, out_params)
|
86
|
+
expanded = []
|
87
|
+
|
88
|
+
out_params.each do |key, value|
|
89
|
+
expanded.push "@#{key.to_s} = @#{value} out"
|
90
|
+
end
|
91
|
+
|
92
|
+
in_params.each do |key, value|
|
93
|
+
expanded.push "@#{key.to_s} = #{sql_value(value)}"
|
94
|
+
end
|
95
|
+
|
96
|
+
expanded.count == 0 ? '' : ' ' + expanded.join(",\n ")
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
# Use this class to pass in table-valued parameters when calling sproc, t_func and s_func.
|
102
|
+
class TableVariable
|
103
|
+
@name = ''
|
104
|
+
@type = ''
|
105
|
+
@fields = []
|
106
|
+
@values = []
|
107
|
+
@usage = 0
|
108
|
+
|
109
|
+
def initialize(name, type, fields, values)
|
110
|
+
@name = name.start_with?('@') ? name : '@' + name
|
111
|
+
@type = type
|
112
|
+
@fields = fields
|
113
|
+
@values = values
|
114
|
+
@usage = 0
|
115
|
+
end
|
116
|
+
|
117
|
+
attr_reader :type
|
118
|
+
attr_reader :fields
|
119
|
+
attr_reader :values
|
120
|
+
|
121
|
+
def name
|
122
|
+
@name + "_" + @usage.to_s
|
123
|
+
end
|
124
|
+
|
125
|
+
def increment
|
126
|
+
@usage += 1
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# This specification explores the use of helper methods sproc, s_func and t_func
|
2
|
+
# used for testing stored procedures, scalar functions and table-valued functions
|
3
|
+
# without the need to create sql template files.
|
4
|
+
# The helper methods are implemented in file lib/helpers/common_helper.rb and are
|
5
|
+
# automatically included and available in every Slacker specification file.
|
6
|
+
#
|
7
|
+
# If you're looking for examples of using the template-files technique
|
8
|
+
# see examples in spec/template_examples.rb.
|
9
|
+
|
10
|
+
describe 'My database' do
|
11
|
+
|
12
|
+
# Create the sample tables before each example.
|
13
|
+
# All updates will be discarded at the end of each example,
|
14
|
+
# including the ones introduced in the 'before :each' section below.
|
15
|
+
before :each do
|
16
|
+
sql.helper_method_examples.create_tables
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
# An example of using helper method sproc.
|
21
|
+
it 'is hosted on a SQL Server instance' do
|
22
|
+
# Call sp_server_info using helper method sproc.
|
23
|
+
result = sproc('sp_server_info')
|
24
|
+
|
25
|
+
# sp_server_info returns a single resultset with server attributes.
|
26
|
+
expect(result.count).to be > 1
|
27
|
+
|
28
|
+
# Convert the returned resultset to a hash of server attributes.
|
29
|
+
server_attributes = result.map{|r| [r[:attribute_name], r[:attribute_value]]}.to_h
|
30
|
+
|
31
|
+
expect(server_attributes['DBMS_NAME']).to be == 'Microsoft SQL Server'
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
# Another sproc example - calling a multi-resultset stored procedures with parameters.
|
37
|
+
it 'contains table dbo.OrderItem' do
|
38
|
+
|
39
|
+
# Invoke sp_help for dbo.OrderItem.
|
40
|
+
result = sproc('sp_help', :objname => 'dbo.OrderItem')
|
41
|
+
|
42
|
+
expect(result.count).to be == 7
|
43
|
+
|
44
|
+
# Verify the name of the table returned in the first resultset.
|
45
|
+
expect(result[0][0][:Name]).to be == 'OrderItem'
|
46
|
+
|
47
|
+
# Inspect a few columns returned in the second resultset.
|
48
|
+
expect(result[1][0][:Column_name]).to be == 'order_id'
|
49
|
+
expect(result[1][1][:Column_name]).to be == 'customer_id'
|
50
|
+
|
51
|
+
# Verify that order_id is the identity of the table - returned in the third resultset.
|
52
|
+
expect(result[2][0][:Identity]).to be == 'order_id'
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
# An example of using sproc with output parameters.
|
58
|
+
it 'can be used to perform formatting operations' do
|
59
|
+
|
60
|
+
# You can call a stored procedure which expects output parameters
|
61
|
+
# by passing the output parameters in a second hash, which provides
|
62
|
+
# the name of the variable to pass into the output parameter and
|
63
|
+
# the type of that variable.
|
64
|
+
# The result of calling a stored procedure will include a resultset with
|
65
|
+
# the value of all output parameters selected as columns.
|
66
|
+
|
67
|
+
result = sproc('xp_sprintf',
|
68
|
+
# Input parameters.
|
69
|
+
{
|
70
|
+
:format => 'Hello %s',
|
71
|
+
:argument1 => 'Marry'
|
72
|
+
},
|
73
|
+
# Output parameters.
|
74
|
+
{
|
75
|
+
:string => 'varchar(100)'
|
76
|
+
})[0][:string]
|
77
|
+
|
78
|
+
expect(result).to be == 'Hello Marry'
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
# An example of using sproc with named output parameters.
|
84
|
+
it 'can be used to perform formatting operations (take 2)' do
|
85
|
+
|
86
|
+
# This example is the same as the above, but this time
|
87
|
+
# the output variable name is different from the name
|
88
|
+
# of the output parameter.
|
89
|
+
# To accomplish this, instead of passing a {:param_name => 'type'} hash
|
90
|
+
# we are passing {:param_name => {:var_name => 'type'}} hash.
|
91
|
+
|
92
|
+
result = sproc('xp_sprintf',
|
93
|
+
# Input parameters.
|
94
|
+
{
|
95
|
+
:format => 'Hello %s',
|
96
|
+
:argument1 => 'John'
|
97
|
+
},
|
98
|
+
# Output parameters.
|
99
|
+
{
|
100
|
+
:string => {:my_output_var => 'varchar(100)'}
|
101
|
+
})[0][:my_output_var]
|
102
|
+
|
103
|
+
expect(result).to be == 'Hello John'
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
# An example of using helper method s_func to call a scalar function.
|
109
|
+
it 'exposes system scalar function COALESCE' do
|
110
|
+
result = s_func('COALESCE', nil, 12, nil, 24)
|
111
|
+
expect(result).to be == 12
|
112
|
+
end
|
113
|
+
|
114
|
+
# An example of using t_func.
|
115
|
+
it 'exposes a dbo.tf_Fibonacci UDF table-valued function' do
|
116
|
+
# Create a Fibonacci sequence generator table-valued function.
|
117
|
+
# This is done here for demonstration purposes only.
|
118
|
+
# Typically you would not be creating your target logic as part of the test.
|
119
|
+
sql.helper_method_examples.create_tf_fibonacci
|
120
|
+
|
121
|
+
# Test the Fibonacci sequence function by invoking it with a variety of parameters
|
122
|
+
# and matching the results with expected data points stored in CSV files.
|
123
|
+
|
124
|
+
expect(t_func('dbo.tf_Fibonacci', 1000000)).to match('helper_method_examples/fibonacci_1.csv')
|
125
|
+
|
126
|
+
expect(t_func('dbo.tf_Fibonacci', 3000000)).to match('helper_method_examples/fibonacci_2.csv')
|
127
|
+
|
128
|
+
expect(t_func('dbo.tf_Fibonacci', 999999999)).to match('helper_method_examples/fibonacci_3.csv')
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# This set of examples demonstrates the use of sql templates.
|
2
|
+
|
1
3
|
# Method "describe" opens up an example group.
|
2
4
|
describe 'My database' do
|
3
5
|
# Simple inline query example.
|
@@ -6,23 +8,23 @@ describe 'My database' do
|
|
6
8
|
expect(query("select * from sysobjects where xtype = 'S';").count).to be > 0
|
7
9
|
end
|
8
10
|
|
9
|
-
# The same query, this time using a SQL template
|
11
|
+
# The same query, this time using a SQL template located in file "sql/template_examples/sysobject.sql.erb".
|
10
12
|
it 'contains system tables (take two)' do
|
11
13
|
# Every (*.sql.erb) file in folder "sql" can be called as a method on object "sql".
|
12
|
-
#
|
13
|
-
expect(sql.
|
14
|
+
# Sub-folders of folder "sql" appear as children of object "sql" with their (*.sql.erb) files automatically available as methods.
|
15
|
+
expect(sql.template_examples.sysobjects.count).to be > 0
|
14
16
|
end
|
15
17
|
|
16
18
|
# This time we'll use a parameterized template.
|
17
19
|
it 'contains system tables (take three)' do
|
18
|
-
# Every template can accept parameters; see file "sql/
|
19
|
-
expect(sql.
|
20
|
+
# Every template can accept parameters; see file "sql/template_examples/sysobject_with_params.sql.erb".
|
21
|
+
expect(sql.template_examples.sysobjects_with_params(:xtype => 'S').count).to be > 0
|
20
22
|
end
|
21
23
|
|
22
24
|
# SQL Templates can contain multiple statements and can return multiple resultsets.
|
23
25
|
it 'can play with numbers' do
|
24
26
|
# Note that this time we're calling the template with a block which receives the results as a block parameter.
|
25
|
-
sql.
|
27
|
+
sql.template_examples.play_with_numbers(:x => 2, :y => 12) do |results|
|
26
28
|
# The results object contains an array of all the resultsets generated by the query script.
|
27
29
|
# A resultset contains an array of records. Each record is a hash of field => value pairs.
|
28
30
|
|
@@ -32,8 +34,8 @@ describe 'My database' do
|
|
32
34
|
# A resultset can be matched directly against an array of hashes using method "match".
|
33
35
|
expect(results[1]).to match([{:x => 2, :y => 12, :sum => 14}])
|
34
36
|
|
35
|
-
# Or against a CSV file stored in project's "data" folder (see file "data/
|
36
|
-
expect(results[2]).to match('
|
37
|
+
# Or against a CSV file stored in project's "data" folder (see file "data/template_examples/numbers_expected_output.csv").
|
38
|
+
expect(results[2]).to match('template_examples/numbers_expected_output.csv')
|
37
39
|
|
38
40
|
# A resultset's values can be matched one-by-one.
|
39
41
|
expect(results[2][0][:p]).to be == 2
|
@@ -51,16 +53,16 @@ describe 'My database' do
|
|
51
53
|
# calculate the exponentiation of one column based on another column
|
52
54
|
# and verify the results against an expected resultset stored in a CSV file.
|
53
55
|
it 'can play with numbers (take two)' do
|
54
|
-
# Create the table - see file "sql/
|
55
|
-
sql.
|
56
|
+
# Create the table - see file "sql/template_examples/create_my_table.sql.erb".
|
57
|
+
sql.template_examples.create_my_table
|
56
58
|
# We can populate any table with data from the "data" folder by calling method "load_csv".
|
57
|
-
# See file "data/
|
58
|
-
load_csv('
|
59
|
+
# See file "data/template_examples/my_table_initial_data.csv".
|
60
|
+
load_csv('template_examples/my_table_initial_data.csv', 'MyTable')
|
59
61
|
|
60
62
|
# Now let's test the system scalar function Power.
|
61
63
|
# We will use it in a query expression executed agaings MyTable and we
|
62
64
|
# will compare the results against a CSV file - we should expect them to match.
|
63
|
-
# See files "sql/
|
64
|
-
expect(sql.
|
65
|
+
# See files "sql/template_examples/my_table_on_power.sql.erb" and "data/template_examples/my_table_expected_power_results.csv".
|
66
|
+
expect(sql.template_examples.my_table_on_power).to match('template_examples/my_table_expected_power_results.csv')
|
65
67
|
end
|
66
68
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
% declare_vars = options[:options][:declare_vars]
|
2
|
+
% vars = options[:vars]
|
3
|
+
% var_count = vars.count
|
4
|
+
% sql_script = options[:sql_script]
|
5
|
+
%
|
6
|
+
<% if declare_vars %>
|
7
|
+
<% vars.each do |var| %>
|
8
|
+
declare @<%= var[0].to_s %> <%= var[1] %>;
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<% end %>
|
12
|
+
%
|
13
|
+
<%= sql_script.split(/\r\n/).map{|i| i.strip}.join("\r\n") %>
|
14
|
+
<% if var_count > 0 %>
|
15
|
+
|
16
|
+
|
17
|
+
select
|
18
|
+
<% vars.each_with_index do |var, index| %>
|
19
|
+
<% var_name = var[0].to_s %>
|
20
|
+
@<%= var_name %> as <%= var_name %><%= index < var_count - 1 ? ',' : ';' %>
|
21
|
+
<% end %>
|
22
|
+
<% end %>
|
@@ -0,0 +1,52 @@
|
|
1
|
+
% params = options[:params]
|
2
|
+
% sproc_name = options[:sproc_name]
|
3
|
+
% out_params = options[:out_params]
|
4
|
+
% out_param_count = out_params.count
|
5
|
+
% out_param_vars = out_params.merge(out_params){|k, v| v.is_a?(Hash) ? v.to_a[0][0] : k}
|
6
|
+
%
|
7
|
+
|
8
|
+
% table_params = []
|
9
|
+
% params.each do |param|
|
10
|
+
% if param[1].class == TableVariable
|
11
|
+
% table_params << param
|
12
|
+
% end
|
13
|
+
% end
|
14
|
+
%
|
15
|
+
%
|
16
|
+
% table_params.each do |param|
|
17
|
+
% tvar = param[1]
|
18
|
+
% tvar.increment # prevent declaring twice if reused
|
19
|
+
|
20
|
+
DECLARE <%= tvar.name %> <%= tvar.type %>;
|
21
|
+
% if tvar.fields != nil && tvar.values != nil && tvar.fields.count > 0 && tvar.values.count > 0
|
22
|
+
INSERT INTO <%= tvar.name %>
|
23
|
+
(
|
24
|
+
% tvar.fields.each_with_index do |field, index|
|
25
|
+
<%= field %><%= index < tvar.fields.count - 1 ? ',' : '' %>
|
26
|
+
% end
|
27
|
+
)
|
28
|
+
VALUES
|
29
|
+
% tvar.values.each_with_index do |row, row_index|
|
30
|
+
(
|
31
|
+
% row.each_with_index do |value, value_index|
|
32
|
+
<%= sql_value(value) %><%= value_index < row.count - 1 ? ', ' : '' %>
|
33
|
+
% end
|
34
|
+
)<%= row_index < tvar.values.count - 1 ? ',' : ';' %>
|
35
|
+
% end
|
36
|
+
|
37
|
+
% end
|
38
|
+
% end
|
39
|
+
|
40
|
+
% out_params.each do |param|
|
41
|
+
DECLARE @<%= out_param_vars[param[0]] %> <%= param[1].is_a?(Hash) ? param[1].to_a[0][1] : param[1] %>;
|
42
|
+
% end
|
43
|
+
|
44
|
+
EXEC <%= sproc_name %>
|
45
|
+
<%= sproc_params(params, out_param_vars) %>;
|
46
|
+
|
47
|
+
% if out_param_count > 0
|
48
|
+
SELECT
|
49
|
+
% out_param_vars.each_with_index do |param, index|
|
50
|
+
@<%= param[1] %> as [<%= param[1] %>]<%= index < out_param_count - 1 ? ',' : ';' %>
|
51
|
+
% end
|
52
|
+
% end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
% func_name = options[:func_name]
|
2
|
+
% params = options[:params]
|
3
|
+
% order_by_clause = options[:order_by_clause]
|
4
|
+
%
|
5
|
+
|
6
|
+
% table_params = []
|
7
|
+
% params.each do |param|
|
8
|
+
% if param.class == TableVariable
|
9
|
+
% table_params << param
|
10
|
+
% end
|
11
|
+
% end
|
12
|
+
%
|
13
|
+
%
|
14
|
+
% table_params.each do |param|
|
15
|
+
% tvar = param
|
16
|
+
% tvar.increment # prevent declaring twice if reused
|
17
|
+
|
18
|
+
DECLARE <%= tvar.name %> <%= tvar.type %>;
|
19
|
+
% if tvar.fields != nil && tvar.values != nil && tvar.fields.count > 0 && tvar.values.count > 0
|
20
|
+
INSERT INTO <%= tvar.name %>
|
21
|
+
(
|
22
|
+
% tvar.fields.each_with_index do |field, index|
|
23
|
+
<%= field %><%= index < tvar.fields.count - 1 ? ',' : '' %>
|
24
|
+
% end
|
25
|
+
)
|
26
|
+
VALUES
|
27
|
+
% tvar.values.each_with_index do |row, row_index|
|
28
|
+
(
|
29
|
+
% row.each_with_index do |value, value_index|
|
30
|
+
<%= sql_value(value) %><%= value_index < row.count - 1 ? ', ' : '' %>
|
31
|
+
% end
|
32
|
+
)<%= row_index < tvar.values.count - 1 ? ',' : ';' %>
|
33
|
+
% end
|
34
|
+
|
35
|
+
% end
|
36
|
+
% end
|
37
|
+
|
38
|
+
SELECT * FROM <%= func_name %>(<%= params.map{|param| sql_value(param) }.join(', ') %>)<%= order_by_clause %>;
|
@@ -0,0 +1,14 @@
|
|
1
|
+
create table dbo.Customer
|
2
|
+
(
|
3
|
+
customer_id int identity primary key,
|
4
|
+
customer_name nvarchar(max) not null
|
5
|
+
);
|
6
|
+
|
7
|
+
create table dbo.OrderItem
|
8
|
+
(
|
9
|
+
order_id int identity primary key,
|
10
|
+
customer_id int not null,
|
11
|
+
order_name nvarchar(max)
|
12
|
+
|
13
|
+
constraint fk_order_item_customer foreign key (customer_id) references dbo.Customer(customer_id)
|
14
|
+
);
|
@@ -0,0 +1,18 @@
|
|
1
|
+
-- Fibonacci sequence generator implemented as an inline table function.
|
2
|
+
create function dbo.tf_Fibonacci
|
3
|
+
(
|
4
|
+
-- Generate a sequence up to the given threshold.
|
5
|
+
@threshold int
|
6
|
+
)
|
7
|
+
returns table
|
8
|
+
return
|
9
|
+
with fibo (prev_n, n) as
|
10
|
+
(
|
11
|
+
select 0, 1
|
12
|
+
union all
|
13
|
+
select n, prev_n + n
|
14
|
+
from fibo
|
15
|
+
where n < @threshold
|
16
|
+
)
|
17
|
+
select prev_n as fibonacci
|
18
|
+
from fibo;
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/slacker_new/project/sql/{sample_1 → template_examples}/sysobjects_with_params.sql.erb
RENAMED
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slacker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vassil Kovatchev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -98,19 +98,27 @@ files:
|
|
98
98
|
- lib/slacker/sql_preprocessor.rb
|
99
99
|
- lib/slacker/string_helper.rb
|
100
100
|
- lib/slacker/version.rb
|
101
|
-
- lib/slacker_new/project/data/
|
102
|
-
- lib/slacker_new/project/data/
|
103
|
-
- lib/slacker_new/project/data/
|
101
|
+
- lib/slacker_new/project/data/helper_method_examples/fibonacci_1.csv
|
102
|
+
- lib/slacker_new/project/data/helper_method_examples/fibonacci_2.csv
|
103
|
+
- lib/slacker_new/project/data/helper_method_examples/fibonacci_3.csv
|
104
|
+
- lib/slacker_new/project/data/template_examples/my_table_expected_power_results.csv
|
105
|
+
- lib/slacker_new/project/data/template_examples/my_table_initial_data.csv
|
106
|
+
- lib/slacker_new/project/data/template_examples/numbers_expected_output.csv
|
104
107
|
- lib/slacker_new/project/database.yml
|
105
|
-
- lib/slacker_new/project/
|
106
|
-
- lib/slacker_new/project/debug/passed_examples/example_001.sql
|
108
|
+
- lib/slacker_new/project/lib/helpers/common_helper.rb
|
107
109
|
- lib/slacker_new/project/lib/helpers/my_helper.rb
|
108
|
-
- lib/slacker_new/project/spec/
|
109
|
-
- lib/slacker_new/project/
|
110
|
-
- lib/slacker_new/project/sql/
|
111
|
-
- lib/slacker_new/project/sql/
|
112
|
-
- lib/slacker_new/project/sql/
|
113
|
-
- lib/slacker_new/project/sql/
|
110
|
+
- lib/slacker_new/project/spec/helper_method_examples.rb
|
111
|
+
- lib/slacker_new/project/spec/template_examples.rb
|
112
|
+
- lib/slacker_new/project/sql/common/select_vars.sql.erb
|
113
|
+
- lib/slacker_new/project/sql/common/sproc.sql.erb
|
114
|
+
- lib/slacker_new/project/sql/common/t_func.sql.erb
|
115
|
+
- lib/slacker_new/project/sql/helper_method_examples/create_tables.sql.erb
|
116
|
+
- lib/slacker_new/project/sql/helper_method_examples/create_tf_fibonacci.sql.erb
|
117
|
+
- lib/slacker_new/project/sql/template_examples/create_my_table.sql.erb
|
118
|
+
- lib/slacker_new/project/sql/template_examples/my_table_on_power.sql.erb
|
119
|
+
- lib/slacker_new/project/sql/template_examples/play_with_numbers.sql.erb
|
120
|
+
- lib/slacker_new/project/sql/template_examples/sysobjects.sql.erb
|
121
|
+
- lib/slacker_new/project/sql/template_examples/sysobjects_with_params.sql.erb
|
114
122
|
- slacker.gemspec
|
115
123
|
- spec/application_spec.rb
|
116
124
|
- spec/query_result_matcher_spec.rb
|
File without changes
|
File without changes
|