flare-up 0.6 → 0.7

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OWIzMWE3OTM0ZWNkMDFkZGQyMzY4ODdmMTQ3MzVlMDI5MzA1YTgzZg==
4
+ YTIzMzhkOTUyZjYwNzUyMzYyYTUxYTEwZGJlZmY1ODdmNWJkYjUzMw==
5
5
  data.tar.gz: !binary |-
6
- N2M1NTg4OGZlMDUyNTVhYWJkOTZlZDA2ZWQzYmY3MDA5YTNlOGQwMw==
6
+ NDJiMGI4OWQ2ZjMyNWQ2MDQ4NmRjZWY4MjVkNTllY2I1NWJkYmVkOA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NzkyMmYwZjdhMjYzNWVhN2IwNDg1N2Y0OTg5MmI5M2IyMTQyNjkzZTc5ODI4
10
- M2MzY2FiN2Y4M2U2OGNkYzdkM2FiNzZjZmI1OTA2ZjE4ODNmNjQ0NzY4Y2Zh
11
- NWI2NDBlMDQ4NjNhYmRmNzg5NzUxNjNhNjYzYzUzZDcyYTYwYWI=
9
+ YTdiYjFkMmFmODI0MTNkYzgyZjAyY2UyNGNkMzM0ZDljMDgxNjNjMjJiNjQx
10
+ ZmM5ZTZiOGI0NDMyZjZhM2VmZGUwMGJkYTg5M2EwM2EzOTFiMTY5ZDBkYjU2
11
+ ZjAxODg1YTFiZTIxNDk4NWVjZmQ3YzJhZjAwNjk5YWM4ZjUxZmY=
12
12
  data.tar.gz: !binary |-
13
- OGQzYjRiN2JlNTM3Y2NmMjMxNWU0NGE3ZTg1ZjY1MjAwMDU4MzU4NzFiNjNh
14
- MjJjMjZlMmFkZmE5ZWIyNGNjNWFmYjk0YTUwOTU2ZDM3ZmJlYTMzYjcwZWNh
15
- NDVkNjQ4MDdmNjZkZmZkMTI2YWJkZDI3MjVmYTE4OTc5NGYzMmI=
13
+ MTFkMTlkOTliMGM0YTMxZDExZjRhNmJlMTA5NGMwODFmM2I3MzM0ZTQ5YTYw
14
+ ZTc4N2VlYjQxZTRkZmEwMTdlYjdjM2E5MjZjNTA0YTczNzVkY2Y1MDVlNDEx
15
+ M2VhNDcyZjI1MzU4NmVlNTIzMjZlMTE0OWU0MzViMzdmMWQzNTI=
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- flare-up (0.6)
4
+ flare-up (0.7)
5
5
  pg (~> 0.17)
6
6
  thor (~> 0.19)
7
7
 
data/README.md CHANGED
@@ -50,5 +50,5 @@ Note that this example assumes you have credentials set as environment variables
50
50
  dev \
51
51
  hearthstone_cards \
52
52
  --column-list name cost attack health description \
