pg_export 1.0.0.rc4 → 1.0.0.rc8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +42 -6
  3. data/CHANGELOG.md +10 -5
  4. data/README.md +63 -32
  5. data/bin/pg_export +15 -134
  6. data/lib/pg_export/{lib/pg_export/adapters/bash_adapter.rb → adapters/shell_adapter.rb} +1 -1
  7. data/lib/pg_export/commands_factory.rb +158 -0
  8. data/lib/pg_export/configuration.rb +74 -31
  9. data/lib/pg_export/configuration_parser.rb +126 -0
  10. data/lib/pg_export/entities/dump.rb +57 -0
  11. data/lib/pg_export/{lib/pg_export/factories → factories}/cipher_factory.rb +8 -4
  12. data/lib/pg_export/{lib/pg_export/factories → factories}/dump_factory.rb +1 -2
  13. data/lib/pg_export/{lib/pg_export/factories → factories}/ftp_gateway_factory.rb +8 -5
  14. data/lib/pg_export/{lib/pg_export/repositories/gateway_dump_file_repository.rb → factories/gateway_dump_file_factory.rb} +4 -5
  15. data/lib/pg_export/{lib/pg_export/factories → factories}/ssh_gateway_factory.rb +8 -5
  16. data/lib/pg_export/{lib/pg_export/gateways → gateways}/ftp.rb +1 -3
  17. data/lib/pg_export/{lib/pg_export/gateways → gateways}/ssh.rb +2 -6
  18. data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/build_dump.rb +1 -1
  19. data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/close_connection.rb +1 -1
  20. data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/decrypt_dump.rb +0 -0
  21. data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/download_dump.rb +0 -0
  22. data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/encrypt_dump.rb +0 -0
  23. data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/fetch_dumps.rb +0 -0
  24. data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/open_connection.rb +0 -0
  25. data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/remove_old_dumps.rb +1 -1
  26. data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/restore.rb +1 -1
  27. data/lib/pg_export/listeners/interactive/select_database.rb +12 -0
  28. data/lib/pg_export/listeners/interactive/select_dump.rb +12 -0
  29. data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/upload_dump.rb +1 -1
  30. data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive_listener.rb +4 -3
  31. data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/build_dump.rb +0 -0
  32. data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/close_connection.rb +0 -0
  33. data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/decrypt_dump.rb +0 -0
  34. data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/download_dump.rb +0 -0
  35. data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/encrypt_dump.rb +0 -0
  36. data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/fetch_dumps.rb +0 -0
  37. data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/open_connection.rb +0 -0
  38. data/lib/pg_export/listeners/plain/prepare_params.rb +15 -0
  39. data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/remove_old_dumps.rb +0 -0
  40. data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/restore.rb +0 -0
  41. data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/upload_dump.rb +0 -0
  42. data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain_listener.rb +11 -5
  43. data/lib/pg_export/operations/decrypt_dump.rb +30 -0
  44. data/lib/pg_export/operations/encrypt_dump.rb +27 -0
  45. data/lib/pg_export/operations/open_connection.rb +28 -0
  46. data/lib/pg_export/operations/remove_old_dumps.rb +34 -0
  47. data/lib/pg_export/{lib/pg_export/repositories → repositories}/gateway_dump_repository.rb +4 -9
  48. data/lib/pg_export/transactions/evaluator.rb +59 -0
  49. data/lib/pg_export/transactions/export_dump.rb +62 -0
  50. data/lib/pg_export/transactions/import_dump_interactively.rb +78 -0
  51. data/lib/pg_export/{lib/pg_export/ui → ui}/interactive/input.rb +0 -0
  52. data/lib/pg_export/{lib/pg_export/ui → ui}/plain/input.rb +0 -0
  53. data/lib/pg_export/{lib/pg_export/value_objects → value_objects}/dump_file.rb +2 -2
  54. data/lib/pg_export/value_objects/result.rb +49 -0
  55. data/lib/pg_export/version.rb +1 -1
  56. data/lib/pg_export.rb +14 -11
  57. data/pg_export.gemspec +2 -9
  58. metadata +57 -129
  59. data/lib/pg_export/container.rb +0 -23
  60. data/lib/pg_export/import.rb +0 -7
  61. data/lib/pg_export/lib/pg_export/entities/dump.rb +0 -45
  62. data/lib/pg_export/lib/pg_export/operations/decrypt_dump.rb +0 -20
  63. data/lib/pg_export/lib/pg_export/operations/encrypt_dump.rb +0 -18
  64. data/lib/pg_export/lib/pg_export/operations/open_connection.rb +0 -19
  65. data/lib/pg_export/lib/pg_export/operations/remove_old_dumps.rb +0 -26
  66. data/lib/pg_export/lib/pg_export/transactions/export_dump.rb +0 -56
  67. data/lib/pg_export/lib/pg_export/transactions/import_dump_interactively.rb +0 -67
  68. data/lib/pg_export/lib/pg_export/types.rb +0 -14
  69. data/lib/pg_export/system/boot/config.rb +0 -27
  70. data/lib/pg_export/system/boot/ftp.rb +0 -11
  71. data/lib/pg_export/system/boot/interactive.rb +0 -26
  72. data/lib/pg_export/system/boot/operations.rb +0 -17
  73. data/lib/pg_export/system/boot/plain.rb +0 -27
  74. data/lib/pg_export/system/boot/ssh.rb +0 -11
