siba-source-mysql 0.0.2

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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in siba-destination-mysql.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'minitest', :notify=>false do
5
+ watch(%r|^test/unit/(.*\/)*test_(.*)\.rb|)
6
+ watch(%r|^lib/siba-source-mysql/(.*\/)*([^/]+)\.rb|) do |m|
7
+ "test/unit/#{m[1]}test_#{m[2]}.rb" unless m[2][0] == '.'
8
+ end
9
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2012 Evgeny Neumerzhitskiy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,23 @@
1
+ # Overview
2
+
3
+ This is a plugin for [SIBA backup and restore utility](https://github.com/evgenyneu/siba). It allows to back and restore MySQL database.
4
+
5
+ ## Installation
6
+
7
+ $ gem install siba-source-mysql
8
+
9
+ ## Usage
10
+
11
+ 1. Create a configuration file:
12
+
13
+ $ siba generate mybak
14
+
15
+ 2. Backup:
16
+
17
+ $ siba backup mybak
18
+
19
+ 3. Restore:
20
+
21
+ $ siba restore mybak
22
+
23
+ Run `siba` command without arguments to see the list of all available options.
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ namespace "test" do
5
+ desc "Run all unit tests"
6
+ Rake::TestTask.new("unit") do |t|
7
+ t.pattern = "test/unit/**/test*.rb"
8
+ t.libs << 'test'
9
+ end
10
+
11
+ desc "Run all integration tests"
12
+ Rake::TestTask.new("integration") do |t|
13
+ t.pattern = "test/integration/**/i9n_*.rb"
14
+ t.libs << 'test'
15
+ end
16
+
17
+ desc "Run all integration tests"
18
+ task :i9n => ["test:integration"] do
19
+ end
20
+ end
21
+
22
+ desc "Run all unit tests"
23
+ task :test => ["test:unit"] do
24
+ end
25
+
26
+ desc "Run tests"
27
+ task :default => "test:unit"
28
+
@@ -0,0 +1,172 @@
1
+ # encoding: UTF-8
2
+
3
+ module Siba::Source
4
+ module Mysql
5
+ class Db
6
+ HIDE_PASSWORD_TEXT = "****p7d****"
7
+ BACKUP_FILE_NAME = "mysql_dump"
8
+ include Siba::FilePlug
9
+ include Siba::LoggerPlug
10
+
11
+ attr_accessor :options
12
+
13
+ def initialize(options)
14
+ @options = options
15
+
16
+ if !tables.nil? && !tables.empty? &&
17
+ (databases.nil? || (!databases.nil? && databases.size != 1))
18
+ raise Siba::CheckError, "When 'tables' option is set there must be a single database specified in 'databases' option."
19
+ end
20
+
21
+ Siba::Source::Mysql::Db.check_spaces_in_arrays databases, 'databases'
22
+ Siba::Source::Mysql::Db.check_spaces_in_arrays tables, 'tables'
23
+ Siba::Source::Mysql::Db.check_spaces_in_arrays ignore_tables, 'ignore_tables'
24
+
25
+ check_installed
26
+ end
27
+
28
+
29
+ def check_installed
30
+ msg = "utility is not found. Please make sure MySQL is installed and its bin directory is added to your PATH."
31
+ raise Siba::Error, "'mysqldump' #{msg}" unless siba_file.shell_ok? "mysqldump --help"
32
+ raise Siba::Error, "'mysql' #{msg}" unless siba_file.shell_ok? "mysql --help"
33
+ logger.debug "Mysql backup utilities verified"
34
+ end
35
+
36
+ def backup(dest_dir)
37
+ unless Siba::FileHelper.dir_empty? dest_dir
38
+ raise Siba::Error, "Failed to backup MySQL: output directory is not empty: #{dest_dir}"
39
+ end
40
+
41
+ path_to_backup = File.join dest_dir, BACKUP_FILE_NAME
42
+ command_without_password = %(mysqldump #{get_mysqldump_params} --routines --result-file="#{path_to_backup}")
43
+ command = command_without_password
44
+ unless password.nil?
45
+ command = command_without_password.gsub HIDE_PASSWORD_TEXT, password
46
+ end
47
+ logger.debug command_without_password
48
+ output = siba_file.run_shell command, "failed to backup MySQL: #{command_without_password}"
49
+ raise Siba::Error, "failed to backup MySQL: #{output}" if output =~ /ERROR:/
50
+
51
+ unless siba_file.file_file? path_to_backup
52
+ raise Siba::Error, "Failed to backup MySQL: backup file was not created"
53
+ end
54
+ end
55
+
56
+ def restore(from_dir)
57
+ path_to_backup = File.join from_dir, BACKUP_FILE_NAME
58
+ unless siba_file.file_file? path_to_backup
59
+ raise Siba::Error, "Failed to restore MySQL: backup file does not exist: #{path_to_backup}"
60
+ end
61
+
62
+ command_without_password = %(mysql -e "source #{path_to_backup}" --silent #{get_mysql_params})
63
+ command = command_without_password
64
+ unless password.nil?
65
+ command = command_without_password.gsub HIDE_PASSWORD_TEXT, password
66
+ end
67
+ logger.debug command_without_password
68
+ output = siba_file.run_shell command, "failed to restore MySQL: #{command_without_password}"
69
+ raise Siba::Error, "Failed to restore MySQL: #{output}" if output =~ /ERROR/
70
+ end
71
+
72
+ def get_mysqldump_params
73
+ params = []
74
+ OPTION_NAMES.each do |name|
75
+ val = options[name]
76
+ next if val.nil? && name != :databases
77
+ if MULTIPLE_CHOISES.include? name
78
+ case name
79
+ when :databases
80
+ if val.nil? || val.empty?
81
+ params << "--all-databases"
82
+ else
83
+ params << "--databases #{val.join(" ")}"
84
+ end
85
+ when :tables
86
+ params << "--tables #{val.join(" ")}"
87
+ when :ignore_tables
88
+ val.each do |ignore_table|
89
+ params << %(--ignore-table=#{ignore_table})
90
+ end
91
+ end
92
+ elsif name == :custom_parameters
93
+ params << val
94
+ else
95
+ params << Siba::Source::Mysql::Db.format_mysql_parameter(name, val)
96
+ end
97
+ end
98
+ params.join " "
99
+ end
100
+
101
+ def get_mysql_params
102
+ params = []
103
+ LOGIN_PARAMETERS.each do |name|
104
+ val = options[name]
105
+ next if val.nil?
106
+ params << Siba::Source::Mysql::Db.format_mysql_parameter(name, val)
107
+ end
108
+ params.join " "
109
+ end
110
+
111
+ def self.format_mysql_parameter(name, val)
112
+ val = HIDE_PASSWORD_TEXT if name == :password
113
+ val = escape_for_shell val
114
+ %(--#{name.to_s}="#{val}")
115
+ end
116
+
117
+ def self.escape_for_shell(str)
118
+ str.gsub "\"", "\\\""
119
+ end
120
+
121
+ def self.check_spaces_in_arrays(array, option_name)
122
+ unless array.nil? || array.empty?
123
+ array.each do |value|
124
+ value.strip!
125
+ if value.gsub(/[,;]/," ").split(" ").size > 1
126
+ raise Siba::CheckError, "'#{option_name}' value can not contain spaces or commas. If you need to specify multiple values please use YAML array sytax instead:
127
+ - one
128
+ - two
129
+ - three"
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ def method_missing(meth, *args, &block)
136
+ if method_defined? meth
137
+ options[meth]
138
+ else
139
+ super
140
+ end
141
+ end
142
+
143
+ def respond_to?(meth)
144
+ if method_defined? meth
145
+ true
146
+ else
147
+ super
148
+ end
149
+ end
150
+
151
+ def method_defined?(meth)
152
+ OPTION_NAMES.include? meth.to_sym
153
+ end
154
+
155
+ def db_and_table_names
156
+ names = []
157
+ unless databases.nil? || databases.empty?
158
+ names << "DB#{databases.size > 1 ? "s": ""}: #{databases.join(", ")}"
159
+ else
160
+ names << "all databases"
161
+ end
162
+
163
+ unless tables.nil? || tables.empty?
164
+ names << "table#{tables.size > 1 ? "s": ""}: #{tables.join(", ")}"
165
+ end
166
+ out = names.join(", ")
167
+ out = " (#{out})" unless out.empty?
168
+ out
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,62 @@
1
+ # encoding: UTF-8
2
+
3
+ require "siba-source-mysql/db"
4
+
5
+ module Siba::Source
6
+ module Mysql
7
+ OPTION_NAMES = [
8
+ :host,
9
+ :port,
10
+ :protocol,
11
+ :socket,
12
+ :user,
13
+ :password,
14
+ :databases,
15
+ :tables,
16
+ :ignore_tables,
17
+ :custom_parameters
18
+ ]
19
+
20
+ MULTIPLE_CHOISES = [:databases, :tables, :ignore_tables]
21
+ LOGIN_PARAMETERS = [:host, :port, :protocol, :socket, :user, :password]
22
+ ENV_PREFIX = "SIBA_MYSQL_"
23
+
24
+ class Init
25
+ include Siba::LoggerPlug
26
+
27
+ attr_accessor :db
28
+
29
+ def initialize(options)
30
+ parsed_options = {}
31
+ OPTION_NAMES.each do |option_name|
32
+ if MULTIPLE_CHOISES.include? option_name
33
+ value = Siba::SibaCheck.options_string_array options, option_name.to_s, true
34
+ else
35
+ value = Siba::SibaCheck.options_string options, option_name.to_s, true
36
+ if value.nil?
37
+ # try get the setting from environment variable
38
+ value = ENV["#{ENV_PREFIX}#{option_name.to_s.upcase}"]
39
+ end
40
+ end
41
+ parsed_options[option_name] = value
42
+ end
43
+
44
+ @db = Siba::Source::Mysql::Db.new parsed_options
45
+ end
46
+
47
+ # Collect source files and put them into dest_dir
48
+ # No return value is expected
49
+ def backup(dest_dir)
50
+ logger.info "Dumping MySQL#{db.db_and_table_names}"
51
+ @db.backup dest_dir
52
+ end
53
+
54
+ # Restore source files from_dir
55
+ # No return value is expected
56
+ def restore(from_dir)
57
+ logger.info "Restoring MySQL#{db.db_and_table_names}"
58
+ @db.restore from_dir
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,17 @@
1
+ host:
2
+ port:
3
+ protocol: # TCP|SOCKET|PIPE|MEMORY
4
+ socket:
5
+ user:
6
+ password:
7
+ databases: # backup all databases if empty
8
+ - db1
9
+ tables: # backup all tables if empty
10
+ - table1
11
+ - table2
12
+ ignore_tables:
13
+ - db1.table1
14
+ - db1.table2
15
+ custom_parameters: # additional parameters passed to mysqldump utility
16
+
17
+ # Note: all above mysql options are optional (except type)
@@ -0,0 +1,9 @@
1
+ # encoding: UTF-8
2
+
3
+ module Siba
4
+ module Source
5
+ module Mysql
6
+ VERSION = "0.0.2"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ require "siba-source-mysql/version"
4
+ require "siba-source-mysql/init"
5
+
6
+ module Siba
7
+ module Source
8
+ module Mysql
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "siba-source-mysql/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "siba-source-mysql"
7
+ s.version = Siba::Source::Mysql::VERSION
8
+ s.authors = ["Evgeny Neumerzhitskiy"]
9
+ s.email = ["sausageskin@gmail.com"]
10
+ s.homepage = "https://github.com/evgenyneu/siba-source-mysql"
11
+ s.license = "MIT"
12
+ s.summary = %q{MySQL backup and restore extention for SIBA utility}
13
+ s.description = %q{An extension for SIBA utility. It allows to backup and restore MySQL database.}
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_runtime_dependency 'siba', '~>0.5'
21
+
22
+ s.add_development_dependency 'minitest', '~>2.10'
23
+ s.add_development_dependency 'rake', '~>0.9'
24
+ s.add_development_dependency 'guard-minitest', '~>0.4'
25
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'siba/helpers/test/require'
4
+ SibaTest.init_integration
5
+
@@ -0,0 +1,4 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'siba/helpers/test/require'
4
+ SibaTest.init_unit
@@ -0,0 +1,95 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'helper/require_integration'
4
+ require 'siba-source-mysql/init'
5
+
6
+ describe Siba::Source::Mysql::Init do
7
+ TEST_DB_NAME = "siba_test_mysql_0992"
8
+ TEST_VALUE = rand 100000
9
+ include Siba::FilePlug
10
+
11
+ before do
12
+ @cls = Siba::Source::Mysql::Init
13
+ end
14
+
15
+ it "should backup and restore" do
16
+ puts "
17
+ ------------------
18
+ Note: to run integration tests on your MySQL database, please set required access parameters in environment variables: SIBA_MYSQL_USER, SIBA_MYSQL_PASSWORD, SIBA_MYSQL_HOST etc.
19
+ ------------------
20
+ "
21
+ begin
22
+ # insert test data into db
23
+ @obj = @cls.new({"databases" => [TEST_DB_NAME]})
24
+ drop_db
25
+ create_db
26
+ create_table
27
+ insert_row
28
+ count_rows.must_equal 1
29
+
30
+ # backup
31
+ out_dir = mkdir_in_tmp_dir "mysql"
32
+ @obj.backup out_dir
33
+ path_to_backup = File.join(out_dir, Siba::Source::Mysql::Db::BACKUP_FILE_NAME)
34
+ File.file?(path_to_backup).must_equal true
35
+
36
+ # add another row after backup
37
+ insert_row
38
+ count_rows.must_equal 2
39
+
40
+ # restore
41
+ @obj.restore out_dir
42
+ count_rows.must_equal 1, "Should restore db to one row"
43
+ ensure
44
+ drop_db rescue nil
45
+ end
46
+ end
47
+
48
+ def drop_db
49
+ sql("drop database if exists #{TEST_DB_NAME}")
50
+ end
51
+
52
+ def create_db
53
+ sql("create database #{TEST_DB_NAME}")
54
+ end
55
+
56
+ def create_table
57
+ sqldb("create table sibatest (id INT)")
58
+ end
59
+
60
+ def insert_row
61
+ sqldb(%(insert into sibatest values (123)))
62
+ end
63
+
64
+ def count_rows
65
+ sqldb(%(select count(*) from sibatest)).to_i
66
+ end
67
+
68
+ def sqldb(sql)
69
+ sql("#{use_database}#{sql}")
70
+ end
71
+
72
+ def sql(sql)
73
+ siba_file.run_shell(%(mysql --silent #{get_mysql_params} -e "#{sql}"))
74
+ end
75
+
76
+ def use_database
77
+ "use #{TEST_DB_NAME}; "
78
+ end
79
+
80
+ def get_mysql_params
81
+ params = @obj.db.get_mysql_params
82
+ unless @obj.db.password.nil?
83
+ params.gsub! Siba::Source::Mysql::Db::HIDE_PASSWORD_TEXT, @obj.db.password
84
+ end
85
+ params
86
+ end
87
+
88
+ def insert_value
89
+ siba_file.run_shell(%(mongo #{TEST_DB_NAME} --quiet --eval "db.foo.save({a: #{TEST_VALUE}})"))
90
+ end
91
+
92
+ def count_values
93
+ siba_file.run_shell(%(mongo #{TEST_DB_NAME} --quiet --eval "db.foo.count({a: #{TEST_VALUE}})")).to_i
94
+ end
95
+ end
@@ -0,0 +1,208 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'helper/require_unit'
4
+ require 'siba-source-mysql/init'
5
+
6
+ describe Siba::Source::Mysql::Db do
7
+ before do
8
+ @cls = Siba::Source::Mysql::Db
9
+ @fmock = mock_file :shell_ok?, true, [String]
10
+ end
11
+
12
+ it "should initialize" do
13
+ options = {a: "b"}
14
+ @obj = @cls.new options
15
+ @obj.options.must_equal options
16
+ end
17
+
18
+ it "init should raise error when table are specified with no databases" do
19
+ ->{@cls.new({tables: ["table"]})}.must_raise Siba::CheckError
20
+ end
21
+
22
+ it "init should raise error when table are specified with empty databases" do
23
+ ->{@cls.new({tables: ["table"], databases: []})}.must_raise Siba::CheckError
24
+ end
25
+
26
+ it "init should raise error when table are specified with more than one database" do
27
+ ->{@cls.new({tables: ["table"], databases: ["one", "two"]})}.must_raise Siba::CheckError
28
+ end
29
+
30
+ it "init should raise no error when table are specified with one database" do
31
+ @cls.new({tables: ["table"], databases: ["one"]})
32
+ end
33
+
34
+ it "init should raise error if databases contain spaces" do
35
+ ->{@cls.new({tables: ["table"], databases: ["with space"]})}.must_raise Siba::CheckError
36
+ end
37
+
38
+ it "init should raise error if tables contain spaces" do
39
+ ->{@cls.new({tables: ["table1 table2"], databases: ["data"]})}.must_raise Siba::CheckError
40
+ end
41
+
42
+ it "init should raise error if ignore_tables contains spaces" do
43
+ ->{@cls.new({ignore_tables: ["table1 table2"], databases: ["data"]})}.must_raise Siba::CheckError
44
+ end
45
+
46
+ it "should call db_and_table_names" do
47
+ @obj = @cls.new({})
48
+ @obj.db_and_table_names.must_equal " (all databases)"
49
+
50
+ @obj = @cls.new({databases: ["one"]})
51
+ @obj.db_and_table_names.must_equal " (DB: one)"
52
+
53
+ @obj = @cls.new({databases: ["one", "two"]})
54
+ @obj.db_and_table_names.must_equal " (DBs: one, two)"
55
+
56
+
57
+ @obj = @cls.new({tables: ["table"], databases: ["one"]})
58
+ @obj.db_and_table_names.must_equal " (DB: one, table: table)"
59
+
60
+ @obj = @cls.new({tables: ["table1", "table2"], databases: ["one"]})
61
+ @obj.db_and_table_names.must_equal " (DB: one, tables: table1, table2)"
62
+ end
63
+
64
+ it "must call check_spaces_in_arrays" do
65
+ @cls.check_spaces_in_arrays ["hi"], "name"
66
+ @cls.check_spaces_in_arrays [" hi "], "name"
67
+ @cls.check_spaces_in_arrays ["hi", "ho"], "name"
68
+ @cls.check_spaces_in_arrays nil, "name"
69
+ @cls.check_spaces_in_arrays [], "name"
70
+ end
71
+
72
+ it "check_spaces_in_arrays should fail" do
73
+ ->{@cls.check_spaces_in_arrays ["with space"], "name"}.must_raise Siba::CheckError
74
+ ->{@cls.check_spaces_in_arrays ["hi", "with space"], "name"}.must_raise Siba::CheckError
75
+ ->{@cls.check_spaces_in_arrays ["hi", "with,comma"], "name"}.must_raise Siba::CheckError
76
+ ->{@cls.check_spaces_in_arrays ["hi", "with, comma"], "name"}.must_raise Siba::CheckError
77
+ ->{@cls.check_spaces_in_arrays ["hi", "with;comma"], "name"}.must_raise Siba::CheckError
78
+ end
79
+
80
+ it "should call get_mysqldump_params" do
81
+ settings = {
82
+ host: "myhost",
83
+ port: "123",
84
+ protocol: "myTCP",
85
+ socket: "mysock",
86
+ user: "uname",
87
+ password: "my password"}
88
+ params = " " + @cls.new(settings).get_mysqldump_params
89
+ params.must_include %( --host="myhost")
90
+ params.must_include %( --port="123")
91
+ params.must_include %( --protocol="myTCP")
92
+ params.must_include %( --socket="mysock")
93
+ params.must_include %( --user="uname")
94
+ params.must_include %( --password="#{@cls::HIDE_PASSWORD_TEXT}")
95
+ params.must_include %( --all-databases)
96
+ end
97
+
98
+ it "get_mysqldump_params should contain database" do
99
+ settings = {
100
+ databases: ["db1"]
101
+ }
102
+ params = " " + @cls.new(settings).get_mysqldump_params
103
+ params.must_include %( --databases db1)
104
+ params.wont_include %( --all-databases)
105
+ end
106
+
107
+ it "get_mysqldump_params should contain databases" do
108
+ settings = {
109
+ databases: ["db1", "db2"]
110
+ }
111
+ params = " " + @cls.new(settings).get_mysqldump_params
112
+ params.must_include %( --databases db1 db2)
113
+ params.wont_include %( --all-databases)
114
+ end
115
+
116
+ it "get_mysqldump_params should contain table" do
117
+ settings = {
118
+ databases: ["db1"],
119
+ tables: ["table1"]
120
+ }
121
+ params = " " + @cls.new(settings).get_mysqldump_params
122
+ params.must_include %( --tables table1)
123
+ end
124
+
125
+ it "get_mysqldump_params should contain tables" do
126
+ settings = {
127
+ databases: ["db1"],
128
+ tables: ["table1", "table2"]
129
+ }
130
+ params = " " + @cls.new(settings).get_mysqldump_params
131
+ params.must_include %( --tables table1 table2)
132
+ end
133
+
134
+ it "get_mysqldump_params should contain ignore-table" do
135
+ settings = {
136
+ ignore_tables: ["ig1","ig2"]
137
+ }
138
+ params = " " + @cls.new(settings).get_mysqldump_params
139
+ params.must_include %( --ignore-table=ig1)
140
+ params.must_include %( --ignore-table=ig2)
141
+ end
142
+
143
+ it "get_mysqldump_params should contain databases" do
144
+ settings = {
145
+ databases: ["db1", "db2"]
146
+ }
147
+ params = " " + @cls.new(settings).get_mysqldump_params
148
+ params.must_include %( --databases db1 db2)
149
+ end
150
+
151
+ it "get_mysqldump_params should contain databases" do
152
+ custom_text = "this is a cutom text"
153
+ settings = {
154
+ custom_parameters: custom_text
155
+ }
156
+ params = " " + @cls.new(settings).get_mysqldump_params
157
+ params.must_include %( #{custom_text})
158
+ end
159
+
160
+ it "get_mysqldump_params should escape double quotes" do
161
+ settings = {
162
+ user: %(user"name)
163
+ }
164
+ params = " " + @cls.new(settings).get_mysqldump_params
165
+ params.must_include %( --user="user\\"name")
166
+ end
167
+
168
+ it "should call get_mysql_params" do
169
+ settings = {
170
+ host: "myhost",
171
+ port: "123",
172
+ protocol: "myTCP",
173
+ socket: "mysock",
174
+ user: "uname",
175
+ password: "my password"}
176
+ params = " " + @cls.new(settings).get_mysql_params
177
+ params.must_include %( --host="myhost")
178
+ params.must_include %( --port="123")
179
+ params.must_include %( --protocol="myTCP")
180
+ params.must_include %( --socket="mysock")
181
+ params.must_include %( --user="uname")
182
+ params.must_include %( --password="#{@cls::HIDE_PASSWORD_TEXT}")
183
+ params.wont_include %( --all-databases)
184
+ end
185
+
186
+ it "should espace for shell" do
187
+ @cls.escape_for_shell("hi\"").must_equal "hi\\\""
188
+ end
189
+
190
+ it "should call format_mysql_parameter" do
191
+ @cls.format_mysql_parameter(:name,%(val"val)).must_equal %(--name="val\\"val")
192
+ @cls.format_mysql_parameter(:password,%(pwd)).must_equal %(--password="#{@cls::HIDE_PASSWORD_TEXT}")
193
+ end
194
+
195
+ it "should run backup" do
196
+ @fmock.expect :run_this, true, []
197
+ @fmock.expect :dir_entries, [], [String]
198
+ @fmock.expect :run_shell, nil, [String, String]
199
+ @fmock.expect :file_file?, true, [String]
200
+ @cls.new({}).backup "/dest/dir"
201
+ end
202
+
203
+ it "should run restore" do
204
+ @fmock.expect :file_file?, true, [String]
205
+ @fmock.expect :run_shell, nil, [String, String]
206
+ @cls.new({}).restore "/from/dir"
207
+ end
208
+ end
@@ -0,0 +1,73 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'helper/require_unit'
4
+ require 'siba-source-mysql/init'
5
+
6
+ describe Siba::Source::Mysql::Init do
7
+ before do
8
+ @yml_path = File.expand_path('../yml', __FILE__)
9
+ options_hash = load_options "valid"
10
+ @fmock = mock_file :shell_ok?, true, [String]
11
+ @plugin = Siba::Source::Mysql::Init.new options_hash
12
+ end
13
+
14
+ it "should load plugin" do
15
+ @plugin.must_be_instance_of Siba::Source::Mysql::Init
16
+ @plugin.db.must_be_instance_of Siba::Source::Mysql::Db
17
+ opt = @plugin.db.options
18
+ opt[:host].must_equal "myhost"
19
+ opt[:port].must_equal "123"
20
+ opt[:protocol].must_equal "TCP"
21
+ opt[:socket].must_equal "/tmp/mysql.sock"
22
+
23
+ opt[:user].must_equal "myuser"
24
+ opt[:password].must_equal "mypassword"
25
+
26
+ opt[:databases].must_equal ["db1"]
27
+ opt[:tables].must_equal ["table1", "table2"]
28
+ opt[:ignore_tables].must_equal ["db1.table1", "db1.table2"]
29
+ opt[:custom_parameters].must_equal "--parameters"
30
+ end
31
+
32
+ it "should load plugin with empty options" do
33
+ Siba::Source::Mysql::Init.new({})
34
+ end
35
+
36
+ it "plugin should load options from environment variables" do
37
+ begin
38
+ env_user = ENV[env_var_name("USER")]
39
+ env_password = ENV[env_var_name("PASSWORD")]
40
+ env_host = ENV[env_var_name("HOST")]
41
+
42
+ ENV[env_var_name("USER")] = "myuser"
43
+ ENV[env_var_name("PASSWORD")] = "mypassword"
44
+ ENV[env_var_name("HOST")] = "myhost"
45
+ @plugin = Siba::Source::Mysql::Init.new({"host"=> "thishost"})
46
+ @plugin.db.user.must_equal "myuser"
47
+ @plugin.db.password.must_equal "mypassword"
48
+ @plugin.db.host.must_equal "thishost" # this is specified, do not get from environment
49
+ ensure
50
+ ENV[env_var_name("USER")] = env_user
51
+ ENV[env_var_name("PASSWORD")] = env_password
52
+ ENV[env_var_name("HOST")] = env_host
53
+ end
54
+ end
55
+
56
+ def env_var_name(name)
57
+ "#{Siba::Source::Mysql::ENV_PREFIX}#{name}"
58
+ end
59
+
60
+ it "should call backup" do
61
+ @fmock.expect :run_this, true, []
62
+ @fmock.expect :dir_entries, [], [String]
63
+ @fmock.expect :run_shell, nil, [String, String]
64
+ @fmock.expect :file_file?, true, [String]
65
+ @plugin.backup "/dest/dir"
66
+ end
67
+
68
+ it "should call restore" do
69
+ @fmock.expect :file_file?, true, [String]
70
+ @fmock.expect :run_shell, nil, [String, String]
71
+ @plugin.restore "/from_dir"
72
+ end
73
+ end
@@ -0,0 +1,15 @@
1
+ host: myhost
2
+ port: 123
3
+ protocol: TCP
4
+ socket: /tmp/mysql.sock
5
+ user: myuser
6
+ password: mypassword
7
+ databases:
8
+ - db1
9
+ tables:
10
+ - table1
11
+ - table2
12
+ ignore_tables:
13
+ - db1.table1
14
+ - db1.table2
15
+ custom_parameters: "--parameters"
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: siba-source-mysql
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Evgeny Neumerzhitskiy
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: siba
16
+ requirement: &76126290 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '0.5'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *76126290
25
+ - !ruby/object:Gem::Dependency
26
+ name: minitest
27
+ requirement: &76126050 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '2.10'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *76126050
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &76125820 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: '0.9'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *76125820
47
+ - !ruby/object:Gem::Dependency
48
+ name: guard-minitest
49
+ requirement: &76125590 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '0.4'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *76125590
58
+ description: An extension for SIBA utility. It allows to backup and restore MySQL
59
+ database.
60
+ email:
61
+ - sausageskin@gmail.com
62
+ executables: []
63
+ extensions: []
64
+ extra_rdoc_files: []
65
+ files:
66
+ - .gitignore
67
+ - Gemfile
68
+ - Guardfile
69
+ - LICENSE
70
+ - README.md
71
+ - Rakefile
72
+ - lib/siba-source-mysql.rb
73
+ - lib/siba-source-mysql/db.rb
74
+ - lib/siba-source-mysql/init.rb
75
+ - lib/siba-source-mysql/options.yml
76
+ - lib/siba-source-mysql/version.rb
77
+ - siba-source-mysql.gemspec
78
+ - test/helper/require_integration.rb
79
+ - test/helper/require_unit.rb
80
+ - test/integration/i9n_init.rb
81
+ - test/unit/test_db.rb
82
+ - test/unit/test_init.rb
83
+ - test/unit/yml/valid.yml
84
+ homepage: https://github.com/evgenyneu/siba-source-mysql
85
+ licenses:
86
+ - MIT
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 1.8.11
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: MySQL backup and restore extention for SIBA utility
109
+ test_files: []