mysql_truck 0.6.4 → 0.6.6

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -2,3 +2,9 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in mysql_truck.gemspec
4
4
  gemspec
5
+
6
+ group :test do
7
+ gem 'minitest'
8
+ gem 'mocha'
9
+ gem 'hashie'
10
+ end
@@ -73,6 +73,10 @@ parser = OptionParser.new do |opts|
73
73
  options[:skip_data_for_tables] = tables.split(",")
74
74
  end
75
75
 
76
+ opts.on("--skip-all-data", "Only load schema") do
77
+ options[:skip_all_data] = true
78
+ end
79
+
76
80
  opts.on("-o", "--only-tables TABLES",
77
81
  "List of tables to dump/load.") do |tables|
78
82
  options[:only_tables] = tables.split(",")
@@ -49,7 +49,7 @@ module MysqlTruck
49
49
  # Dump data
50
50
  puts "Writing data for #{table} ..."
51
51
  benchmark do
52
- puts `mysql #{db_connection_options} --skip-column-names --batch -e "select * from #{table}" | lzop -6 > #{filename(table)[:compressed_data_file]} 2>/var/log/mysql_truck_dump.log`
52
+ puts `mysql #{db_connection_options} --skip-column-names --batch -e "select * from #{table}" | sed -e 's/\tNULL/\t\\\\N/g'| lzop -6 > #{filename(table)[:compressed_data_file]} 2>/var/log/mysql_truck_dump.log`
53
53
  if $?.exitstatus != 0
54
54
  puts "Command did not execute successfully"
55
55
  end
@@ -19,7 +19,6 @@ module MysqlTruck
19
19
  end
20
20
 
21
21
  def load_backup
22
-
23
22
  # Default to latest backup
24
23
  backup_date_str = config[:backup_date] || backups.first.split("/").last
25
24
 
@@ -30,7 +29,6 @@ module MysqlTruck
30
29
  puts "Download & decompressing backups"
31
30
  puts "-------------------"
32
31
 
33
-
34
32
  @bucket.keys(:prefix => s3_path).each do |key|
35
33
  next if key.to_s.match(/\/$/)
36
34
  next unless (filename = download_file(key))
@@ -68,7 +66,7 @@ module MysqlTruck
68
66
  csv_data_file = tmp_path.join("#{table}.csv")
69
67
  tsv_data_file = tmp_path.join("#{table}.data.tsv")
70
68
 
71
-
69
+ # Create table
72
70
  if schema_file.exist?
73
71
  print " - Loading schema: #{File.basename(schema_file)} ... "
74
72
  execute_sql_file(table, backup_date_str, schema_file)
@@ -84,23 +82,26 @@ module MysqlTruck
84
82
  next
85
83
  end
86
84
 
87
-
88
- if data_file.exist?
89
- print " - Importing #{File.basename(data_file)} ... "
90
- execute_sql_file(table, backup_date_str, data_file)
91
- data_file.delete
92
-
93
- elsif csv_data_file.exist?
94
- print " - Importing #{File.basename(csv_data_file)} ... "
95
- csv_data_file = import_csv_file(table, backup_date_str, csv_data_file)
96
- File.delete(csv_data_file)
97
-
98
- elsif tsv_data_file.exist?
99
- print " - Importing #{File.basename(tsv_data_file)} ... "
100
- tsv_data_file = import_tsv_file(table, backup_date_str, tsv_data_file)
101
- File.delete(tsv_data_file)
85
+ # Load data
86
+ if !config[:skip_all_data]
87
+ if data_file.exist?
88
+ print " - Importing #{File.basename(data_file)} ... "
89
+ execute_sql_file(table, backup_date_str, data_file)
90
+ data_file.delete
91
+
92
+ elsif csv_data_file.exist?
93
+ print " - Importing #{File.basename(csv_data_file)} ... "
94
+ csv_data_file = import_csv_file(table, backup_date_str, csv_data_file)
95
+ File.delete(csv_data_file)
96
+
97
+ elsif tsv_data_file.exist?
98
+ print " - Importing #{File.basename(tsv_data_file)} ... "
99
+ tsv_data_file = import_tsv_file(table, backup_date_str, tsv_data_file)
100
+ File.delete(tsv_data_file)
101
+ end
102
102
  end
103
103
 
104
+ # Add indices
104
105
  if index_file.exist?
