├── .gitignore ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── bin ├── console ├── dbmgr ├── dbmgr-dev └── setup ├── dbmgr.gemspec ├── lib ├── database │ ├── database.rb │ ├── mysql.rb │ └── postgresql.rb ├── dbmgr.rb └── dbmgr │ ├── mysql.rb │ ├── mysql │ ├── backup.rb │ └── restore.rb │ ├── postgresql.rb │ ├── postgresql │ ├── backup.rb │ └── restore.rb │ └── version.rb └── test ├── dbmgr ├── backup_test.rb ├── dbmgr_test.rb └── restore_test.rb ├── dbmgr_test.rb ├── helpers ├── mysql_helper.rb └── postgresql_helper.rb └── test_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: ruby 3 | services: 4 | - mysql 5 | - postgresql 6 | rvm: 7 | - 2.3.1 8 | before_install: gem install bundler -v 1.13.6 9 | before_script: 10 | - psql -c 'create database travis;' -U postgres 11 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/callahanrts/dbmgr/590e777178beb008a5da49c2586b2a4df9da1aa4/CODE_OF_CONDUCT.md -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in dbmgr.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Cody 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dbmgr 2 | [![Build Status](https://travis-ci.org/callahanrts/dbmgr.svg?branch=master)](https://travis-ci.org/callahanrts/dbmgr) 3 | 4 | `dbmgr` is a command line tool for backing up and restoring databases. It's a useful 5 | tool for: 6 | - Backing up and restoring your development databases 7 | - Sharing databases between developers 8 | - Provisioning new Vagrant VMs and Docker images 9 | - Provisioning new developers with a working database 10 | 11 | ## Installation 12 | 13 | ``` 14 | $ brew tap callahanrts/dbmgr 15 | $ brew install dbmgr 16 | ``` 17 | 18 | or 19 | 20 | ``` 21 | $ gem install dbmgr 22 | ``` 23 | 24 | ## Usage 25 | ``` 26 | dbmgr [dbms] [action] --options-list 27 | ``` 28 | ### DBMSs 29 | - MySQL (mysql) 30 | - PostgreSQL (psql) 31 | 32 | ### Backup 33 | #### Back up a database 34 | ```bash 35 | # Back up database from local server 36 | dbmgr [dbms] backup database_name 37 | 38 | # Back up database from a remote server 39 | dbmgr [dbms] backup database_name -P 3307 -h 192.168.33.10 -u root 40 | 41 | # Back up database and store in a specific location 42 | dbmgr [dbms] backup database_name -p ~/Downloads 43 | 44 | # Back up database as a named backup 45 | dbmgr [dbms] backup database_name -f my_backup.sql 46 | ``` 47 | 48 | ### Restore 49 | #### Restore a MySQL database 50 | ```bash 51 | # Restore local database from the latest backup in the default location 52 | dbmgr [dbms] restore database_name 53 | 54 | # Restore remote database with the latest backup 55 | dbmgr [dbms] restore database_name -P 3307 -h 192.168.33.10 -u root 56 | 57 | # Restore local database from the latest backup in a specific location 58 | dbmgr [dbms] restore database_name -p ~/Downloads 59 | 60 | # Restore database from a named backup 61 | dbmgr [dbms] restore database_name -f my_backup.sql 62 | ``` 63 | 64 | ## Help 65 | ``` 66 | dbmgr help 67 | dbmgr help mysql 68 | dbmgr mysql help backup 69 | dbmgr psql help backup 70 | ... 71 | ``` 72 | 73 | ## Tips 74 | Add a function in your `~/.bashrc` to back up a specific database so you don't 75 | have to type out all of the options each time. 76 | ```bash 77 | function dbbackup(){ 78 | dbmgr mysql backup mydb_dev -P 3306 -h 192.168.99.100 79 | } 80 | 81 | function dbrestore() { 82 | dbmgr mysql restore mydb_dev -P 3306 -h 192.168.99.100 83 | } 84 | ``` 85 | 86 | ## Contributing 87 | 88 | ### Build the Gem 89 | ```bash 90 | gem build dbmgr.gemspec 91 | ``` 92 | 93 | ### Install the Built Gem 94 | ```bash 95 | gem install ./dbmgr-x.x.x.gem 96 | ``` 97 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require "rake/testtask" 3 | 4 | Rake::TestTask.new(:test) do |t| 5 | t.libs << "test" 6 | t.libs << "lib" 7 | t.test_files = FileList['test/**/*_test.rb'] 8 | end 9 | 10 | task :default => :test 11 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "bundler/setup" 4 | require "dbmgr" 5 | 6 | # You can add fixtures and/or initialization code here to make experimenting 7 | # with your gem easier. You can also use a different console, if you like. 8 | 9 | # (If you use this, don't forget to add pry to your Gemfile!) 10 | # require "pry" 11 | # Pry.start 12 | 13 | require "irb" 14 | IRB.start 15 | -------------------------------------------------------------------------------- /bin/dbmgr: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | DBMGR_HOME = File.expand_path('../..', __FILE__) 4 | 5 | $LOAD_PATH.unshift(File.join(DBMGR_HOME, 'lib')) 6 | 7 | require 'dbmgr' 8 | 9 | Dbmgr::CLI.start(ARGV) 10 | -------------------------------------------------------------------------------- /bin/dbmgr-dev: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby -WU 2 | 3 | require 'dbmgr' 4 | 5 | Dbmgr::CLI.start( ARGV ) 6 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | bundle install 7 | 8 | # Do any other automated setup that you need to do here 9 | -------------------------------------------------------------------------------- /dbmgr.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'dbmgr/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "dbmgr" 8 | spec.version = Dbmgr::VERSION 9 | spec.authors = ["Cody"] 10 | spec.email = ["callahanrts@gmail.com"] 11 | 12 | spec.required_ruby_version = '< 2.5' 13 | 14 | spec.summary = %q{Create database backups and restore from previously created backups} 15 | spec.description = %q{Create database backups to share with others across your dev team. 16 | Other developers can restore from backups you've created.} 17 | spec.homepage = "https://github.com/callahanrts/dbmgr" 18 | spec.license = "MIT" 19 | 20 | spec.files = `git ls-files -z`.split("\x0").reject do |f| 21 | f.match(%r{^(test|spec|features)/}) 22 | end 23 | spec.bindir = "bin" 24 | spec.executables = spec.files.grep(%r{^bin/dbmgr$}) { |f| File.basename(f) } 25 | spec.require_paths = ["lib"] 26 | 27 | spec.add_dependency 'thor', "~> 0" 28 | 29 | spec.add_development_dependency "bundler", "~> 1.13" 30 | spec.add_development_dependency "rake", "~> 10.0" 31 | spec.add_development_dependency "minitest", "~> 5.0" 32 | spec.add_development_dependency "mysql2", "~> 0.4.5" 33 | spec.add_development_dependency "pg", "~> 0.18.2" 34 | spec.add_development_dependency "mocha", "~> 1.2" 35 | end 36 | -------------------------------------------------------------------------------- /lib/database/database.rb: -------------------------------------------------------------------------------- 1 | require "database/mysql" 2 | require "database/postgresql" 3 | 4 | # Database Class 5 | class Database 6 | def initialize(options = {}) 7 | @user = options[:user] 8 | @host = options[:host] 9 | @port = options[:port] 10 | @path = options[:path] 11 | @file = options[:filename] 12 | @backup = options[:backup] 13 | end 14 | 15 | private 16 | 17 | # Construct a name for the backup. This is either a given name or a timestamped name 18 | # for the given database name 19 | def filename db_name 20 | @file || "#{db_name}_#{Time.now.to_i}.sql" 21 | end 22 | 23 | # Back up from a given backup file--default to the most recent timestamped backup 24 | def backup_file db_name 25 | # Grab the backup file or the latest backup from the backups directory 26 | backup = @backup || Dir.glob("#{@path}/#{db_name}_*.sql").last 27 | raise "Restore failed: backup not found" unless File.file?(backup.to_s) 28 | backup 29 | end 30 | 31 | # Construct the /file/path/backup.sql string 32 | def filepath db_name 33 | "#{@path}/#{filename db_name}" 34 | end 35 | 36 | end 37 | -------------------------------------------------------------------------------- /lib/database/mysql.rb: -------------------------------------------------------------------------------- 1 | require 'fileutils' 2 | 3 | module MySQL 4 | def backup(db_name) 5 | FileUtils::mkdir_p @path 6 | 7 | # Create a mysql backup from the user supplied options 8 | system backup_db_command db_name 9 | rescue 10 | raise 'Unable to back up database' 11 | end 12 | 13 | def restore(db_name) 14 | # Create the database to restore if it doesn't exist already 15 | system create_db_command db_name 16 | 17 | # Restore the database from a backup 18 | system restore_db_command db_name 19 | rescue 20 | raise 'Unable to restore database' 21 | end 22 | 23 | private 24 | 25 | def backup_db_command(db_name) 26 | %( mysqldump -u#{@user} \ 27 | -h #{@host} \ 28 | -P #{@port} #{db_name} > #{filepath db_name} ) 29 | end 30 | 31 | def create_db_command(db_name) 32 | %( mysql -u#{@user} \ 33 | -h #{@host} \ 34 | -P #{@port} \ 35 | -e \"CREATE DATABASE IF NOT EXISTS #{db_name}\" ) 36 | end 37 | 38 | def restore_db_command(db_name) 39 | %( mysql -u#{@user} #{db_name} \ 40 | -h #{@host} \ 41 | -P #{@port} < #{backup_file db_name}) 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /lib/database/postgresql.rb: -------------------------------------------------------------------------------- 1 | require 'fileutils' 2 | 3 | module PostgreSQL 4 | def backup(db_name) 5 | FileUtils::mkdir_p @path 6 | 7 | # Create a postgresql backup from the user supplied options 8 | system backup_db_command(db_name), out: File::NULL 9 | rescue 10 | raise 'Unable to back up database' 11 | end 12 | 13 | def restore(db_name) 14 | # Create the database to restore if it doesn't exist already 15 | system create_db_command(db_name), out: File::NULL 16 | 17 | # Restore the database from a backup 18 | system restore_db_command(db_name), out: File::NULL 19 | rescue 20 | raise 'Unable to restore database' 21 | end 22 | 23 | private 24 | 25 | def backup_db_command(db_name) 26 | %( pg_dump -U #{@user} \ 27 | -h #{@host} \ 28 | -p #{@port} #{db_name} > #{filepath db_name}) 29 | end 30 | 31 | def create_db_command(db_name) 32 | %( PGOPTIONS='--client-min-messages=warning' \ 33 | psql -U postgres \ 34 | -h #{@host} \ 35 | -p #{@port} \ 36 | -c "DROP DATABASE IF EXISTS #{db_name}" \ 37 | -c "CREATE DATABASE #{db_name}") 38 | end 39 | 40 | def restore_db_command(db_name) 41 | %( psql -d #{db_name} \ 42 | -U #{@user} \ 43 | -h #{@host} \ 44 | -p #{@port} \ 45 | -f #{backup_file db_name}) 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /lib/dbmgr.rb: -------------------------------------------------------------------------------- 1 | require 'thor' 2 | require "database/database" 3 | require "dbmgr/version" 4 | require 'dbmgr/mysql' 5 | require 'dbmgr/postgresql' 6 | 7 | module Dbmgr 8 | end 9 | -------------------------------------------------------------------------------- /lib/dbmgr/mysql.rb: -------------------------------------------------------------------------------- 1 | require 'dbmgr/mysql/backup' 2 | require 'dbmgr/mysql/restore' 3 | 4 | module Dbmgr 5 | class CLI < Thor 6 | 7 | desc "mysql", "Run commands on MySQL Databases" 8 | subcommand "mysql", Dbmgr::MySQLCLI 9 | 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/dbmgr/mysql/backup.rb: -------------------------------------------------------------------------------- 1 | module Dbmgr 2 | class MySQLCLI < Thor 3 | 4 | desc "backup", "Create a backup" 5 | method_option :filename, 6 | aliases: ["f"], 7 | type: :string, 8 | banner: "my_backup.sql", 9 | desc: "Name of the backup created" 10 | 11 | method_option :path, 12 | aliases: ["p"], 13 | type: :string, 14 | default: "#{ENV["HOME"]}/.db_backups", 15 | banner: "#{ENV["HOME"]}/.db_backups", 16 | desc: "Directory of database backups" 17 | 18 | method_option :port, 19 | aliases: ["P"], 20 | type: :numeric, 21 | default: 3306, 22 | banner: "3306", 23 | desc: "MySQL database port" 24 | 25 | method_option :host, 26 | aliases: ["h"], 27 | type: :string, 28 | default: "localhost", 29 | banner: "localhost", 30 | desc: "MySQL database host" 31 | 32 | method_option :user, 33 | aliases: ["u"], 34 | type: :string, 35 | default: 'root', 36 | banner: "root", 37 | desc: "MySQL database user" 38 | 39 | def backup db_name 40 | Database.new(options) 41 | .extend(MySQL) 42 | .backup db_name 43 | end 44 | 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /lib/dbmgr/mysql/restore.rb: -------------------------------------------------------------------------------- 1 | 2 | module Dbmgr 3 | class MySQLCLI < Thor 4 | 5 | desc "restore", "Restore from a backup" 6 | method_option :backup, 7 | aliases: ["b"], 8 | type: :string, 9 | banner: "#{ENV["HOME"]}/.db_backups/backup.sql", 10 | desc: "Path to backup to restore from" 11 | 12 | method_option :path, 13 | aliases: ["p"], 14 | type: :string, 15 | default: "#{ENV["HOME"]}/.db_backups", 16 | banner: "#{ENV["HOME"]}/.db_backups", 17 | desc: "Directory of database backups" 18 | 19 | method_option :port, 20 | aliases: ["P"], 21 | type: :numeric, 22 | default: 3306, 23 | banner: "3306", 24 | desc: "MySQL database port" 25 | 26 | method_option :host, 27 | aliases: ["h"], 28 | type: :string, 29 | default: "localhost", 30 | banner: "localhost", 31 | desc: "MySQL database host" 32 | 33 | method_option :user, 34 | aliases: ["u"], 35 | type: :string, 36 | default: "root", 37 | banner: "root", 38 | desc: "MySQL database user" 39 | 40 | def restore db_name 41 | Database.new(options) 42 | .extend(MySQL) 43 | .restore db_name 44 | end 45 | 46 | end 47 | end 48 | 49 | -------------------------------------------------------------------------------- /lib/dbmgr/postgresql.rb: -------------------------------------------------------------------------------- 1 | require 'dbmgr/postgresql/backup' 2 | require 'dbmgr/postgresql/restore' 3 | 4 | module Dbmgr 5 | class CLI < Thor 6 | 7 | desc "psql", "Run commands on PostgreSQL Databases" 8 | subcommand "psql", Dbmgr::PostgreSQLCLI 9 | 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/dbmgr/postgresql/backup.rb: -------------------------------------------------------------------------------- 1 | module Dbmgr 2 | class PostgreSQLCLI < Thor 3 | 4 | desc "backup", "Create a backup" 5 | method_option :filename, 6 | aliases: ["f"], 7 | type: :string, 8 | banner: "my_backup.sql", 9 | desc: "Name of the backup created" 10 | 11 | method_option :path, 12 | aliases: ["p"], 13 | type: :string, 14 | default: "#{ENV["HOME"]}/.db_backups", 15 | banner: "#{ENV["HOME"]}/.db_backups", 16 | desc: "Directory of database backups" 17 | 18 | method_option :port, 19 | aliases: ["P"], 20 | type: :numeric, 21 | default: 5432, 22 | banner: "5432", 23 | desc: "PostgreSQL database port" 24 | 25 | method_option :host, 26 | aliases: ["h"], 27 | type: :string, 28 | default: "localhost", 29 | banner: "localhost", 30 | desc: "PostgreSQL database host" 31 | 32 | method_option :user, 33 | aliases: ["u"], 34 | type: :string, 35 | default: 'postgres', 36 | banner: "postgres", 37 | desc: "PostgreSQL database user" 38 | 39 | def backup db_name 40 | Database.new(options) 41 | .extend(PostgreSQL) 42 | .backup db_name 43 | end 44 | 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /lib/dbmgr/postgresql/restore.rb: -------------------------------------------------------------------------------- 1 | 2 | module Dbmgr 3 | class PostgreSQLCLI < Thor 4 | 5 | desc "restore", "Restore from a backup" 6 | method_option :backup, 7 | aliases: ["b"], 8 | type: :string, 9 | banner: "#{ENV["HOME"]}/.db_backups/backup.sql", 10 | desc: "Path to backup to restore from" 11 | 12 | method_option :path, 13 | aliases: ["p"], 14 | type: :string, 15 | default: "#{ENV["HOME"]}/.db_backups", 16 | banner: "#{ENV["HOME"]}/.db_backups", 17 | desc: "Directory of database backups" 18 | 19 | method_option :port, 20 | aliases: ["P"], 21 | type: :numeric, 22 | default: 5432, 23 | banner: "5432", 24 | desc: "PostgreSQL database port" 25 | 26 | method_option :host, 27 | aliases: ["h"], 28 | type: :string, 29 | default: "localhost", 30 | banner: "localhost", 31 | desc: "PostgreSQL database host" 32 | 33 | method_option :user, 34 | aliases: ["u"], 35 | type: :string, 36 | default: "postgres", 37 | banner: "postgres", 38 | desc: "PostgreSQL database user" 39 | 40 | def restore db_name 41 | Database.new(options) 42 | .extend(PostgreSQL) 43 | .restore db_name 44 | end 45 | 46 | end 47 | end 48 | 49 | -------------------------------------------------------------------------------- /lib/dbmgr/version.rb: -------------------------------------------------------------------------------- 1 | module Dbmgr 2 | VERSION = "0.2.0" 3 | end 4 | -------------------------------------------------------------------------------- /test/dbmgr/backup_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | describe Dbmgr::CLI do 4 | DATABASES.each do |database| 5 | describe "Backing up a #{database} database" do 6 | before do 7 | @db = database_helper database 8 | `mkdir -p #{HOME}` # Create test home directory 9 | end 10 | 11 | after do 12 | `rm -rf #{HOME}` 13 | end 14 | 15 | it "should provision the #{database} database for testing" do 16 | @db.num_users.must_equal NAMES.size 17 | end 18 | 19 | describe "when backing up a #{database} database" do 20 | it 'should create a backup directory' do 21 | Dbmgr::CLI.start([database, "backup", "dbmgr_test"]) 22 | File.directory?(BACKUPS) 23 | end 24 | 25 | it 'should create a backup' do 26 | Dbmgr::CLI.start([database, "backup", "dbmgr_test"]) 27 | Dir.glob("#{BACKUPS}/*.sql").length.must_equal 1 28 | end 29 | 30 | it 'should, by default, create a backup named: [database]_[timestamp]' do 31 | Dbmgr::CLI.start([database, "backup", "dbmgr_test"]) 32 | backup = Dir.glob("#{BACKUPS}/*.sql").first 33 | (backup =~ /dbmgr_test_\d*.sql/).nil?.must_equal false 34 | end 35 | 36 | it 'should create a backup with a given filename' do 37 | Dbmgr::CLI.start([database, "backup", "dbmgr_test", "-f", "my_backup.sql"]) 38 | File.file?("#{BACKUPS}/my_backup.sql").must_equal true 39 | end 40 | end 41 | end 42 | end 43 | 44 | end 45 | 46 | -------------------------------------------------------------------------------- /test/dbmgr/dbmgr_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require "dbmgr" 3 | 4 | describe Dbmgr do 5 | 6 | describe "VERSION" do 7 | it 'should be a semantic version' do 8 | (Dbmgr::VERSION =~ /\d*\.\d*\.\d*/).wont_be_nil 9 | end 10 | end 11 | 12 | end 13 | -------------------------------------------------------------------------------- /test/dbmgr/restore_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | describe Dbmgr::CLI do 4 | 5 | DATABASES.each do |database| 6 | describe "when restoring a #{database} database" do 7 | before do 8 | @db = database_helper database 9 | @users = @db.num_users 10 | `mkdir -p #{HOME}` # Create test home directory 11 | end 12 | 13 | after do 14 | `rm -rf #{HOME}` 15 | end 16 | 17 | it 'should restore from the latest backup in the default path' do 18 | Dbmgr::CLI.start([database, "backup", "dbmgr_test"]) 19 | @db.truncate 20 | Dbmgr::CLI.start([database, "restore", "dbmgr_test"]) 21 | @db.num_users.must_equal @users 22 | end 23 | 24 | it 'should restore from the latest backup when the database does not exist' do 25 | Dbmgr::CLI.start([database, "backup", "dbmgr_test"]) 26 | @db.drop 27 | Dbmgr::CLI.start([database, "restore", "dbmgr_test"]) 28 | @db.num_users.must_equal @users 29 | end 30 | 31 | it 'should throw an error if no backup is found' do 32 | assert_raises RuntimeError do 33 | Dbmgr::CLI.start([database, "restore", "dbmgr_test"]) 34 | end 35 | end 36 | 37 | describe 'using a named backup' do 38 | before do 39 | Dbmgr::CLI.start([database, "backup", "dbmgr_test", "-f", "my_backup.sql"]) 40 | end 41 | 42 | it 'should restore from a specified backup' do 43 | @db.drop 44 | Dbmgr::CLI.start([database, "restore", "dbmgr_test", "-b", "#{HOME}/.db_backups/my_backup.sql"]) 45 | @db.num_users.must_equal @users 46 | end 47 | 48 | end 49 | 50 | end 51 | 52 | end 53 | 54 | end 55 | 56 | -------------------------------------------------------------------------------- /test/dbmgr_test.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/callahanrts/dbmgr/590e777178beb008a5da49c2586b2a4df9da1aa4/test/dbmgr_test.rb -------------------------------------------------------------------------------- /test/helpers/mysql_helper.rb: -------------------------------------------------------------------------------- 1 | require 'mysql2' 2 | 3 | class MySQLHelper 4 | DB_NAME = "dbmgr_test" 5 | 6 | def initialize names 7 | initialize_database 8 | insert_users names 9 | end 10 | 11 | def truncate 12 | mysql_client(DB_NAME).query "TRUNCATE TABLE users" 13 | end 14 | 15 | def drop 16 | mysql_client(DB_NAME).query "DROP DATABASE IF EXISTS dbmgr_test" 17 | end 18 | 19 | def num_users 20 | results = mysql_client(DB_NAME).query("SELECT * from users") 21 | results.count 22 | end 23 | 24 | private 25 | 26 | def initialize_database 27 | client = mysql_client 28 | client.query("DROP DATABASE IF EXISTS #{DB_NAME}") 29 | client.query("CREATE DATABASE #{DB_NAME}") 30 | end 31 | 32 | def insert_users names 33 | client = mysql_client DB_NAME 34 | client.query("CREATE TABLE users (name VARCHAR(20))") 35 | names.each do |name| 36 | client.query("INSERT INTO users VALUES ('#{name}')") 37 | end 38 | end 39 | 40 | def mysql_client(db_name = nil) 41 | options = { host: "localhost", username: "root" } 42 | options.merge!(database: db_name) unless db_name.nil? 43 | Mysql2::Client.new(options) 44 | end 45 | 46 | end 47 | -------------------------------------------------------------------------------- /test/helpers/postgresql_helper.rb: -------------------------------------------------------------------------------- 1 | require 'pg' 2 | 3 | class PostgreSQLHelper 4 | PG_DB_NAME = 'postgres' 5 | DB_NAME = 'dbmgr_test' 6 | 7 | def initialize names 8 | drop 9 | create 10 | insert_users names 11 | end 12 | 13 | def truncate 14 | pg_exec DB_NAME, ["TRUNCATE TABLE users"] 15 | end 16 | 17 | def drop 18 | pg_exec ["DROP DATABASE IF EXISTS #{DB_NAME}"] 19 | end 20 | 21 | def num_users 22 | users = 0 23 | pg_exec DB_NAME, ["SELECT * FROM users"] do |results| 24 | users = results.first.values.size 25 | end 26 | users 27 | end 28 | 29 | private 30 | 31 | def create 32 | pg_exec ["CREATE DATABASE #{DB_NAME}"] 33 | pg_exec DB_NAME, ["CREATE TABLE users (name varchar(20))"] 34 | end 35 | 36 | def insert_users names 37 | commands = names.map{|name| "INSERT INTO users VALUES ('#{name}')"} 38 | pg_exec DB_NAME, commands 39 | end 40 | 41 | def pg_exec(db_name = nil, queries, &block) 42 | client = pg_client(db_name) 43 | results = queries.map{ |query| client.exec query } 44 | yield results if block_given? 45 | client.close 46 | end 47 | 48 | def pg_client(db_name = nil) 49 | PG::Connection.new(nil, 5432, nil, nil, db_name, nil, nil) 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) 2 | 3 | HOME = '/tmp/dbmgr' 4 | ENV["HOME"] = HOME 5 | BACKUPS = "#{HOME}/.db_backups" 6 | NAMES = ["fred", "joe", "bob", "sue", "jane"] 7 | DATABASES = [:mysql, :psql] 8 | 9 | require 'dbmgr' 10 | require 'minitest/autorun' 11 | require 'mocha/mini_test' 12 | require 'helpers/mysql_helper' 13 | require 'helpers/postgresql_helper' 14 | 15 | def database_helper(database) 16 | case database.to_sym 17 | when :mysql then MySQLHelper.new NAMES 18 | when :psql then PostgreSQLHelper.new NAMES 19 | end 20 | end 21 | --------------------------------------------------------------------------------