Completed
Push — master ( 3abe44...88845b )
by Sergii
02:23
created

DatabaseManager::cloneDatabase()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 17
rs 9.4286
cc 3
eloc 8
nc 4
nop 0
1
<?php
2
/**
3
 * @author Sergey Bondarenko, <[email protected]>
4
 */
5
namespace Drupal\TqExtension\Utils;
6
7
class DatabaseManager
8
{
9
    /**
10
     * @var string
11
     */
12
    private $credentials = '-u%s -p%s';
13
    /**
14
     * Name of original database.
15
     *
16
     * @var string
17
     */
18
    private $originalName = '';
19
    /**
20
     * Name of temporary database that will store data from original.
21
     *
22
     * @var string
23
     */
24
    private $newName = '';
25
    /**
26
     * Name of an object where this class is called.
27
     *
28
     * @var string
29
     */
30
    private $callee;
31
32
    /**
33
     * @param string $connection
34
     *   Database connection name (key in $databases array from settings.php).
35
     * @param string $callee
36
     *   Must be the value of "self::class" of callee object.
37
     */
38
    public function __construct($connection, $callee)
39
    {
40
        if (!defined('DRUPAL_ROOT') || !function_exists('conf_path')) {
41
            throw new \RuntimeException('Drupal is not bootstrapped.');
42
        }
43
44
        if (!class_exists($callee)) {
45
            throw new \InvalidArgumentException(sprintf('An object of "%s" type does not exist.', $callee));
46
        }
47
48
        $databases = [];
49
50
        require sprintf('%s/%s/settings.php', DRUPAL_ROOT, conf_path());
51
52
        if (empty($databases[$connection])) {
53
            throw new \InvalidArgumentException(sprintf('The "%s" database connection does not exist.', $connection));
54
        }
55
56
        $info = $databases[$connection]['default'];
57
58
        $this->callee = $callee;
59
        $this->originalName = $info['database'];
60
        $this->newName = "tqextension_$this->originalName";
61
        $this->credentials = sprintf($this->credentials, $info['username'], $info['password']);
62
63
        $this->cloneDatabase();
64
    }
65
66
    /**
67
     * Restore original database.
68
     */
69
    public function __destruct()
70
    {
71
        $this->exec("mysqldump $this->credentials $this->newName | mysql $this->credentials $this->originalName");
72
    }
73
74
    /**
75
     * Store original database to temporary for future restoring.
76
     */
77
    private function cloneDatabase()
78
    {
79
        $actions = [];
80
81
        // Need to drop temporary database if it was created previously.
82
        if (!empty($this->exec("mysql $this->credentials -e 'show databases' | grep $this->newName"))) {
83
            $actions[] = "drop";
84
        }
85
86
        $actions[] = "create";
87
88
        foreach ($actions as $action) {
89
            $this->exec("mysql $this->credentials -e '$action database $this->newName;'");
90
        }
91
92
        $this->exec("mysqldump $this->credentials $this->originalName | mysql $this->credentials $this->newName");
93
    }
94
95
    /**
96
     * Executes a shell command.
97
     *
98
     * @param string $command
99
     *   Command to execute.
100
     *
101
     * @return string
102
     *   Result of a shell command.
103
     */
104
    private function exec($command)
105
    {
106
        $command = vsprintf($command, array_slice(func_get_args(), 1));
107
108
        if (method_exists($this->callee, 'debug')) {
109
            call_user_func([$this->callee, 'debug'], [$command]);
110
        }
111
112
        return trim(shell_exec($command));
113
    }
114
}
115