53
- --copy_options "REGION 'us-east-1' CSV"
53
+ --copy-options "REGION 'us-east-1' CSV"
54
54
  ```
data/lib/flare_up/boot.rb CHANGED
@@ -2,14 +2,28 @@ module FlareUp
2
2
 
3
3
  class Boot
4
4
 
5
- # TODO: This control flow is untested
5
+ # TODO: This control flow is untested and too procedural
6
6
  def self.boot(options)
7
7
  conn = create_connection(options)
8
8
  copy = create_copy_command(options)
9
9
 
10
10
  begin
11
+ trap('SIGINT') do
12
+ Emitter.warn('CTRL-C received; cancelling COPY command...')
13
+ error_message = conn.cancel_current_command
14
+ if error_message
15
+ Emitter.error("Error cancelling COPY: #{error_message}")
16
+ else
17
+ Emitter.success('COPY command cancelled.')
18
+ end
19
+ CLI.bailout(1)
20
+ end
21
+
11
22
  Emitter.info("Executing command: #{copy.get_command}")
12
23
  handle_load_errors(copy.execute(conn))
24
+ rescue ConnectionError => e
25
+ Emitter.error(e.message)
26
+ CLI.bailout(1)
13
27
  rescue CopyCommandError => e
14
28
  Emitter.error(e.message)
15
29
  CLI.bailout(1)
@@ -1,14 +1,16 @@
1
1
  module FlareUp
2
2
 
3
- class HostUnknownOrInaccessibleError < StandardError
3
+ class ConnectionError < StandardError
4
4
  end
5
- class TimeoutError < StandardError
5
+ class HostUnknownOrInaccessibleError < ConnectionError
6
6
  end
7
- class NoDatabaseError < StandardError
7
+ class TimeoutError < ConnectionError
8
8
  end
9
- class AuthenticationError < StandardError
9
+ class NoDatabaseError < ConnectionError
10
10
  end
11
- class UnknownError < StandardError
11
+ class AuthenticationError < ConnectionError
12
+ end
13
+ class UnknownError < ConnectionError
12
14
  end
13
15
 
14
16
  class Connection
@@ -30,15 +32,20 @@ module FlareUp
30
32
  @connect_timeout = 5
31
33
  end
32
34
 
33
- # TODO - Not quite sure how to test this; perhaps fold connect/execute into
34
- # TODO one method so we can close connections in case of failure, etc.
35
35
  def execute(statement)
36
- @pg_conn ||= connect
37
- @pg_conn.exec(statement)
36
+ connection.async_exec(statement)
37
+ end
38
+
39
+ def cancel_current_command
40
+ connection.cancel
38
41
  end
39
42
 
40
43
  private
41
44
 
45
+ def connection
46
+ @pg_conn ||= connect
47
+ end
48
+
42
49
  def connect
43
50
  begin
44
51
  PG.connect(connection_parameters)
@@ -53,11 +60,12 @@ module FlareUp
53
60
  when /password authentication failed for user/
54
61
  raise AuthenticationError, "Either username '#{@user}' or password invalid"
55
62
  else
56
- raise UnknownError
63
+ raise UnknownError, e.message
57
64
  end
58
65
  end
59
66
  end
60
67
 
68
+ # http://www.postgresql.org/docs/9.3/static/libpq-connect.html#LIBPQ-PARAMKEYWORDS
61
69
  def connection_parameters
62
70
  {
63
71
  :host => @host,
@@ -65,7 +73,17 @@ module FlareUp
65
73
  :dbname => @dbname,
66
74
  :user => @user,
67
75
  :password => @password,
68
- :connect_timeout => @connect_timeout
76
+ :connect_timeout => @connect_timeout,
77
+ # Enable keep-alives
78
+ :keepalives => 1,
79
+ # Idle time in between keep-alives when there is a response from the peer
80
+ :keepalives_idle => 30,
81
+ # Interval between keep-alives when there is no response from the peer
82
+ # This is done to probe the peer until there is a response
83
+ :keepalives_interval => 10,
84
+ # Number of keep-alives that can be lost before the client's connection
85
+ # to the server is considered dead
86
+ :keepalives_count => 3
69
87
  }
70
88
  end
71
89
 
@@ -14,6 +14,16 @@ module FlareUp
14
14
  $stderr.puts sanitize("\x1b[31m#{message}") unless ENV['TESTING']
15
15
  end
16
16
 
17
+ # TODO: How do we test this?
18
+ def self.success(message)
19
+ $stdout.puts sanitize("\x1b[32m#{message}") unless ENV['TESTING']
20
+ end
21
+
22
+ # TODO: How do we test this?
23
+ def self.warn(message)
24
+ $stdout.puts sanitize("\x1b[33m#{message}") unless ENV['TESTING']
25
+ end
26
+
17
27
  # TODO: How do we test this?
18
28
  def self.info(message)
19
29
  $stdout.puts sanitize(message) unless ENV['TESTING']
@@ -1,3 +1,3 @@
1
1
  module FlareUp
2
- VERSION = '0.6'
2
+ VERSION = '0.7'
3
3
  end
@@ -1,13 +1,15 @@
1
1
  describe FlareUp::Boot do
2
2
 
3
3
  describe '.boot' do
4
+ let(:connection) { instance_double('FlareUp::Connection') }
4
5
  let(:copy_command) { instance_double('FlareUp::CopyCommand') }
5
6
 
6
7
  before do
7
8
  allow(copy_command).to receive(:get_command)
8
9
  end
9
10
 
10
- context 'when there is an error' do
11
+ context 'when there is an error connecting' do
12
+
11
13
  before do
12
14
  expect(FlareUp::Boot).to receive(:create_copy_command).and_return(copy_command)
13
15
  expect(copy_command).to receive(:execute).and_raise(copy_command_error)
@@ -39,6 +41,55 @@ describe FlareUp::Boot do
39
41
 
40
42
  end
41
43
 
44
+ context 'when there is an error copying' do
45
+
46
+ before do
47
+ expect(FlareUp::Boot).to receive(:create_connection).and_return(connection)
48
+ expect(connection).to receive(:execute).and_raise(connection_error)
49
+ end
50
+
51
+ context 'when there is a HostUnknownOrInaccessibleError' do
52
+ let(:connection_error) { FlareUp::HostUnknownOrInaccessibleError }
53
+ it 'should handle the error' do
54
+ expect(FlareUp::CLI).to receive(:bailout).with(1)
55
+ expect { FlareUp::Boot.boot({}) }.not_to raise_error
56
+ end
57
+ end
58
+
59
+ context 'when there is a TimeoutError' do
60
+ let(:connection_error) { FlareUp::TimeoutError }
61
+ it 'should handle the error' do
62
+ expect(FlareUp::CLI).to receive(:bailout).with(1)
63
+ expect { FlareUp::Boot.boot({}) }.not_to raise_error
64
+ end
65
+ end
66
+
67
+ context 'when there is a NoDatabaseError' do
68
+ let(:connection_error) { FlareUp::NoDatabaseError }
69
+ it 'should handle the error' do
70
+ expect(FlareUp::CLI).to receive(:bailout).with(1)
71
+ expect { FlareUp::Boot.boot({}) }.not_to raise_error
72
+ end
73
+ end
74
+
75
+ context 'when there is a AuthenticationError' do
76
+ let(:connection_error) { FlareUp::AuthenticationError }
77
+ it 'should handle the error' do
78
+ expect(FlareUp::CLI).to receive(:bailout).with(1)
79
+ expect { FlareUp::Boot.boot({}) }.not_to raise_error
80
+ end
81
+ end
82
+
83
+ context 'when there is a UnknownError' do
84
+ let(:connection_error) { FlareUp::UnknownError }
85
+ it 'should handle the error' do
86
+ expect(FlareUp::CLI).to receive(:bailout).with(1)
87
+ expect { FlareUp::Boot.boot({}) }.not_to raise_error
88
+ end
89
+ end
90
+
91
+ end
92
+
42
93
  end
43
94
 
44
95
  describe '.create_connection' do
@@ -4,6 +4,8 @@ describe FlareUp::Connection do
4
4
  FlareUp::Connection.new('TEST_HOST', 'TEST_DB_NAME', 'TEST_USER', 'TEST_PASSWORD')
5
5
  end
6
6
 
7
+ let(:mock_pg_connection) { instance_double('PGConn') }
8
+
7
9
  its(:host) { should == 'TEST_HOST' }
8
10
  its(:port) { should == 5439 }
9
11
  its(:dbname) { should == 'TEST_DB_NAME' }
@@ -97,7 +99,6 @@ describe FlareUp::Connection do
97
99
  end
98
100
 
99
101
  describe '#connection_parameters' do
100
-
101
102
  it 'should return the required parameters' do
102
103
  expect(subject.send(:connection_parameters)).to eq({
103
104
  :host => 'TEST_HOST',
@@ -106,9 +107,32 @@ describe FlareUp::Connection do
106
107
  :user => 'TEST_USER',
107
108
  :password => 'TEST_PASSWORD',
108
109
  :connect_timeout => 5,
110
+ :keepalives => 1,
111
+ :keepalives_idle => 30,
112
+ :keepalives_interval => 10,
113
+ :keepalives_count => 3
109
114
  })
110
115
  end
116
+ end
111
117
 
118
+ describe '#execute' do
119
+ before do
120
+ allow(subject).to receive(:connect).and_return(mock_pg_connection)
121
+ end
122
+ it 'should execute the specified command' do
123
+ expect(mock_pg_connection).to receive(:async_exec).with('TEST_STATEMENT')
124
+ subject.execute('TEST_STATEMENT')
125
+ end
126
+ end
127
+
128
+ describe '#cancel_current_command' do
129
+ before do
130
+ allow(subject).to receive(:connect).and_return(mock_pg_connection)
131
+ end
132
+ it 'should execute the specified command' do
133
+ expect(mock_pg_connection).to receive(:cancel)
134
+ subject.cancel_current_command
135
+ end
112
136
  end
113
137
 
114
138
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flare-up
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.6'
4
+ version: '0.7'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Slifka
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-12 00:00:00.000000000 Z
11
+ date: 2014-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg