dbsync 0.1.2 → 0.2.0

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.
@@ -0,0 +1,3 @@
1
+ ## 0.2.0
2
+ * Internal refactoring.
3
+ * Updated gem dependencies.
@@ -3,31 +3,36 @@
3
3
  A set of rake tasks to help you sync your production
4
4
  data with your local database for development.
5
5
 
6
- Currently only supports:
7
- * Rails
8
- * MySQL
6
+ Currently only supports MySQL. The Rake tasks are written for Rails-only,
7
+ but the Sync class can be used with ruby framework, as long as you pass in the
8
+ correct database configuration.
9
9
 
10
10
  Support for more things will happen if anybody needs it.
11
11
 
12
+
12
13
  ## Usage
13
14
 
14
15
  Add to your gemfile for the groups that will need it:
15
16
 
16
- group :development, :staging do
17
- gem 'dbsync'
18
- end
19
-
17
+ ```ruby
18
+ group :development, :staging do
19
+ gem 'dbsync'
20
+ end
21
+ ```
22
+
20
23
  Add the following to your `config/environments/development.rb`
21
24
  file. Depending on your staging setup, it may also be useful
22
25
  to you to add some `dbsync` config to your `staging.rb`
23
26
  environment file. **Note** `dbsync` will not run in production.
24
27
 
25
- config.dbsync = ActiveSupport::OrderedOptions.new
26
-
27
- config.dbsync.filename = "yourapp_production_data.dump" # The name of the remote dumpfile
28
- config.dbsync.local_dir = "#{Rails.root}/../dbsync" # The local directory to store the dump file. No trailing slash
29
- config.dbsync.remote_host = "66.123.4.567" # Remote server where the dumpfile is
30
- config.dbsync.remote_dir = "~dbsync" # The directory on the remote server where the dumpfile is
28
+ ```ruby
29
+ config.dbsync = {
30
+ :filename => "yourapp_production_data.dump", # The name of the remote dumpfile.
31
+ :local_dir => "#{Rails.root}/../dbsync", # The local directory to store the dump file.
32
+ :remote_host => "66.123.4.567", # Remote server where the dumpfile is located.
33
+ :remote_dir => "~dbsync" # The directory on the remote server where the dumpfile is.
34
+ }
35
+ ```
31
36
 
32
37
  Now just make sure you have something on the remote
33
38
  server updating that dumpfile. I recommend a cronjob:
@@ -42,18 +47,21 @@ Run `rake -T dbsync` for all of the available tasks. The
42
47
  tasks are named after `git` commands mostly, so they
43
48
  should be pretty straight-forward for those who use `git`:
44
49
 
45
- rake dbsync # Alias for dbsync:pull
46
- rake dbsync:clone # Copy the remote dump file, reset the local database, and load in the dump file
47
- rake dbsync:clone_dump # Copy the remote dump file to a local destination
48
- rake dbsync:config # Show the dbsync configuration
49
- rake dbsync:fetch # Update the local dump file from the remote source
50
- rake dbsync:merge # Merge the local dump file into the local database
51
- rake dbsync:pull # Update the local dump file, and merge it into the local database
52
- rake dbsync:reset # Drop & Create the database, then load the dump file.
53
-
50
+ ```
51
+ rake dbsync # Alias for dbsync:pull
52
+ rake dbsync:clone # Copy the remote dump file, reset the local database, and load in the dump file
53
+ rake dbsync:clone_dump # Copy the remote dump file to a local destination
54
+ rake dbsync:config # Show the dbsync configuration
55
+ rake dbsync:fetch # Update the local dump file from the remote source
56
+ rake dbsync:merge # Update the local database with the local dump file
57
+ rake dbsync:pull # Update the local dump file, and merge it into the local database
58
+ rake dbsync:reset # Drop and Create the database, then load the dump file
59
+ ```
60
+
54
61
  ### TODO
55
62
 
56
- - Specs!
63
+ - Support postgres, sqlite, and anything else.
64
+
57
65
 
58
66
  ### Copyright
59
67
 
@@ -1,27 +1,25 @@
1
- # -*- encoding: utf-8 -*-
2
1
  $:.push File.expand_path("../lib", __FILE__)
3
2
  require "dbsync/version"
4
3
 
5
- Gem::Specification.new do |gem|
6
- gem.name = "dbsync"
7
- gem.version = Dbsync::VERSION
8
- gem.authors = ["Bryan Ricker"]
9
- gem.email = ["bricker88@gmail.com"]
10
- gem.description = %q{A set of rake tasks to help you sync your remote production data with your local database for development.}
11
- gem.summary = %q{Easy syncing from remote to development database in Rails.}
12
- gem.homepage = "http://github.com/bricker/dbsync"
4
+ Gem::Specification.new do |s|
5
+ s.name = "dbsync"
6
+ s.version = Dbsync::VERSION
7
+ s.authors = ["Bryan Ricker"]
8
+ s.email = ["bricker88@gmail.com"]
9
+ s.homepage = "https://github.com/bricker/dbsync"
10
+ s.license = 'MIT'
11
+ s.description = "A set of rake tasks to help you sync your remote " \
12
+ "production data with your local database for development."
13
+ s.summary = "Easy syncing from remote to development database in Rails."
13
14
 
14
- gem.rubyforge_project = "dbsync"
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", "lib/tasks"]
15
19
 
16
- gem.files = `git ls-files`.split("\n")
17
- gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
- gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
- gem.require_paths = ["lib", "lib/tasks"]
20
-
21
- # specify any dependencies here; for example:
22
- # s.add_development_dependency "rspec"
23
- gem.add_runtime_dependency "activesupport", ">= 3.2.8"
24
- gem.add_runtime_dependency "activerecord", ">= 3.2.8"
25
- gem.add_runtime_dependency "railties", ">= 3.2.8"
20
+ s.add_dependency "activerecord", [">= 3.2.8", "< 5"]
21
+ s.add_dependency "railties", [">= 3.2.8", "< 5"]
22
+ s.add_dependency "cocaine", "~> 0.5.3"
26
23
 
24
+ s.add_development_dependency "rspec"
27
25
  end
@@ -1,4 +1,5 @@
1
1
  require "dbsync/version"
2
+ require 'dbsync/sync'
2
3
 
3
4
  module Dbsync
4
5
  class Railtie < Rails::Railtie
@@ -0,0 +1,99 @@
1
+ require 'cocaine'
2
+
3
+ module Dbsync
4
+ class Sync
5
+ class << self
6
+ def notify(message="")
7
+ $stdout.puts "[#{Time.now.strftime('%T')}] [dbsync] #{message}"
8
+ end
9
+ end
10
+
11
+
12
+ def initialize(ssh_config, db_config, options={})
13
+ ssh_config = ssh_config.with_indifferent_access
14
+ db_config = db_config.with_indifferent_access
15
+
16
+ @verbose = !!options[:verbose]
17
+
18
+ @remote_host = ssh_config[:remote_host] || raise_missing("remote_host")
19
+ @remote_dir = ssh_config[:remote_dir] || raise_missing("remote_dir")
20
+ @local_dir = ssh_config[:local_dir] || raise_missing("local_dir")
21
+ @filename = ssh_config[:filename] || raise_missing("filename")
22
+
23
+ @db_username = db_config[:username]
24
+ @db_password = db_config[:password]
25
+ @db_host = db_config[:host]
26
+ @db_database = db_config[:database]
27
+
28
+ @remote_file = "#{@remote_host}:" + File.join(@remote_dir, @filename)
29
+ @local_file = File.expand_path(File.join(@local_dir, @filename))
30
+ end
31
+
32
+
33
+ # Update the local dump file from the remote source (using rsync).
34
+ def fetch
35
+ notify "Updating '#{@local_file}' from '#{@remote_file}' via rsync..."
36
+
37
+ line = Cocaine::CommandLine.new('rsync', '-v :remote :local')
38
+ line.run({
39
+ :remote => @remote_file,
40
+ :local => @local_file
41
+ })
42
+ end
43
+
44
+
45
+ # Update the local database with the local dump file.
46
+ def merge
47
+ notify "Dumping data from '#{@local_file}' into '#{@db_database}'..."
48
+
49
+ options = ""
50
+ options += "-u :username " if @db_username.present?
51
+ options += "-p:password " if @db_password.present?
52
+ options += "-h :host " if @db_host.present?
53
+
54
+ line = Cocaine::CommandLine.new('mysql', "#{options} :database < :local")
55
+ line.run({
56
+ :username => @db_username,
57
+ :password => @db_password,
58
+ :host => @db_host,
59
+ :database => @db_database,
60
+ :local => @local_file
61
+ })
62
+ end
63
+
64
+
65
+ # Update the local dump file, and update the local database.
66
+ def pull
67
+ fetch
68
+ merge
69
+ end
70
+
71
+
72
+ # Copy the remote dump file to a local destination.
73
+ # This does a full copy (using scp), so it will take longer than
74
+ # fetch (which uses rsync).
75
+ def clone_dump
76
+ notify "Copying '#{@remote_file}' into '#{@local_dir}' via scp..."
77
+
78
+ line = Cocaine::CommandLine.new('scp', ':remote :local_dir')
79
+ line.run({
80
+ :remote => @remote_file,
81
+ :local_dir => @local_dir
82
+ })
83
+ end
84
+
85
+
86
+ private
87
+
88
+ def raise_missing(config="")
89
+ raise "Missing Configuration: '#{config}'. " \
90
+ "See README for required config."
91
+ end
92
+
93
+ def notify(*args)
94
+ if @verbose
95
+ Sync.notify(*args)
96
+ end
97
+ end
98
+ end
99
+ end
@@ -1,3 +1,3 @@
1
1
  module Dbsync
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -2,116 +2,70 @@
2
2
 
