Completed
Push — master ( e61662...273c09 )
by Sebastian
06:26
created

Mysqldump::lockTables()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 1
cts 1
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
namespace phpbu\App\Cli\Executable;
3
4
use phpbu\App\Backup\Target\Compression;
5
use phpbu\App\Cli\Executable;
6
use phpbu\App\Exception;
7
use phpbu\App\Util\Cli;
8
use SebastianFeldmann\Cli\CommandLine;
9
use SebastianFeldmann\Cli\Command\Executable as Cmd;
10
11
/**
12
 * Mysqldump Executable class.
13
 *
14
 * @package    phpbu
15
 * @subpackage Backup
16
 * @author     Sebastian Feldmann <[email protected]>
17
 * @copyright  Sebastian Feldmann <[email protected]>
18
 * @license    https://opensource.org/licenses/MIT The MIT License (MIT)
19
 * @link       http://phpbu.de/
20
 * @since      Class available since Release 1.0.0
21
 */
22
class Mysqldump extends Abstraction implements Executable
23
{
24
    use OptionMasker;
25
26
    /**
27
     * Host to connect to
28
     * --host <hostname>
29
     *
30
     * @var string
31
     */
32
    private $host;
33
34
    /**
35
     * Port to connect to
36
     * --port <number>
37
     *
38
     * @var int
39
     */
40
    private $port;
41
42
    /**
43
     * User to connect with
44
     * --user <username>
45
     *
46
     * @var string
47
     */
48
    private $user;
49
50
    /**
51
     * Password to authenticate with
52
     * --password <password>
53
     *
54
     * @var string
55
     */
56
    private $password;
57
58
    /**
59
     * List of tables to backup
60
     * --tables array of strings
61
     *
62
     * @var array
63
     */
64
    private $tablesToDump = [];
65
66
    /**
67
     * List of databases to backup
68
     * --databases array of strings
69
     *
70
     * @var array
71
     */
72
    private $databasesToDump = [];
73
74
    /**
75
     * List of tables to ignore
76
     *
77
     * @var array
78
     */
79
    private $tablesToIgnore = [];
80
81
    /**
82
     * List of tables where only the table structure is stored
83
     *
84
     * @var array
85
     */
86
    private $structureOnly = [];
87
88
    /**
89
     * Use mysqldump quick mode
90
     * -q
91
     *
92
     * @var bool
93
     */
94
    private $quick = false;
95
96
    /**
97
     * Lock tables option
98
     * --lock-tables
99
     *
100
     * @var bool
101
     */
102
    private $lockTables;
103
104
    /**
105
     * Issue a BEGIN SQL statement before dumping data from server
106
     * --single-transaction
107
     *
108
     * @var bool
109
     */
110
    private $singleTransaction;
111
112
    /**
113
     * Use mysqldump with compression
114
     * -C
115
     *
116
     * @var bool
117
     */
118
    private $compress = false;
119
120
    /**
121
     * Dump only table structures
122
     * --no-data
123
     *
124
     * @var boolean
125
     */
126
    private $noData = false;
127
128
    /**
129
     * Whether to add SET @@GLOBAL.GTID_PURGED to output
130
     *
131
     * @var string
132
     */
133
    private $gtidPurged;
134
135
    /**
136
     * Table separated data files
137
     * --tab
138
     *
139
     * @var bool
140
     */
141
    private $filePerTable;
142
143
    /**
144
     * Use mysqldump extended insert mode
145
     * -e, --extended-insert
146
     *
147
     * @var boolean
148
     */
149
    private $extendedInsert = false;
150
151
    /**
152
     * Dump blob fields as hex.
153
     * --hex-blob
154
     *
155
     * @var boolean
156
     */
157
    private $hexBlob = false;
158
159
    /**
160
     * Path to dump file
161
     *
162
     * @var string
163
     */
164
    private $dumpPathname;
165
166
    /**
167
     * Compression command to pipe output to
168
     *
169
     * @var \phpbu\App\Backup\Target\Compression
170 30
     */
171
    private $compression;
172 30
173 30
    /**
174 30
     * Constructor.
175
     *
176
     * @param string $path
177
     */
178
    public function __construct(string $path = '')
179
    {
180
        $this->setup('mysqldump', $path);
181
        $this->setMaskCandidates(['password']);
182
    }
183 14
184
    /**
185 14
     * Set the mysql credentials.
186 14
     *
187 14
     * @param  string $user
188
     * @param  string $password
189
     * @return \phpbu\App\Cli\Executable\Mysqldump
190
     */
191
    public function credentials(string $user = '', string $password = '') : Mysqldump
192
    {
193
        $this->user     = $user;
194
        $this->password = $password;
195
        return $this;
196 12
    }
197
198 12
    /**
199 12
     * Set the mysql hostname.
200
     *
201
     * @param  string $host
202
     * @return \phpbu\App\Cli\Executable\Mysqldump
203
     */
204
    public function useHost(string $host) : Mysqldump
205
    {
206
        $this->host = $host;
207
        return $this;
208 12
    }
209
210 12
    /**
211 12
     * Set the mysql port.
212
     *
213
     * @param  int $port
214
     * @return \phpbu\App\Cli\Executable\Mysqldump
215
     */
216
    public function usePort(int $port) : Mysqldump
217
    {
218
        $this->port = $port;
219
        return $this;
220 13
    }
221
222 13
    /**
223 13
     * Use '-q' quick mode.
224
     *
225
     * @param  boolean $bool
226
     * @return \phpbu\App\Cli\Executable\Mysqldump
227
     */
228
    public function useQuickMode(bool $bool) : Mysqldump
229
    {
230
        $this->quick = $bool;
231
        return $this;
232 13
    }
233
234 13
    /**
235 13
     * Use '--lock-tables' option.
236
     *
237
     * @param  bool $bool
238
     * @return \phpbu\App\Cli\Executable\Mysqldump
239
     */
240
    public function lockTables(bool $bool) : Mysqldump
241
    {
242
        $this->lockTables = $bool;
243
        return $this;
244 12
    }
245
246 12
    /**
247 12
     * Use '--single-transaction' option.
248
     *
249
     * @param  bool $bool
250
     * @return \phpbu\App\Cli\Executable\Mysqldump
251
     */
252
    public function singleTransaction(bool $bool) : Mysqldump
253
    {
254
        $this->singleTransaction = $bool;
255
        return $this;
256 13
    }
257
258 13
    /**
259 13
     * Use '-C' compress mode.
260
     *
261
     * @param  bool $bool
262
     * @return \phpbu\App\Cli\Executable\Mysqldump
263
     */
264
    public function useCompression(bool $bool) : Mysqldump
265
    {
266
        $this->compress = $bool;
267
        return $this;
268 13
    }
269
270 13
    /**
271 13
     * Use '-e' extended insert mode.
272
     *
273
     * @param  bool $bool
274
     * @return \phpbu\App\Cli\Executable\Mysqldump
275
     */
276
    public function useExtendedInsert(bool $bool) : Mysqldump
277
    {
278
        $this->extendedInsert = $bool;
279
        return $this;
280 14
    }
281
282 14
    /**
283 14
     * Use '--hex-blob' to encode binary fields.
284
     *
285
     * @param  bool $bool
286
     * @return \phpbu\App\Cli\Executable\Mysqldump
287
     */
288
    public function dumpBlobsHexadecimal(bool $bool) : Mysqldump
289
    {
290
        $this->hexBlob = $bool;
291
        return $this;
292 15
    }
293
294 15
    /**
295 15
     * Set tables to dump.
296
     *
297
     * @param  array $tables
298
     * @return \phpbu\App\Cli\Executable\Mysqldump
299
     */
300
    public function dumpTables(array $tables) : Mysqldump
301
    {
302
        $this->tablesToDump = $tables;
303
        return $this;
304 13
    }
305
306 13
    /**
307 13
     * Set databases to dump.
308
     *
309
     * @param  array $databases
310
     * @return \phpbu\App\Cli\Executable\Mysqldump
311
     */
312
    public function dumpDatabases(array $databases) : Mysqldump
313
    {
314
        $this->databasesToDump = $databases;
315
        return $this;
316 13
    }
317
318 13
    /**
319 13
     * Set tables to ignore.
320
     *
321
     * @param  array $tables
322
     * @return \phpbu\App\Cli\Executable\Mysqldump
323
     */
324
    public function ignoreTables(array $tables) : Mysqldump
325
    {
326
        $this->tablesToIgnore = $tables;
327
        return $this;
328 13
    }
329
330 13
    /**
331 13
     * Set tables where only table structure should be dumped.
332
     *
333
     * @param  array $tables
334
     * @return \phpbu\App\Cli\Executable\Mysqldump
335
     */
336
    public function dumpStructureOnly(array $tables) : Mysqldump
337
    {
338
        $this->structureOnly = $tables;
339
        return $this;
340 14
    }
341
342 14
    /**
343 14
     * Dump no table data at all.
344
     *
345
     * @param  bool $bool
346
     * @return \phpbu\App\Cli\Executable\Mysqldump
347
     */
348
    public function dumpNoData(bool $bool) : Mysqldump
349
    {
350
        $this->noData = $bool;
351
        return $this;
352 12
    }
353
354 12
    /**
355 12
     * Add a general transaction ID statement to the dump file.
356
     *
357
     * @param  string $purge
358
     * @return \phpbu\App\Cli\Executable\Mysqldump
359
     */
360
    public function addGTIDStatement(string $purge)
361
    {
362
        $this->gtidPurged = in_array($purge, ['ON', 'OFF', 'AUTO']) ? strtoupper($purge) : '';
363
        return $this;
364 3
    }
365
366 3
    /**
367 3
     * Produce table separated data files.
368
     *
369
     * @param  bool $bool
370
     * @return \phpbu\App\Cli\Executable\Mysqldump
371
     */
372
    public function produceFilePerTable(bool $bool) : Mysqldump
373
    {
374
        $this->filePerTable = $bool;
375
        return $this;
376 13
    }
377
378 13
    /**
379 13
     * Pipe compressor.
380
     *
381
     * @param  \phpbu\App\Backup\Target\Compression $compression
382
     * @return \phpbu\App\Cli\Executable\Mysqldump
383
     */
384
    public function compressOutput(Compression $compression) : Mysqldump
385
    {
386
        $this->compression = $compression;
387 30
        return $this;
388
    }
389 30
390 30
    /**
391 30
     * Set the dump target path.
392
     *
393 30
     * @param  string $path
394 30
     * @return \phpbu\App\Cli\Executable\Mysqldump
395 30
     */
396 30
    public function dumpTo(string $path) : Mysqldump
397 30
    {
398 30
        $this->dumpPathname = $path;
399 30
        return $this;
400 30
    }
401 30
402 30
    /**
403
     * Mysqldump CommandLine generator.
404 30
     *
405 29
     * @return \SebastianFeldmann\Cli\CommandLine
406
     */
407 29
    protected function createCommandLine() : CommandLine
408 2
    {
409
        $process = new CommandLine();
410
        $cmd     = new Cmd($this->binary);
411 29
        $process->addCommand($cmd);
412 1
413
        $cmd->addOptionIfNotEmpty('--user', $this->user);
414 28
        $cmd->addOptionIfNotEmpty('--password', $this->password);
415 1
        $cmd->addOptionIfNotEmpty('--host', $this->host);
416 1
        $cmd->addOptionIfNotEmpty('--port', $this->port);
417 1
        $cmd->addOptionIfNotEmpty('--lock-tables', $this->lockTables, false);
418
        $cmd->addOptionIfNotEmpty('--single-transaction', $this->singleTransaction, false);
419 1
        $cmd->addOptionIfNotEmpty('-q', $this->quick, false);
420 1
        $cmd->addOptionIfNotEmpty('-C', $this->compress, false);
421 1
        $cmd->addOptionIfNotEmpty('-e', $this->extendedInsert, false);
422 1
        $cmd->addOptionIfNotEmpty('--hex-blob', $this->hexBlob, false);
423 1
        $cmd->addOptionIfNotEmpty('--set-gtid-purged', $this->gtidPurged);
424
425
        $this->configureSourceData($cmd);
426 29
        $this->configureIgnoredTables($cmd);
427 29
428 29
        if ($this->filePerTable) {
429
            $cmd->addOption('--tab', $this->dumpPathname);
430
        }
431
432
        if ($this->noData) {
433
            $cmd->addOption('--no-data');
434
        } else {
435
            if (count($this->structureOnly)) {
436
                $cmd2 = clone($cmd);
437 30
                foreach ($this->structureOnly as $table) {
438
                    $cmd2->addOption('--ignore-table', $table);
439 30
                }
440 2
                $cmd2->addOption('--skip-add-drop-table');
441
                $cmd2->addOption('--no-create-db');
442 28
                $cmd2->addOption('--no-create-info');
443
                $cmd->addOption('--no-data');
444 29
                $process->addCommand($cmd2);
445
            }
446
        }
447
        $this->configureCompression($process);
448
        $this->configureOutput($process);
449
        return $process;
450
    }
451
452 2
    /**
453
     * Configure source data (tables, databases).
454 2
     *
455 1
     * @param  \SebastianFeldmann\Cli\Command\Executable $cmd
456
     * @throws \phpbu\App\Exception
457 1
     */
458 1
    private function configureSourceData(Cmd $cmd)
459 1
    {
460
        if (count($this->tablesToDump)) {
461
            $this->configureSourceTables($cmd);
462
        } else {
463
            $this->configureSourceDatabases($cmd);
464
        }
465
    }
466 28
467
    /**
468 28
     * Configure source tables.
469
     *
470
     * @param  \SebastianFeldmann\Cli\Command\Executable $cmd
471 28
     * @throws \phpbu\App\Exception
472
     */
473 1
    private function configureSourceTables(Cmd $cmd)
474 27
    {
475
        if (count($this->databasesToDump) !== 1) {
476 1
            throw new Exception('mysqldump --tables needs exactly one database');
477
        }
478
        $cmd->addArgument($this->databasesToDump[0]);
479 26
        $cmd->addOption('--tables', $this->tablesToDump);
480
    }
481 28
482
    /**
483
     * Configure source databases.
484
     *
485
     * @param \SebastianFeldmann\Cli\Command\Executable $cmd
486
     */
487
    private function configureSourceDatabases(Cmd $cmd)
488 29
    {
489
        $databasesToDump = count($this->databasesToDump);
490 29
491 1
        // different handling for different amounts of databases
492 1
        if ($databasesToDump == 1) {
493
            // single database use argument
494
            $cmd->addArgument($this->databasesToDump[0]);
495 29
        } elseif ($databasesToDump > 1) {
496
            // multiple databases add list with --databases
497
            $cmd->addOption('--databases', $this->databasesToDump);
498
        } else {
499
            // no databases set dump all databases
500
            $cmd->addOption('--all-databases');
501
        }
502 29
    }
503
504
    /**
505 29
     * Add --ignore-table options
506 3
     *
507 3
     * @param \SebastianFeldmann\Cli\Command\Executable $cmd
508 3
     */
509
    private function configureIgnoredTables(Cmd $cmd)
510 29
    {
511
        if (count($this->tablesToIgnore)) {
512
            foreach ($this->tablesToIgnore as $table) {
513
                $cmd->addOption('--ignore-table', $table);
514
            }
515
        }
516
    }
517 29
518
    /**
519
     * Add compressor pipe if set.
520 29
     *
521 27
     * @param \SebastianFeldmann\Cli\CommandLine $process
522 27
     */
523
    private function configureCompression(CommandLine $process)
524
    {
525 29
        // if file per table isn't active and a compressor is set
526
        if (!$this->filePerTable && !empty($this->compression)) {
527
            $binary = Cli::detectCmdLocation($this->compression->getCommand(), $this->compression->getPath());
528
            $cmd    = new Cmd($binary);
529
            $process->pipeOutputTo($cmd);
530
        }
531
    }
532
533
    /**
534
     * Configure output redirect.
535
     *
536
     * @param \SebastianFeldmann\Cli\CommandLine $process
537
     */
538
    private function configureOutput(CommandLine $process)
539
    {
540
        // disable output redirection if files per table is active
541
        if (!$this->filePerTable) {
542
            $process->redirectOutputTo(
543
                $this->dumpPathname . (!empty($this->compression) ? '.' . $this->compression->getSuffix() : '')
544
            );
545
        }
546
    }
547
}
548