Completed
Push — master ( c0eb0e...9013f2 )
by Freek
01:29
created

MySql::dontUseQuick()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
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 bool */
21
    protected $skipLockTables = false;
22
23
    /** @var bool */
24
    protected $useQuick = false;
25
26
    /** @var string */
27
    protected $defaultCharacterSet = '';
28
29
    /** @var bool */
30
    protected $dbNameWasSetAsExtraOption = false;
31
32
    /** @var bool */
33
    protected $allDatabasesWasSetAsExtraOption = false;
34
35
    /** @var string */
36
    protected $setGtidPurged = 'AUTO';
37
38
    /** @var bool */
39
    protected $createTables = true;
40
41
    public function __construct()
42
    {
43
        $this->port = 3306;
44
    }
45
46
    /**
47
     * @return $this
48
     */
49
    public function skipComments()
50
    {
51
        $this->skipComments = true;
52
53
        return $this;
54
    }
55
56
    /**
57
     * @return $this
58
     */
59
    public function dontSkipComments()
60
    {
61
        $this->skipComments = false;
62
63
        return $this;
64
    }
65
66
    /**
67
     * @return $this
68
     */
69
    public function useExtendedInserts()
70
    {
71
        $this->useExtendedInserts = true;
72
73
        return $this;
74
    }
75
76
    /**
77
     * @return $this
78
     */
79
    public function dontUseExtendedInserts()
80
    {
81
        $this->useExtendedInserts = false;
82
83
        return $this;
84
    }
85
86
    /**
87
     * @return $this
88
     */
89
    public function useSingleTransaction()
90
    {
91
        $this->useSingleTransaction = true;
92
93
        return $this;
94
    }
95
96
    /**
97
     * @return $this
98
     */
99
    public function dontUseSingleTransaction()
100
    {
101
        $this->useSingleTransaction = false;
102
103
        return $this;
104
    }
105
106
    /**
107
     * @return $this
108
     */
109
    public function skipLockTables()
110
    {
111
        $this->skipLockTables = true;
112
113
        return $this;
114
    }
115
116
    /**
117
     * @return $this
118
     */
119
    public function dontSkipLockTables()
120
    {
121
        $this->skipLockTables = false;
122
123
        return $this;
124
    }
125
126
    /**
127
     * @return $this
128
     */
129
    public function useQuick()
130
    {
131
        $this->useQuick = true;
132
133
        return $this;
134
    }
135
136
    /**
137
     * @return $this
138
     */
139
    public function dontUseQuick()
140
    {
141
        $this->useQuick = false;
142
143
        return $this;
144
    }
145
146
    /**
147
     * @param string $characterSet
148
     *
149
     * @return $this
150
     */
151
    public function setDefaultCharacterSet(string $characterSet)
152
    {
153
        $this->defaultCharacterSet = $characterSet;
154
155
        return $this;
156
    }
157
158
    /**
159
     * @return $this
160
     */
161
    public function setGtidPurged(string $setGtidPurged)
162
    {
163
        $this->setGtidPurged = $setGtidPurged;
164
165
        return $this;
166
    }
167
168
    /**
169
     * Dump the contents of the database to the given file.
170
     *
171
     * @param string $dumpFile
172
     *
173
     * @throws \Spatie\DbDumper\Exceptions\CannotStartDump
174
     * @throws \Spatie\DbDumper\Exceptions\DumpFailed
175
     */
176 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...
177
    {
178
        $this->guardAgainstIncompleteCredentials();
179
180
        $tempFileHandle = tmpfile();
181
        fwrite($tempFileHandle, $this->getContentsOfCredentialsFile());
182
        $temporaryCredentialsFile = stream_get_meta_data($tempFileHandle)['uri'];
183
184
        $command = $this->getDumpCommand($dumpFile, $temporaryCredentialsFile);
185
186
        $process = Process::fromShellCommandline($command, null, null, null, $this->timeout);
187
188
        $process->run();
189
190
        $this->checkIfDumpWasSuccessFul($process, $dumpFile);
191
    }