105
106
  print " - Adding indices: #{File.basename(index_file)} ... "
106
107
  execute_sql_file(table, backup_date_str, index_file)
@@ -191,8 +192,7 @@ module MysqlTruck
191
192
 
192
193
  def should_download_file?(filename)
193
194
  table_name = filename.gsub(/\..*\..*$/, '')
194
-
195
- if only_tables.empty? and skip_data_for_tables.empty?
195
+ if only_tables.empty? and skip_data_for_tables.empty? and !config[:skip_all_data]
196
196
  return true
197
197
  end
198
198
 
@@ -202,7 +202,8 @@ module MysqlTruck
202
202
  return only_tables.include?(table_name)
203
203
  end
204
204
 
205
- if filename.match(/\.data\.sql\.gz$/)
205
+ if filename.match(/\.data\.(sql|tsv)\.(lzo|gz)$/)
206
+ return false if config[:skip_all_data]
206
207
  is_data = true
207
208
  is_schema = false
208
209
  else
@@ -210,8 +211,10 @@ module MysqlTruck
210
211
  is_schema = true
211
212
  end
212
213
 
214
+ return true if is_schema && config[:skip_all_data]
215
+
213
216
  if !skip_data_for_tables.empty?
214
- if is_schema or (is_data and !skip_data_for_tables.include?(table_name))
217
+ if is_schema || (is_data && !skip_data_for_tables.include?(table_name))
215
218
  return true
216
219
  end
217
220
  end
@@ -237,6 +240,7 @@ module MysqlTruck
237
240
  end
238
241
  @backups = @backups.sort { |a,b| b <=> a }
239
242
  end
243
+
240
244
  @backups
241
245
  end
242
246
 
@@ -1,3 +1,3 @@
1
1
  module MysqlTruck
2
- VERSION = "0.6.4"
2
+ VERSION = "0.6.6"
3
3
  end
