1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace N98\Magento\Command\Database; |
4
|
|
|
|
5
|
|
|
use InvalidArgumentException; |
6
|
|
|
use N98\Magento\Command\Database\Compressor\Compressor; |
7
|
|
|
use N98\Util\Console\Enabler; |
8
|
|
|
use N98\Util\Console\Helper\DatabaseHelper; |
9
|
|
|
use N98\Util\Exec; |
10
|
|
|
use N98\Util\VerifyOrDie; |
11
|
|
|
use Symfony\Component\Console\Helper\QuestionHelper; |
12
|
|
|
use Symfony\Component\Console\Input\InputArgument; |
13
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
14
|
|
|
use Symfony\Component\Console\Input\InputOption; |
15
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
16
|
|
|
use Symfony\Component\Console\Question\Question; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Class DumpCommand |
20
|
|
|
* @package N98\Magento\Command\Database |
21
|
|
|
*/ |
22
|
|
|
class DumpCommand extends AbstractDatabaseCommand |
23
|
|
|
{ |
24
|
|
|
/** |
25
|
|
|
* @var array |
26
|
|
|
*/ |
27
|
|
|
protected $tableDefinitions = null; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @var array |
31
|
|
|
*/ |
32
|
|
|
protected $commandConfig = null; |
33
|
|
|
|
34
|
|
|
protected function configure() |
35
|
|
|
{ |
36
|
|
|
parent::configure(); |
37
|
|
|
$this |
38
|
|
|
->setName('db:dump') |
39
|
|
|
->addArgument('filename', InputArgument::OPTIONAL, 'Dump filename') |
40
|
|
|
->addOption( |
41
|
|
|
'add-time', |
42
|
|
|
't', |
43
|
|
|
InputOption::VALUE_OPTIONAL, |
44
|
|
|
'Append or prepend a timestamp to filename if a filename is provided. ' . |
45
|
|
|
'Possible values are "suffix", "prefix" or "no".', |
46
|
|
|
'' |
47
|
|
|
) |
48
|
|
|
->addOption( |
49
|
|
|
'compression', |
50
|
|
|
'c', |
51
|
|
|
InputOption::VALUE_REQUIRED, |
52
|
|
|
'Compress the dump file using one of the supported algorithms' |
53
|
|
|
) |
54
|
|
|
->addOption( |
55
|
|
|
'only-command', |
56
|
|
|
null, |
57
|
|
|
InputOption::VALUE_NONE, |
58
|
|
|
'Print only mysqldump command. Do not execute' |
59
|
|
|
) |
60
|
|
|
->addOption( |
61
|
|
|
'print-only-filename', |
62
|
|
|
null, |
63
|
|
|
InputOption::VALUE_NONE, |
64
|
|
|
'Execute and prints no output except the dump filename' |
65
|
|
|
) |
66
|
|
|
->addOption( |
67
|
|
|
'dry-run', |
68
|
|
|
null, |
69
|
|
|
InputOption::VALUE_NONE, |
70
|
|
|
'Do everything but the actual dump' |
71
|
|
|
) |
72
|
|
|
->addOption( |
73
|
|
|
'no-single-transaction', |
74
|
|
|
null, |
75
|
|
|
InputOption::VALUE_NONE, |
76
|
|
|
'Do not use single-transaction (not recommended, this is blocking)' |
77
|
|
|
) |
78
|
|
|
->addOption( |
79
|
|
|
'human-readable', |
80
|
|
|
null, |
81
|
|
|
InputOption::VALUE_NONE, |
82
|
|
|
'Use a single insert with column names per row. Useful to track database differences. Use db:import ' . |
83
|
|
|
'--optimize for speeding up the import.' |
84
|
|
|
) |
85
|
|
|
->addOption( |
86
|
|
|
'git-friendly', |
87
|
|
|
null, |
88
|
|
|
InputOption::VALUE_NONE, |
89
|
|
|
'Use one insert statement, but with line breaks instead of separate insert statements. Similar to --human-readable, but you wont need to use --optimize to speed up the import.' |
90
|
|
|
) |
91
|
|
|
->addOption( |
92
|
|
|
'add-routines', |
93
|
|
|
null, |
94
|
|
|
InputOption::VALUE_NONE, |
95
|
|
|
'Include stored routines in dump (procedures & functions)' |
96
|
|
|
) |
97
|
|
|
->addOption( |
98
|
|
|
'stdout', |
99
|
|
|
null, |
100
|
|
|
InputOption::VALUE_NONE, |
101
|
|
|
'Dump to stdout' |
102
|
|
|
) |
103
|
|
|
->addOption( |
104
|
|
|
'strip', |
105
|
|
|
's', |
106
|
|
|
InputOption::VALUE_OPTIONAL, |
107
|
|
|
'Tables to strip (dump only structure of those tables)' |
108
|
|
|
) |
109
|
|
|
->addOption( |
110
|
|
|
'exclude', |
111
|
|
|
'e', |
112
|
|
|
InputOption::VALUE_OPTIONAL, |
113
|
|
|
'Tables to exclude entirely from the dump (including structure)' |
114
|
|
|
) |
115
|
|
|
->addOption( |
116
|
|
|
'force', |
117
|
|
|
'f', |
118
|
|
|
InputOption::VALUE_NONE, |
119
|
|
|
'Do not prompt if all options are defined' |
120
|
|
|
) |
121
|
|
|
->addOption( |
122
|
|
|
'keep-column-statistics', |
123
|
|
|
null, |
124
|
|
|
InputOption::VALUE_NONE, |
125
|
|
|
'Keeps the Column Statistics table in SQL dump' |
126
|
|
|
) |
127
|
|
|
->setDescription('Dumps database with mysqldump cli client'); |
128
|
|
|
|
129
|
|
|
$help = <<<HELP |
130
|
|
|
Dumps configured magento database with `mysqldump`. You must have installed |
131
|
|
|
the MySQL client tools. |
132
|
|
|
|
133
|
|
|
On debian systems run `apt-get install mysql-client` to do that. |
134
|
|
|
|
135
|
|
|
The command reads app/etc/env.php to find the correct settings. |
136
|
|
|
|
137
|
|
|
See it in action: http://youtu.be/ttjZHY6vThs |
138
|
|
|
|
139
|
|
|
- If you like to prepend a timestamp to the dump name the --add-time option |
140
|
|
|
can be used. |
141
|
|
|
|
142
|
|
|
- The command comes with a compression function. Add i.e. `--compression=gz` |
143
|
|
|
to dump directly in gzip compressed file. |
144
|
|
|
|
145
|
|
|
HELP; |
146
|
|
|
$this->setHelp($help); |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* @return array |
151
|
|
|
* |
152
|
|
|
* @deprecated Use database helper |
153
|
|
|
*/ |
154
|
|
|
private function getTableDefinitions() |
155
|
|
|
{ |
156
|
|
|
$this->commandConfig = $this->getCommandConfig(); |
157
|
|
|
|
158
|
|
|
if ($this->tableDefinitions === null) { |
159
|
|
|
/* @var $dbHelper DatabaseHelper */ |
160
|
|
|
$dbHelper = $this->getHelper('database'); |
161
|
|
|
|
162
|
|
|
$this->tableDefinitions = $dbHelper->getTableDefinitions($this->commandConfig); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
return $this->tableDefinitions; |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* Generate help for table definitions |
170
|
|
|
* |
171
|
|
|
* @return string |
172
|
|
|
*/ |
173
|
|
|
public function getTableDefinitionHelp() |
174
|
|
|
{ |
175
|
|
|
$messages = PHP_EOL; |
176
|
|
|
$this->commandConfig = $this->getCommandConfig(); |
177
|
|
|
$messages .= <<<HELP |
178
|
|
|
<comment>Strip option</comment> |
179
|
|
|
If you like to skip data of some tables you can use the --strip option. |
180
|
|
|
The strip option creates only the structure of the defined tables and |
181
|
|
|
forces `mysqldump` to skip the data. |
182
|
|
|
|
183
|
|
|
Separate each table to strip by a space. |
184
|
|
|
You can use wildcards like * and ? in the table names to strip multiple |
185
|
|
|
tables. In addition you can specify pre-defined table groups, that start |
186
|
|
|
with an |
187
|
|
|
|
188
|
|
|
Example: "dataflow_batch_export unimportant_module_* @log |
189
|
|
|
|
190
|
|
|
$ n98-magerun2.phar db:dump --strip="@stripped" |
191
|
|
|
|
192
|
|
|
<comment>Available Table Groups</comment> |
193
|
|
|
|
194
|
|
|
HELP; |
195
|
|
|
|
196
|
|
|
$definitions = $this->getTableDefinitions(); |
|
|
|
|
197
|
|
|
$list = []; |
198
|
|
|
$maxNameLen = 0; |
199
|
|
|
foreach ($definitions as $id => $definition) { |
200
|
|
|
$name = '@' . $id; |
201
|
|
|
$description = isset($definition['description']) ? $definition['description'] . '.' : ''; |
202
|
|
|
$nameLen = strlen($name); |
203
|
|
|
if ($nameLen > $maxNameLen) { |
204
|
|
|
$maxNameLen = $nameLen; |
205
|
|
|
} |
206
|
|
|
$list[] = [$name, $description]; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
$decrSize = 78 - $maxNameLen - 3; |
210
|
|
|
|
211
|
|
|
foreach ($list as $entry) { |
212
|
|
|
list($name, $description) = $entry; |
213
|
|
|
$delta = max(0, $maxNameLen - strlen($name)); |
214
|
|
|
$spacer = $delta ? str_repeat(' ', $delta) : ''; |
215
|
|
|
$buffer = wordwrap($description, $decrSize); |
216
|
|
|
$buffer = strtr($buffer, ["\n" => "\n" . str_repeat(' ', 3 + $maxNameLen)]); |
217
|
|
|
$messages .= sprintf(" <info>%s</info>%s %s\n", $name, $spacer, $buffer); |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
$messages .= <<<HELP |
221
|
|
|
|
222
|
|
|
Extended: https://github.com/netz98/n98-magerun/wiki/Stripped-Database-Dumps |
223
|
|
|
HELP; |
224
|
|
|
|
225
|
|
|
return $messages; |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
public function getHelp() |
229
|
|
|
{ |
230
|
|
|
return |
231
|
|
|
parent::getHelp() . PHP_EOL |
232
|
|
|
. $this->getCompressionHelp() . PHP_EOL |
233
|
|
|
. $this->getTableDefinitionHelp(); |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* @param InputInterface $input |
238
|
|
|
* @param OutputInterface $output |
239
|
|
|
* |
240
|
|
|
* @return int|void |
241
|
|
|
* @throws \Magento\Framework\Exception\FileSystemException |
242
|
|
|
*/ |
243
|
|
|
protected function execute(InputInterface $input, OutputInterface $output) |
244
|
|
|
{ |
245
|
|
|
// communicate early what is required for this command to run (is enabled) |
246
|
|
|
$enabler = new Enabler($this); |
247
|
|
|
$enabler->functionExists('exec'); |
248
|
|
|
$enabler->functionExists('passthru'); |
249
|
|
|
$enabler->operatingSystemIsNotWindows(); |
250
|
|
|
|
251
|
|
|
$this->detectDbSettings($output); |
252
|
|
|
|
253
|
|
|
if ($this->nonCommandOutput($input)) { |
254
|
|
|
$this->writeSection($output, 'Dump MySQL Database'); |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
$execs = $this->createExecs($input, $output); |
258
|
|
|
|
259
|
|
|
$success = $this->runExecs($execs, $input, $output); |
260
|
|
|
|
261
|
|
|
return $success ? 0 : 1; |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
/** |
265
|
|
|
* @param InputInterface $input |
266
|
|
|
* @param OutputInterface $output |
267
|
|
|
* @return Execs |
268
|
|
|
* @throws \Magento\Framework\Exception\FileSystemException |
269
|
|
|
*/ |
270
|
|
|
private function createExecs(InputInterface $input, OutputInterface $output) |
271
|
|
|
{ |
272
|
|
|
$execs = new Execs('mysqldump'); |
273
|
|
|
$execs->setCompression($input->getOption('compression')); |
274
|
|
|
$execs->setFileName($this->getFileName($input, $output, $execs->getCompressor())); |
275
|
|
|
|
276
|
|
|
if (!$input->getOption('no-single-transaction')) { |
277
|
|
|
$execs->addOptions('--single-transaction --quick'); |
278
|
|
|
} |
279
|
|
|
|
280
|
|
|
if ($input->getOption('human-readable')) { |
281
|
|
|
$execs->addOptions('--complete-insert --skip-extended-insert '); |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
if ($input->getOption('add-routines')) { |
285
|
|
|
$execs->addOptions('--routines '); |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
if ($this->checkColumnStatistics()) { |
289
|
|
|
if ($input->getOption('keep-column-statistics')) { |
290
|
|
|
$execs->addOptions('--column-statistics=1 '); |
291
|
|
|
} else { |
292
|
|
|
$execs->addOptions('--column-statistics=0 '); |
293
|
|
|
} |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
$postDumpGitFriendlyPipeCommands = ''; |
297
|
|
|
if ($input->getOption('git-friendly')) { |
298
|
|
|
$postDumpGitFriendlyPipeCommands = ' | sed \'s$VALUES ($VALUES\n($g\' | sed \'s$),($),\n($g\''; |
299
|
|
|
} |
300
|
|
|
|
301
|
|
|
/* @var $database DatabaseHelper */ |
302
|
|
|
$database = $this->getDatabaseHelper(); |
303
|
|
|
|
304
|
|
|
$mysqlClientToolConnectionString = $database->getMysqlClientToolConnectionString(); |
305
|
|
|
|
306
|
|
|
$excludeTables = $this->excludeTables($input, $output); |
307
|
|
|
$stripTables = array_diff($this->stripTables($input, $output), $excludeTables); |
308
|
|
|
if ($stripTables) { |
|
|
|
|
309
|
|
|
// dump structure for strip-tables |
310
|
|
|
$execs->add( |
311
|
|
|
'--no-data ' . $mysqlClientToolConnectionString . |
312
|
|
|
' ' . implode(' ', $stripTables) . $this->postDumpPipeCommands() |
313
|
|
|
); |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
// dump data for all other tables |
317
|
|
|
$ignore = ''; |
318
|
|
|
foreach (array_merge($excludeTables, $stripTables) as $ignoreTable) { |
319
|
|
|
$ignore .= '--ignore-table=' . $this->dbSettings['dbname'] . '.' . $ignoreTable . ' '; |
320
|
|
|
} |
321
|
|
|
|
322
|
|
|
$execs->add($ignore . $mysqlClientToolConnectionString . $postDumpGitFriendlyPipeCommands . $this->postDumpPipeCommands()); |
323
|
|
|
|
324
|
|
|
return $execs; |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
/** |
328
|
|
|
* @param Execs $execs |
329
|
|
|
* @param InputInterface $input |
330
|
|
|
* @param OutputInterface $output |
331
|
|
|
* @return bool |
332
|
|
|
*/ |
333
|
|
|
private function runExecs(Execs $execs, InputInterface $input, OutputInterface $output) |
334
|
|
|
{ |
335
|
|
|
if ($input->getOption('only-command') && !$input->getOption('print-only-filename')) { |
336
|
|
|
foreach ($execs->getCommands() as $command) { |
337
|
|
|
$output->writeln($command); |
338
|
|
|
} |
339
|
|
|
} else { |
340
|
|
|
if ($this->nonCommandOutput($input)) { |
341
|
|
|
$output->writeln( |
342
|
|
|
'<comment>Start dumping database <info>' . $this->dbSettings['dbname'] . |
343
|
|
|
'</info> to file <info>' . $execs->getFileName() . '</info>' |
344
|
|
|
); |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
$commands = $input->getOption('dry-run') ? [] : $execs->getCommands(); |
348
|
|
|
|
349
|
|
|
foreach ($commands as $command) { |
350
|
|
|
if (!$this->runExec($command, $input, $output)) { |
351
|
|
|
return false; |
352
|
|
|
} |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
if (!$input->getOption('stdout') && !$input->getOption('print-only-filename')) { |
356
|
|
|
$output->writeln('<info>Finished</info>'); |
357
|
|
|
} |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
if ($input->getOption('print-only-filename')) { |
361
|
|
|
$output->writeln($execs->getFileName()); |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
return true; |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
/** |
368
|
|
|
* @param string $command |
369
|
|
|
* @param InputInterface $input |
370
|
|
|
* @param OutputInterface $output |
371
|
|
|
* @return bool |
372
|
|
|
*/ |
373
|
|
|
private function runExec($command, InputInterface $input, OutputInterface $output) |
374
|
|
|
{ |
375
|
|
|
$commandOutput = ''; |
376
|
|
|
|
377
|
|
|
if ($input->getOption('stdout')) { |
378
|
|
|
passthru($command, $returnCode); |
379
|
|
|
} else { |
380
|
|
|
Exec::run($command, $commandOutput, $returnCode); |
381
|
|
|
} |
382
|
|
|
|
383
|
|
|
if ($returnCode > 0) { |
384
|
|
|
$output->writeln('<error>' . $commandOutput . '</error>'); |
385
|
|
|
$output->writeln('<error>Return Code: ' . $returnCode . '. ABORTED.</error>'); |
386
|
|
|
|
387
|
|
|
return false; |
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
return true; |
391
|
|
|
} |
392
|
|
|
|
393
|
|
|
/** |
394
|
|
|
* @param InputInterface $input |
395
|
|
|
* @param OutputInterface $output |
396
|
|
|
* @return array |
397
|
|
|
* @throws \Magento\Framework\Exception\FileSystemException |
398
|
|
|
*/ |
399
|
|
View Code Duplication |
private function stripTables(InputInterface $input, OutputInterface $output) |
|
|
|
|
400
|
|
|
{ |
401
|
|
|
if (!$input->getOption('strip')) { |
402
|
|
|
return []; |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
$stripTables = $this->resolveDatabaseTables($input->getOption('strip')); |
406
|
|
|
|
407
|
|
|
if ($this->nonCommandOutput($input)) { |
408
|
|
|
$output->writeln( |
409
|
|
|
sprintf('<comment>No-data export for: <info>%s</info></comment>', implode(' ', $stripTables)) |
410
|
|
|
); |
411
|
|
|
} |
412
|
|
|
|
413
|
|
|
return $stripTables; |
414
|
|
|
} |
415
|
|
|
|
416
|
|
|
/** |
417
|
|
|
* @param InputInterface $input |
418
|
|
|
* @param OutputInterface $output |
419
|
|
|
* @return array |
420
|
|
|
* @throws \Magento\Framework\Exception\FileSystemException |
421
|
|
|
*/ |
422
|
|
View Code Duplication |
private function excludeTables(InputInterface $input, OutputInterface $output) |
|
|
|
|
423
|
|
|
{ |
424
|
|
|
if (!$input->getOption('exclude')) { |
425
|
|
|
return []; |
426
|
|
|
} |
427
|
|
|
|
428
|
|
|
$excludeTables = $this->resolveDatabaseTables($input->getOption('exclude')); |
429
|
|
|
|
430
|
|
|
if ($this->nonCommandOutput($input)) { |
431
|
|
|
$output->writeln( |
432
|
|
|
sprintf('<comment>Excluded: <info>%s</info></comment>', implode(' ', $excludeTables)) |
433
|
|
|
); |
434
|
|
|
} |
435
|
|
|
|
436
|
|
|
return $excludeTables; |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
/** |
440
|
|
|
* @param string $list space separated list of tables |
441
|
|
|
* @return array |
442
|
|
|
* @throws \Magento\Framework\Exception\FileSystemException |
443
|
|
|
*/ |
444
|
|
|
private function resolveDatabaseTables($list) |
445
|
|
|
{ |
446
|
|
|
$database = $this->getDatabaseHelper(); |
447
|
|
|
|
448
|
|
|
return $database->resolveTables( |
449
|
|
|
explode(' ', $list), |
450
|
|
|
$database->getTableDefinitions($this->getCommandConfig()) |
451
|
|
|
); |
452
|
|
|
} |
453
|
|
|
|
454
|
|
|
/** |
455
|
|
|
* Commands which filter mysql data. Piped to mysqldump command |
456
|
|
|
* |
457
|
|
|
* @return string |
458
|
|
|
*/ |
459
|
|
|
protected function postDumpPipeCommands() |
460
|
|
|
{ |
461
|
|
|
return ' | LANG=C LC_CTYPE=C LC_ALL=C sed -e ' . escapeshellarg('s/DEFINER[ ]*=[ ]*[^*]*\*/\*/'); |
462
|
|
|
} |
463
|
|
|
|
464
|
|
|
/** |
465
|
|
|
* Command which makes the dump git friendly. Piped to mysqldump command. |
466
|
|
|
* |
467
|
|
|
* @return string |
468
|
|
|
*/ |
469
|
|
|
protected function postDumpGitFriendlyPipeCommands() |
470
|
|
|
{ |
471
|
|
|
return ' | sed \'s$VALUES ($VALUES\n($g\' | sed \'s$),($),\n($g\''; |
472
|
|
|
} |
473
|
|
|
|
474
|
|
|
/** |
475
|
|
|
* @param InputInterface $input |
476
|
|
|
* @param OutputInterface $output |
477
|
|
|
* @param Compressor $compressor |
478
|
|
|
* |
479
|
|
|
* @return string |
480
|
|
|
*/ |
481
|
|
|
protected function getFileName(InputInterface $input, OutputInterface $output, Compressor $compressor) |
482
|
|
|
{ |
483
|
|
|
$nameExtension = '.sql'; |
484
|
|
|
|
485
|
|
|
$optionAddTime = 'no'; |
486
|
|
|
if ($input->getOption('add-time')) { |
487
|
|
|
$optionAddTime = $input->getOption('add-time'); |
488
|
|
|
if (empty($optionAddTime)) { |
489
|
|
|
$optionAddTime = 'suffix'; |
490
|
|
|
} |
491
|
|
|
} |
492
|
|
|
|
493
|
|
|
list($namePrefix, $nameSuffix) = $this->getFileNamePrefixSuffix($optionAddTime); |
494
|
|
|
|
495
|
|
|
if ( |
496
|
|
|
( |
497
|
|
|
($fileName = $input->getArgument('filename')) === null |
498
|
|
|
|| ($isDir = is_dir($fileName)) |
499
|
|
|
) |
500
|
|
|
&& !$input->getOption('stdout') |
501
|
|
|
) { |
502
|
|
|
$defaultName = VerifyOrDie::filename( |
503
|
|
|
$namePrefix . $this->dbSettings['dbname'] . $nameSuffix . $nameExtension |
504
|
|
|
); |
505
|
|
|
if (isset($isDir) && $isDir) { |
506
|
|
|
$defaultName = rtrim($fileName, '/') . '/' . $defaultName; |
507
|
|
|
} |
508
|
|
|
if (!$input->getOption('force')) { |
509
|
|
|
$question = new Question( |
510
|
|
|
'<question>Filename for SQL dump:</question> [<comment>' . $defaultName . '</comment>]', |
511
|
|
|
$defaultName |
512
|
|
|
); |
513
|
|
|
|
514
|
|
|
/** @var QuestionHelper $questionHelper */ |
515
|
|
|
$questionHelper = $this->getHelper('question'); |
516
|
|
|
$fileName = $questionHelper->ask( |
517
|
|
|
$input, |
518
|
|
|
$output, |
519
|
|
|
$question |
520
|
|
|
); |
521
|
|
|
} else { |
522
|
|
|
$fileName = $defaultName; |
523
|
|
|
} |
524
|
|
|
} elseif ($optionAddTime && $fileName !== null) { |
525
|
|
|
$pathParts = pathinfo($fileName); |
526
|
|
|
|
527
|
|
|
$fileName = ($pathParts['dirname'] === '.' ? '' : $pathParts['dirname'] . '/') |
528
|
|
|
. $namePrefix |
529
|
|
|
. (isset($pathParts['filename']) ? $pathParts['filename'] : '') |
530
|
|
|
. $nameSuffix |
531
|
|
|
. (isset($pathParts['extension']) ? ('.' . $pathParts['extension']) : ''); |
532
|
|
|
} |
533
|
|
|
|
534
|
|
|
$fileName = $compressor->getFileName($fileName); |
535
|
|
|
|
536
|
|
|
return $fileName; |
537
|
|
|
} |
538
|
|
|
|
539
|
|
|
/** |
540
|
|
|
* @param null|bool|string $optionAddTime [optional] true for default "suffix", other string values: "prefix", "no" |
541
|
|
|
* @return array |
542
|
|
|
*/ |
543
|
|
|
private function getFileNamePrefixSuffix($optionAddTime = null) |
544
|
|
|
{ |
545
|
|
|
$namePrefix = ''; |
546
|
|
|
$nameSuffix = ''; |
547
|
|
|
if ($optionAddTime === null) { |
548
|
|
|
return [$namePrefix, $nameSuffix]; |
549
|
|
|
} |
550
|
|
|
|
551
|
|
|
$timeStamp = date('Y-m-d_His'); |
552
|
|
|
|
553
|
|
|
if (in_array($optionAddTime, ['suffix', true], true)) { |
554
|
|
|
$nameSuffix = '_' . $timeStamp; |
555
|
|
|
} elseif ($optionAddTime === 'prefix') { |
556
|
|
|
$namePrefix = $timeStamp . '_'; |
557
|
|
|
} elseif ($optionAddTime !== 'no') { |
558
|
|
|
throw new InvalidArgumentException( |
559
|
|
|
sprintf( |
560
|
|
|
'Invalid --add-time value %s, possible values are none (for) "suffix", "prefix" or "no"', |
561
|
|
|
var_export($optionAddTime, true) |
562
|
|
|
) |
563
|
|
|
); |
564
|
|
|
} |
565
|
|
|
|
566
|
|
|
return [$namePrefix, $nameSuffix]; |
567
|
|
|
} |
568
|
|
|
|
569
|
|
|
/** |
570
|
|
|
* @param InputInterface $input |
571
|
|
|
* @return bool |
572
|
|
|
*/ |
573
|
|
|
private function nonCommandOutput(InputInterface $input) |
574
|
|
|
{ |
575
|
|
|
return |
576
|
|
|
!$input->getOption('stdout') |
577
|
|
|
&& !$input->getOption('only-command') |
578
|
|
|
&& !$input->getOption('print-only-filename'); |
579
|
|
|
} |
580
|
|
|
|
581
|
|
|
/** |
582
|
|
|
* Checks if 'column statistics' are present in the current MySQL distribution |
583
|
|
|
* |
584
|
|
|
* @return bool |
585
|
|
|
*/ |
586
|
|
|
private function checkColumnStatistics() |
587
|
|
|
{ |
588
|
|
|
Exec::run('mysqldump --help | grep -c column-statistics || true', $output, $returnCode); |
589
|
|
|
|
590
|
|
|
if ($output > 0) { |
591
|
|
|
return true; |
592
|
|
|
} |
593
|
|
|
|
594
|
|
|
return false; |
595
|
|
|
} |
596
|
|
|
} |
597
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.