DatabaseManager   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 16
c 0
b 0
f 0
lcom 1
cbo 0
dl 0
loc 151
ccs 0
cts 52
cp 0
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
C __construct() 0 34 7
A __destruct() 0 7 1
A exist() 0 4 1
A drop() 0 6 2
A create() 0 6 2
A copy() 0 6 1
A exec() 0 15 2
1
<?php
2
/**
3
 * @author Sergii Bondarenko, <[email protected]>
4
 */
5
namespace Drupal\TqExtension\Utils;
6
7
class DatabaseManager
8
{
9
    /**
10
     * MySQL and MySQLDump login arguments.
11
     *
12
     * @var string
13
     */
14
    private $credentials = '-u%s -p%s -h%s -P%s';
15
    /**
16
     * Name of original database.
17
     *
18
     * @var string
19
     */
20
    private $source = '';
21
    /**
22
     * Name of temporary database that will store data from original.
23
     *
24
     * @var string
25
     */
26
    private $temporary = '';
27
    /**
28
     * Name of an object where this class is called.
29
     *
30
     * @var string
31
     */
32
    private $callee;
33
34
    /**
35
     * @param string $connection
36
     *   Database connection name (key in $databases array from settings.php).
37
     * @param string $callee
38
     *   Must be the value of "self::class" of callee object.
39
     */
40
    public function __construct($connection, $callee)
41
    {
42
        if (!defined('DRUPAL_ROOT') || !function_exists('conf_path')) {
43
            throw new \RuntimeException('Drupal is not bootstrapped.');
44
        }
45
46
        if (!class_exists($callee)) {
47
            throw new \InvalidArgumentException(sprintf('An object of "%s" type does not exist.', $callee));
48
        }
49
50
        $databases = [];
51
52
        require sprintf('%s/%s/settings.php', DRUPAL_ROOT, conf_path());
53
54
        if (empty($databases[$connection])) {
55
            throw new \InvalidArgumentException(sprintf('The "%s" database connection does not exist.', $connection));
56
        }
57
58
        $db = $databases[$connection]['default'];
59
60
        foreach (['port' => 3306, 'host' => '127.0.0.1'] as $option => $default) {
61
            if (empty($db[$option])) {
62
                $db[$option] = $default;
63
            }
64
        }
65
66
        $this->callee = $callee;
67
        $this->source = $db['database'];
68
        $this->temporary = "tqextension_$this->source";
69
        $this->credentials = sprintf($this->credentials, $db['username'], $db['password'], $db['host'], $db['port']);
70
71
        // Drop and create temporary DB and copy source into it.
72
        $this->copy($this->source, $this->temporary);
73
    }
74
75
    /**
76
     * Restore original database.
77
     */
78
    public function __destruct()
79
    {
80
        // Drop and create source DB and copy temporary into it.
81
        $this->copy($this->temporary, $this->source);
82
        // Kill temporary DB.
83
        $this->drop($this->temporary);
84
    }
85
86
    /**
87
     * @param string $name
88
     *   Name of the database to check.
89
     *
90
     * @return bool
91
     *   Checking state.
92
     */
93
    public function exist($name)
94
    {
95
        return !empty($this->exec("mysql -e 'show databases' | grep '^$name$'"));
96
    }
97
98
    /**
99
     * @param string $name
100
     *   Name of the database to drop.
101
     */
102
    public function drop($name)
103
    {
104
        if ($this->exist($name)) {
105
            $this->exec("mysql -e '%s database $name;'", __FUNCTION__);
106
        }
107
    }
108
109
    /**
110
     * @param string $name
111
     *   Name of the database to create.
112
     */
113
    public function create($name)
114
    {
115
        if (!$this->exist($name)) {
116
            $this->exec("mysql -e '%s database $name;'", __FUNCTION__);
117
        }
118
    }
119
120
    /**
121
     * @param string $source
122
     *   Source DB name.
123
     * @param string $destination
124
     *   Name of the new DB.
125
     */
126
    public function copy($source, $destination)
127
    {
128
        $this->drop($destination);
129
        $this->create($destination);
130
        $this->exec("mysqldump $source | mysql $destination");
131
    }
132
133
    /**
134
     * Executes a shell command.
135
     *
136
     * @param string $command
137
     *   Command to execute.
138
     *
139
     * @return string
140
     *   Result of a shell command.
141
     */
142
    private function exec($command)
143
    {
144
        // Adding credentials after "mysql" and "mysqldump" commands.
145
        $command = preg_replace(
146
            '/(mysql(?:dump)?)/',
147
            "\\1 $this->credentials",
148
            vsprintf($command, array_slice(func_get_args(), 1))
149
        );
150
151
        if (method_exists($this->callee, 'debug')) {
152
            call_user_func([$this->callee, 'debug'], [$command]);
153
        }
154
155
        return trim(shell_exec($command));
156
    }
157
}
158