3
3
  desc "Alias for dbsync:pull"
4
4
  task :dbsync do
5
- Rake::Task["dbsync:pull"].invoke
5
+ Rake::Task['dbsync:pull'].invoke
6
6
  end
7
7
 
8
8
  namespace :dbsync do
9
9
  task :setup => :environment do
10
- module Dbsync
11
- LOGGER = $stdout
12
- CONFIG = Rails.application.config.dbsync
13
-
14
- CONFIG['remote'] = "#{CONFIG['remote_host']}:" + File.join(CONFIG['remote_dir'], CONFIG['filename'])
15
- CONFIG['local'] = File.join CONFIG['local_dir'], CONFIG['filename']
16
- end
17
-
18
- # ---------------
19
-
20
- Dbsync::LOGGER.puts "Environment: #{Rails.env}"
21
-
10
+ Dbsync::Sync.notify "Environment: #{Rails.env}"
11
+
22
12
  if Rails.env == 'production'
23
- raise "These tasks are destructive and shouldn't be used in the production environment."
13
+ raise "These tasks are destructive and shouldn't " \
14
+ "be used in the production environment."
24
15
  end
25
16
 
26
- #-----------------
27
-
28
- if Dbsync::CONFIG['filename'].blank?
29
- raise "No dump filename specified."
30
- elsif Dbsync::CONFIG['remote'].blank?
31
- raise "No remote dump file specified."
32
- end
33
-
34
- #-----------------
35
-
36
- VERBOSE = %w{1 true}.include? ENV['VERBOSE']
37
- DB = ActiveRecord::Base.configurations[Rails.env]
17
+ @dbsync = Dbsync::Sync.new(
18
+ Rails.application.config.dbsync,
19
+ ActiveRecord::Base.configurations[Rails.env],
20
+ verbose: true
21
+ )
38
22
  end
39
-
40
- #-----------------------
41
-
23
+
24
+
42
25
  desc "Show the dbsync configuration"
43
26
  task :config => :setup do
44
- Dbsync::LOGGER.puts "Config:"
45
- Dbsync::LOGGER.puts Dbsync::CONFIG.to_yaml
27
+ # We don't use Sync.notify here because we don't want or need
28
+ # the extra output that comes with it.
29
+ $stdout.puts Rails.application.config.dbsync.to_yaml
46
30
  end
47
-
48
- #-----------------------
49
-
31
+
32
+
50
33
  desc "Update the local dump file, and merge it into the local database"
51
- task :pull => [:fetch, :merge]
52
-
53
- desc "Copy the remote dump file, reset the local database, and load in the dump file"
54
- task :clone => [:clone_dump, :reset]
55
-
56
- #-----------------------
57
-
58
- desc "Update the local dump file from the remote source"
34
+ task :pull => :setup do
35
+ @dbsync.pull
36
+ end
37
+
38
+
39
+ desc "Copy the remote dump file, reset the local database, " \
40
+ "and load in the dump file"
41
+ task :clone => :setup do
42
+ @dbsync.clone_dump
43
+ Rake::Task['dbsync:reset'].invoke
44
+ end
45
+
46
+
47
+ desc "Update the local dump file from the remote source."
59
48
  task :fetch => :setup do
