backup-gundua 2.3.1.1

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.
Files changed (52) hide show
  1. data/.document +5 -0
  2. data/.gitignore +5 -0
  3. data/CHANGELOG +77 -0
  4. data/LICENSE +9 -0
  5. data/README.textile +175 -0
  6. data/Rakefile +69 -0
  7. data/VERSION +1 -0
  8. data/backup.gemspec +123 -0
  9. data/bin/backup +124 -0
  10. data/generators/backup/backup_generator.rb +72 -0
  11. data/generators/backup/templates/config/backup.rb +202 -0
  12. data/generators/backup/templates/migrations/create_backup_tables.rb +18 -0
  13. data/generators/backup/templates/tasks/backup.rake +71 -0
  14. data/generators/backup_update/backup_update_generator.rb +50 -0
  15. data/generators/backup_update/templates/migrations/update_backup_tables.rb +27 -0
  16. data/lib/backup/adapters/archive.rb +34 -0
  17. data/lib/backup/adapters/base.rb +113 -0
  18. data/lib/backup/adapters/custom.rb +41 -0
  19. data/lib/backup/adapters/mysql.rb +54 -0
  20. data/lib/backup/adapters/postgresql.rb +56 -0
  21. data/lib/backup/adapters/sqlite.rb +25 -0
  22. data/lib/backup/command_helper.rb +11 -0
  23. data/lib/backup/configuration/adapter.rb +21 -0
  24. data/lib/backup/configuration/adapter_options.rb +8 -0
  25. data/lib/backup/configuration/attributes.rb +19 -0
  26. data/lib/backup/configuration/base.rb +55 -0
  27. data/lib/backup/configuration/helpers.rb +24 -0
  28. data/lib/backup/configuration/mail.rb +20 -0
  29. data/lib/backup/configuration/smtp.rb +8 -0
  30. data/lib/backup/configuration/storage.rb +8 -0
  31. data/lib/backup/connection/s3.rb +85 -0
  32. data/lib/backup/environment/base.rb +12 -0
  33. data/lib/backup/environment/rails.rb +17 -0
  34. data/lib/backup/environment/unix.rb +94 -0
  35. data/lib/backup/mail/base.rb +93 -0
  36. data/lib/backup/mail/mail.txt +7 -0
  37. data/lib/backup/record/base.rb +65 -0
  38. data/lib/backup/record/ftp.rb +37 -0
  39. data/lib/backup/record/local.rb +26 -0
  40. data/lib/backup/record/s3.rb +24 -0
  41. data/lib/backup/record/scp.rb +31 -0
  42. data/lib/backup/record/sftp.rb +36 -0
  43. data/lib/backup/storage/ftp.rb +36 -0
  44. data/lib/backup/storage/local.rb +24 -0
  45. data/lib/backup/storage/s3.rb +14 -0
  46. data/lib/backup/storage/scp.rb +28 -0
  47. data/lib/backup/storage/sftp.rb +29 -0
  48. data/lib/backup.rb +118 -0
  49. data/setup/backup.rb +202 -0
  50. data/setup/backup.sqlite3 +0 -0
  51. data/spec/configuration/attributes_spec.rb +35 -0
  52. metadata +185 -0