@@ -1,42 +1,85 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pg_export/lib/pg_export/types'
4
- require 'dry-struct'
3
+ require 'optparse'
5
4
 
6
5
  class PgExport
7
- class Configuration < Dry::Struct
8
- attribute :encryption_key, PgExport::Types::Strict::String.constrained(size: 16)
9
- attribute :encryption_algorithm, PgExport::Types::Strict::String
10
- attribute :gateway_host, PgExport::Types::Strict::String
11
- attribute :gateway_user, PgExport::Types::Strict::String
12
- attribute :gateway_password, PgExport::Types::Strict::String.optional
13
- attribute :logger_format, PgExport::Types::Coercible::String.enum('plain', 'timestamped', 'muted')
14
- attribute :keep_dumps, PgExport::Types::Coercible::Integer.constrained(gteq: 0)
15
-
16
- def self.build(env)
17
- new(
18
- encryption_key: env['PG_EXPORT_ENCRYPTION_KEY'],
19
- encryption_algorithm: env['PG_EXPORT_ENCRYPTION_ALGORITHM'],
20
- gateway_host: env['PG_EXPORT_GATEWAY_HOST'],
21
- gateway_user: env['PG_EXPORT_GATEWAY_USER'],
22
- gateway_password: env['PG_EXPORT_GATEWAY_PASSWORD'] == '' ? nil : env['PG_EXPORT_GATEWAY_PASSWORD'],
23
- logger_format: env['LOGGER_FORMAT'] || 'plain',
24
- keep_dumps: env['KEEP_DUMPS'] || 10
25
- )
26
- rescue Dry::Struct::Error => e
27
- raise PgExport::InitializationError, e.message.gsub('[PgExport::Configuration.new] ', '')
28
- end
6
+ class Configuration
7
+ ATTRS = %i[
8
+ encryption_key
9
+ encryption_algorithm
10
+ gateway_host
11
+ gateway_user
12
+ gateway_password
13
+ logger_format
14
+ keep_dumps
15
+ gateway mode
16
+ database
17
+ command
18
+ ].freeze
29
19
 