192
193
    public function addExtraOption(string $extraOption)
194
    {
195
        if (strpos($extraOption, '--all-databases') !== false) {
196
            $this->dbNameWasSetAsExtraOption = true;
197
            $this->allDatabasesWasSetAsExtraOption = true;
198
        }
199
200
        if (preg_match('/^--databases (\S+)/', $extraOption, $matches) === 1) {
201
            $this->setDbName($matches[1]);
202
            $this->dbNameWasSetAsExtraOption = true;
203
        }
204
205
        return parent::addExtraOption($extraOption);
206
    }
207
208
    /**
209
     * @return $this
210
     */
211
    public function doNotCreateTables()
212
    {
213
        $this->createTables = false;
214
215
        return $this;
216
    }
217
218
    /**
219
     * Get the command that should be performed to dump the database.
220
     *
221
     * @param string $dumpFile
222
     * @param string $temporaryCredentialsFile
223
     *
224
     * @return string
225
     */
226
    public function getDumpCommand(string $dumpFile, string $temporaryCredentialsFile): string
227
    {
228
        $quote = $this->determineQuote();
229
230
        $command = [
231
            "{$quote}{$this->dumpBinaryPath}mysqldump{$quote}",
232
            "--defaults-extra-file=\"{$temporaryCredentialsFile}\"",
233
        ];
234
235
        if (! $this->createTables) {
236
            $command[] = '--no-create-info';
237
        }
238
239
        if ($this->skipComments) {
240
            $command[] = '--skip-comments';
241
        }
242
243
        $command[] = $this->useExtendedInserts ? '--extended-insert' : '--skip-extended-insert';
244
245
        if ($this->useSingleTransaction) {
246
            $command[] = '--single-transaction';
247
        }
248
249
        if ($this->skipLockTables) {
250
            $command[] = '--skip-lock-tables';
251
        }
252
253
        if ($this->useQuick) {
254
            $command[] = '--quick';
255
        }
256
257
        if ($this->socket !== '') {
258
            $command[] = "--socket={$this->socket}";
259
        }
260
261
        foreach ($this->excludeTables as $tableName) {
262
            $command[] = "--ignore-table={$this->dbName}.{$tableName}";
263
        }
264
265
        if (! empty($this->defaultCharacterSet)) {
266
            $command[] = '--default-character-set='.$this->defaultCharacterSet;
267
        }
268
269
        foreach ($this->extraOptions as $extraOption) {
270
            $command[] = $extraOption;
271
        }
272
273
        if ($this->setGtidPurged !== 'AUTO') {
274
            $command[] = '--set-gtid-purged='.$this->setGtidPurged;
275
        }
276
277
        if (! $this->dbNameWasSetAsExtraOption) {
278
            $command[] = $this->dbName;
279
        }
280
281
        if (! empty($this->includeTables)) {
282
            $includeTables = implode(' ', $this->includeTables);
283
            $command[] = "--tables {$includeTables}";
284
        }
285
286
        return $this->echoToFile(implode(' ', $command), $dumpFile);
287
    }
288
289
    public function getContentsOfCredentialsFile(): string
290
    {
291
        $contents = [
292
            '[client]',
293
            "user = '{$this->userName}'",
294
            "password = '{$this->password}'",
295
            "host = '{$this->host}'",
296
            "port = '{$this->port}'",
297
        ];
298
299
        return implode(PHP_EOL, $contents);
300
    }
301
302
    protected function guardAgainstIncompleteCredentials()
303
    {
304 View Code Duplication
        foreach (['userName', 'host'] as $requiredProperty) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
305
            if (strlen($this->$requiredProperty) === 0) {
306
                throw CannotStartDump::emptyParameter($requiredProperty);
307
            }
308
        }
309
310
        if (strlen('dbName') === 0 && ! $this->allDatabasesWasSetAsExtraOption) {
311
            throw CannotStartDump::emptyParameter($requiredProperty);
312
        }
313
    }
314
315
    protected function determineQuote(): string
316
    {
317
        return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? '"' : "'";
318
    }
319
}
320