Completed
Push — master ( c8d43c...43d1dd )
by Sebastian
02:49
created

Mysqldump::useProtocol()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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