Completed
Pull Request — master (#71)
by Costin
01:17
created

MySql::setGtidPurged()   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 1
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
    public function __construct()
30
    {
31
        $this->port = 3306;
32
    }
33
34
    /**
35
     * @return $this
36
     */
37
    public function skipComments()
38
    {
39
        $this->skipComments = true;
40
41
        return $this;
42
    }
43
44
    /**
45
     * @return $this
46
     */
47
    public function dontSkipComments()
48
    {
49
        $this->skipComments = false;
50
51
        return $this;
52
    }
53
54
    /**
55
     * @return $this
56
     */
57
    public function useExtendedInserts()
58
    {
59
        $this->useExtendedInserts = true;
60
61
        return $this;
62
    }
63
64
    /**
65
     * @return $this
66
     */
67
    public function dontUseExtendedInserts()
68
    {
69
        $this->useExtendedInserts = false;
70
71
        return $this;
72
    }
73
74
    /**
75
     * @return $this
76
     */
77
    public function useSingleTransaction()
78
    {
79
        $this->useSingleTransaction = true;
80
81
        return $this;
82
    }
83
84
    /**
85
     * @return $this
86
     */
87
    public function dontUseSingleTransaction()
88
    {
89
        $this->useSingleTransaction = false;
90
91
        return $this;
92
    }
93
94
    /**
95
     * @param string $characterSet
96
     *
97
     * @return $this
98
     */
99
    public function setDefaultCharacterSet(string $characterSet)
100
    {
101
        $this->defaultCharacterSet = $characterSet;
102
103
        return $this;
104
    }
105
106
    /**
107
     * @return $this
108
     */
109
    public function setGtidPurged(string $setGtidPurged)
110
    {
111
        $this->setGtidPurged = $setGtidPurged;
112
113
        return $this;
114
    }
115
116
    /**
117
     * Dump the contents of the database to the given file.
118
     *
119
     * @param string $dumpFile
120
     *
121
     * @throws \Spatie\DbDumper\Exceptions\CannotStartDump
122
     * @throws \Spatie\DbDumper\Exceptions\DumpFailed
123
     */
124 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...
125
    {
126
        $this->guardAgainstIncompleteCredentials();
127
128
        $tempFileHandle = tmpfile();
129
        fwrite($tempFileHandle, $this->getContentsOfCredentialsFile());
130
        $temporaryCredentialsFile = stream_get_meta_data($tempFileHandle)['uri'];
131
132
        $command = $this->getDumpCommand($dumpFile, $temporaryCredentialsFile);
133
134
        $process = new Process($command);
135
136
        if (! is_null($this->timeout)) {
137
            $process->setTimeout($this->timeout);
138
        }
139
140
        $process->run();
141
142
        $this->checkIfDumpWasSuccessFul($process, $dumpFile);
143
    }
144
145
    public function addExtraOption(string $extraOption)
146
    {
147
        if (preg_match('/^--databases (\S+)/', $extraOption, $matches) === 1) {
148
            $this->setDbName($matches[1]);
149
            $this->dbNameWasSetAsExtraOption = true;
150
        }
151
152
        return parent::addExtraOption($extraOption);
153
    }
154
155
    /**
156
     * Get the command that should be performed to dump the database.
157
     *
158
     * @param string $dumpFile
159
     * @param string $temporaryCredentialsFile
160
     *
161
     * @return string
162
     */
163
    public function getDumpCommand(string $dumpFile, string $temporaryCredentialsFile): string
164
    {
165
        $quote = $this->determineQuote();
166
167
        $command = [
168
            "{$quote}{$this->dumpBinaryPath}mysqldump{$quote}",
169
            "--defaults-extra-file=\"{$temporaryCredentialsFile}\"",
170
        ];
171
172
        if ($this->skipComments) {
173
            $command[] = '--skip-comments';
174
        }
175
176
        $command[] = $this->useExtendedInserts ? '--extended-insert' : '--skip-extended-insert';
177
178
        if ($this->useSingleTransaction) {
179
            $command[] = '--single-transaction';
180
        }
181
182
        if ($this->socket !== '') {
183
            $command[] = "--socket={$this->socket}";
184
        }
185
186
        foreach ($this->excludeTables as $tableName) {
187
            $command[] = "--ignore-table={$this->dbName}.{$tableName}";
188
        }
189
190
        if (! empty($this->defaultCharacterSet)) {
191
            $command[] = '--default-character-set='.$this->defaultCharacterSet;
192
        }
193
194
        foreach ($this->extraOptions as $extraOption) {
195
            $command[] = $extraOption;
196
        }
197
198
        if (!empty($this->defaultCharacterSet)) {
199
            $command[] = '--default-character-set=' . $this->defaultCharacterSet;
200
        }
201
202
        if ($this->setGtidPurged != 'AUTO') {
203
            $command[] = '--set-gtid-purged='. $this->setGtidPurged;
204
        }
205
206
        $command[] = "--result-file=\"{$dumpFile}\"";
207
208
        if (! $this->dbNameWasSetAsExtraOption) {
209
            $command[] = $this->dbName;
210
        }
211
212
        if (! empty($this->includeTables)) {
213
            $includeTables = implode(' ', $this->includeTables);
214
            $command[] = "--tables {$includeTables}";
215
        }
216
217
        return implode(' ', $command);
218
    }
219
220
    public function getContentsOfCredentialsFile(): string
221
    {
222
        $contents = [
223
            '[client]',
224
            "user = '{$this->userName}'",
225
            "password = '{$this->password}'",
226
            "host = '{$this->host}'",
227
            "port = '{$this->port}'",
228
        ];
229
230
        return implode(PHP_EOL, $contents);
231
    }
232
233 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...
234
    {
235
        foreach (['userName', 'dbName', 'host'] as $requiredProperty) {
236
            if (strlen($this->$requiredProperty) === 0) {
237
                throw CannotStartDump::emptyParameter($requiredProperty);
238
            }
239
        }
240
    }
241
242
    protected function determineQuote(): string
243
    {
244
        return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? '"' : "'";
245
    }
246
}
247