Completed
Pull Request — master (#71)
by Costin
03:02
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 ($this->setGtidPurged !== 'AUTO') {
199
            $command[] = '--set-gtid-purged=' . $this->setGtidPurged;
200
        }
201
202
        $command[] = "--result-file=\"{$dumpFile}\"";
203
204
        if (! $this->dbNameWasSetAsExtraOption) {
205
            $command[] = $this->dbName;
206
        }
207
208
        if (! empty($this->includeTables)) {
209
            $includeTables = implode(' ', $this->includeTables);
210
            $command[] = "--tables {$includeTables}";
211
        }
212
213
        return implode(' ', $command);
214
    }
215
216
    public function getContentsOfCredentialsFile(): string
217
    {
218
        $contents = [
219
            '[client]',
220
            "user = '{$this->userName}'",
221
            "password = '{$this->password}'",
222
            "host = '{$this->host}'",
223
            "port = '{$this->port}'",
224
        ];
225
226
        return implode(PHP_EOL, $contents);
227
    }
228
229 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...
230
    {
231
        foreach (['userName', 'dbName', 'host'] as $requiredProperty) {
232
            if (strlen($this->$requiredProperty) === 0) {
233
                throw CannotStartDump::emptyParameter($requiredProperty);
234
            }
235
        }
236
    }
237
238
    protected function determineQuote(): string
239
    {
240
        return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? '"' : "'";
241
    }
242
}
243