30
- def gateway
31
- ENV['GATEWAY'].to_sym
32
- end
20
+ attr_reader *ATTRS
21
+
22
+ def initialize(
23
+ encryption_key: nil,
24
+ encryption_algorithm: nil,
25
+ gateway_host: nil,
26
+ gateway_user: nil,
27
+ gateway_password: nil,
28
+ logger_format: nil,
29
+ keep_dumps: nil,
30
+ gateway: nil,
31
+ mode: nil,
32
+ database: nil,
33
+ command: nil
34
+ )
35
+
36
+ @encryption_key = String(encryption_key)
37
+ raise ArgumentError, 'Encryption key must be 16 chars long' if @encryption_key.length != 16
38
+
39
+ @encryption_algorithm = String(encryption_algorithm)
40
+ @encryption_algorithm = 'AES-128-CBC' if @encryption_algorithm.empty?
41
+
42
+ @gateway_host = String(gateway_host)
43
+ raise ArgumentError, 'Gatway host must not be empty' if @gateway_host.empty?
44
+
45
+ @gateway_user = String(gateway_user)
46
+ raise ArgumentError, 'Gatway user must not be empty' if @gateway_user.empty?
33
47
 
34
- def mode
35
- ENV['PG_EXPORT_MODE'].to_sym
48
+ @gateway_password = nil if gateway_password.nil? || gateway_password.to_s.empty?
49
+
50
+ @logger_format = logger_format.to_s.to_sym
51
+ @logger_format = :plain if @logger_format.empty?
52
+ unless %i[plain timestamped muted].include?(@logger_format)
53
+ raise ArgumentError, 'Logger format must be one of: plain, timestamped, muted'
54
+ end
55
+
56
+ @keep_dumps = Integer(keep_dumps || 10)
57
+ raise ArgumentError, 'Keep dumps must greater or equal to 1' unless @keep_dumps >= 1
58
+
59
+ @gateway = gateway.to_s.to_sym
60
+ @gateway = :ftp if @gateway.empty?
61
+ raise ArgumentError, 'Gateway must be one of: ftp, ssh' unless %i[ftp ssh].include?(@gateway)
62
+
63
+ @mode = mode.to_s.to_sym
64
+ @mode = :plain if @mode.empty?
65
+ raise ArgumentError, 'Mode must be one of: plain, interactive' unless %i[plain interactive].include?(@mode)
66
+
67
+ @database = String(database) unless database.nil?
68
+
69
+ @command = command.to_s.to_sym
70
+ @command = :export_dump if @command.empty?
36
71
  end
37
72
 
38
- def logger_muted?
39
- logger_format == 'muted'
73
+ def to_s
74
+ ATTRS.map do |name|
75
+ value = public_send(name)
76
+
77
+ if %i[encryption_key gateway_password].include?(name)
78
+ " #{name} #{value.nil? ? '' : value[0..2] + '***'}"
79
+ else
80
+ " #{name} #{value}"
81
+ end
82
+ end.join("\n")
40
83
  end
41
84
  end
42
85
  end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'optparse'