@@ -0,0 +1,202 @@
1
+ # Backup Configuration File
2
+ #
3
+ # Use the "backup" block to add backup settings to the configuration file.
4
+ # The argument before the "do" in (backup "argument" do) is called a "trigger".
5
+ # This acts as the identifier for the configuration.
6
+ #
7
+ # In the example below we have a "mysql-backup-s3" trigger for the backup setting.
8
+ # All the configuration is done inside this block. To initialize the backup process for this block,
9
+ # you invoke it using the following rake task:
10
+ #
11
+ # rake backup:run trigger="mysql-backup-s3"
12
+ #
13
+ # You can add as many backup block settings as you want, just be sure every trigger is unique and you can run
14
+ # each of them separately.
15
+ #
16
+ # ADAPTERS
17
+ # - MySQL
18
+ # - PostgreSQL
19
+ # - SQLite
20
+ # - Archive
21
+ # - Custom
22
+ #
23
+ # STORAGE METHODS
24
+ # - S3 (Amazon)
25
+ # - SCP (Remote Server)
26
+ # - FTP (Remote Server)
27
+ # - SFTP (Remote Server)
28
+ # - LOCAL (Local Server)
29
+ #
30
+ # GLOBAL OPTIONS
31
+ # - Keep Backups (keep_backups)
32
+ # - Encrypt With Pasword (encrypt_with_password)
33
+ # - Notify (notify)
34
+ #
35
+ # This is the "decrypt" command for all encrypted backups:
36
+ # sudo backup --decrypt /path/to/encrypted/file
37
+ #
38
+ # Each Backup Setting can contain:
39
+ # - 1 Adapter
40
+ # - 1 Storage Method
41
+ # - Multiple Global Options
42
+ #
43
+ # The combination of these, however, do not matter! So experiment with it.
44
+ #
45
+ # You can also let Backup notify you by email on successfully created backups.
46
+ # - Just uncomment the block of code below (notifier_settings) and fill in your credentials.
47
+ # - Then for set "notify" to "true" in each (backup) block you wish to be notified of.
48
+ #
49
+ # For more information on "Backup", please refer to the wiki on github
50
+ # http://wiki.github.com/meskyanichi/backup/configuration-file
51
+
52
+
53
+ # Notifier
54
+ # Uncomment this if you want to enable notification by email on successful backup runs
55
+ # You will also have to set "notify true" inside each backup block below to enable it for that particular backup
56
+ # notifier_settings do
57
+ #
58
+ # to "example1@gmail.com"
59
+ # from "example2@gmail.com"
60
+ #
61
+ # smtp do
62
+ # host "smtp.gmail.com"
63
+ # port "587"
64
+ # username "example1@gmail.com"
65
+ # password "example1password"
66
+ # authentication "plain"
67
+ # domain "localhost.localdomain"
68
+ # tls true
69
+ # end
70
+ #
71
+ # end
72
+
73
+
74
+ # Initialize with:
75
+ # rake backup:run trigger='mysql-backup-s3'
76
+ backup 'mysql-backup-s3' do
77
+
78
+ adapter :mysql do
79
+ user 'user'
80
+ password 'password'
81
+ database 'database'
82
+
83
+ # skip_tables ['table1', 'table2', 'table3']
84
+ #
85
+ # options do
86
+ # host '123.45.678.90'
87
+ # port '80'
88
+ # socket '/tmp/socket.sock'
89
+ # end
90
+ # additional_options '--single-transaction --quick'
91
+ end
92
+
93
+ storage :s3 do
94
+ access_key_id 'access_key_id'
95
+ secret_access_key 'secret_access_key'
96
+ bucket '/bucket/backups/mysql/'
97
+ use_ssl true
98
+ end
99
+
100
+ keep_backups 25
101
+ encrypt_with_password 'password'
102
+ notify false
103
+
104
+ end
105
+
106
+
107
+ # Initialize with:
108
+ # rake backup:run trigger='postgresql-backup-s3'
109
+ backup 'postgresql-backup-scp' do
110
+
111
+ adapter :postgresql do
112
+ user 'user'
113
+ database 'database'
114
+
115
+ # skip_tables ['table1', 'table2', 'table3']
116
+
117
+ # options do
118
+ # host '123.45.678.90'
119
+ # port '80'
120
+ # socket '/tmp/socket.sock'
121
+ # end
122
+ # additional_options '--clean --blobs'
123
+ end
124
+
125
+ storage :scp do
126
+ ip 'example.com'
127
+ user 'user'
128
+ password 'password'
129
+ path '/var/backups/postgresql/'
130
+ end
131
+
132
+ keep_backups :all
133
+ encrypt_with_password false
134
+ notify false
135
+
136
+ end
137
+
138
+
139
+ # Initialize with:
140
+ # rake backup:run trigger='archive-backup-ftp'
141
+ backup 'archive-backup-ftp' do
142
+
143
+ adapter :archive do
144
+ files ["#{RAILS_ROOT}/log", "#{RAILS_ROOT}/db"]
145
+ end
146
+
147
+ storage :ftp do
148
+ ip 'example.com'
149
+ user 'user'
150
+ password 'password'
151
+ path '/var/backups/archive/'
152
+ end
153
+
154
+ keep_backups 10
155
+ encrypt_with_password false
156
+ notify false
157
+
158
+ end
159
+
160
+
161
+ # Initialize with:
162
+ # rake backup:run trigger='custom-backup-sftp'
163
+ backup 'custom-backup-sftp' do
164
+
165
+ adapter :custom do
166
+ commands \
167
+ [ "mysqldump [options] [database] > :tmp_path/my_mysql_dump.sql",
168
+ "pg_dump [options] [database] > :tmp_path/my_postgresql_dump.sql",
169
+ "any_other_db_format [options] [database] > :tmp_path/my_any_other_db_format.sql" ]
170
+ end
171
+
172
+ storage :sftp do
173
+ ip 'example.com'
174
+ user 'user'
175
+ password 'password'
176
+ path '/var/backups/custom/'
177
+ end
178
+
179
+ keep_backups :all
180
+ encrypt_with_password 'password'
181
+ notify false
182
+
183
+ end
184
+
185
+
186
+ # Initializ with:
187
+ # rake backup:run trigger='sqlite-backup-local'
188
+ backup 'sqlite-backup-local' do
189
+
190
+ adapter :sqlite do
191
+ database "#{RAILS_ROOT}/db/production.sqlite3"
192
+ end
193
+
194
+ storage :local do
195
+ path "/path/to/storage/location/"
196
+ end
197
+
198
+ keep_backups :all
199
+ encrypt_with_password false
200
+ notify false
201
+
202
+ end
@@ -0,0 +1,18 @@
1
+ class CreateBackupTables < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :backup do |t|
4
+ t.string :trigger
5
+ t.string :adapter
6
+ t.string :filename
7
+ t.string :md5sum
8
+ t.string :path
9
+ t.string :bucket
10
+ t.string :type
11
+ t.timestamps
12
+ end
13
+ end
14
+
15
+ def self.down
16
+ drop_table :backup
17
+ end
18
+ end
@@ -0,0 +1,71 @@
1
+ namespace :backup do
2
+
3
+ desc "Run Backup Procedure."
4
+ task :run => :environment do
5
+ puts "Running: #{ENV['trigger']}."
6
+ Backup::Setup.new(ENV['trigger'], @backup_procedures).initialize_adapter
7
+ end
8
+
9
+ desc "Finds backup records by trigger"
10
+ task :find => :environment do
11
+ puts "Finding backup records with trigger: #{ENV['trigger']}."
12
+ backup = Backup::Setup.new(ENV['trigger'], @backup_procedures)
13
+ records = Array.new
14
+ case backup.procedure.storage_name.to_sym
15
+ when :s3 then records = Backup::Record::S3.all :conditions => {:trigger => ENV['trigger']}
16
+ when :scp then records = Backup::Record::SCP.all :conditions => {:trigger => ENV['trigger']}
17
+ when :ftp then records = Backup::Record::FTP.all :conditions => {:trigger => ENV['trigger']}
18
+ when :sftp then records = Backup::Record::SFTP.all :conditions => {:trigger => ENV['trigger']}
19
+ when :local then records = Backup::Record::Local.all :conditions => {:trigger => ENV['trigger']}
20
+ end
21
+
22
+ if ENV['table'].eql?("true")
23
+ puts Hirb::Helpers::AutoTable.render(records)
24
+ else
25
+ records.each do |record|
26
+ puts record.to_yaml
27
+ end
28
+ end
29
+ end
30
+
31
+ desc "Truncates all records for the specified \"trigger\", excluding the physical files on s3 or the remote server."
32
+ task :truncate => :environment do
33
+ puts "Truncating backup records with trigger: #{ENV['trigger']}."
34
+ Backup::Record::Base.destroy_all :trigger => ENV['trigger']
35
+ end
36
+
37
+ desc "Truncates everything."
38
+ task :truncate_all => :environment do
39
+ puts "Truncating all backup records."
40
+ Backup::Record::Base.destroy_all
41
+ end
42
+
43
+ desc "Destroys all records for the specified \"trigger\", including the physical files on s3 or the remote server."
44
+ task :destroy => :environment do
45
+ puts "Destroying backup records with trigger: #{ENV['trigger']}."
46
+ backup = Backup::Setup.new(ENV['trigger'], @backup_procedures)
47
+ case backup.procedure.storage_name.to_sym
48
+ when :s3 then Backup::Record::S3.destroy_all_backups backup.procedure, ENV['trigger']
49
+ when :scp then Backup::Record::SCP.destroy_all_backups backup.procedure, ENV['trigger']
50
+ when :ftp then Backup::Record::FTP.destroy_all_backups backup.procedure, ENV['trigger']
51
+ when :sftp then Backup::Record::SFTP.destroy_all_backups backup.procedure, ENV['trigger']
52
+ when :local then Backup::Record::Local.destroy_all_backups backup.procedure, ENV['trigger']
53
+ end
54
+ end
55
+
56
+ desc "Destroys all records for the specified \"trigger\", including the physical files on s3 or the remote server."
57
+ task :destroy_all => :environment do
58
+ puts "Destroying all backup records."
59
+ backup = Backup::Setup.new(false, @backup_procedures)
60
+ backup.procedures.each do |backup_procedure|
61
+ case backup_procedure.storage_name.to_sym
62
+ when :s3 then Backup::Record::S3.destroy_all_backups backup_procedure, backup_procedure.trigger
63
+ when :scp then Backup::Record::SCP.destroy_all_backups backup_procedure, backup_procedure.trigger
64
+ when :ftp then Backup::Record::FTP.destroy_all_backups backup_procedure, backup_procedure.trigger
65
+ when :sftp then Backup::Record::SFTP.destroy_all_backups backup_procedure, backup_procedure.trigger
66
+ when :local then Backup::Record::Local.destroy_all_backups backup_procedure, backup_procedure.trigger
67
+ end
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,50 @@
1
+ class BackupUpdateGenerator < Rails::Generator::Base
2
+
3
+ # This method gets initialized when the generator gets run.
4
+ # It will receive an array of arguments inside @args
5
+ def initialize(runtime_args, runtime_options = {})
6
+ super
7
+ end
8
+
9
+ # Processes the file generation/templating
10
+ # This will automatically be run after the initialize method
11
+ def manifest
12
+ record do |m|
13
+
14
+ # Generates the database update migration file
15
+ m.migration_template "migrations/update_backup_tables.rb",
16
+ "db/migrate",
17
+ :migration_file_name => "update_backup_tables"
18
+
19
+ # Outputs the generators message to the terminal
20
+ puts message
21
+ end
22
+ end
23
+
24
+ def message
25
+ <<-MESSAGE
26
+
27
+
28
+
29
+ ==============================================================
30
+ Backup's update files have been generated!
31
+ ==============================================================
32
+
33
+ Please follow these instructions Backup:
34
+
35
+ 1: Please migrate the database to finish the update!
36
+
37
+ rake db:migrate
38
+
39
+
40
+ For More Information:
41
+ http://github.com/meskyanichi/backup
42
+
43
+ ==============================================================
44
+
45
+
46
+
47
+ MESSAGE
48
+ end
49
+
50
+ end
@@ -0,0 +1,27 @@
1
+ class UpdateBackupTables < ActiveRecord::Migration
2
+ def self.up
3
+ change_table :backup do |t|
4
+ t.rename :storage, :type # will use STI from now
5
+ t.string :md5sum
6
+ end
7
+
8
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='Backup::Record::FTP' WHERE type='ftp'"
9
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='Backup::Record::Local' WHERE type='local'"
10
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='Backup::Record::S3' WHERE type='s3'"
11
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='Backup::Record::SCP' WHERE type='scp'"
12
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='Backup::Record::SFTP' WHERE type='sftp'"
13
+ end
14
+
15
+ def self.down
16
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='ftp' WHERE type='Backup::Record::FTP'"
17
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='local' WHERE type='Backup::Record::Local'"
18
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='s3' WHERE type='Backup::Record::S3'"
19
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='scp' WHERE type='Backup::Record::SCP'"
20
+ ActiveRecord::Base.connection.execute "UPDATE backup SET type='sftp' WHERE type='Backup::Record::SFTP'"
21
+
22
+ change_table :backup do |t|
23
+ t.rename :type, :storage
24
+ t.remove :md5sum
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,34 @@
1
+ module Backup
2
+ module Adapters
3
+ class Archive < Backup::Adapters::Base
4
+
5
+ attr_accessor :files, :exclude
6
+
7
+ private
8
+
9
+ # Archives and Compresses all files
10
+ def perform
11
+ log system_messages[:archiving]; log system_messages[:compressing]
12
+ run "tar -czf #{File.join(tmp_path, compressed_file)} #{exclude_files} #{tar_files}"
13
+ end
14
+
15
+ def load_settings
16
+ self.files = procedure.get_adapter_configuration.attributes['files']
17
+ self.exclude = procedure.get_adapter_configuration.attributes['exclude']
18
+ end
19
+
20
+ def performed_file_extension
21
+ ".tar"
22
+ end
23
+
24
+ def tar_files
25
+ [*files].map{|f| f.gsub(' ', '\ ')}.join(' ')
26
+ end
27
+
28
+ def exclude_files
29
+ [*exclude].compact.map{|x| "--exclude=#{x}"}.join(' ')
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,113 @@
1
+ module Backup
2
+ module Adapters
3
+ class Base
4
+
5
+ include Backup::CommandHelper
6
+
7
+ attr_accessor :procedure, :timestamp, :options, :tmp_path, :encrypt_with_password, :keep_backups, :trigger
8
+
9
+ # IMPORTANT
10
+ # final_file must have the value of the final filename result
11
+ # so if a file gets compressed, then the file could look like this:
12
+ # myfile.gz
13
+ #
14
+ # and if a file afterwards gets encrypted, the file will look like:
15
+ # myfile.gz.enc
16
+ #
17
+ # It is important that, whatever the final filename of the file will be, that :final_file will contain it.
18
+ attr_accessor :performed_file, :compressed_file, :encrypted_file, :final_file
19
+
20
+ # Initializes the Backup Process
21
+ #
22
+ # This will first load in any prefixed settings from the Backup::Adapters::Base
23
+ # Then it will add it's own settings.
24
+ #
25
+ # First it will call the 'perform' method. This method is concerned with the backup, and must
26
+ # be implemented by derived classes!
27
+ # Then it will optionally encrypt the backed up file
28
+ # Then it will store it to the specified storage location
29
+ # Then it will record the data to the database
30
+ # Once this is all done, all the temporary files will be removed
31
+ #
32
+ # Wrapped inside of begin/ensure/end block to ensure the deletion of any files in the tmp directory
33
+ def initialize(trigger, procedure)
34
+ self.trigger = trigger
35
+ self.procedure = procedure
36
+ self.timestamp = Time.now.strftime("%Y%m%d%H%M%S")
37
+ self.tmp_path = File.join(BACKUP_PATH.gsub(' ', '\ '), 'tmp', 'backup', trigger)
38
+ self.encrypt_with_password = procedure.attributes['encrypt_with_password']
39
+ self.keep_backups = procedure.attributes['keep_backups']
40
+
41
+ self.performed_file = "#{timestamp}.#{trigger.gsub(' ', '-')}#{performed_file_extension}"
42
+ self.compressed_file = "#{performed_file}.gz"
43
+ self.encrypted_file = "#{compressed_file}.enc"
44
+ self.final_file = compressed_file
45
+
46
+ begin
47
+ create_tmp_folder
48
+ load_settings # if respond_to?(:load_settings)
49
+ perform
50
+ encrypt
51
+ store
52
+ record
53
+ notify
54
+ ensure
55
+ remove_tmp_files
56
+ end
57
+ end
58
+
59
+ # Creates the temporary folder for the specified adapter
60
+ def create_tmp_folder
61
+ run "mkdir -p #{tmp_path}"
62
+ end
63
+
64
+ # TODO make methods in derived classes public? respond_to cannot identify private methods
65
+ def load_settings
66
+ end
67
+
68
+ # Removes the files inside the temporary folder
69
+ def remove_tmp_files
70
+ run "rm #{File.join(tmp_path, '*')}"
71
+ end
72
+
73
+ # Encrypts the archive file
74
+ def encrypt
75
+ if encrypt_with_password.is_a?(String)
76
+ log system_messages[:encrypting]
77
+ run "openssl enc -des-cbc -in #{File.join(tmp_path, compressed_file)} -out #{File.join(tmp_path, encrypted_file)} -k #{encrypt_with_password}"
78
+ self.final_file = encrypted_file
79
+ end
80
+ end
81
+
82
+ # Initializes the storing process
83
+ def store
84
+ procedure.initialize_storage(self)
85
+ end
86
+
87
+ # Records data on every individual file to the database
88
+ def record
89
+ record = procedure.initialize_record
90
+ record.load_adapter(self)
91
+ record.save
92
+ end
93
+
94
+ # Delivers a notification by email regarding the successfully stored backup
95
+ def notify
96
+ if Backup::Mail::Base.setup?
97
+ Backup::Mail::Base.notify!(self)
98
+ end
99
+ end
100
+
101
+ def system_messages
102
+ { :compressing => "Compressing backup..",
103
+ :archiving => "Archiving backup..",
104
+ :encrypting => "Encrypting backup..",
105
+ :mysqldump => "Creating MySQL dump..",
106
+ :pgdump => "Creating PostgreSQL dump..",
107
+ :sqlite => "Copying and compressing SQLite database..",
108
+ :commands => "Executing commands.." }
109
+ end
110
+
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,41 @@
1
+ module Backup
2
+ module Adapters
3
+ class Custom < Backup::Adapters::Base
4
+
5
+ attr_accessor :commands
6
+
7
+ private
8
+
9
+ # Execute any given commands, then archive and compress every folder/file
10
+ def perform
11
+ execute_commands
12
+ targz
13
+ end
14
+
15
+ # Executes the commands
16
+ def execute_commands
17
+ return unless commands
18
+ log system_messages[:commands]
19
+ [*commands].each do |command|
20
+ run "#{command.gsub(':tmp_path', tmp_path)}"
21
+ end
22
+ end
23
+
24
+ # Archives and Compresses
25
+ def targz
26
+ log system_messages[:archiving]; log system_messages[:compressing]
27
+ run "tar -czf #{File.join(tmp_path, compressed_file)} #{File.join(tmp_path, '*')}"
28
+ end
29
+
30
+ def performed_file_extension
31
+ ".tar"
32
+ end
33
+
34
+ # Loads the initial settings
35
+ def load_settings
36
+ self.commands = procedure.get_adapter_configuration.attributes['commands']
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,54 @@
1
+ module Backup
2
+ module Adapters
3
+ class MySQL < Backup::Adapters::Base
4
+
5
+ attr_accessor :user, :password, :database, :skip_tables, :host, :port, :socket, :additional_options
6
+
7
+ private
8
+
9
+ # Dumps and Compresses the MySQL file
10
+ def perform
11
+ log system_messages[:mysqldump]; log system_messages[:compressing]
12
+ run "#{mysqldump} -u #{user} --password='#{password}' #{options} #{additional_options} #{database} #{tables_to_skip} | gzip -f --best > #{File.join(tmp_path, compressed_file)}"
13
+ end
14
+
15
+ def mysqldump
16
+ # try to determine the full path, and fall back to myqsldump if not found
17
+ cmd = `which mysqldump`.chomp
18
+ cmd = 'mysqldump' if cmd.empty?
19
+ cmd
20
+ end
21
+
22
+ def performed_file_extension
23
+ ".sql"
24
+ end
25
+
26
+ # Loads the initial settings
27
+ def load_settings
28
+ %w(user password database skip_tables additional_options).each do |attribute|
29
+ send(:"#{attribute}=", procedure.get_adapter_configuration.attributes[attribute])
30
+ end
31
+
32
+ %w(host port socket).each do |attribute|
33
+ send(:"#{attribute}=", procedure.get_adapter_configuration.get_options.attributes[attribute])
34
+ end
35
+ end
36
+
37
+ # Returns a list of options in MySQL syntax
38
+ def options
39
+ options = String.new
40
+ options += " --host='#{host}' " unless host.blank?
41
+ options += " --port='#{port}' " unless port.blank?
42
+ options += " --socket='#{socket}' " unless socket.blank?
43
+ options
44
+ end
45
+
46
+ # Returns a list of tables to skip in MySQL syntax
47
+ def tables_to_skip
48
+ return "" unless skip_tables
49
+ [*skip_tables].map {|table| " --ignore-table='#{database}.#{table}' "}
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,56 @@
1
+ module Backup
2
+ module Adapters
3
+ class PostgreSQL < Backup::Adapters::Base
4
+
5
+ attr_accessor :user, :password, :database, :skip_tables, :host, :port, :socket, :additional_options
6
+
7
+ private
8
+
9
+ # Dumps and Compresses the PostgreSQL file
10
+ def perform
11
+ log system_messages[:pgdump]; log system_messages[:compressing]
12
+ ENV['PGPASSWORD'] = password
13
+ run "#{pg_dump} -U #{user} #{options} #{additional_options} #{tables_to_skip} #{database} | gzip -f --best > #{File.join(tmp_path, compressed_file)}"
14
+ ENV['PGPASSWORD'] = nil
15
+ end
16
+
17
+ def pg_dump
18
+ # try to determine the full path, and fall back to pg_dump if not found
19
+ cmd = `which pg_dump`.chomp
20
+ cmd = 'pg_dump' if cmd.empty?
21
+ cmd
22
+ end
23
+
24
+ def performed_file_extension
25
+ ".sql"
26
+ end
27
+
28
+ # Loads the initial settings
29
+ def load_settings
30
+ %w(user password database skip_tables additional_options).each do |attribute|
31
+ send(:"#{attribute}=", procedure.get_adapter_configuration.attributes[attribute])
32
+ end
33
+
34
+ %w(host port socket).each do |attribute|
35
+ send(:"#{attribute}=", procedure.get_adapter_configuration.get_options.attributes[attribute])
36
+ end
37
+ end
38
+
39
+ # Returns a list of options in PostgreSQL syntax
40
+ def options
41
+ options = String.new
42
+ options += " --port='#{port}' " unless port.blank?
43
+ options += " --host='#{host}' " unless host.blank?
44
+ options += " --host='#{socket}' " unless socket.blank? unless options.include?('--host=')
45
+ options
46
+ end
47
+
48
+ # Returns a list of tables to skip in PostgreSQL syntax
49
+ def tables_to_skip
50
+ return "" unless skip_tables
51
+ [*skip_tables].map {|table| " -T \"#{table}\" "}
52
+ end
53
+
54
+ end
55
+ end
56
+ end