Completed
Pull Request — master (#37)
by
unknown
03:14
created

MySql::guardAgainstIncompleteCredentials()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 8
Ratio 100 %

Importance

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