wordpress-deploy 1.0.0.alpha2 → 1.0.0.rc1
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/.gitignore +7 -1
- data/Guardfile +1 -16
- data/README.md +56 -0
- data/lib/wordpress_deploy.rb +43 -9
- data/lib/wordpress_deploy/cli/helpers.rb +6 -3
- data/lib/wordpress_deploy/cli/utility.rb +56 -33
- data/lib/wordpress_deploy/config.rb +77 -0
- data/lib/wordpress_deploy/database/mysql.rb +281 -20
- data/lib/wordpress_deploy/environment.rb +85 -43
- data/lib/wordpress_deploy/environments.rb +89 -0
- data/lib/wordpress_deploy/logger.rb +3 -3
- data/lib/wordpress_deploy/{transfer_protocols → storage}/ftp.rb +52 -116
- data/lib/wordpress_deploy/storage/local.rb +12 -0
- data/lib/wordpress_deploy/version.rb +1 -1
- data/lib/wordpress_deploy/wordpress/salts.rb +68 -0
- data/spec/data/blue.rb +52 -0
- data/spec/data/development.rb +49 -0
- data/spec/data/green.rb +52 -0
- data/spec/data/production.rb +52 -0
- data/spec/data/red.rb +52 -0
- data/spec/data/wp-config.php +90 -0
- data/spec/spec_helper.rb +16 -5
- data/spec/wordpress_deploy/cli/utility_spec.rb +48 -0
- data/spec/{environment_spec.rb → wordpress_deploy/config_spec.rb} +9 -7
- data/spec/wordpress_deploy/database/mysql_spec.rb +147 -0
- data/spec/wordpress_deploy/environment_spec.rb +96 -0
- data/spec/wordpress_deploy/environments_spec.rb +65 -0
- data/spec/wordpress_deploy/storage/ftp_spec.rb +58 -0
- data/spec/wordpress_deploy/storage/local_spec.rb +0 -0
- data/spec/wordpress_deploy/wordpress/salts_spec.rb +70 -0
- data/{spec/data/wp-config-sample.php → templates/wp-config.erb} +17 -17
- data/wordpress_deploy.gemspec +7 -6
- metadata +64 -30
- data/Gemfile.lock +0 -83
- data/lib/wordpress_deploy/wordpress/configuration.rb +0 -196
- data/spec/data/ftp.yml +0 -4
- data/spec/data/wp-config.yml +0 -128
- data/spec/database/mysql_spec.rb +0 -93
- data/spec/transfer_protocols/ftp_spec.rb +0 -193
- data/spec/wordpress/configuration_spec.rb +0 -202
data/.gitignore
CHANGED
@@ -12,6 +12,8 @@ test/tmp
|
|
12
12
|
test/version_tmp
|
13
13
|
tmp
|
14
14
|
|
15
|
+
*.swp
|
16
|
+
|
15
17
|
# YARD artifacts
|
16
18
|
.yardoc
|
17
19
|
_yardoc
|
@@ -20,8 +22,12 @@ doc/
|
|
20
22
|
# Mac files
|
21
23
|
.DS_Store
|
22
24
|
|
25
|
+
# Development gems
|
26
|
+
Gemfile.lock
|
27
|
+
|
23
28
|
# Spec data made during tests
|
24
|
-
spec/data
|
29
|
+
spec/data/*.sql
|
25
30
|
*.log
|
26
31
|
config/
|
27
32
|
site/
|
33
|
+
sql/
|
data/Guardfile
CHANGED
@@ -3,22 +3,7 @@
|
|
3
3
|
|
4
4
|
guard 'rspec', :version => 2 do
|
5
5
|
watch(%r{^spec/.+_spec\.rb$})
|
6
|
-
watch(%r{^lib/
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
7
7
|
watch('spec/spec_helper.rb') { "spec" }
|
8
|
-
|
9
|
-
# Rails example
|
10
|
-
#watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
11
|
-
#watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
12
|
-
#watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
13
|
-
#watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
14
|
-
#watch('config/routes.rb') { "spec/routing" }
|
15
|
-
#watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
16
|
-
|
17
|
-
# Capybara request specs
|
18
|
-
#watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
|
19
|
-
|
20
|
-
# Turnip features and steps
|
21
|
-
#watch(%r{^spec/acceptance/(.+)\.feature$})
|
22
|
-
#watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
23
8
|
end
|
24
9
|
|
data/README.md
CHANGED
@@ -35,3 +35,59 @@ Usage
|
|
35
35
|
-----
|
36
36
|
|
37
37
|
wp-deploy help
|
38
|
+
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
##
|
42
|
+
# This is an example of a default WordpressDeploy configuration file. The
|
43
|
+
# values here are examples to show you what to do.
|
44
|
+
WordpressDeploy::Environment.new(:red) do
|
45
|
+
|
46
|
+
base_url "localhost"
|
47
|
+
|
48
|
+
##
|
49
|
+
# Connection and settings for the MySQL database that wordpress
|
50
|
+
# connects to
|
51
|
+
database do
|
52
|
+
name "red"
|
53
|
+
user "red_user"
|
54
|
+
password "Bun__huPEMeBreM6tebRAp@eguzuQExe"
|
55
|
+
host "hanerutherford.biz"
|
56
|
+
charset "utf8"
|
57
|
+
collate ""
|
58
|
+
|
59
|
+
##
|
60
|
+
# If this parameter is not defined wp_
|
61
|
+
# is assumed.
|
62
|
+
table_prefix "wp_";
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# Authentication Unique Keys and Salts
|
67
|
+
# https://api.wordpress.org/secret-key/1.1/salt/
|
68
|
+
# If no salts are supplied they will be generated automatically
|
69
|
+
#
|
70
|
+
# NOTE This entire block is optional
|
71
|
+
salts do
|
72
|
+
auth_key '*oH{(q=`tIzdNJKUk$XfHNNjKd$W=f$S`CtD.,;x0R}$/A,}]!+q0>>QfB#.Bsw]'
|
73
|
+
secure_auth_key '{yg|7Q*j-?$%`b|Z!+5U,pvM,eA0+$/ruprp.mO[;|fExU:n0,-!at0+3UY@;h`X'
|
74
|
+
logged_in_key 'k]N 9I<-rZq#k Xg)IPhv$E*ktbD7Z_AtI){U;(P;0r#LJlYncEr%8v9tG`>BHU+'
|
75
|
+
nonce_key ' /w9->::-YB Xa#lf%TPH+cIf?]Ru4OfKGF2h8PHsa)2,n-~kRJ<[slUg<GZ Asx'
|
76
|
+
auth_salt 'VYwGGP,#|9P[5RCUTdv2c8)`^{dotU0fWrU`JE9qq^n=F4//e)fCs<HF6sd>~yjW'
|
77
|
+
secure_auth_salt 'ok}@vSs=n6%_%UCO|&[?Jc;,-,.#Q3}zR4ej%IoAL7RavTN/Xe,UrQ4)p}onRie0'
|
78
|
+
logged_in_salt 'Z!,C*:Q_I9A`[pJm-b0Z/(Gm2qvK8>0~| T&)lM+sxG.OdEmgHbAGF&(^>2.rDGW'
|
79
|
+
nonce_salt 'ay)${bFV=F1KH[`NZ+W+Zk?Hc:@}jN}Ec)+Zn[F1fyP,mwi|@tk/(1hdp[G2F%os'
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Block defines the settings for the transfer of files
|
84
|
+
# to this configuration.
|
85
|
+
transfer :Ftp do
|
86
|
+
host "ftp.hanerutherford.biz"
|
87
|
+
user "red_user"
|
88
|
+
password "Bun__huPEMeBreM6tebRAp@eguzuQExe"
|
89
|
+
destination "/html"
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
```
|
data/lib/wordpress_deploy.rb
CHANGED
@@ -1,16 +1,49 @@
|
|
1
1
|
require "thor"
|
2
2
|
require "open3"
|
3
3
|
require "fileutils"
|
4
|
+
require "yaml"
|
5
|
+
|
6
|
+
class Hash
|
7
|
+
|
8
|
+
def find_and_replace!(find, replace)
|
9
|
+
RecursiveReplace.find_and_replace!(find, replace, self)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
class RecursiveReplace
|
15
|
+
|
16
|
+
def self.find_and_replace!(find, replace, obj)
|
17
|
+
m = "find_and_replace_#{obj.class}!"
|
18
|
+
send(m, find, replace, obj) if respond_to? m, true
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def self.find_and_replace_Hash!(find, replace, hash)
|
24
|
+
hash.each { |k,v| find_and_replace!(find, replace, v) }
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.find_and_replace_Array!(find, replace, arr)
|
28
|
+
arr.each { |x| find_and_replace!(find, replace, x) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.find_and_replace_String!(find, replace, str)
|
32
|
+
str.gsub!(/#{find}/, replace)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
4
36
|
|
5
37
|
module WordpressDeploy
|
6
38
|
##
|
7
39
|
# WordpressDeploy's internal paths
|
8
40
|
#
|
9
|
-
LIBRARY_PATH
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
41
|
+
LIBRARY_PATH = File.join(File.dirname(__FILE__), 'wordpress_deploy')
|
42
|
+
TEMPLATE_PATH = File.join(File.dirname(__FILE__), '..', 'templates')
|
43
|
+
CLI_PATH = File.join(LIBRARY_PATH, 'cli')
|
44
|
+
WORDPRESS_PATH = File.join(LIBRARY_PATH, 'wordpress')
|
45
|
+
STORAGE_PATH = File.join(LIBRARY_PATH, 'storage')
|
46
|
+
DATABASE_PATH = File.join(LIBRARY_PATH, 'database')
|
14
47
|
|
15
48
|
module Cli
|
16
49
|
autoload :Helpers, File.join(CLI_PATH, 'helpers')
|
@@ -18,18 +51,19 @@ module WordpressDeploy
|
|
18
51
|
end
|
19
52
|
|
20
53
|
module Wordpress
|
21
|
-
autoload :
|
54
|
+
autoload :Salts, File.join(WORDPRESS_PATH, 'salts')
|
22
55
|
end
|
23
56
|
|
24
|
-
module
|
25
|
-
autoload :Ftp,
|
57
|
+
module Storage
|
58
|
+
autoload :Ftp, File.join(STORAGE_PATH, 'ftp')
|
59
|
+
autoload :Local, File.join(STORAGE_PATH, 'local')
|
26
60
|
end
|
27
61
|
|
28
62
|
module Database
|
29
63
|
autoload :MySql, File.join(DATABASE_PATH, 'mysql')
|
30
64
|
end
|
31
65
|
|
32
|
-
%w{version logger errors environment}.each do |klass|
|
66
|
+
%w{version logger errors config environments environment}.each do |klass|
|
33
67
|
require File.join(LIBRARY_PATH, klass)
|
34
68
|
end
|
35
69
|
end
|
@@ -14,7 +14,7 @@ module WordpressDeploy
|
|
14
14
|
# If the command fails to execute, or returns a non-zero exit status
|
15
15
|
# an Error will be raised.
|
16
16
|
#
|
17
|
-
# Returns
|
17
|
+
# Returns STDOUT
|
18
18
|
def run(command)
|
19
19
|
name = command_name(command)
|
20
20
|
Logger.debug "Running system utility '#{ name }'..."
|
@@ -47,7 +47,7 @@ module WordpressDeploy
|
|
47
47
|
)
|
48
48
|
end
|
49
49
|
|
50
|
-
return
|
50
|
+
return out
|
51
51
|
else
|
52
52
|
raise Errors::Cli::SystemCallError, <<-EOS
|
53
53
|
'#{ name }' Failed on #{ RUBY_PLATFORM }
|
@@ -69,7 +69,10 @@ module WordpressDeploy
|
|
69
69
|
raise Errors::Cli::UtilityNotFoundError,
|
70
70
|
'Utility Name Empty' if name.empty?
|
71
71
|
|
72
|
+
# Return the utility immediately if it has already been found
|
72
73
|
path = UTILITY[name]
|
74
|
+
return path unless path.nil?
|
75
|
+
|
73
76
|
err, ps = '', nil
|
74
77
|
Open3.popen3 "which #{name}" do |stdin, stdout, stderr, wait_thr|
|
75
78
|
stdin.close
|
@@ -78,7 +81,7 @@ module WordpressDeploy
|
|
78
81
|
|
79
82
|
# Process::Status object returned
|
80
83
|
ps = wait_thr.value
|
81
|
-
end
|
84
|
+
end
|
82
85
|
|
83
86
|
if !ps.nil? && ps.success?
|
84
87
|
UTILITY[name] = path
|
@@ -9,24 +9,26 @@ module WordpressDeploy
|
|
9
9
|
# These options apply to all commands
|
10
10
|
class_option :root_dir, type: :string, default: '', aliases: '-r'
|
11
11
|
class_option :wp_dir, type: :string, default: '', aliases: '-w'
|
12
|
-
class_option :
|
12
|
+
class_option :config_dir, type: :string, default: '', aliases: '-c'
|
13
|
+
class_option :sql_dir, type: :string, default: '', aliases: '-s'
|
13
14
|
class_option :verbose, type: :boolean, default: false, aliases: '-v'
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
def generate
|
18
|
-
##
|
16
|
+
desc "config ENVIRONMENT", "Generate the wp-config.php file for the specified environment."
|
17
|
+
def config(environment)
|
19
18
|
# Set Logger into verbose mode (if the user requested it)
|
20
19
|
Logger.verbose = options[:verbose]
|
21
20
|
|
22
21
|
# Set environment options
|
23
|
-
|
22
|
+
Config.set_options options
|
23
|
+
|
24
|
+
# Load ALL the available environments
|
25
|
+
WordpressDeploy::Environments.load
|
24
26
|
|
25
|
-
#
|
26
|
-
|
27
|
+
# Get the Environment the user requested
|
28
|
+
env = WordpressDeploy::Environments.find environment.to_sym
|
27
29
|
|
28
30
|
# Save the configuration file
|
29
|
-
|
31
|
+
env.save_wp_config
|
30
32
|
rescue => err
|
31
33
|
Logger.error Errors::Cli::Utility::Error.wrap(err)
|
32
34
|
|
@@ -34,62 +36,83 @@ module WordpressDeploy
|
|
34
36
|
exit(1)
|
35
37
|
end
|
36
38
|
|
37
|
-
desc "deploy",
|
38
|
-
|
39
|
-
|
39
|
+
desc "deploy FROM TO", <<-EOS
|
40
|
+
Deploy Wordpress onto the TO environment.
|
41
|
+
|
42
|
+
This is achieved by first generating the appropriate wp-config.php file for the
|
43
|
+
desired environment. This wp-config.php, along with all other files within the
|
44
|
+
wp_dir, are then transmitted to the configured TO environment.
|
45
|
+
|
46
|
+
Next, the FROM database is backed up into the sql_dir, and then sent to the
|
47
|
+
configured TO environment. Finally, all records in the TO database are scrubbed
|
48
|
+
to be relative to the new hostname configured for the environment (this
|
49
|
+
includes PHP serialized strings).
|
50
|
+
EOS
|
51
|
+
def deploy(from, to)
|
40
52
|
# Set Logger into verbose mode (if the user requested it)
|
41
53
|
Logger.verbose = options[:verbose]
|
42
54
|
|
43
55
|
# Set environment options
|
44
|
-
|
56
|
+
Config.set_options options
|
45
57
|
|
46
|
-
#
|
47
|
-
|
58
|
+
# Load ALL the available environments
|
59
|
+
WordpressDeploy::Environments.load
|
48
60
|
|
49
|
-
#
|
50
|
-
|
61
|
+
# Get the Environment the user requested
|
62
|
+
from = WordpressDeploy::Environments.find from.to_sym
|
63
|
+
to = WordpressDeploy::Environments.find to.to_sym
|
51
64
|
|
52
65
|
rescue => err
|
53
66
|
Logger.error Errors::Cli::Utility::Error.wrap(err)
|
54
67
|
|
55
68
|
# Exit with an error
|
56
69
|
exit(1)
|
57
|
-
ensure
|
58
|
-
puts "Closing connection.".colorize(color: :red, background: :yellow) if ftp_client.close
|
59
70
|
end
|
60
71
|
|
61
|
-
desc "backup", "
|
62
|
-
def backup
|
63
|
-
##
|
72
|
+
desc "backup ENVIRONMENT", "Call mysqldump on the database specified by ENVIRONMENT"
|
73
|
+
def backup(environment)
|
64
74
|
# Set Logger into verbose mode (if the user requested it)
|
65
75
|
Logger.verbose = options[:verbose]
|
66
76
|
|
67
77
|
# Set environment options
|
68
|
-
|
78
|
+
Config.set_options options
|
79
|
+
|
80
|
+
# Load ALL the available environments
|
81
|
+
WordpressDeploy::Environments.load
|
69
82
|
|
70
|
-
#
|
71
|
-
|
83
|
+
# Get the Environment the user requested
|
84
|
+
env = WordpressDeploy::Environments.find environment.to_sym
|
72
85
|
|
73
|
-
#
|
74
|
-
|
86
|
+
# Backup the database to the sql_dir
|
87
|
+
env.database.save!
|
75
88
|
|
76
89
|
rescue => err
|
77
90
|
Logger.error Errors::Cli::Utility::Error.wrap(err)
|
78
91
|
|
79
92
|
# Exit with an error
|
80
93
|
exit(1)
|
81
|
-
ensure
|
82
|
-
puts "Closing connection.".colorize(color: :red, background: :yellow) if ftp_client.close
|
83
94
|
end
|
84
95
|
|
85
|
-
desc "
|
86
|
-
def
|
87
|
-
##
|
96
|
+
desc "transmit ENVIRONMENT", "Transmit the files in wp_dir"
|
97
|
+
def transmit(environment)
|
88
98
|
# Set Logger into verbose mode (if the user requested it)
|
89
99
|
Logger.verbose = options[:verbose]
|
90
100
|
|
91
101
|
# Set environment options
|
92
|
-
|
102
|
+
Config.set_options options
|
103
|
+
|
104
|
+
# Load ALL the available environments
|
105
|
+
WordpressDeploy::Environments.load
|
106
|
+
|
107
|
+
# Get the Environment the user requested
|
108
|
+
env = WordpressDeploy::Environments.find environment.to_sym
|
109
|
+
|
110
|
+
# Save the configuration file
|
111
|
+
env.save_wp_config
|
112
|
+
|
113
|
+
# Send the files in wp_dir
|
114
|
+
env.transfer.transmit!
|
115
|
+
|
93
116
|
rescue => err
|
94
117
|
Logger.error Errors::Cli::Utility::Error.wrap(err)
|
95
118
|
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module WordpressDeploy
|
2
|
+
##
|
3
|
+
# Config defines all of the locations of input and
|
4
|
+
# output files. Specifically, the locations of the test
|
5
|
+
# definitions, the locations of the test results, and
|
6
|
+
# the locations of the build applications.
|
7
|
+
module Config
|
8
|
+
|
9
|
+
##
|
10
|
+
# Setup required paths based on the given options
|
11
|
+
def self.set_options(options = {})
|
12
|
+
options.each do |option, value|
|
13
|
+
method = "#{option}="
|
14
|
+
send(method, value) if respond_to? method and !value.empty?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.logging=(new_log)
|
19
|
+
# Only set @@logging if new_log is a boolean
|
20
|
+
if !!new_log == new_log
|
21
|
+
@@logging = new_log
|
22
|
+
else
|
23
|
+
@@logging = false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.logging?
|
28
|
+
@@logging ||= false
|
29
|
+
@@logging
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.root_dir=(new_root)
|
33
|
+
@@root_dir = new_root
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.root_dir
|
37
|
+
@@root_dir ||= Dir.pwd
|
38
|
+
File.expand_path @@root_dir
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.config_dir=(new_config_dir)
|
42
|
+
@@config_dir = new_config_dir
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.config_dir
|
46
|
+
@@config_dir ||= "config"
|
47
|
+
File.expand_path File.join(root_dir, @@config_dir)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.wp_dir=(new_wp_dir)
|
51
|
+
@@wp_dir = new_wp_dir
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.wp_dir
|
55
|
+
@@wp_dir ||= "site"
|
56
|
+
File.expand_path File.join(root_dir, @@wp_dir)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.sql_dir=(new_sql_dir)
|
60
|
+
@@sql_dir = new_sql_dir
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.sql_dir
|
64
|
+
@@sql_dir ||= "sql"
|
65
|
+
File.expand_path File.join(root_dir, @@sql_dir)
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.log_file
|
69
|
+
@@log_file ||= "#{Time.now.strftime("%Y_%m_%d_%H_%M_%S")}.log"
|
70
|
+
File.expand_path File.join(root_dir, @@log_file)
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.clean!
|
74
|
+
FileUtils.rm Dir.glob(File.join(root_dir, "*.log"))
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'tempfile'
|
2
|
+
require 'mysql2'
|
3
|
+
require 'php_serialize'
|
2
4
|
|
3
5
|
module WordpressDeploy
|
4
6
|
module Database
|
@@ -6,37 +8,296 @@ module WordpressDeploy
|
|
6
8
|
class MySql
|
7
9
|
include WordpressDeploy::Cli::Helpers
|
8
10
|
|
9
|
-
attr_reader :configuration
|
10
|
-
|
11
11
|
def initialize
|
12
|
-
@
|
12
|
+
@user ||= "root"
|
13
|
+
@password ||= ""
|
14
|
+
|
15
|
+
@host ||= "localhost"
|
16
|
+
@port ||= 3306
|
17
|
+
@socket ||= ""
|
18
|
+
@name ||= "wordpress"
|
19
|
+
|
20
|
+
@has_port ||= true
|
21
|
+
@has_socket ||= false
|
13
22
|
end
|
14
23
|
|
15
|
-
|
16
|
-
|
24
|
+
##
|
25
|
+
# Name of the database (DB_NAME)
|
26
|
+
def name(new_name = nil)
|
27
|
+
@name = new_name.to_s unless new_name.nil?
|
28
|
+
@name
|
17
29
|
end
|
18
30
|
|
19
|
-
|
20
|
-
|
31
|
+
##
|
32
|
+
# User credentials for the specified database
|
33
|
+
def user(new_user = nil)
|
34
|
+
@user = new_user.to_s unless new_user.nil?
|
35
|
+
@user
|
21
36
|
end
|
22
37
|
|
23
|
-
|
38
|
+
##
|
39
|
+
# Password credentials for the specified database
|
40
|
+
def password(new_password = nil)
|
41
|
+
@password = new_password.to_s unless new_password.nil?
|
42
|
+
@password
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Get just the hostname from DB_HOST. Only different from
|
47
|
+
# DB_HOST if DB_HOST has a socket or a port number in it.
|
48
|
+
def host(new_host = nil)
|
49
|
+
unless new_host.nil?
|
50
|
+
match = /(?<host>.*?)(?=:|\z)(:(?<socket>\/.*)|:(?<port>\d+))?/.match(new_host.to_s)
|
51
|
+
@host = match[:host].to_s unless match[:host].nil?
|
52
|
+
|
53
|
+
# Set the socket information
|
54
|
+
if @has_socket = !match[:socket].nil?
|
55
|
+
@has_socket = true
|
56
|
+
@socket = match[:socket]
|
57
|
+
end
|
58
|
+
|
59
|
+
# Set the port information
|
60
|
+
unless match[:port].nil?
|
61
|
+
@port = match[:port].to_i
|
62
|
+
end
|
63
|
+
|
64
|
+
# Has port is true; unless a socket was set
|
65
|
+
@has_port = !@has_socket
|
66
|
+
end
|
67
|
+
|
68
|
+
# return the host
|
69
|
+
@host
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# This value should be able to be plugged directly into
|
74
|
+
# DB_HOST int he wp-config.php file.
|
75
|
+
def wp_host
|
76
|
+
extra = nil
|
77
|
+
extra = ":#{socket}" if socket?
|
78
|
+
extra = ":#{port}" if port?
|
79
|
+
"#{host}#{extra}"
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Extract just the port number from the DB_HOST
|
84
|
+
# configuration file. Or return the default port of 3306.
|
85
|
+
def port
|
86
|
+
@port
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
# Does DB_HOST contain a port number? (it does if one was
|
91
|
+
# specified and it does not equal 3306; the default MySQL
|
92
|
+
# port number.
|
93
|
+
def port?
|
94
|
+
@has_port && port != 3306
|
95
|
+
end
|
96
|
+
|
97
|
+
##
|
98
|
+
# Extract just the socket part from the DB_HOST
|
99
|
+
# configuration file. Or return an empty string if none.
|
100
|
+
def socket
|
101
|
+
@socket
|
102
|
+
end
|
103
|
+
|
104
|
+
##
|
105
|
+
# Does DB_HOST contain a socket path?
|
106
|
+
def socket?
|
107
|
+
@has_socket
|
108
|
+
end
|
109
|
+
|
110
|
+
def charset(new_charset = nil)
|
111
|
+
@charset = new_charset.to_s unless new_charset.nil?
|
112
|
+
@charset
|
113
|
+
end
|
24
114
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
password = configuration.DB_PASSWORD
|
30
|
-
db_name = configuration.DB_NAME
|
115
|
+
def collate(new_collate = nil)
|
116
|
+
@collate = new_collate.to_s unless new_collate.nil?
|
117
|
+
@collate
|
118
|
+
end
|
31
119
|
|
32
|
-
|
120
|
+
def table_prefix(new_prefix = nil)
|
121
|
+
@prefix = new_prefix.to_s unless new_prefix.nil?
|
122
|
+
@prefix
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# The file that the instance would save to if
|
127
|
+
# save is called.
|
128
|
+
def file
|
129
|
+
File.join(Config.sql_dir, "#{name}.sql")
|
33
130
|
end
|
34
131
|
|
35
132
|
##
|
36
|
-
#
|
37
|
-
|
38
|
-
|
39
|
-
|
133
|
+
# Save the database to a file locally.
|
134
|
+
#
|
135
|
+
# The database will be output into #file.
|
136
|
+
def save!
|
137
|
+
# Get the output from MySQL Dump
|
138
|
+
cmd = mysqldump
|
139
|
+
dump_str = run cmd
|
140
|
+
|
141
|
+
# Open the supplied file; or create a temporary one
|
142
|
+
file_io = File.new(file, 'w')
|
143
|
+
|
144
|
+
# Start writing to file
|
145
|
+
file_io.write(dump_str)
|
146
|
+
|
147
|
+
true
|
148
|
+
ensure
|
149
|
+
file_io.close unless file_io.nil?
|
150
|
+
end
|
151
|
+
|
152
|
+
##
|
153
|
+
#
|
154
|
+
def send!(to_config_name)
|
155
|
+
# Check to see if there is a SQL file
|
156
|
+
if File.exists? file
|
157
|
+
# Create the 'to' configuration
|
158
|
+
mysql = self.class.new(to_config_name)
|
159
|
+
|
160
|
+
# Open the source sql file for reading
|
161
|
+
tmp_file = Tempfile.new(["#{to_config_name}", '.sql'])
|
162
|
+
|
163
|
+
# Write sql to tmpfile while changing the
|
164
|
+
# the CREATE DATABASE and USE commands to make sense for
|
165
|
+
# the 'to' configuration
|
166
|
+
sql_dump = File.read(file)
|
167
|
+
sql_dump.gsub!(/^USE\ `#{self.DB_NAME}`/, "USE `#{mysql.DB_NAME}`")
|
168
|
+
tmp_file.puts sql_dump
|
169
|
+
|
170
|
+
# Get the MySQL load command
|
171
|
+
cmd = mysqlload to_config_name, tmp_file.path
|
172
|
+
|
173
|
+
# Run the mysql command to load the mysqldump into
|
174
|
+
# the destination mysql instance
|
175
|
+
run cmd
|
176
|
+
end
|
177
|
+
ensure
|
178
|
+
# Delete the temp file unless it was never made
|
179
|
+
tmp_file.unlink unless tmp_file.nil?
|
180
|
+
end
|
181
|
+
|
182
|
+
##
|
183
|
+
#
|
184
|
+
def migrate!(to_config_name)
|
185
|
+
mysql = self.class.new(to_config_name)
|
186
|
+
|
187
|
+
client = Mysql2::Client.new(
|
188
|
+
:host => mysql.db_hostname,
|
189
|
+
:username => mysql.DB_USER,
|
190
|
+
:password => mysql.DB_PASSWORD,
|
191
|
+
:port => mysql.db_port,
|
192
|
+
:database => mysql.DB_NAME,
|
193
|
+
#:socket = '/path/to/mysql.sock',
|
194
|
+
:encoding => mysql.DB_CHARSET
|
195
|
+
)
|
196
|
+
|
197
|
+
value_to_find = "localhost/~lindsey/huntsvillecrawfishboil.com"
|
198
|
+
value_to_replace = "huntsvillecrawfishboil.com"
|
199
|
+
escaped_value_to_find = client.escape(value_to_find)
|
200
|
+
|
201
|
+
# wp_options option_value
|
202
|
+
sql = <<-EOS
|
203
|
+
SELECT `option_id`, `option_value`
|
204
|
+
FROM `wp_options`
|
205
|
+
WHERE `option_value` REGEXP '#{escaped_value_to_find}';
|
206
|
+
EOS
|
207
|
+
wp_options = client.query(sql)
|
208
|
+
wp_options.each do |row|
|
209
|
+
row.each do |key, value|
|
210
|
+
if PHP.serialized?(value)
|
211
|
+
ruby_php = PHP.unserialize(value)
|
212
|
+
ruby_php.find_and_replace!(value_to_find, value_to_replace)
|
213
|
+
value.replace PHP.serialize(ruby_php)
|
214
|
+
else
|
215
|
+
value.gsub!(/#{value_to_find}/, value_to_replace) if value.instance_of? String
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# Update the database
|
220
|
+
sql = <<-EOD
|
221
|
+
UPDATE `wp_options`
|
222
|
+
SET `option_value`='#{client.escape(row['option_value'])}'
|
223
|
+
WHERE `option_id` = #{row['option_id']};
|
224
|
+
EOD
|
225
|
+
Logger.debug sql
|
226
|
+
client.query(sql)
|
227
|
+
end
|
228
|
+
|
229
|
+
# wp_posts post_content, guid
|
230
|
+
sql = <<-EOS
|
231
|
+
SELECT `ID`, `post_content`, `guid`
|
232
|
+
FROM `wp_posts`
|
233
|
+
WHERE `post_content` REGEXP '#{escaped_value_to_find}'
|
234
|
+
AND `guid` REGEXP '#{escaped_value_to_find}';
|
235
|
+
EOS
|
236
|
+
wp_posts = client.query(sql)
|
237
|
+
wp_posts.each do |row|
|
238
|
+
row.each do |key, value|
|
239
|
+
if PHP.serialized?(value)
|
240
|
+
ruby_php = PHP.unserialize(value)
|
241
|
+
ruby_php.find_and_replace!(value_to_find, value_to_replace)
|
242
|
+
value.replace PHP.serialize(ruby_php)
|
243
|
+
else
|
244
|
+
value.gsub!(/#{value_to_find}/, value_to_replace) if value.instance_of? String
|
245
|
+
end
|
246
|
+
end
|
247
|
+
sql = <<-EOD
|
248
|
+
UPDATE `wp_posts`
|
249
|
+
SET `post_content` = '#{client.escape(row['post_content'])}',
|
250
|
+
`guid` = '#{client.escape(row['guid'])}'
|
251
|
+
WHERE `ID` = #{row['ID']};
|
252
|
+
EOD
|
253
|
+
Logger.debug sql
|
254
|
+
client.query(sql)
|
255
|
+
end
|
256
|
+
|
257
|
+
# wp_postmeta
|
258
|
+
sql = <<-EOS
|
259
|
+
SELECT `meta_id`, `meta_value`
|
260
|
+
FROM `wp_postmeta`
|
261
|
+
WHERE `meta_value` REGEXP '#{escaped_value_to_find}';
|
262
|
+
EOS
|
263
|
+
wp_postmeta = client.query(sql)
|
264
|
+
wp_postmeta.each do |row|
|
265
|
+
row.each do |key, value|
|
266
|
+
if PHP.serialized?(value)
|
267
|
+
ruby_php = PHP.unserialize(value)
|
268
|
+
ruby_php.find_and_replace!(value_to_find, value_to_replace)
|
269
|
+
value.replace PHP.serialize(ruby_php)
|
270
|
+
else
|
271
|
+
value.gsub!(/#{value_to_find}/, value_to_replace) if value.instance_of? String
|
272
|
+
end
|
273
|
+
end
|
274
|
+
sql = <<-EOD
|
275
|
+
UPDATE `wp_postmeta`
|
276
|
+
SET `meta_value` = '#{client.escape(row['meta_value'])}'
|
277
|
+
WHERE `meta_id` = #{row['meta_id']};
|
278
|
+
EOD
|
279
|
+
Logger.debug sql
|
280
|
+
client.query(sql)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
private
|
285
|
+
|
286
|
+
def mysqldump
|
287
|
+
arguments = "-P \"#{port}\" -h \"#{host}\" -u \"#{user}\" -p\"#{password}\" -B \"#{name}\""
|
288
|
+
"#{utility("mysqldump")} #{arguments}"
|
289
|
+
end
|
290
|
+
|
291
|
+
def mysqlload(config_name, file_name)
|
292
|
+
mysql = self.class.new config_name
|
293
|
+
arg_port = mysql.db_port
|
294
|
+
arg_host = mysql.db_hostname
|
295
|
+
arg_user = mysql.DB_USER
|
296
|
+
arg_pass = mysql.DB_PASSWORD
|
297
|
+
arg_name = mysql.DB_NAME
|
298
|
+
arguments = "-P \"#{arg_port}\" -u \"#{arg_user}\" -h \"#{arg_host}\" -p\"#{arg_pass}\" -D \"#{arg_name}\""
|
299
|
+
|
300
|
+
"#{utility("mysql")} #{arguments} < #{file_name}"
|
40
301
|
end
|
41
302
|
|
42
303
|
end
|