Completed
Pull Request — master (#72)
by
unknown
18:20
created

MySql::enableCompression()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
3
namespace Spatie\DbDumper\Databases;
4
5
use Spatie\DbDumper\DbDumper;
6
use Symfony\Component\Process\Process;
7
use Spatie\DbDumper\Exceptions\CannotStartDump;
8
9
class MySql extends DbDumper
10
{
11
    /** @var bool */
12
    protected $skipComments = true;
13
14
    /** @var bool */
15
    protected $useExtendedInserts = true;
16
17
    /** @var bool */
18
    protected $useSingleTransaction = false;
19
20
    /** @var string */
21
    protected $defaultCharacterSet = '';
22
23
    /** @var bool */
24
    protected $dbNameWasSetAsExtraOption = false;
25
26
    /** @var string */
27
    protected $setGtidPurged = 'AUTO';
28
29
    /** @var bool */
30
    protected $enableCompression = false;
31
32
    public function __construct()
33
    {
34
        $this->port = 3306;
35
    }
36
37
    /**
38
     * @return $this
39
     */
40
    public function skipComments()
41
    {
42
        $this->skipComments = true;
43
44
        return $this;
45
    }
46
47
    /**
48
     * @return $this
49
     */
50
    public function dontSkipComments()
51
    {
52
        $this->skipComments = false;
53
54
        return $this;
55
    }
56
57
    /**
58
     * @return $this
59
     */
60
    public function useExtendedInserts()
61
    {
62
        $this->useExtendedInserts = true;
63
64
        return $this;
65
    }
66
67
    /**
68
     * @return $this
69
     */
70
    public function dontUseExtendedInserts()
71
    {
72
        $this->useExtendedInserts = false;
73
74
        return $this;
75
    }
76
77
    /**
78
     * @return $this
79
     */
80
    public function useSingleTransaction()
81
    {
82
        $this->useSingleTransaction = true;
83
84
        return $this;
85
    }
86
87
    /**
88
     * @return $this
89
     */
90
    public function dontUseSingleTransaction()
91
    {
92
        $this->useSingleTransaction = false;
93
94
        return $this;
95
    }
96
97
    /**
98
     * @param string $characterSet
99
     *
100
     * @return $this
101
     */
102
    public function setDefaultCharacterSet(string $characterSet)
103
    {
104
        $this->defaultCharacterSet = $characterSet;
105
106
        return $this;
107
    }
108
109
    /**
110
     * @return $this
111
     */
112
    public function enableCompression()
113
    {
114
        $this->enableCompression = true;
115
116
        return $this;
117
    }
118
119
    /**
120
     * @return $this
121
     */
122
    public function setGtidPurged(string $setGtidPurged)
123
    {
124
        $this->setGtidPurged = $setGtidPurged;
125
126
        return $this;
127
    }
128
129
    /**
130
     * Dump the contents of the database to the given file.
131
     *
132
     * @param string $dumpFile
133
     *
134
     * @throws \Spatie\DbDumper\Exceptions\CannotStartDump
135
     * @throws \Spatie\DbDumper\Exceptions\DumpFailed
136
     */
137 View Code Duplication
    public function dumpToFile(string $dumpFile)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
138
    {
139
        $this->guardAgainstIncompleteCredentials();
140
141
        $tempFileHandle = tmpfile();
142
        fwrite($tempFileHandle, $this->getContentsOfCredentialsFile());
143
        $temporaryCredentialsFile = stream_get_meta_data($tempFileHandle)['uri'];
144
145
        $command = $this->getDumpCommand($dumpFile, $temporaryCredentialsFile);
146
147
        $process = new Process($command);
148
149
        if (! is_null($this->timeout)) {
150
            $process->setTimeout($this->timeout);
151
        }
152
153
        $process->run();
154
155
        $this->checkIfDumpWasSuccessFul($process, $dumpFile);
156
    }
157
158
    public function addExtraOption(string $extraOption)
159
    {
160
        if (preg_match('/^--databases (\S+)/', $extraOption, $matches) === 1) {
161
            $this->setDbName($matches[1]);
162
            $this->dbNameWasSetAsExtraOption = true;
163
        }
164
165
        return parent::addExtraOption($extraOption);
166
    }
167
168
    /**
169
     * Get the command that should be performed to dump the database.
170
     *
171
     * @param string $dumpFile
172
     * @param string $temporaryCredentialsFile
173
     *
174
     * @return string
175
     */
176
    public function getDumpCommand(string $dumpFile, string $temporaryCredentialsFile): string
177
    {
178
        $quote = $this->determineQuote();
179
180
        $command = [
181
            "{$quote}{$this->dumpBinaryPath}mysqldump{$quote}",
182
            "--defaults-extra-file=\"{$temporaryCredentialsFile}\"",
183
        ];
184
185
        if ($this->skipComments) {
186
            $command[] = '--skip-comments';
187
        }
188
189
        $command[] = $this->useExtendedInserts ? '--extended-insert' : '--skip-extended-insert';
190
191
        if ($this->useSingleTransaction) {
192
            $command[] = '--single-transaction';
193
        }
194
195
        if ($this->socket !== '') {
196
            $command[] = "--socket={$this->socket}";
197
        }
198
199
        foreach ($this->excludeTables as $tableName) {
200
            $command[] = "--ignore-table={$this->dbName}.{$tableName}";
201
        }
202
203
        if (! empty($this->defaultCharacterSet)) {
204
            $command[] = '--default-character-set='.$this->defaultCharacterSet;
205
        }
206
207
        foreach ($this->extraOptions as $extraOption) {
208
            $command[] = $extraOption;
209
        }
210
211
        if ($this->setGtidPurged !== 'AUTO') {
212
            $command[] = '--set-gtid-purged='.$this->setGtidPurged;
213
        }
214
215
        if (! $this->enableCompression) {
216
            $command[] = "--result-file=\"{$dumpFile}\"";
217
        }
218
219
        if (! $this->dbNameWasSetAsExtraOption) {
220
            $command[] = $this->dbName;
221
        }
222
223
        if (! empty($this->includeTables)) {
224
            $includeTables = implode(' ', $this->includeTables);
225
            $command[] = "--tables {$includeTables}";
226
        }
227
228
        if ($this->enableCompression) {
229
            $command[] = "| gzip > {$dumpFile}";
230
        }
231
232
        return implode(' ', $command);
233
    }
234
235
    public function getContentsOfCredentialsFile(): string
236
    {
237
        $contents = [
238
            '[client]',
239
            "user = '{$this->userName}'",
240
            "password = '{$this->password}'",
241
            "host = '{$this->host}'",
242
            "port = '{$this->port}'",
243
        ];
244
245
        return implode(PHP_EOL, $contents);
246
    }
247
248 View Code Duplication
    protected function guardAgainstIncompleteCredentials()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
249
    {
250
        foreach (['userName', 'dbName', 'host'] as $requiredProperty) {
251
            if (strlen($this->$requiredProperty) === 0) {
252
                throw CannotStartDump::emptyParameter($requiredProperty);
253
            }
254
        }
255
    }
256
257
    protected function determineQuote(): string
258
    {
259
        return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? '"' : "'";
260
    }
261
}
262