Skip to content

Commit e55a0ca

Browse files
committed
Merge pull request #173 from Iristyle/maint/sqlconnection-refactor
(FM-5324) Fix TSQL error propagation
2 parents 419e3d0 + 1203586 commit e55a0ca

File tree

5 files changed

+24
-72
lines changed

5 files changed

+24
-72
lines changed

lib/puppet/provider/sqlserver_tsql/mssql.rb

-8
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,4 @@ def get_config
2424

2525
config_resc.original_parameters
2626
end
27-
28-
def run_check
29-
return self.run(resource[:onlyif])
30-
end
31-
32-
def run_update
33-
return self.run(resource[:command])
34-
end
3527
end

lib/puppet/type/sqlserver_tsql.rb

+6-5
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ def self.checks
4242
def check(value)
4343
output = provider.run(value)
4444
debug("OnlyIf returned exitstatus of #{output.exitstatus}")
45+
debug("OnlyIf error: #{output.error_message}") if output.has_errors
4546
output.exitstatus != 0
4647
end
4748
end
@@ -68,10 +69,7 @@ def output
6869

6970
def refresh
7071
if self.check_all_attributes(true)
71-
result = provider.run_update
72-
if result.has_errors
73-
fail("Unable to apply changes, failed with error message #{result.error_message}")
74-
end
72+
self.property(:returns).sync
7573
end
7674
end
7775

@@ -110,7 +108,10 @@ def retrieve
110108
def sync
111109
event = :executed_command
112110
begin
113-
@output = provider.run_update
111+
@output = provider.run(self.resource[:command])
112+
if @output.has_errors
113+
fail("Unable to apply changes, failed with error message #{@output.error_message}")
114+
end
114115
end
115116
unless @output.exitstatus.to_s == "0"
116117
self.fail("#{self.resource[:command]} returned #{@output.exitstatus} instead of one of [#{self.should.join(",")}]")

lib/puppet_x/sqlserver/sql_connection.rb

+4-33
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,17 @@ module Sqlserver
44
CONNECTION_CLOSED = 0
55

66
class SqlConnection
7-
attr_reader :exception_caught
8-
97
def open_and_run_command(query, config)
108
begin
119
open(config)
12-
command(query)
10+
execute(query)
1311
rescue win32_exception => e
14-
@exception_caught = e
12+
return ResultOutput.new(true, e.message)
1513
ensure
1614
close
1715
end
1816

19-
result
17+
ResultOutput.new(false, nil)
2018
end
2119

2220
private
@@ -45,40 +43,13 @@ def get_connection_string(config)
4543
params.map { |k, v| "#{k}=#{v}" }.join(';')
4644
end
4745

48-
def command(sql)
49-
reset_instance
50-
begin
51-
r = execute(sql)
52-
yield(r) if block_given?
53-
rescue win32_exception => e
54-
@exception_caught = e
55-
end
56-
nil
57-
end
58-
59-
def result
60-
ResultOutput.new(has_errors, error_message)
61-
end
62-
63-
def has_errors
64-
@exception_caught != nil
65-
end
66-
67-
def error_message
68-
@exception_caught.message unless @exception_caught == nil
69-
end
70-
7146
def close
7247
begin
7348
connection.Close unless connection_closed?
7449
rescue win32_exception => e
7550
end
7651
end
7752

78-
def reset_instance
79-
@exception_caught = nil
80-
end
81-
8253
def connection_closed?
8354
connection.State == CONNECTION_CLOSED
8455
end
@@ -119,7 +90,7 @@ def has_errors
11990

12091
private
12192
def parse_for_error(result)
122-
match = result.match(/SQL Server\n\s+(.*)/i)
93+
match = result.match(/SQL Server\n\s*(.*)/i)
12394
match[1] unless match == nil
12495
end
12596
end

spec/unit/puppet/provider/sqlserver__tsql_spec.rb

+6-6
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ def gen_query(query)
3737
PP
3838
end
3939

40-
context 'run_update' do
40+
context 'run with a command' do
4141
describe 'against non master database' do
4242
it {
4343
create_sqlserver_tsql({:title => 'runme', :command => 'whacka whacka', :instance => 'MSSQLSERVER', :database => 'myDb'})
4444
stub_get_instance_config(config)
4545
stub_open_and_run('whacka whacka', config.merge({:database => 'myDb'}))
4646

47-
@provider.run_update
47+
@provider.run(gen_query('whacka whacka'))
4848
}
4949
end
5050
describe 'against default database' do
@@ -53,18 +53,18 @@ def gen_query(query)
5353
stub_get_instance_config(config)
5454
stub_open_and_run('whacka whacka', config.merge({:database => 'master'}))
5555