4
+ require 'pg_export/configuration'
5
+
6
+ class PgExport
7
+ class ConfigurationParser
8
+ class Error < OptionParser::ParseError; end
9
+
10
+ class << self
11
+ def parse
12
+ h = {
13
+ encryption_key: ENV['PG_EXPORT_ENCRYPTION_KEY'],
14
+ encryption_algorithm: ENV['PG_EXPORT_ENCRYPTION_ALGORITHM'],
15
+ gateway_user: ENV['PG_EXPORT_GATEWAY_USER'],
16
+ gateway_host: ENV['PG_EXPORT_GATEWAY_HOST'],
17
+ gateway_password: ENV['PG_EXPORT_GATEWAY_PASSWORD'],
18
+ logger_format: ENV['PG_EXPORT_LOGGER_FORMAT'],
19
+ keep_dumps: ENV['PG_EXPORT_KEEP_DUMPS'],
20
+ gateway: ENV['PG_EXPORT_GATEWAY'],
21
+ database: ENV['PG_EXPORT_DATABASE'],
22
+ mode: ENV['PG_EXPORT_MODE'],
23
+ command: :export_dump
24
+ }
25
+
26
+ option_parser(h).parse!
27
+ h[:database] = ARGV.first unless ARGV.empty?
28
+
29
+ Configuration.new(**h)
30
+ rescue OptionParser::ParseError => e
31
+ error = Error.new(*e.args)
32
+ error.reason = e.reason
33
+ raise error
34
+ end
35
+
36
+ def help
37
+ option_parser.to_s
38
+ end
39
+
40
+ BANNER = <<~TXT
41
+ NAME
42
+ pg_export - CLI for exporting/importing PostgreSQL dumps via FTP/SSH
43
+
44
+ SYNOPSIS
45
+ pg_export DATABASE [OPTION..]
46
+ pg_export --interactive DATABASE [OPTION..]
47
+
48
+ EXIT VALUES
49
+ 0 - Success
50
+ 1 - Error
51
+
52
+ ARGUMENTS
53
+ DATABASE - database name to export (when default mode)
54
+ - phrase to filter database dumps by (when interactive mode)
55
+
56
+ OPTIONS
57
+ TXT
58
+
59
+ EXAMPLE = <<~TXT
60
+ ENV
61
+ Each of the above options can be also set using enviromental variables.
62
+ Use full option names prepending with PG_EXPORT_ phrase.
63
+ Command line options takes precedence over the ENVs.
64
+
65
+ Eg. below two commands are equivalent:
66
+ pg_export -s -U user -H host database_name -k 10
67
+
68
+ Is equivalent to:
69
+ export PG_EXPORT_GATEWAY_USER=user
70
+ export PG_EXPORT_GATEWAY_HOST=host
71
+ export PG_EXPORT_KEEP=20
72
+ pg_export -s database_name -k 10
73
+ TXT
74
+
75
+ N = "\n "
76
+
77
+ O = {
78
+ g: 'Allowed values: ftp, ssh. Default: ftp',
79
+ U: 'Gateway (ftp or ssh) user',
80
+ H: 'Gateway (ftp or ssh) host',
81
+ P: 'Gateway (ftp or ssh) password',
82
+ d: "In plain mode: database name to export;#{N}In interactive mode: phrase to filter by",
83
+ e: 'Dumps will be SSL encrypted using this key. Should have exactly 16 characters',
84
+ a: "Encryption cipher algorithm (default: AES-128-CBC);#{N}For available option see `$ openssl list -cipher-algorithms`",
85
+ k: 'Number of dump files to keep on FTP (default: 10)',
86
+ s: 'Same as "--gateway ssh". When set, the --gateway option is ignored',
87
+ f: 'Same as "--gateway ftp". When set, the --gateway option is ignored',
88
+ t: 'Prepends log messages with timestamps',
89
+ m: 'Mutes log messages. When set, the -t option is ignored. Prints message only on error',
90
+ i: 'Interactive mode, for importing dumps. Whan set, the -t and -m options are ignored',
91
+ w: 'Try connecting to the gateway (FTP or SSH) to verify the connection and exit',
92
+ c: 'Print the configuration and exit',
93
+ v: 'Print version',
94
+ h: 'Print this message and exit'
95
+ }.freeze
96
+ private_constant :BANNER, :EXAMPLE, :N, :O
97
+
98
+ def option_parser(h = {})
99
+ OptionParser.new do |o|
100
+ o.banner = BANNER
101
+ o.program_name = 'pg_export'
102
+ o.version = PgExport::VERSION
103
+ o.on('-g', '--gateway GATEWAY', %w[ftp ssh], O[:g]) { |v| h[:gateway] = v }
104
+ o.on('-U', '--user USER', String, O[:U]) { |v| h[:gateway_user] = v }
105
+ o.on('-H', '--host HOST', String, O[:H]) { |v| h[:gateway_host] = v }
106
+ o.on('-P', '--password PASSWORD', String, O[:P]) { |v| h[:gateway_password] = v }
107
+ o.on('-d', '--database DATABASE', String, O[:d]) { |v| h[:database] = v }
108
+ o.on('-e', '--encryption_key KEY', String, O[:e]) { |v| h[:encryption_key] = v }
109
+ o.on('-a', '--algorithm ALGORITHM', String, O[:a]) { |v| h[:encryption_algorithm] = v }
110
+ o.on('-k', '--keep KEEP', Integer, O[:k]) { |v| h[:keep_dumps] = v }
111
+ o.on('-s', '--ssh', O[:s]) { h[:gateway] = 'ssh' }
112
+ o.on('-f', '--ftp', O[:f]) { h[:gateway] = 'ftp' }
113
+ o.on('-t', '--timestamped', O[:t]) { h[:logger_format] = 'timestamped' }
114
+ o.on('-m', '--muted', O[:m]) { h[:logger_format] = 'muted' }
115
+ o.on('-i', '--interactive', O[:i]) { h[:command] = :import_dump_interactively }
116
+ o.on('-w', '--welcome', O[:w]) { h[:command] = :gateway_welcome }
117
+ o.on('-c', '--configuration', O[:c]) { h[:command] = :print_configuration }
118
+ o.on('-v', '--version', O[:v]) { h[:command] = :print_version }
119
+ o.on('-h', '--help', O[:h]) { h[:command] = :print_help }
120
+ o.separator ''
121
+ o.separator EXAMPLE
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ class PgExport
4
+ module Entities
5
+ class Dump
6
+ attr_reader :name, :type, :database, :file
7
+
8
+ def initialize(name: nil, type: nil, database: nil, file: nil)
9
+ @name = String(name)
10
+ raise ArgumentError, 'Dump name must not be empty' if @name.empty?
11
+ raise ArgumentError, 'Dump name does not match criteria' unless /.+_20[0-9]{6}_[0-9]{6}\Z/.match?(@name)
12
+
13
+ @type = String(type)
14
+ @type = 'plain' if @type.empty?
15
+ raise ArgumentError, 'Dump type must be one of: plain, encrypted' unless %w[plain encrypted].include?(@type)
16
+
17
+ @database = database
18
+
19
+ @file = file
20
+ @file = ValueObjects::DumpFile.new if @file.nil?
21
+ raise ArgumentError, "Invalid file type: #{@file.class}" unless @file.is_a?(ValueObjects::DumpFile)
22
+ end
23
+
24
+ def encrypt(cipher_factory:)
25
+ self.file = file.copy(cipher: cipher_factory.encryptor)
26
+ self.type = :encrypted
27
+
28
+ self
29
+ end
30
+
31
+ def decrypt(cipher_factory:)
32
+ self.file = file.copy(cipher: cipher_factory.decryptor)
33
+ self.type = :plain
34
+
35
+ self
36
+ end
37
+
38
+ def to_s
39
+ "#{name} (#{file.size_human})"
40
+ end
41
+
42
+ def file=(f)
43
+ @file = f
44
+
45
+ raise ArgumentError, "Invalid file type: '#{f}'" unless @file.is_a?(ValueObjects::DumpFile)
46
+ end
47
+
48
+ protected
49
+
50
+ def type=(t)
51
+ @type = t.to_s
52
+
53
+ raise ArgumentError, "Dump type '#{t}' must be one of: plain, encrypted" unless %w[plain encrypted].include?(@type)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'openssl'
4
- require 'pg_export/import'
5
4
 
