pg_export 0.6.1 → 0.7.0
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 +5 -5
- data/.rubocop.yml +9 -13
- data/.travis.yml +2 -2
- data/CHANGELOG.md +9 -0
- data/Gemfile +2 -0
- data/README.md +28 -29
- data/Rakefile +2 -0
- data/bin/console +2 -8
- data/bin/pg_export +44 -45
- data/lib/pg_export/build_logger.rb +4 -2
- data/lib/pg_export/configuration.rb +22 -2
- data/lib/pg_export/container.rb +48 -0
- data/lib/pg_export/import.rb +7 -0
- data/lib/pg_export/lib/pg_export/adapters/bash_adapter.rb +37 -0
- data/lib/pg_export/lib/pg_export/adapters/ftp_adapter.rb +67 -0
- data/lib/pg_export/lib/pg_export/entities/dump.rb +45 -0
- data/lib/pg_export/lib/pg_export/factories/cipher_factory.rb +32 -0
- data/lib/pg_export/lib/pg_export/factories/dump_factory.rb +31 -0
- data/lib/pg_export/lib/pg_export/factories/ftp_adapter_factory.rb +22 -0
- data/lib/pg_export/lib/pg_export/listeners/interactive/build_dump.rb +19 -0
- data/lib/pg_export/lib/pg_export/listeners/interactive/close_ftp_connection.rb +19 -0
- data/lib/pg_export/lib/pg_export/listeners/interactive/decrypt_dump.rb +19 -0
- data/lib/pg_export/lib/pg_export/listeners/interactive/download_dump_from_ftp.rb +19 -0
- data/lib/pg_export/lib/pg_export/listeners/interactive/encrypt_dump.rb +19 -0
- data/lib/pg_export/lib/pg_export/listeners/interactive/fetch_dumps_from_ftp.rb +19 -0
- data/lib/pg_export/lib/pg_export/listeners/interactive/open_ftp_connection.rb +19 -0
- data/lib/pg_export/lib/pg_export/listeners/interactive/remove_old_dumps_from_ftp.rb +23 -0
- data/lib/pg_export/lib/pg_export/listeners/interactive/restore.rb +19 -0
- data/lib/pg_export/lib/pg_export/listeners/interactive/upload_dump_to_ftp.rb +19 -0
- data/lib/pg_export/lib/pg_export/listeners/interactive_listener.rb +49 -0
- data/lib/pg_export/lib/pg_export/listeners/plain/build_dump.rb +15 -0
- data/lib/pg_export/lib/pg_export/listeners/plain/close_ftp_connection.rb +15 -0
- data/lib/pg_export/lib/pg_export/listeners/plain/decrypt_dump.rb +15 -0
- data/lib/pg_export/lib/pg_export/listeners/plain/download_dump_from_ftp.rb +15 -0
- data/lib/pg_export/lib/pg_export/listeners/plain/encrypt_dump.rb +15 -0
- data/lib/pg_export/lib/pg_export/listeners/plain/fetch_dumps_from_ftp.rb +15 -0
- data/lib/pg_export/lib/pg_export/listeners/plain/open_ftp_connection.rb +15 -0
- data/lib/pg_export/lib/pg_export/listeners/plain/remove_old_dumps_from_ftp.rb +17 -0
- data/lib/pg_export/lib/pg_export/listeners/plain/restore.rb +15 -0
- data/lib/pg_export/lib/pg_export/listeners/plain/upload_dump_to_ftp.rb +15 -0
- data/lib/pg_export/lib/pg_export/listeners/plain_listener.rb +17 -0
- data/lib/pg_export/lib/pg_export/operations/decrypt_dump.rb +20 -0
- data/lib/pg_export/lib/pg_export/operations/encrypt_dump.rb +18 -0
- data/lib/pg_export/lib/pg_export/operations/open_ftp_connection.rb +19 -0
- data/lib/pg_export/lib/pg_export/operations/remove_old_dumps_from_ftp.rb +22 -0
- data/lib/pg_export/lib/pg_export/repositories/ftp_dump_file_repository.rb +19 -0
- data/lib/pg_export/lib/pg_export/repositories/ftp_dump_repository.rb +36 -0
- data/lib/pg_export/lib/pg_export/transactions/export_dump.rb +56 -0
- data/lib/pg_export/lib/pg_export/transactions/import_dump_interactively.rb +67 -0
- data/lib/pg_export/lib/pg_export/types.rb +14 -0
- data/lib/pg_export/lib/pg_export/ui/interactive/input.rb +36 -0
- data/lib/pg_export/lib/pg_export/ui/plain/input.rb +17 -0
- data/lib/pg_export/lib/pg_export/value_objects/dump_file.rb +70 -0
- data/lib/pg_export/system/boot/config.rb +11 -0
- data/lib/pg_export/system/boot/interactive.rb +32 -0
- data/lib/pg_export/system/boot/logger.rb +15 -0
- data/lib/pg_export/system/boot/plain.rb +33 -0
- data/lib/pg_export/version.rb +3 -1
- data/lib/pg_export.rb +23 -20
- data/pg_export.gemspec +13 -10
- metadata +108 -52
- data/lib/pg_export/aes/base.rb +0 -47
- data/lib/pg_export/aes/decryptor.rb +0 -13
- data/lib/pg_export/aes/encryptor.rb +0 -13
- data/lib/pg_export/aes.rb +0 -3
- data/lib/pg_export/bash/adapter.rb +0 -31
- data/lib/pg_export/bash/factory.rb +0 -23
- data/lib/pg_export/bash/repository.rb +0 -18
- data/lib/pg_export/boot_container.rb +0 -69
- data/lib/pg_export/dump.rb +0 -62
- data/lib/pg_export/errors.rb +0 -5
- data/lib/pg_export/ftp/adapter.rb +0 -41
- data/lib/pg_export/ftp/connection.rb +0 -40
- data/lib/pg_export/ftp/repository.rb +0 -40
- data/lib/pg_export/roles/colourable_string.rb +0 -19
- data/lib/pg_export/roles/human_readable.rb +0 -17
- data/lib/pg_export/roles/interactive.rb +0 -98
- data/lib/pg_export/roles/validatable.rb +0 -24
- data/lib/pg_export/services/create_and_export_dump.rb +0 -20
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
class PgExport
|
|
2
|
-
module Ftp
|
|
3
|
-
class Repository
|
|
4
|
-
def initialize(adapter:, logger:)
|
|
5
|
-
@adapter, @logger = adapter, logger
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def persist(dump)
|
|
9
|
-
adapter.persist(dump.path, dump.timestamped_name)
|
|
10
|
-
logger.info "Persist #{dump} #{dump.timestamped_name} to #{adapter}"
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def get(db_name)
|
|
14
|
-
dump = Dump.new(name: 'Encrypted Dump', db_name: db_name)
|
|
15
|
-
adapter.get(dump.path, dump.db_name)
|
|
16
|
-
logger.info "Get #{dump} #{db_name} from #{adapter}"
|
|
17
|
-
dump
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def remove_old(name, keep)
|
|
21
|
-
find_by_name(name).drop(keep).each do |filename|
|
|
22
|
-
adapter.delete(filename)
|
|
23
|
-
logger.info "Remove #{filename} from #{adapter}"
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def find_by_name(name)
|
|
28
|
-
adapter.list(name + '_*')
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def all
|
|
32
|
-
adapter.list('*')
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
private
|
|
36
|
-
|
|
37
|
-
attr_reader :adapter, :logger
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
class PgExport
|
|
2
|
-
module Roles
|
|
3
|
-
module HumanReadable
|
|
4
|
-
MAPPING = {
|
|
5
|
-
'B' => 1024,
|
|
6
|
-
'kB' => 1024 * 1024,
|
|
7
|
-
'MB' => 1024 * 1024 * 1024,
|
|
8
|
-
'GB' => 1024 * 1024 * 1024 * 1024,
|
|
9
|
-
'TB' => 1024 * 1024 * 1024 * 1024 * 1024
|
|
10
|
-
}.freeze
|
|
11
|
-
|
|
12
|
-
def size_human
|
|
13
|
-
MAPPING.each_pair { |e, s| return "#{(size.to_f / (s / 1024)).round(2)}#{e}" if size < s }
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
require 'cli_spinnable'
|
|
2
|
-
require_relative 'colourable_string'
|
|
3
|
-
|
|
4
|
-
class PgExport
|
|
5
|
-
module Roles
|
|
6
|
-
module Interactive
|
|
7
|
-
include CliSpinnable
|
|
8
|
-
using ColourableString
|
|
9
|
-
|
|
10
|
-
def self.extended(_)
|
|
11
|
-
puts 'Interactive mode, for restoring dump into database.'.green
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def call(database, _keep_dumps = nil)
|
|
15
|
-
initialize_connection
|
|
16
|
-
dumps = print_all_dumps
|
|
17
|
-
dump = download_dump(select_dump(dumps))
|
|
18
|
-
t = Thread.new { container[:ftp_connection].close }
|
|
19
|
-
restore_downloaded_dump(dump, database)
|
|
20
|
-
t.join
|
|
21
|
-
puts 'Success'.green
|
|
22
|
-
self
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
def initialize_connection
|
|
28
|
-
with_spinner do |cli|
|
|
29
|
-
cli.print 'Connecting to FTP'
|
|
30
|
-
container[:ftp_connection].ftp
|
|
31
|
-
cli.tick
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def print_all_dumps
|
|
36
|
-
dumps = container[:ftp_repository].all
|
|
37
|
-
dumps.each.with_index(1) do |name, i|
|
|
38
|
-
print "(#{i}) "
|
|
39
|
-
puts name.to_s.gray
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
dumps
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def select_dump(dumps)
|
|
46
|
-
puts 'Which dump would you like to import?'
|
|
47
|
-
number = loop do
|
|
48
|
-
print "Type from 1 to #{dumps.count} (1): "
|
|
49
|
-
number = gets.chomp.to_i
|
|
50
|
-
break number if (1..dumps.count).cover?(number)
|
|
51
|
-
puts 'Invalid number. Please try again.'.red
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
dumps.fetch(number - 1)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def download_dump(name)
|
|
58
|
-
dump = nil
|
|
59
|
-
|
|
60
|
-
with_spinner do |cli|
|
|
61
|
-
cli.print "Downloading dump #{name}"
|
|
62
|
-
encrypted_dump = container[:ftp_repository].get(name)
|
|
63
|
-
cli.print " (#{encrypted_dump.size_human})"
|
|
64
|
-
cli.tick
|
|
65
|
-
cli.print "Decrypting dump #{name}"
|
|
66
|
-
dump = container[:decryptor].call(encrypted_dump)
|
|
67
|
-
cli.print " (#{dump.size_human})"
|
|
68
|
-
cli.tick
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
dump
|
|
72
|
-
rescue OpenSSL::Cipher::CipherError => e
|
|
73
|
-
puts "Problem decrypting dump file: #{e}. Try again.".red
|
|
74
|
-
retry
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def restore_downloaded_dump(dump, database)
|
|
78
|
-
puts 'To which database you would like to restore the downloaded dump?'
|
|
79
|
-
if database == 'undefined'
|
|
80
|
-
print 'Enter a local database name: '
|
|
81
|
-
else
|
|
82
|
-
print "Enter a local database name (#{database}): "
|
|
83
|
-
end
|
|
84
|
-
db_name = gets.chomp
|
|
85
|
-
db_name = db_name.empty? ? database : db_name
|
|
86
|
-
with_spinner do |cli|
|
|
87
|
-
cli.print "Restoring dump to #{db_name} database"
|
|
88
|
-
container[:bash_repository].persist(dump, db_name)
|
|
89
|
-
cli.tick
|
|
90
|
-
end
|
|
91
|
-
self
|
|
92
|
-
rescue PgRestoreError => e
|
|
93
|
-
puts e.to_s.red
|
|
94
|
-
retry
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
end
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
require 'dry-types'
|
|
2
|
-
|
|
3
|
-
class PgExport
|
|
4
|
-
module Roles
|
|
5
|
-
module Validatable
|
|
6
|
-
include Dry::Types.module
|
|
7
|
-
|
|
8
|
-
VALID_NON_EMPTY_STRING = Strict::String.constrained(min_size: 1)
|
|
9
|
-
VALID_POSITIVE_INTEGER = Strict::Int.constrained(gteq: 0)
|
|
10
|
-
|
|
11
|
-
def validate_database_name(database)
|
|
12
|
-
VALID_NON_EMPTY_STRING[database]
|
|
13
|
-
rescue Dry::Types::ConstraintError
|
|
14
|
-
raise ArgumentError, 'The "database" parameter has to be a valid, non-empty string'
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def validate_keep_dumps(keep_dumps)
|
|
18
|
-
VALID_POSITIVE_INTEGER[keep_dumps]
|
|
19
|
-
rescue Dry::Types::ConstraintError
|
|
20
|
-
raise ArgumentError, 'The "keep_dumps" parameter has to be a valid, non-negative integer'
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
class PgExport
|
|
2
|
-
module Services
|
|
3
|
-
class CreateAndExportDump
|
|
4
|
-
def initialize(bash_factory:, encryptor:, ftp_repository:)
|
|
5
|
-
@bash_factory, @encryptor, @ftp_repository = bash_factory, encryptor, ftp_repository
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def call(database_name, keep_dumps)
|
|
9
|
-
dump = bash_factory.build_dump(database_name)
|
|
10
|
-
encrypted_dump = encryptor.call(dump)
|
|
11
|
-
ftp_repository.persist(encrypted_dump)
|
|
12
|
-
ftp_repository.remove_old(database_name, keep_dumps)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
private
|
|
16
|
-
|
|
17
|
-
attr_reader :bash_factory, :encryptor, :ftp_repository
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|