Completed
Push — master ( d6f67e...133714 )
by CodexShaper
02:10
created

MysqlDumper::runCommand()   B

Complexity

Conditions 6
Paths 36

Size

Total Lines 32
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 6.1215

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 6
eloc 21
c 4
b 0
f 0
nc 36
nop 2
dl 0
loc 32
ccs 17
cts 20
cp 0.85
crap 6.1215
rs 8.9617
1
<?php
2
3
namespace CodexShaper\Dumper\Drivers;
4
5
use CodexShaper\Dumper\Dumper;
6
use Symfony\Component\Process\Exception\ProcessFailedException;
7
8
class MysqlDumper extends Dumper
9
{
10
    /*@var bool*/
11
    protected $singleTransaction = false;
12
    /*@var bool*/
13
    protected $skipLockTables = false;
14
    /*@var bool*/
15
    protected $quick = false;
16
    /*@var bool*/
17
    protected $skipComments = true;
18
    /*@var string*/
19
    protected $defaultCharacterSet = '';
20
    /*@var bool*/
21
    protected $createTables = true;
22
23
    public function useSingleTransaction()
24
    {
25
        $this->singleTransaction = true;
26
        return $this;
27
    }
28
    public function useSkipLockTables()
29
    {
30
        $this->skipLockTables = true;
31
        return $this;
32
    }
33
    public function useQuick()
34
    {
35
        $this->quick = true;
36
        return $this;
37
    }
38 2
    public function doNotUseSkipComments()
39
    {
40 2
        $this->skipComments = false;
41 2
        return $this;
42
    }
43
    public function doNotUseCreateTables()
44
    {
45
        $this->createTables = false;
46
        return $this;
47
    }
48
    public function setDefaultCharacterSet(string $charecterSet)
49
    {
50
        $this->defaultCharacterSet = $charecterSet;
51
        return $this;
52
    }
53
54 8
    public function dump(string $destinationPath = "")
55
    {
56 8
        $destinationPath = !empty($destinationPath) ? $destinationPath : $this->destinationPath;
57 8
        $this->runCommand($destinationPath, "dump");
58 8
        return $this;
59
    }
60
61 6
    public function restore(string $restorePath = "")
62
    {
63 6
        $restorePath = !empty($restorePath) ? $restorePath : $this->restorePath;
64 6
        $this->runCommand($restorePath, 'restore');
65 6
        return $this;
66
    }
67
68 8
    protected function prepareDumpCommand(string $credentialFile, string $destinationPath): string
69
    {
70 8
        $dumpCommand = sprintf(
71 8
            '%smysqldump %s %s %s %s %s %s %s %s %s %s %s',
72 8
            $this->dumpCommandPath,
73 8
            $this->prepareAuthentication($credentialFile),
74 8
            $this->prepareDatabase(),
75 8
            $this->prepareSocket(),
76 8
            $this->prepareSkipComments(),
77 8
            $this->prepareCreateTables(),
78 8
            $this->prepareSingleTransaction(),
79 8
            $this->prepareSkipLockTables(),
80 8
            $this->prepareQuick(),
81 8
            $this->prepareDefaultCharSet(),
82 8
            $this->prepareIncludeTables(),
83 8
            $this->prepareIgnoreTables()
84
        );
85
86 8
        if ($this->isCompress) {
87
88 2
            return "{$dumpCommand} | {$this->compressBinaryPath}{$this->compressCommand} > {$destinationPath}{$this->compressExtension}";
89
        }
90
91 6
        return "{$dumpCommand} > {$destinationPath}";
92
    }
93
94 6
    protected function prepareRestoreCommand(string $credentialFile, string $filePath): string
95
    {
96 6
        $restoreCommand = sprintf("%smysql %s %s",
97 6
            $this->dumpCommandPath,
98 6
            $this->prepareAuthentication($credentialFile),
99 6
            $this->prepareDatabase()
100
        );
101
102 6
        if ($this->isCompress) {
103
104 2
            return "{$this->compressBinaryPath}{$this->compressCommand} < {$filePath} | {$restoreCommand}";
105
        }
106
107 4
        return "{$restoreCommand} < {$filePath}";
108
    }
109
110 14
    protected function runCommand($filePath, $action)
111
    {
112
        try {
113
114 14
            $credentials    = $this->getCredentials();
115 14
            $this->tempFile = $tempFile = tempnam(sys_get_temp_dir(), 'mysqlpass');
116 14
            $handler        = fopen($tempFile, 'r+');
117 14
            if ($handler !== false) {
118 14
                fwrite($handler, $credentials);
119
120 14
                if ($action == 'dump') {
121 8
                    $dumpCommand   = $this->prepareDumpCommand($tempFile, $filePath);
122 8
                    $this->command = $this->removeExtraSpaces($dumpCommand);
123 6
                } else if ($action == 'restore') {
124 6
                    $dumpCommand   = $this->prepareRestoreCommand($tempFile, $filePath);
125 6
                    $this->command = $this->removeExtraSpaces($dumpCommand);
126
                }
127
128 14
                $process = $this->prepareProcessCommand();
129
130 14
                if ($this->debug) {
131
                    $process->mustRun();
132
                } else {
133 14
                    $process->run();
134
                }
135
136 14
                fclose($handler);
137 14
                unlink($tempFile);
138
            }
139
140
        } catch (ProcessFailedException $e) {
141
            throw new \Exception($e->getMessage());
142
143
        }
144 14
    }
145
146 14
    protected function getCredentials()
147
    {
148
        $contents = [
149 14
            '[client]',
150 14
            "user = '{$this->username}'",
151 14
            "password = '{$this->password}'",
152 14
            "host = '{$this->host}'",
153 14
            "port = '{$this->port}'",
154
        ];
155 14
        return implode(PHP_EOL, $contents);
156
    }
157
158 14
    public function prepareDatabase()
159
    {
160 14
        return $this->dbName ? $this->dbName : "";
161
    }
162
163 8
    public function prepareIncludeTables()
164
    {
165 8
        $includeTables    = (count($this->tables) > 0) ? implode(' ', $this->tables) : '';
166 8
        $includeTablesArg = !empty($includeTables) ? "--tables {$includeTables}" : '';
167 8
        return $includeTablesArg;
168
    }
169
170 8
    public function prepareIgnoreTables()
171
    {
172 8
        $ignoreTablesArgs = [];
173 8
        foreach ($this->ignoreTables as $tableName) {
174
            $ignoreTablesArgs[] = "--ignore-table={$this->dbName}.{$tableName}";
175
        }
176 8
        $ignoreTablesArg = (count($ignoreTablesArgs) > 0) ? implode(' ', $ignoreTablesArgs) : '';
177 8
        return $ignoreTablesArg;
178
    }
179
180 8
    public function prepareSingleTransaction()
181
    {
182 8
        return $this->singleTransaction ? '--single-transaction' : '';
183
    }
184
185 8
    public function prepareSkipLockTables()
186
    {
187 8
        return $this->skipLockTables ? '--skip-lock-tables' : '';
188
    }
189
190 8
    public function prepareQuick()
191
    {
192 8
        return $this->quick ? '--quick' : '';
193
    }
194
195 8
    public function prepareCreateTables()
196
    {
197 8
        return !$this->createTables ? '--no-create-info' : '';
198
    }
199
200 8
    public function prepareSkipComments()
201
    {
202 8
        return $this->skipComments ? '--skip-comments' : '';
203
    }
204
205 8
    public function prepareSocket()
206
    {
207 8
        return ($this->socket !== '') ? "--socket={$this->socket}" : '';
208
    }
209
210 8
    public function prepareDefaultCharSet()
211
    {
212 8
        return ($this->defaultCharacterSet !== '') ? "--default-character-set={$this->defaultCharacterSet}" : '';
213
    }
214
215 14
    public function prepareAuthentication(string $credentialFile)
216
    {
217 14
        return "--defaults-extra-file={$credentialFile}";
218
    }
219
}
220