eedb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ pkg/*
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Nathan Herald
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1 @@
1
+ ...
data/Rakefile ADDED
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "eedb"
8
+ gem.summary = %Q{Migrating your EE DB to and from a server is now easy}
9
+ gem.description = %Q{Migrates your EE DB to and from a server with rollback capabilities and find and replace to change paths automagically.}
10
+ gem.email = "nathan@myobie.com"
11
+ gem.homepage = "http://github.com/myobie/eedb"
12
+ gem.authors = ["Nathan Herald"]
13
+ gem.add_development_dependency "bacon", ">= 0"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+
16
+ gem.files.include FileList['lib/eedb/templates/*']
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ require 'rake/testtask'
24
+ Rake::TestTask.new(:spec) do |spec|
25
+ spec.libs << 'lib' << 'spec'
26
+ spec.pattern = 'spec/**/*_spec.rb'
27
+ spec.verbose = true
28
+ end
29
+
30
+ begin
31
+ require 'rcov/rcovtask'
32
+ Rcov::RcovTask.new do |spec|
33
+ spec.libs << 'spec'
34
+ spec.pattern = 'spec/**/*_spec.rb'
35
+ spec.verbose = true
36
+ end
37
+ rescue LoadError
38
+ task :rcov do
39
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
40
+ end
41
+ end
42
+
43
+ task :spec => :check_dependencies
44
+
45
+ task :default => :spec
46
+
47
+ require 'rake/rdoctask'
48
+ Rake::RDocTask.new do |rdoc|
49
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "eedb #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/bin/eedb ADDED
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "eedb"
4
+
5
+ existing_yaml_file = File.exists?("eedb.yml")
6
+
7
+ def create_yaml_file
8
+ yaml_file = File.expand_path(File.join(File.dirname(__FILE__), "../lib/eedb/templates/eedb.yml"))
9
+ yaml_contents = File.new(yaml_file, "r").read
10
+ File.open("eedb.yml", "w+") do |f|
11
+ f.write(yaml_contents)
12
+ end
13
+
14
+ puts "!!! An example eedb.yml file has been created for you. Please update it"
15
+ puts " with the correct information before running eedb."
16
+ puts yaml_file
17
+ end
18
+
19
+ if !existing_yaml_file
20
+ puts "!!! An eedb.yml file must exist and contain your database information."
21
+ create_yaml_file
22
+ exit
23
+ end
24
+
25
+ if ARGV.length < 1
26
+ puts "eedb [init|export|import|rollback (local|remote)]"
27
+ exit
28
+ end
29
+
30
+ case ARGV[0]
31
+ when "import"
32
+ Eedb.import
33
+ when "export"
34
+ Eedb.export
35
+ when "rollback"
36
+ Eedb.rollback(ARGV[1])
37
+ when "init"
38
+
39
+ if existing_yaml_file
40
+ print "- Do you want to ovewrite the existing eedb.yml file? (Y/n): "
41
+ answer = STDIN.gets.chomp
42
+
43
+ if answer == "Y"
44
+ create_yaml_file
45
+ end
46
+ else
47
+ create_yaml_file
48
+ end
49
+
50
+ end
data/eedb.gemspec ADDED
@@ -0,0 +1,53 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{eedb}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Nathan Herald"]
12
+ s.date = %q{2010-02-25}
13
+ s.default_executable = %q{eedb}
14
+ s.description = %q{Migrates your EE DB to and from a server with rollback capabilities and find and replace to change paths automagically.}
15
+ s.email = %q{nathan@myobie.com}
16
+ s.executables = ["eedb"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.markdown"
20
+ ]
21
+ s.files = [
22
+ ".gitignore",
23
+ "LICENSE",
24
+ "README.markdown",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "bin/eedb",
28
+ "eedb.gemspec",
29
+ "lib/eedb.rb",
30
+ "lib/eedb/ext.rb",
31
+ "lib/eedb/mysql.rb",
32
+ "lib/eedb/templates/eedb.yml"
33
+ ]
34
+ s.homepage = %q{http://github.com/myobie/eedb}
35
+ s.rdoc_options = ["--charset=UTF-8"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = %q{1.3.6}
38
+ s.summary = %q{Migrating your EE DB to and from a server is now easy}
39
+
40
+ if s.respond_to? :specification_version then
41
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
42
+ s.specification_version = 3
43
+
44
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
45
+ s.add_development_dependency(%q<bacon>, [">= 0"])
46
+ else
47
+ s.add_dependency(%q<bacon>, [">= 0"])
48
+ end
49
+ else
50
+ s.add_dependency(%q<bacon>, [">= 0"])
51
+ end
52
+ end
53
+
data/lib/eedb.rb ADDED
@@ -0,0 +1,90 @@
1
+ require "yaml"
2
+ require "eedb/ext"
3
+ require "eedb/mysql"
4
+
5
+ # setup our constants
6
+
7
+ TIME = Time.now.to_i
8
+
9
+ LOCAL_DUMP_FILE = File.expand_path("tmp/local-dump-#{TIME}.sql")
10
+ REMOTE_DUMP_FILE = File.expand_path("tmp/remote-dump-#{TIME}.sql")
11
+
12
+ if File.exists?("eedb.yml")
13
+ PREFS = YAML.load_file("eedb.yml")
14
+ else
15
+ PREFS = Hash.new(Hash.new({})) # make a fake hash that has hashes in it
16
+ end
17
+
18
+ if PREFS["opt"].empty?
19
+ OPT = '--skip-add-locks --skip-create-options --skip-disable-keys --skip-lock-tables --skip-set-charset --compatible="mysql40"'
20
+ else
21
+ OPT = PREFS["opt"]
22
+ end
23
+
24
+ if PREFS["regex"].empty?
25
+ REGEX = 's:([0-9]+):\\\\":search([a-zA-Z0-9 .+?#-_\/\\\\]*)\\\\";'
26
+ else
27
+ REGEX = PREFS["regex"]
28
+ end
29
+
30
+ if PREFS["replace"].empty?
31
+ PATTERNS = {}
32
+ else
33
+ PATTERNS = PREFS["replace"]
34
+ end
35
+
36
+ class Eedb
37
+
38
+ def self.rollback(which)
39
+ backup = File.expand_path(Dir["tmp/#{which}-dump-*.sql.backup"].last)
40
+
41
+ print "- Are you sure you want to rollback the #{which} DB? (Y/n): "
42
+ answer = STDIN.gets.chomp
43
+
44
+ if answer == "Y"
45
+ log "*** Rolling back #{which} using #{backup}..."
46
+ Mysql.import(backup => which)
47
+ end
48
+
49
+ log "*** Done."
50
+ end
51
+
52
+ def self.export(server = :local)
53
+ other_server = server == :local ? :remote : :local
54
+
55
+ log "*** Starting dump..."
56
+
57
+ log "* Dumping #{server}..."
58
+ Mysql.dump(server)
59
+
60
+ print "- Do you want to push this into the #{other_server} server? (Y/n): "
61
+ answer = STDIN.gets.chomp
62
+
63
+ if answer == "Y"
64
+ print "- Do you want to backup the #{other_server} DB? (Y/n): "
65
+ answer2 = STDIN.gets.chomp
66
+
67
+ if answer2 == "Y"
68
+ log "* Dumping #{other_server} as backup..."
69
+ Mysql.dump(other_server, :backup)
70
+ end
71
+
72
+ log "** Cleanup #{server}..."
73
+ cleaned_file = Mysql.cleanup_file(server)
74
+
75
+ log "*** Pushing #{server} cleaned file to #{other_server}..."
76
+ Mysql.import(cleaned_file => other_server)
77
+ end
78
+
79
+ log "*** Done."
80
+ end
81
+
82
+ def self.import
83
+ export(:remote)
84
+ end
85
+
86
+ def self.log(what)
87
+ puts what
88
+ end
89
+
90
+ end
data/lib/eedb/ext.rb ADDED
@@ -0,0 +1,17 @@
1
+ class Hash
2
+ def to_mysql_options
3
+ collect do |k, v|
4
+ unless v.empty?
5
+ "--#{k}=\"#{v}\""
6
+ else
7
+ nil
8
+ end
9
+ end.reject { |a| a.nil? }.join(" ")
10
+ end
11
+ end
12
+
13
+ class NilClass
14
+ def empty?
15
+ true
16
+ end
17
+ end
data/lib/eedb/mysql.rb ADDED
@@ -0,0 +1,82 @@
1
+ class Mysql
2
+ def self.dump(server, backup = false)
3
+ options = PREFS["databases"][server.to_s]["options"].to_mysql_options
4
+ db = PREFS["databases"][server.to_s]["database"]
5
+ file = const_get(server.to_s.upcase + "_DUMP_FILE")
6
+
7
+ file += ".backup" if backup
8
+
9
+ `mysqldump #{options} #{OPT} #{db} > #{file}`
10
+ end
11
+
12
+ def self.import(server, file = nil)
13
+ if file.nil?
14
+ # assume it's a hash
15
+ file = server.keys.first # if it's :local => :remote, the file is :local
16
+ server = server.values.first # if it's :local => :remote, the server is :remote
17
+ end
18
+
19
+ options = PREFS["databases"][server.to_s]["options"].to_mysql_options
20
+ db = PREFS["databases"][server.to_s]["database"]
21
+
22
+ if file.is_a?(Symbol)
23
+ file = const_get(file.to_s.upcase + "_DUMP_FILE")
24
+ end
25
+
26
+ `mysql #{options} #{db} -e "SOURCE #{file}"`
27
+ end
28
+
29
+ def self.cleanup_file(file)
30
+ other_server = nil
31
+
32
+ if file.is_a?(Symbol)
33
+ other_server = :remote if file == :local
34
+ other_server = :local if file == :remote
35
+
36
+ file = const_get(file.to_s.upcase + "_DUMP_FILE")
37
+ end
38
+
39
+ cleaned_file = File.expand_path(file + ".cleaned")
40
+
41
+ # only clean it if we know what server it's going to
42
+ if other_server
43
+ contents = File.new(file, "r").read
44
+
45
+ if other_server == :remote
46
+ first, second = "local", "remote"
47
+ # if remote is the server, we want to substitue all local for remote
48
+ else
49
+ first, second = "remote", "local"
50
+ # if local is the server, we want to substitue all remote for local
51
+ end
52
+
53
+ PATTERNS.each do |name, pattern|
54
+ f = pattern[first]
55
+ r = pattern[second]
56
+
57
+ f_escaped = Regexp.escape(f)
58
+ f_regex = Regexp.new(f_escaped)
59
+ s_regex = Regexp.new(REGEX.gsub(/:search/, f_escaped))
60
+ difference = r.length - f.length
61
+
62
+ # first, update any s: freaking strings
63
+ contents.gsub!(s_regex) do |match|
64
+ parts = match.scan(s_regex).first
65
+ number = parts[0].to_i + difference
66
+ "s:#{number}:\\\"#{r}#{parts[1]}\\\";"
67
+ end
68
+
69
+ # then just update all remaining instances of it
70
+ contents.gsub!(f_regex, r)
71
+ end
72
+ end#if server
73
+
74
+ # save the cleaned file
75
+ File.open(cleaned_file, "w+") do |f|
76
+ f.write(contents)
77
+ end
78
+
79
+ # return the cleaned file path
80
+ cleaned_file
81
+ end
82
+ end
@@ -0,0 +1,21 @@
1
+ databases:
2
+ local:
3
+ database: example
4
+ options:
5
+ host: localhost
6
+ user: root
7
+ password:
8
+ remote:
9
+ database: example_production
10
+ options:
11
+ host: db.example.com
12
+ user: example_db_user
13
+ password: db_password
14
+
15
+ replace:
16
+ file_path:
17
+ local: "/Users/you/Sites/example.com"
18
+ remote: "/home/1234/domains/example.com/html"
19
+ url:
20
+ local: "http://example.local"
21
+ remote: "http://example.com"
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eedb
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Nathan Herald
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-02-25 00:00:00 -05:00
18
+ default_executable: eedb
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: bacon
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :development
31
+ version_requirements: *id001
32
+ description: Migrates your EE DB to and from a server with rollback capabilities and find and replace to change paths automagically.
33
+ email: nathan@myobie.com
34
+ executables:
35
+ - eedb
36
+ extensions: []
37
+
38
+ extra_rdoc_files:
39
+ - LICENSE
40
+ - README.markdown
41
+ files:
42
+ - .gitignore
43
+ - LICENSE
44
+ - README.markdown
45
+ - Rakefile
46
+ - VERSION
47
+ - bin/eedb
48
+ - eedb.gemspec
49
+ - lib/eedb.rb
50
+ - lib/eedb/ext.rb
51
+ - lib/eedb/mysql.rb
52
+ - lib/eedb/templates/eedb.yml
53
+ has_rdoc: true
54
+ homepage: http://github.com/myobie/eedb
55
+ licenses: []
56
+
57
+ post_install_message:
58
+ rdoc_options:
59
+ - --charset=UTF-8
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ requirements: []
77
+
78
+ rubyforge_project:
79
+ rubygems_version: 1.3.6
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: Migrating your EE DB to and from a server is now easy
83
+ test_files: []
84
+