6
5
  class PgExport
7
6
  module Factories
8
7
  class CipherFactory
9
- include Import['config']
8
+ def initialize(encryption_algorithm:, encryption_key:)
9
+ @encryption_algorithm = encryption_algorithm
10
+ @encryption_key = encryption_key
11
+ end
10
12
 
11
13
  def encryptor
12
14
  build_cipher(:encrypt)
@@ -18,10 +20,12 @@ class PgExport
18
20
 
19
21
  private
20
22
 
23
+ attr_reader :encryption_algorithm, :encryption_key
24
+
21
25
  def build_cipher(type)
22
- cipher = OpenSSL::Cipher.new(config.encryption_algorithm)
26
+ cipher = OpenSSL::Cipher.new(encryption_algorithm)
23
27
  cipher.public_send(type)
24
- cipher.key = config.encryption_key
28
+ cipher.key = encryption_key
25
29
  cipher
26
30
  end
27
31
  end
@@ -3,8 +3,7 @@
3
3
  require 'open3'
4
4
  require 'tempfile'
5
5
 
6
- require 'pg_export/lib/pg_export/entities/dump'
7
- require 'pg_export/import'
6
+ require 'pg_export/entities/dump'
8
7
 
9
8
  class PgExport
10
9
  module Factories
@@ -1,14 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # auto_register: false
4
-
5
- require 'pg_export/lib/pg_export/gateways/ftp'
6
- require 'pg_export/import'
3
+ require 'pg_export/gateways/ftp'
7
4
 