@@ -0,0 +1,69 @@
1
+ require 'hashie'
2
+
3
+ class FakeAws
4
+
5
+ def initialize
6
+ @files = []
7
+ end
8
+
9
+ def bucket(bucket_name)
10
+ BucketContent.new(bucket_name, @files)
11
+ end
12
+
13
+ def add_fake_file(path)
14
+ @files << path
15
+ end
16
+
17
+ end
18
+
19
+ class BucketContent
20
+
21
+ def initialize(name, data)
22
+ @data = data
23
+ @name = name
24
+ end
25
+
26
+ def name
27
+ @name
28
+ end
29
+
30
+ def s3
31
+ FakeS3.new(@data)
32
+ end
33
+
34
+ def keys(configs)
35
+ prefix = configs[:prefix]
36
+ @data.map do |file|
37
+ Hashie::Mash.new({name: file})
38
+ end
39
+ end
40
+ end
41
+
42
+
43
+ class FakeS3
44
+
45
+ def initialize(data)
46
+ @data = data
47
+ end
48
+
49
+ def interface
50
+ #TODO calculate common_prefixes
51
+ Interface.new(@data)
52
+ end
53
+ end
54
+
55
+ class Interface
56
+
57
+ def initialize(data)
58
+ @data = data
59
+ end
60
+
61
+ def incrementally_list_bucket(bucket_name, options)
62
+ yield common_prefixes: [@data.first.split('/')[0..2].join('/') ]
63
+ end
64
+
65
+ def get(bucket_name, key_name)
66
+ yield 'content'
67
+ end
68
+
69
+ end
@@ -0,0 +1,82 @@
1
+ require 'test_helper'
2
+
3
+ module MysqlTruck
4
+ class LoaderTest < Minitest::Unit::TestCase
5
+
6
+ def setup
7
+ mock_aws_with_fake_backups('2013-01-01', ['users', 'mixes'])
8
+ end
9
+
10
+ def test_loads_old_backups_with_only_tables
11
+ config = { s3_access_key: 'key', s3_secret_access_key: 'password', :only_tables => ['users'] }
12
+ loader = MysqlTruck::Loader.new(config)
13
+
14
+ assert loader.should_download_file?('users.data.sql.gz')
15
+ assert loader.should_download_file?('users.indices.sql.gz')
16
+ assert loader.should_download_file?('users.no_index.sql.gz')
17
+
18
+
19
+ refute loader.should_download_file?('mixes.data.sql.gz')
20
+ refute loader.should_download_file?('mixes.indices.sql.gz')
21
+ refute loader.should_download_file?('mixes.no_index.sql.gz')
22
+ end
23
+
24
+ def test_old_backups_with_skip_data_for_tables
25
+ config = { s3_access_key: 'key', s3_secret_access_key: 'password', :skip_data_for_tables => ['users'] }
26
+ loader = MysqlTruck::Loader.new(config)
27
+
28
+
29
+ #refutes data files for the ones you want to ignore
30
+ refute loader.should_download_file?('users.data.sql.gz')
31
+ assert loader.should_download_file?('users.indices.sql.gz')
32
+ assert loader.should_download_file?('users.no_index.sql.gz')
33
+
34
+ assert loader.should_download_file?('mixes.data.sql.gz')
35
+ assert loader.should_download_file?('mixes.indices.sql.gz')
36
+ assert loader.should_download_file?('mixes.no_index.sql.gz')
37
+ end
38
+
39
+ def test_new_backups_with_only_tables
40
+ config = { s3_access_key: 'key', s3_secret_access_key: 'password', :only_tables => ['users'] }
41
+ loader = MysqlTruck::Loader.new(config)
42
+
43
+ assert loader.should_download_file?('users.data.tsv.lzo')
44
+ assert loader.should_download_file?('users.indices.sql.lzo')
45
+ assert loader.should_download_file?('users.no_index.sql.lzo')
46
+
47
+
48
+ refute loader.should_download_file?('mixes.data.tsv.lzo')
49
+ refute loader.should_download_file?('mixes.indices.sql.lzo')
50
+ refute loader.should_download_file?('mixes.no_index.sql.lzo')
51
+ end
52
+
53
+ def test_new_backups_with_with_skip_data_for_tables
54
+ config = { s3_access_key: 'key', s3_secret_access_key: 'password', :skip_data_for_tables => ['users'] }
55
+ loader = MysqlTruck::Loader.new(config)
56
+
57
+ #refutes data files for the ones you want to ignore
58
+ refute loader.should_download_file?('users.data.tsv.lzo')
59
+ assert loader.should_download_file?('users.indices.sql.lzo')
60
+ assert loader.should_download_file?('users.no_index.sql.lzo')
61
+
62
+ assert loader.should_download_file?('mixes.data.tsv.lzo')
63
+ assert loader.should_download_file?('mixes.indices.sql.lzo')
64
+ assert loader.should_download_file?('mixes.no_index.sql.lzo')
65
+ end
66
+
67
+ def mock_aws_with_fake_backups(date, tables)
68
+ fake_aws = FakeAws.new
69
+
70
+ tables.each do |table|
71
+ base_name = "mysql/8trackscom/#{date}/#{table}"
72
+
73
+ fake_aws.add_fake_file("#{base_name}.data.sql.gz")
74
+ fake_aws.add_fake_file("#{base_name}.indices.sql.gz")
75
+ fake_aws.add_fake_file("#{base_name}.no_index.sql.gz")
76
+ end
77
+
78
+ RightAws::S3.expects(:new).returns(fake_aws)
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,4 @@
1
+ require 'minitest/autorun'
2
+ require 'mocha/setup'
3
+ require 'fake_aws'
4
+ require_relative '../lib/mysql_truck'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mysql_truck
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4
4
+ version: 0.6.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-02-04 00:00:00.000000000 Z
14
+ date: 2013-02-27 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: right_aws
@@ -66,6 +66,9 @@ files:
66
66
  - lib/mysql_truck/loader.rb
67
67
  - lib/mysql_truck/version.rb
68
68
  - mysql_truck.gemspec
69
+ - test/fake_aws.rb
70
+ - test/lib/mysql_truck/loader_test.rb
71
+ - test/test_helper.rb
69
72
  homepage: ''
70
73
  licenses: []
71
74
  post_install_message:
@@ -90,4 +93,7 @@ rubygems_version: 1.8.23
90
93
  signing_key:
91
94
  specification_version: 3
92
95
  summary: Mysql database backup tool. Dumps/Loads to/from S3.
93
- test_files: []
96
+ test_files:
97
+ - test/fake_aws.rb
98
+ - test/lib/mysql_truck/loader_test.rb
99
+ - test/test_helper.rb