Passed
Push — master ( d15b5c...66f0ce )
by CodexShaper
02:08
created

MysqlDumper::prepareIncludeTables()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 3
c 1
b 0
f 0
nc 4
nop 0
dl 0
loc 5
rs 10
1
<?php
2
3
namespace CodexShaper\Dumper\Drivers;
4
5
use CodexShaper\Dumper\Dumper;
6
7
class MysqlDumper extends Dumper
8
{
9
    /*@var bool*/
10
    protected $singleTransaction = false;
11
    /*@var bool*/
12
    protected $skipLockTables = false;
13
    /*@var bool*/
14
    protected $quick = false;
15
    /*@var bool*/
16
    protected $skipComments = true;
17
    /*@var string*/
18
    protected $defaultCharacterSet = '';
19
    /*@var bool*/
20
    protected $createTables = true;
21
22
    public function useSingleTransaction()
23
    {
24
        $this->singleTransaction = true;
25
        return $this;
26
    }
27
    public function useSkipLockTables()
28
    {
29
        $this->skipLockTables = true;
30
        return $this;
31
    }
32
    public function useQuick()
33
    {
34
        $this->quick = true;
35
        return $this;
36
    }
37
    public function doNotUseSkipComments()
38
    {
39
        $this->skipComments = false;
40
        return $this;
41
    }
42
    public function doNotUseCreateTables()
43
    {
44
        $this->createTables = false;
45
        return $this;
46
    }
47
    public function setDefaultCharacterSe(string $charecterSet)
48
    {
49
        $this->defaultCharacterSe = $charecterSet;
0 ignored issues
show
Bug Best Practice introduced by
The property defaultCharacterSe does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
50
        return $this;
51
    }
52
53
    public function dump(string $destinationPath = "")
54
    {
55
        $destinationPath = !empty($destinationPath) ? $destinationPath : $this->destinationPath;
56
        $this->runCommand($destinationPath, "dump");
57
        return $this;
58
    }
59
60
    public function restore(string $restorePath = "")
61
    {
62
        $restorePath = !empty($restorePath) ? $restorePath : $this->restorePath;
63
        $this->runCommand($restorePath, 'restore');
64
        return $this;
65
    }
66
67
    protected function prepareDumpCommand(string $credentialFile, string $destinationPath): string
68
    {
69
        $dumpCommand = sprintf(
70
            '%smysqldump %s %s %s %s %s %s %s %s %s %s %s',
71
            $this->dumpCommandPath,
72
            $this->prepareAuthentication($credentialFile),
73
            $this->prepareDatabase(),
74
            $this->prepareSocket(),
75
            $this->prepareSkipComments(),
76
            $this->prepareCreateTables(),
77
            $this->prepareSingleTransaction(),
78
            $this->prepareSkipLockTables(),
79
            $this->prepareQuick(),
80
            $this->prepareDefaultCharSet(),
81
            $this->prepareIncludeTables(),
82
            $this->prepareIgnoreTables()
83
        );
84
85
        if ($this->isCompress) {
86
87
            return "{$dumpCommand} | {$this->compressBinaryPath}{$this->compressCommand} > {$destinationPath}{$this->compressExtension}";
88
        }
89
90
        return "{$dumpCommand} > {$destinationPath}";
91
    }
92
93
    protected function prepareRestoreCommand(string $credentialFile, string $filePath): string
94
    {
95
        $restoreCommand = sprintf("%smysql %s %s",
96
            $this->dumpCommandPath,
97
            $this->prepareAuthentication($credentialFile),
98
            $this->prepareDatabase()
99
        );
100
101
        if ($this->isCompress) {
102
103
            return "{$this->compressBinaryPath}{$this->compressCommand} < {$filePath} | {$restoreCommand}";
104
        }
105
106
        return "{$restoreCommand} < {$filePath}";
107
    }
108
109
    protected function runCommand($filePath, $action)
110
    {
111
        try {
112
113
            $credentials    = $this->getCredentials();
114
            $this->tempFile = tempnam(sys_get_temp_dir(), 'mysqlpass');
115
            $handler        = fopen($this->tempFile, 'r+');
116
            fwrite($handler, $credentials);
0 ignored issues
show
Bug introduced by
It seems like $handler can also be of type false; however, parameter $handle of fwrite() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

116
            fwrite(/** @scrutinizer ignore-type */ $handler, $credentials);
Loading history...
117
118
            if ($action == 'dump') {
119
                $this->command = preg_replace('/\s+/', ' ', $this->prepareDumpCommand($this->tempFile, $filePath));
120
            }
121
122
            if ($action == 'restore') {
123
                $this->command = preg_replace('/\s+/', ' ', $this->prepareRestoreCommand($this->tempFile, $filePath));
124
            }
125
126
            $process = $this->prepareProcessCommand();
127
128
            if ($this->debug) {
129
                $process->mustRun();
130
            } else {
131
                $process->run();
132
            }
133
134
            fclose($handler);
0 ignored issues
show
Bug introduced by
It seems like $handler can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

134
            fclose(/** @scrutinizer ignore-type */ $handler);
Loading history...
135
            unlink($this->tempFile);
136
137
        } catch (ProcessFailedException $e) {
0 ignored issues
show
Bug introduced by
The type CodexShaper\Dumper\Drivers\ProcessFailedException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
138
            throw new \Exception($e->getMessage());
139
140
        }
141
    }
142
143
    protected function getCredentials()
144
    {
145
        $contents = [
146
            '[client]',
147
            "user = '{$this->username}'",
148
            "password = '{$this->password}'",
149
            "host = '{$this->host}'",
150
            "port = '{$this->port}'",
151
        ];
152
        return implode(PHP_EOL, $contents);
153
    }
154
155
    public function prepareDatabase()
156
    {
157
        return $this->dbName;
158
    }
159
160
    public function prepareIncludeTables()
161
    {
162
        $includeTables    = (count($this->tables) > 0) ? implode(' ', $this->tables) : "";
163
        $includeTablesArg = !empty($includeTables) ? '--tables ' . $includeTables : '';
164
        return $includeTablesArg;
165
    }
166
167
    public function prepareIgnoreTables()
168
    {
169
        $ignoreTablesArgs = [];
170
        foreach ($this->ignoreTables as $tableName) {
171
            $ignoreTablesArgs[] = "--ignore-table=" . $databaseArg . "." . $tableName;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $databaseArg seems to be never defined.
Loading history...
172
        }
173
        $ignoreTablesArg = (count($ignoreTablesArgs) > 0) ? implode(' ', $ignoreTablesArgs) : '';
174
        return $ignoreTablesArg;
175
    }
176
177
    public function prepareSingleTransaction()
178
    {
179
        return $this->singleTransaction ? "--single-transaction" : "";
180
    }
181
182
    public function prepareSkipLockTables()
183
    {
184
        return $this->skipLockTables ? "--skip-lock-tables" : "";
185
    }
186
187
    public function prepareQuick()
188
    {
189
        return $this->quick ? "--quick" : "";
190
    }
191
192
    public function prepareCreateTables()
193
    {
194
        return !$this->createTables ? '--no-create-info' : '';
195
    }
196
197
    public function prepareSkipComments()
198
    {
199
        return $this->skipComments ? '--skip-comments' : '';
200
    }
201
202
    public function prepareSocket()
203
    {
204
        return ($this->socket !== '') ? "--socket={$this->socket}" : '';
205
    }
206
207
    public function prepareDefaultCharSet()
208
    {
209
        return ($this->defaultCharacterSet !== '') ? "--default-character-set={$this->defaultCharacterSet}" : '';
210
    }
211
212
    public function prepareAuthentication(string $credentialFile)
213
    {
214
        return "--defaults-extra-file={$credentialFile}";
215
    }
216
}
217