8
5
  class PgExport
9
6
  module Factories
10
7
  class FtpGatewayFactory
11
- include Import['config']
8
+ def initialize(config:)
9
+ @config = config
10
+ end
12
11
 
13
12
  def gateway
14
13
  ::PgExport::Gateways::Ftp.new(
@@ -17,6 +16,10 @@ class PgExport
17
16
  password: config.gateway_password
18
17
  )
19
18
  end
19
+
20
+ private
21
+
22
+ attr_reader :config
20
23
  end
21
24
  end
22
25
  end
@@ -1,13 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'open3'
4
- require 'pg_export/import'
5
- require 'pg_export/lib/pg_export/entities/dump'
6
- require 'pg_export/lib/pg_export/value_objects/dump_file'
4
+ require 'pg_export/entities/dump'
5
+ require 'pg_export/value_objects/dump_file'
7
6
 
8
7
  class PgExport
9
- module Repositories
10
- class GatewayDumpFileRepository
8
+ module Factories
9
+ class GatewayDumpFileFactory
11
10
  def by_name(name:, gateway:)
12
11
  file = ValueObjects::DumpFile.new
13
12
  gateway.get(file, name)
@@ -1,14 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # auto_register: false
4
-
5
- require 'pg_export/lib/pg_export/gateways/ssh'
6
- require 'pg_export/import'
3
+ require 'pg_export/gateways/ssh'
7
4
 
8
5
  class PgExport
9
6
  module Factories
10
7
  class SshGatewayFactory
11
- include Import['config']
8
+ def initialize(config:)
9
+ @config = config
10
+ end
12
11
 
13
12
  def gateway
14
13
  ::PgExport::Gateways::Ssh.new(
@@ -17,6 +16,10 @@ class PgExport
17
16
  password: config.gateway_password
18
17
  )
19
18
  end
19
+
20
+ private
21
+
22
+ attr_reader :config
20
23
  end
21
24
  end
22
25
  end
@@ -1,13 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # auto_register: false
4
-
5
3
  require 'net/ftp'
6
4
 
7
5
  class PgExport
8
6
  module Gateways
9
7
  class Ftp
10
- CHUNK_SIZE = (2**16).freeze
8
+ CHUNK_SIZE = (2**16)
11
9
 
12
10
  def initialize(host:, user:, password:)
13
11
  @host, @user, @password, @logger = host, user, password
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # auto_register: false
4
-
5
3
  require 'ed25519'
6
4
  require 'net/ssh'
7
5
  require 'net/scp'
@@ -9,8 +7,6 @@ require 'net/scp'
9
7
  class PgExport
10
8
  module Gateways
11
9
  class Ssh
12
- CHUNK_SIZE = (2**16).freeze
13
-
14
10
  def initialize(host:, user:, password:)
15
11
  @host, @user, @password, @logger = host, user, password
16
12
  end
@@ -25,7 +21,7 @@ class PgExport
25
21
  end
26
22
 
27
23
  def welcome
28
- open.exec!('hostname')
24
+ open.exec!('hostname; whoami')
29
25
  end
30
26
 
31
27
  def close
@@ -49,7 +45,7 @@ class PgExport
49
45
  end
50
46
 
51
47
  def delete(name)