60
- Dbsync::LOGGER.puts "Fetching #{Dbsync::CONFIG['remote']} using rsync"
61
- output = %x{ rsync -v #{Dbsync::CONFIG['remote']} #{Dbsync::CONFIG['local']} }
62
-
63
- if VERBOSE
64
- Dbsync::LOGGER.puts output
65
- end
66
-
67
- Dbsync::LOGGER.puts "Finished."
49
+ @dbsync.fetch
68
50
  end
69
51
 
70
- #-----------------------
71
52
 
72
53
  desc "Copy the remote dump file to a local destination"
73
54
  task :clone_dump => :setup do
74
- Dbsync::LOGGER.puts "Fetching #{Dbsync::CONFIG['remote']} using scp"
75
- output = %x{ scp #{Dbsync::CONFIG['remote']} #{Dbsync::CONFIG['local_dir']}/ }
76
-
77
- if VERBOSE
78
- Dbsync::LOGGER.puts output
79
- end
80
-
81
- Dbsync::LOGGER.puts "Finished."
55
+ @dbsync.clone_dump
82
56
  end
83
57
 
84
- #-----------------------
85
-
86
- desc "Merge the local dump file into the local database"
58
+
59
+ desc "Update the local database with the local dump file."
87
60
  task :merge => :setup do
88
- Dbsync::LOGGER.puts "Dumping data from #{Dbsync::CONFIG['local']} into #{DB['database']}"
89
-
90
- command = "mysql "
91
- command += "-u #{DB['username']} " if DB['username'].present?
92
- command += "-p#{DB['password']} " if DB['password'].present?
93
- command += "-h #{DB['host']} " if DB['host'].present?
94
- command += "#{DB['database']} < #{Dbsync::CONFIG['local']}"
95
-
96
- output = %x{#{command}}
97
-
98
- if VERBOSE
99
- Dbsync::LOGGER.puts output
100
- end
101
-
102
- Dbsync::LOGGER.puts "Finished."
61
+ @dbsync.merge
103
62
  end
104
63
 
105
- #-----------------------
106
-
107
- desc "Drop & Create the database, then load the dump file."
64
+
65
+ desc "Drop and Create the database, then load the dump file."
108
66
  task :reset => :setup do
109
- if VERBOSE
110
- Dbsync::LOGGER.puts "Resetting database..."
111
- end
112
-
113
67
  Rake::Task["db:drop"].invoke
114
68
  Rake::Task["db:create"].invoke
115
- Rake::Task["dbsync:merge"].invoke
69
+ @dbsync.merge
116
70
  end
117
71
  end
@@ -0,0 +1,5 @@
1
+ require 'bundler/setup'
2
+ Bundler.require
3
+
4
+ RSpec.configure do |config|
5
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dbsync::Sync do
4
+ let(:ssh_config) do
5
+ end
6
+
7
+ let(:db_config) do
8
+ end
9
+
10
+
11
+ describe "::notify" do
12
+ end
13
+
14
+ describe '#fetch' do
15
+ end
16
+
17
+ describe '#merge' do
18
+ end
19
+
20
+ describe '#clone_dump' do
21
+ end
22
+
23
+ describe '#pull' do
24
+ end
25
+ end
metadata CHANGED
@@ -1,57 +1,66 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbsync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Bryan Ricker
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-04-03 00:00:00.000000000 Z
12
+ date: 2014-02-13 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
- name: activesupport
15
- requirement: !ruby/object:Gem::Requirement
15
+ name: activerecord
16
+ requirement: &70160586951120 !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
19
  - - ! '>='
18
20
  - !ruby/object:Gem::Version
19
21
  version: 3.2.8
22
+ - - <
23
+ - !ruby/object:Gem::Version
24
+ version: '5'
20
25
  type: :runtime
21
26
  prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ! '>='
25
- - !ruby/object:Gem::Version
26
- version: 3.2.8
27
+ version_requirements: *70160586951120
27
28
  - !ruby/object:Gem::Dependency
28
- name: activerecord
29
- requirement: !ruby/object:Gem::Requirement
29
+ name: railties
30
+ requirement: &70160586945980 !ruby/object:Gem::Requirement
31
+ none: false
30
32
  requirements:
31
33
  - - ! '>='
32
34
  - !ruby/object:Gem::Version
33
35
  version: 3.2.8
36
+ - - <
37
+ - !ruby/object:Gem::Version
38
+ version: '5'
34
39
  type: :runtime
35
40
  prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ! '>='
39
- - !ruby/object:Gem::Version
40
- version: 3.2.8
41
+ version_requirements: *70160586945980
41
42
  - !ruby/object:Gem::Dependency
42
- name: railties
43
- requirement: !ruby/object:Gem::Requirement
43
+ name: cocaine
44
+ requirement: &70160586961540 !ruby/object:Gem::Requirement
45
+ none: false
44
46
  requirements:
45
- - - ! '>='
47
+ - - ~>
46
48
  - !ruby/object:Gem::Version
47
- version: 3.2.8
49
+ version: 0.5.3
48
50
  type: :runtime
49
51
  prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
52
+ version_requirements: *70160586961540
53
+ - !ruby/object:Gem::Dependency
54
+ name: rspec
55
+ requirement: &70160586961120 !ruby/object:Gem::Requirement
56
+ none: false
51
57
  requirements:
52
58
  - - ! '>='
53
59
  - !ruby/object:Gem::Version
54
- version: 3.2.8
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: *70160586961120
55
64
  description: A set of rake tasks to help you sync your remote production data with
56
65
  your local database for development.
57
66
  email:
@@ -61,36 +70,44 @@ extensions: []
61
70
  extra_rdoc_files: []
62
71
  files:
63
72
  - .gitignore
73
+ - CHANGELOG.md
64
74
  - Gemfile
65
75
  - MIT-LICENSE
66
76
  - README.markdown
67
77
  - Rakefile
68
78
  - dbsync.gemspec
69
79
  - lib/dbsync.rb
80
+ - lib/dbsync/sync.rb
70
81
  - lib/dbsync/version.rb
71
82
  - lib/tasks/dbsync.rake
72
- homepage: http://github.com/bricker/dbsync
73
- licenses: []
74
- metadata: {}
83
+ - spec/spec_helper.rb
84
+ - spec/sync_spec.rb
85
+ homepage: https://github.com/bricker/dbsync
86
+ licenses:
87
+ - MIT
75
88
  post_install_message:
76
89
  rdoc_options: []
77
90
  require_paths:
78
91
  - lib
79
92
  - lib/tasks
80
93
  required_ruby_version: !ruby/object:Gem::Requirement
94
+ none: false
81
95
  requirements:
82
96
  - - ! '>='
83
97
  - !ruby/object:Gem::Version
84
98
  version: '0'
85
99
  required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
86
101
  requirements:
87
102
  - - ! '>='
88
103
  - !ruby/object:Gem::Version
89
104
  version: '0'
90
105
  requirements: []
91
- rubyforge_project: dbsync
92
- rubygems_version: 2.0.2
106
+ rubyforge_project:
107
+ rubygems_version: 1.8.11
93
108
  signing_key:
94
- specification_version: 4
109
+ specification_version: 3
95
110
  summary: Easy syncing from remote to development database in Rails.
96
- test_files: []
111
+ test_files:
112
+ - spec/spec_helper.rb
113
+ - spec/sync_spec.rb
checksums.yaml DELETED
@@ -1,15 +0,0 @@
1
- ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MjJhN2M5OTY4OGQ4MjE2MzY1NjU5OWEyZDMxMTVhMmYxZDZlMzUwMQ==
5
- data.tar.gz: !binary |-
6
- MWI5MWUwOTU4NGVhMjI1ZjY1OGE0MWEwYmVlYmY2ZTQ0MDcyZTM4Yg==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- MGI4MjJmYmIxNTdhZWI1M2JlNTdlMjI0ZmY5YjQyYWRjN2QyM2YzNmU4NDI5
10
- Y2UyMjhkNTZjYTIxNGVhZDI0MGZmMDNhY2RiODJiYTIwZWZmZjNmYWUzNjBj
11
- ZWVlNDEyYWQzYjA5ZGU2OTU3MDRkYTNhYzc5NTY5NzkzNmViNTQ=
12
- data.tar.gz: !binary |-
13
- YWRjOWQ4MWI0ODNhOWNmYTI1YWQ1Y2UzYjVmYTkwNGJiZmJjM2NmNWMwYjRj
14
- OTgwYTZiNDZlMjNmMDliMjFlZmRkOTEwNGIyODAxZjU4YjViMDhkNThlNzUy
15
- ODY2MGNhMjIyZjI0ZjBhNTQ5NjViOWQ5Yzk5MDEzZmQyZmRjMmM=