siba-source-mysql 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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: []