52
- # @TODO
48
+ ssh.exec!("rm #{name}")
53
49
  end
54
50
 
55
51
  def persist(file, name)
@@ -7,7 +7,7 @@ class PgExport
7
7
  class Interactive
8
8
  class BuildDump < InteractiveListener
9
9
  def on_step(event)
10
- @spinner = build_spinner("Dumping database #{event[:args].first[:database_name]}")
10
+ @spinner = build_spinner("Dumping database #{event[:value][:database_name]}")
11
11
  end
12
12
 
13
13
  def on_step_succeeded(event)
@@ -7,7 +7,7 @@ class PgExport
7
7
  class Interactive
8
8
  class CloseConnection < InteractiveListener
9
9
  def on_step(*)
10
- @spinner = build_spinner('Closing FTP')
10
+ @spinner = build_spinner('Closing connection')
11
11
  end
12
12
 
13
13
  def on_step_succeeded(*)
@@ -7,7 +7,7 @@ class PgExport
7
7
  class Interactive
8
8
  class RemoveOldDumps < InteractiveListener
9
9
  def on_step(event)
10
- @spinner = build_spinner("Checking for old dumps on #{event[:args].first[:gateway]}")
10
+ @spinner = build_spinner("Checking for old dumps on #{event[:value][:gateway]}")
11
11
  end
12
12
 
13
13
  def on_step_succeeded(event)
@@ -7,7 +7,7 @@ class PgExport
7
7
  class Interactive
8
8
  class Restore < InteractiveListener
9
9
  def on_step(event)
10
- @spinner = build_spinner("Restoring dump to database #{event[:args].first[:database]}")
10
+ @spinner = build_spinner("Restoring dump to database #{event[:value][:database]}")
11
11
  end
12
12
 
13
13
  def on_step_succeeded(*)
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../interactive_listener'
4
+
5
+ class PgExport
6
+ module Listeners
7
+ class Interactive
8
+ class SelectDatabase < InteractiveListener
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../interactive_listener'
4
+
5
+ class PgExport
6
+ module Listeners
7
+ class Interactive
8
+ class SelectDump < InteractiveListener
9
+ end
10
+ end
11
+ end
12
+ end
@@ -7,7 +7,7 @@ class PgExport
7
7
  class Interactive
8
8
  class UploadDump < InteractiveListener
9
9
  def on_step(event)
10
- @spinner = build_spinner("Uploading #{event[:args].first[:dump]} to #{event[:args].first[:gateway]}")
10
+ @spinner = build_spinner("Uploading #{event[:value][:dump]} to #{event[:value][:gateway]}")
11
11
  end
12
12
 
13
13
  def on_step_succeeded(*)
@@ -1,13 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # auto_register: false
4
-
5
- require 'pg_export/import'
6
3
  require 'tty-spinner'
7
4
 
8
5
  class PgExport
9
6
  module Listeners
10
7
  class InteractiveListener
8
+ def on_step(*); end
9
+
10
+ def on_step_succeeded(*); end
11
+
11
12
  def on_step_failed(event)
12
13
  @spinner.error([error, self.class.red(event[:value][:message])].join("\n"))
13
14
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../plain_listener'
4
+
5
+ class PgExport
6
+ module Listeners
7
+ class Plain
8
+ class PrepareParams < PlainListener
9
+ def on_step_succeeded(event)
10
+ logger.info('Init')
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,17 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # auto_register: false
4
-
5
- require 'pg_export/import'
6
-
7
3
  class PgExport
8
4
  module Listeners
9
5
  class PlainListener
10
- include Import['logger']
6
+ def initialize(logger:)
7
+ @logger = logger
8
+ end
9
+
10
+ def on_step(*); end
11
+
12
+ def on_step_succeeded(*); end
11
13
 
12
14
  def on_step_failed(event)
13
15
  logger.info("Error: #{event[:value][:message]}")
14
16
  end
17
+
18
+ private
19
+
20
+ attr_reader :logger
15
21
  end
16
22
  end
17
23
  end