56-
@provider.run_update
56+
@provider.run(gen_query('whacka whacka'))
5757
}
5858
end
5959
end
60-
context 'run_check' do
60+
context 'run with onlyif' do
6161
describe 'against default database' do
6262
it {
6363
create_sqlserver_tsql({:title => 'runme', :command => 'whacka whacka', :onlyif => 'fozy wozy', :instance => 'MSSQLSERVER'})
6464
stub_get_instance_config(config)
6565
stub_open_and_run('fozy wozy', config.merge({:database => 'master'}))
6666

67-
@provider.run_check
67+
@provider.run(gen_query('fozy wozy'))
6868
}
6969
end
7070
describe 'against non master database' do
@@ -78,7 +78,7 @@ def gen_query(query)
7878
stub_get_instance_config(config)
7979
stub_open_and_run('fozy wozy', config.merge({:database => 'myDb'}))
8080

81-
@provider.run_check
81+
@provider.run(gen_query('fozy wozy'))
8282
}
8383
end
8484
end

spec/unit/puppet_x/sql_connection_spec.rb

+8-20
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,17 @@
99
def stub_connection
1010
@connection = mock()
1111
subject.stubs(:create_connection).returns(@connection)
12+
@connection.stubs(:State).returns(PuppetX::Sqlserver::CONNECTION_CLOSED)
1213
subject.stubs(:win32_exception).returns(Exception)
1314
end
1415

15-
def stub_no_errors
16-
subject.stubs(:has_errors).returns(false)
17-
subject.stubs(:error_message).returns(nil)
18-
end
19-
2016
describe 'open_and_run_command' do
21-
context 'command' do
17+
context 'command execution' do
2218
before :each do
2319
stub_connection
24-
@connection.stubs(:State).returns(0)
2520
@connection.stubs(:Open).with('Provider=SQLOLEDB.1;User ID=sa;Password=Pupp3t1@;Initial Catalog=master;Application Name=Puppet;Data Source=localhost')
2621
end
2722
it 'should not raise an error but populate has_errors with message' do
28-
subject.stubs(:win32_exception).returns(Exception)
2923
subject.stubs(:execute).raises(Exception.new("SQL Server\n error has happened"))
3024
expect {
3125
result = subject.open_and_run_command('whacka whacka whacka', config)
@@ -44,36 +38,32 @@ def stub_no_errors
4438
context 'closed connection' do
4539
before :each do
4640
stub_connection
47-
stub_no_errors
48-
@connection.stubs(:State).returns(0)
41+
@connection.stubs(:Execute)
4942
end
5043
it 'should not add MSSQLSERVER to connection string' do
51-
@connection.stubs(:Open).with('Provider=SQLOLEDB.1;User ID=sa;Password=Pupp3t1@;Initial Catalog=master;Application Name=Puppet;Data Source=localhost')
44+
@connection.expects(:Open).with('Provider=SQLOLEDB.1;User ID=sa;Password=Pupp3t1@;Initial Catalog=master;Application Name=Puppet;Data Source=localhost')
5245
subject.open_and_run_command('query', config)
5346
end
5447
it 'should add a non default instance to connection string' do
55-
@connection.stubs(:Open).with('Provider=SQLOLEDB.1;User ID=superuser;Password=puppetTested;Initial Catalog=master;Application Name=Puppet;Data Source=localhost\LOGGING')
48+
@connection.expects(:Open).with('Provider=SQLOLEDB.1;User ID=superuser;Password=puppetTested;Initial Catalog=master;Application Name=Puppet;Data Source=localhost\LOGGING')
5649
subject.open_and_run_command('query', {:admin_user => 'superuser', :admin_pass => 'puppetTested', :instance_name => 'LOGGING'})
5750
end
5851
end
5952
context 'open connection' do
6053
it 'should not reopen an existing connection' do
6154
stub_connection
6255
@connection.expects(:open).never
63-
@connection.stubs(:State).returns(1)
56+
@connection.stubs(:State).returns(1) # any value other than CONNECTION_CLOSED
6457
@connection.expects(:Execute).with('query', nil, nil)
6558
subject.open_and_run_command('query', config)
6659
end
6760
end
6861
context 'return result with errors' do
6962
it {
63+
subject.stubs(:win32_exception).returns(Exception)
7064
subject.expects(:open).with({:admin_user => 'sa', :admin_pass => 'Pupp3t1@', :instance_name => 'MSSQLSERVER'})
71-
subject.expects(:command).with('SELECT * FROM sys.databases')
65+
subject.expects(:execute).with('SELECT * FROM sys.databases').raises(Exception.new("SQL Server\ninvalid syntax provider"))
7266
subject.expects(:close).once
73-
subject.stubs(:has_errors).returns(:true)
74-
subject.stubs(:error_message).returns(
75-
'SQL Server
76-
invalid syntax provider')
7767
result =
7868
subject.open_and_run_command('SELECT * FROM sys.databases', config)
7969
expect(result.exitstatus).to eq(1)
@@ -85,8 +75,6 @@ def stub_no_errors
8575
stub_connection
8676
err_message = "SQL Server\n ConnectionFailed"
8777
@connection.stubs(:Open).raises(Exception.new(err_message))
88-
subject.stubs(:has_errors).returns(true)
89-
subject.stubs(:error_message).returns(err_message)
9078
expect {
9179
result = subject.open_and_run_command('whacka whacka whacka', config)
9280
expect(result.exitstatus).to eq(1)

0 commit comments

Comments
 (0)