mysql_truck 0.6.4 → 0.6.6

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/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