1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace N98\Util\Console\Helper; |
4
|
|
|
|
5
|
|
|
use InvalidArgumentException; |
6
|
|
|
use N98\Magento\Application; |
7
|
|
|
use N98\Magento\DbSettings; |
8
|
|
|
use PDO; |
9
|
|
|
use PDOStatement; |
10
|
|
|
use RuntimeException; |
11
|
|
|
use Symfony\Component\Console\Application as BaseApplication; |
12
|
|
|
use Symfony\Component\Console\Helper\Helper as AbstractHelper; |
13
|
|
|
use Symfony\Component\Console\Output\NullOutput; |
14
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Class DatabaseHelper |
18
|
|
|
* |
19
|
|
|
* @package N98\Util\Console\Helper |
20
|
|
|
*/ |
21
|
|
|
class DatabaseHelper extends AbstractHelper |
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* @var array|DbSettings |
25
|
|
|
*/ |
26
|
|
|
protected $dbSettings = null; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* @var bool |
30
|
|
|
* @deprecated since 1.97.9, use $dbSettings->isSocketConnect() |
31
|
|
|
*/ |
32
|
|
|
protected $isSocketConnect = false; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* @var PDO |
36
|
|
|
*/ |
37
|
|
|
protected $_connection = null; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @var array |
41
|
|
|
*/ |
42
|
|
|
protected $_tables; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* @param OutputInterface $output |
46
|
|
|
* |
47
|
|
|
* @throws RuntimeException |
48
|
|
|
* @return void |
49
|
|
|
*/ |
50
|
|
|
public function detectDbSettings(OutputInterface $output) |
51
|
|
|
{ |
52
|
|
|
if (null !== $this->dbSettings) { |
53
|
|
|
return; |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
$application = $this->getApplication(); |
57
|
|
|
$application->detectMagento(); |
58
|
|
|
|
59
|
|
|
$configFile = $application->getMagentoRootFolder() . '/app/etc/local.xml'; |
60
|
|
|
|
61
|
|
|
if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { |
62
|
|
|
$output->writeln( |
63
|
|
|
sprintf('<debug>Loading database configuration from file <info>%s</info></debug>', $configFile) |
64
|
|
|
); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
try { |
68
|
|
|
$this->dbSettings = new DbSettings($configFile); |
69
|
|
|
} catch (InvalidArgumentException $e) { |
70
|
|
|
$output->writeln('<error>' . $e->getMessage() . '</error>'); |
71
|
|
|
throw new RuntimeException('Failed to load database settings from config file', 0, $e); |
72
|
|
|
} |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Connects to the database without initializing magento |
77
|
|
|
* |
78
|
|
|
* @param OutputInterface $output = null |
79
|
|
|
* |
80
|
|
|
* @return PDO |
81
|
|
|
*/ |
82
|
|
|
public function getConnection(OutputInterface $output = null) |
83
|
|
|
{ |
84
|
|
|
if (!$this->_connection) { |
85
|
|
|
$this->_connection = $this->getDbSettings($output)->getConnection(); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
return $this->_connection; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Creates a PDO DSN for the adapter from $this->_config settings. |
93
|
|
|
* |
94
|
|
|
* @see Zend_Db_Adapter_Pdo_Abstract |
95
|
|
|
* @return string |
96
|
|
|
*/ |
97
|
|
|
public function dsn() |
98
|
|
|
{ |
99
|
|
|
return $this->getDbSettings()->getDsn(); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Check whether current mysql user has $privilege privilege |
104
|
|
|
* |
105
|
|
|
* @param string $privilege |
106
|
|
|
* |
107
|
|
|
* @return bool |
108
|
|
|
*/ |
109
|
|
|
public function mysqlUserHasPrivilege($privilege) |
110
|
|
|
{ |
111
|
|
|
$statement = $this->getConnection()->query('SHOW GRANTS'); |
112
|
|
|
|
113
|
|
|
$result = $statement->fetchAll(PDO::FETCH_COLUMN); |
114
|
|
|
foreach ($result as $row) { |
115
|
|
|
if (preg_match('/^GRANT(.*)' . strtoupper($privilege) . '/', $row) |
116
|
|
|
|| preg_match('/^GRANT(.*)ALL/', $row) |
117
|
|
|
) { |
118
|
|
|
return true; |
119
|
|
|
} |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
return false; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* @return string |
127
|
|
|
*/ |
128
|
|
|
public function getMysqlClientToolConnectionString() |
129
|
|
|
{ |
130
|
|
|
return $this->getDbSettings()->getMysqlClientToolConnectionString(); |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Get mysql variable value |
135
|
|
|
* |
136
|
|
|
* @param string $variable |
137
|
|
|
* |
138
|
|
|
* @return bool|array returns array on success, false on failure |
139
|
|
|
*/ |
140
|
|
|
public function getMysqlVariableValue($variable) |
141
|
|
|
{ |
142
|
|
|
$statement = $this->getConnection()->query("SELECT @@{$variable};"); |
143
|
|
|
if (false === $statement) { |
144
|
|
|
throw new RuntimeException(sprintf('Failed to query mysql variable %s', var_export($variable, 1))); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
$result = $statement->fetch(PDO::FETCH_ASSOC); |
148
|
|
|
if ($result) { |
149
|
|
|
return $result; |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
return false; |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* obtain mysql variable value from the database connection. |
157
|
|
|
* |
158
|
|
|
* in difference to @see getMysqlVariableValue(), this method allows to specify the type of the variable as well |
159
|
|
|
* as to use any variable identifier even such that need quoting. |
160
|
|
|
* |
161
|
|
|
* @param string $name mysql variable name |
162
|
|
|
* @param string $type [optional] variable type, can be a system variable ("@@", default) or a session variable |
163
|
|
|
* ("@"). |
164
|
|
|
* |
165
|
|
|
* @return string variable value, null if variable was not defined |
166
|
|
|
* @throws RuntimeException in case a system variable is unknown (SQLSTATE[HY000]: 1193: Unknown system variable |
167
|
|
|
* 'nonexistent') |
168
|
|
|
*/ |
169
|
|
|
public function getMysqlVariable($name, $type = null) |
170
|
|
|
{ |
171
|
|
|
if (null === $type) { |
172
|
|
|
$type = "@@"; |
173
|
|
|
} else { |
174
|
|
|
$type = (string) $type; |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
if (!in_array($type, array("@@", "@"), true)) { |
178
|
|
|
throw new InvalidArgumentException( |
179
|
|
|
sprintf('Invalid mysql variable type "%s", must be "@@" (system) or "@" (session)', $type) |
180
|
|
|
); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
$quoted = '`' . strtr($name, array('`' => '``')) . '`'; |
184
|
|
|
$query = "SELECT {$type}{$quoted};"; |
185
|
|
|
|
186
|
|
|
$connection = $this->getConnection(); |
187
|
|
|
$statement = $connection->query($query, PDO::FETCH_COLUMN, 0); |
188
|
|
|
if ($statement instanceof PDOStatement) { |
189
|
|
|
$result = $statement->fetchColumn(0); |
190
|
|
|
} else { |
191
|
|
|
$reason = $connection->errorInfo() |
192
|
|
|
? vsprintf('SQLSTATE[%s]: %s: %s', $connection->errorInfo()) |
193
|
|
|
: 'no error info'; |
194
|
|
|
|
195
|
|
|
throw new RuntimeException( |
196
|
|
|
sprintf('Failed to query mysql variable %s: %s', var_export($name, true), $reason) |
197
|
|
|
); |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
return $result; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
/** |
204
|
|
|
* @param array $commandConfig |
205
|
|
|
* |
206
|
|
|
* @throws RuntimeException |
207
|
|
|
* @return array |
208
|
|
|
*/ |
209
|
|
|
public function getTableDefinitions(array $commandConfig) |
210
|
|
|
{ |
211
|
|
|
$tableDefinitions = array(); |
212
|
|
|
if (!isset($commandConfig['table-groups'])) { |
213
|
|
|
return $tableDefinitions; |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
$tableGroups = $commandConfig['table-groups']; |
217
|
|
|
foreach ($tableGroups as $index => $definition) { |
218
|
|
|
if (!isset($definition['id'])) { |
219
|
|
|
throw new RuntimeException("Invalid definition of table-groups (id missing) at index: $index"); |
220
|
|
|
} |
221
|
|
|
$id = $definition['id']; |
222
|
|
|
if (isset($tableDefinitions[$id])) { |
223
|
|
|
throw new RuntimeException("Invalid definition of table-groups (duplicate id) id: $id"); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
if (!isset($definition['tables'])) { |
227
|
|
|
throw new RuntimeException("Invalid definition of table-groups (tables missing) id: $id"); |
228
|
|
|
} |
229
|
|
|
$tables = $definition['tables']; |
230
|
|
|
|
231
|
|
|
if (is_string($tables)) { |
232
|
|
|
$tables = preg_split('~\s+~', $tables, -1, PREG_SPLIT_NO_EMPTY); |
233
|
|
|
} |
234
|
|
|
if (!is_array($tables)) { |
235
|
|
|
throw new RuntimeException("Invalid tables definition of table-groups id: $id"); |
236
|
|
|
} |
237
|
|
|
$tables = array_map('trim', $tables); |
238
|
|
|
|
239
|
|
|
$description = isset($definition['description']) ? $definition['description'] : ''; |
240
|
|
|
|
241
|
|
|
$tableDefinitions[$id] = array( |
242
|
|
|
'tables' => $tables, |
243
|
|
|
'description' => $description, |
244
|
|
|
); |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
return $tableDefinitions; |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
/** |
251
|
|
|
* @param array $list to resolve |
252
|
|
|
* @param array $definitions from to resolve |
253
|
|
|
* @param array $resolved Which definitions where already resolved -> prevent endless loops |
254
|
|
|
* |
255
|
|
|
* @return array |
256
|
|
|
* @throws RuntimeException |
257
|
|
|
*/ |
258
|
|
|
public function resolveTables(array $list, array $definitions = array(), array $resolved = array()) |
259
|
|
|
{ |
260
|
|
|
if ($this->_tables === null) { |
261
|
|
|
$this->_tables = $this->getTables(true); |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
$resolvedList = array(); |
265
|
|
|
foreach ($list as $entry) { |
266
|
|
|
if (substr($entry, 0, 1) == '@') { |
267
|
|
|
$code = substr($entry, 1); |
268
|
|
|
if (!isset($definitions[$code])) { |
269
|
|
|
throw new RuntimeException('Table-groups could not be resolved: ' . $entry); |
270
|
|
|
} |
271
|
|
|
if (!isset($resolved[$code])) { |
272
|
|
|
$resolved[$code] = true; |
273
|
|
|
$tables = $this->resolveTables( |
274
|
|
|
$this->resolveRetrieveDefinitionsTablesByCode($definitions, $code), |
275
|
|
|
$definitions, |
276
|
|
|
$resolved |
277
|
|
|
); |
278
|
|
|
$resolvedList = array_merge($resolvedList, $tables); |
279
|
|
|
} |
280
|
|
|
continue; |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
// resolve wildcards |
284
|
|
|
if (strpos($entry, '*') !== false) { |
285
|
|
|
$connection = $this->getConnection(); |
286
|
|
|
$sth = $connection->prepare( |
287
|
|
|
'SHOW TABLES LIKE :like', |
288
|
|
|
array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY) |
289
|
|
|
); |
290
|
|
|
$sth->execute( |
291
|
|
|
array(':like' => str_replace('*', '%', $this->dbSettings['prefix'] . $entry)) |
292
|
|
|
); |
293
|
|
|
$rows = $sth->fetchAll(); |
294
|
|
|
foreach ($rows as $row) { |
295
|
|
|
$resolvedList[] = $row[0]; |
296
|
|
|
} |
297
|
|
|
continue; |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
if (in_array($entry, $this->_tables)) { |
301
|
|
|
$resolvedList[] = $this->dbSettings['prefix'] . $entry; |
302
|
|
|
} |
303
|
|
|
} |
304
|
|
|
|
305
|
|
|
asort($resolvedList); |
306
|
|
|
$resolvedList = array_unique($resolvedList); |
307
|
|
|
|
308
|
|
|
return $resolvedList; |
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
/** |
312
|
|
|
* @param array $definitions |
313
|
|
|
* @param string $code |
314
|
|
|
* @return array tables |
315
|
|
|
*/ |
316
|
|
|
private function resolveRetrieveDefinitionsTablesByCode(array $definitions, $code) |
317
|
|
|
{ |
318
|
|
|
$tables = $definitions[$code]['tables']; |
319
|
|
|
|
320
|
|
|
if (is_string($tables)) { |
321
|
|
|
$tables = preg_split('~\s+~', $tables, -1, PREG_SPLIT_NO_EMPTY); |
322
|
|
|
} |
323
|
|
|
if (!is_array($tables)) { |
324
|
|
|
throw new RuntimeException("Invalid tables definition of table-groups code: @$code"); |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
$tables = array_reduce((array) $tables, array($this, 'resolveTablesArray'), null); |
328
|
|
|
|
329
|
|
|
return $tables; |
330
|
|
|
} |
331
|
|
|
|
332
|
|
|
/** |
333
|
|
|
* @param array|null $carry [optional] |
334
|
|
|
* @param $item [optional] |
335
|
|
|
* @return array |
336
|
|
|
* @throws InvalidArgumentException if item is not an array or string |
337
|
|
|
*/ |
338
|
|
|
private function resolveTablesArray(array $carry = null, $item = null) |
339
|
|
|
{ |
340
|
|
|
if (is_string($item)) { |
341
|
|
|
$item = preg_split('~\s+~', $item, -1, PREG_SPLIT_NO_EMPTY); |
342
|
|
|
} |
343
|
|
|
|
344
|
|
|
if (is_array($item)) { |
345
|
|
|
if (count($item) > 1) { |
346
|
|
|
$item = array_reduce($item, array($this, 'resolveTablesArray'), (array) $carry); |
347
|
|
|
} |
348
|
|
|
} else { |
349
|
|
|
throw new InvalidArgumentException(sprintf('Unable to handle %s', var_export($item, true))); |
350
|
|
|
} |
351
|
|
|
|
352
|
|
|
return array_merge((array) $carry, $item); |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
/** |
356
|
|
|
* Get list of database tables |
357
|
|
|
* |
358
|
|
|
* @param bool $withoutPrefix [optional] remove prefix from the returned table names. prefix is obtained from |
359
|
|
|
* magento database configuration. defaults to false. |
360
|
|
|
* |
361
|
|
|
* @return array |
362
|
|
|
* @throws RuntimeException |
363
|
|
|
*/ |
364
|
|
|
public function getTables($withoutPrefix = null) |
365
|
|
|
{ |
366
|
|
|
$withoutPrefix = (bool) $withoutPrefix; |
367
|
|
|
|
368
|
|
|
$db = $this->getConnection(); |
369
|
|
|
$prefix = $this->dbSettings['prefix']; |
370
|
|
|
$prefixLength = strlen($prefix); |
371
|
|
|
|
372
|
|
|
$column = $columnName = 'table_name'; |
373
|
|
|
|
374
|
|
|
$input = array(); |
375
|
|
|
|
376
|
|
|
if ($withoutPrefix && $prefixLength) { |
377
|
|
|
$column = sprintf('SUBSTRING(%1$s FROM 1 + CHAR_LENGTH(:name)) %1$s', $columnName); |
378
|
|
|
$input[':name'] = $prefix; |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
$condition = 'table_schema = database()'; |
382
|
|
|
|
383
|
|
|
if ($prefixLength) { |
384
|
|
|
$escape = '='; |
385
|
|
|
$condition .= sprintf(" AND %s LIKE :like ESCAPE '%s'", $columnName, $escape); |
386
|
|
|
$input[':like'] = $this->quoteLike($prefix, $escape) . '%'; |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
$query = sprintf('SELECT %s FROM information_schema.tables WHERE %s;', $column, $condition); |
390
|
|
|
$statement = $db->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); |
391
|
|
|
$result = $statement->execute($input); |
392
|
|
|
|
393
|
|
|
if (!$result) { |
394
|
|
|
// @codeCoverageIgnoreStart |
395
|
|
|
$this->throwRuntimeException( |
396
|
|
|
$statement, |
397
|
|
|
sprintf('Failed to obtain tables from database: %s', var_export($query, true)) |
398
|
|
|
); |
399
|
|
|
} // @codeCoverageIgnoreEnd |
400
|
|
|
|
401
|
|
|
$result = $statement->fetchAll(PDO::FETCH_COLUMN, 0); |
402
|
|
|
|
403
|
|
|
return $result; |
404
|
|
|
} |
405
|
|
|
|
406
|
|
|
/** |
407
|
|
|
* throw a runtime exception and provide error info for the statement if available |
408
|
|
|
* |
409
|
|
|
* @param PDOStatement $statement |
410
|
|
|
* @param string $message |
411
|
|
|
* |
412
|
|
|
* @throws RuntimeException |
413
|
|
|
*/ |
414
|
|
|
private function throwRuntimeException(PDOStatement $statement, $message = "") |
415
|
|
|
{ |
416
|
|
|
$reason = $statement->errorInfo() |
417
|
|
|
? vsprintf('SQLSTATE[%s]: %s: %s', $statement->errorInfo()) |
418
|
|
|
: 'no error info for statement'; |
419
|
|
|
|
420
|
|
|
if (strlen($message)) { |
421
|
|
|
$message .= ': '; |
422
|
|
|
} else { |
423
|
|
|
$message = ''; |
424
|
|
|
} |
425
|
|
|
|
426
|
|
|
throw new RuntimeException($message . $reason); |
427
|
|
|
} |
428
|
|
|
|
429
|
|
|
/** |
430
|
|
|
* quote a string so that it is safe to use in a LIKE |
431
|
|
|
* |
432
|
|
|
* @param string $string |
433
|
|
|
* @param string $escape character - single us-ascii character |
434
|
|
|
* |
435
|
|
|
* @return string |
436
|
|
|
*/ |
437
|
|
|
private function quoteLike($string, $escape = '=') |
438
|
|
|
{ |
439
|
|
|
$translation = array( |
440
|
|
|
$escape => $escape . $escape, |
441
|
|
|
'%' => $escape . '%', |
442
|
|
|
'_' => $escape . '_', |
443
|
|
|
); |
444
|
|
|
|
445
|
|
|
return strtr($string, $translation); |
446
|
|
|
} |
447
|
|
|
|
448
|
|
|
/** |
449
|
|
|
* Get list of db tables status |
450
|
|
|
* |
451
|
|
|
* @param bool $withoutPrefix |
452
|
|
|
* |
453
|
|
|
* @return array |
454
|
|
|
*/ |
455
|
|
|
public function getTablesStatus($withoutPrefix = false) |
456
|
|
|
{ |
457
|
|
|
$db = $this->getConnection(); |
458
|
|
|
$prefix = $this->dbSettings['prefix']; |
459
|
|
|
if (strlen($prefix) > 0) { |
460
|
|
|
$statement = $db->prepare('SHOW TABLE STATUS LIKE :like', array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); |
461
|
|
|
$statement->execute( |
462
|
|
|
array(':like' => $prefix . '%') |
463
|
|
|
); |
464
|
|
|
} else { |
465
|
|
|
$statement = $db->query('SHOW TABLE STATUS'); |
466
|
|
|
} |
467
|
|
|
|
468
|
|
|
if ($statement) { |
469
|
|
|
$result = $statement->fetchAll(PDO::FETCH_ASSOC); |
470
|
|
|
$return = array(); |
471
|
|
|
foreach ($result as $table) { |
472
|
|
|
if (true === $withoutPrefix) { |
473
|
|
|
$table['Name'] = str_replace($prefix, '', $table['Name']); |
474
|
|
|
} |
475
|
|
|
$return[$table['Name']] = $table; |
476
|
|
|
} |
477
|
|
|
|
478
|
|
|
return $return; |
479
|
|
|
} |
480
|
|
|
|
481
|
|
|
return array(); |
482
|
|
|
} |
483
|
|
|
|
484
|
|
|
/** |
485
|
|
|
* @param OutputInterface $output [optional] |
486
|
|
|
* |
487
|
|
|
* @return array|DbSettings |
488
|
|
|
*/ |
489
|
|
|
public function getDbSettings(OutputInterface $output = null) |
490
|
|
|
{ |
491
|
|
|
if ($this->dbSettings) { |
492
|
|
|
return $this->dbSettings; |
493
|
|
|
} |
494
|
|
|
|
495
|
|
|
$output = $this->fallbackOutput($output); |
496
|
|
|
|
497
|
|
|
$this->detectDbSettings($output); |
498
|
|
|
|
499
|
|
|
if (!$this->dbSettings) { |
500
|
|
|
throw new RuntimeException('Database settings fatal error'); |
501
|
|
|
} |
502
|
|
|
|
503
|
|
|
return $this->dbSettings; |
504
|
|
|
} |
505
|
|
|
|
506
|
|
|
/** |
507
|
|
|
* @return boolean |
508
|
|
|
*/ |
509
|
|
|
public function getIsSocketConnect() |
510
|
|
|
{ |
511
|
|
|
return $this->getDbSettings()->isSocketConnect(); |
512
|
|
|
} |
513
|
|
|
|
514
|
|
|
/** |
515
|
|
|
* Returns the canonical name of this helper. |
516
|
|
|
* |
517
|
|
|
* @return string The canonical name |
518
|
|
|
* |
519
|
|
|
* @api |
520
|
|
|
*/ |
521
|
|
|
public function getName() |
522
|
|
|
{ |
523
|
|
|
return 'database'; |
524
|
|
|
} |
525
|
|
|
|
526
|
|
|
/** |
527
|
|
|
* @param OutputInterface $output |
528
|
|
|
*/ |
529
|
|
View Code Duplication |
public function dropDatabase($output) |
|
|
|
|
530
|
|
|
{ |
531
|
|
|
$this->detectDbSettings($output); |
532
|
|
|
$db = $this->getConnection(); |
533
|
|
|
$db->query('DROP DATABASE `' . $this->dbSettings['dbname'] . '`'); |
534
|
|
|
$output->writeln('<info>Dropped database</info> <comment>' . $this->dbSettings['dbname'] . '</comment>'); |
535
|
|
|
} |
536
|
|
|
|
537
|
|
|
/** |
538
|
|
|
* @param OutputInterface $output |
539
|
|
|
*/ |
540
|
|
|
public function dropTables($output) |
541
|
|
|
{ |
542
|
|
|
$result = $this->getTables(); |
543
|
|
|
$query = 'SET FOREIGN_KEY_CHECKS = 0; '; |
544
|
|
|
$count = 0; |
545
|
|
|
foreach ($result as $tableName) { |
546
|
|
|
$query .= 'DROP TABLE IF EXISTS `' . $tableName . '`; '; |
547
|
|
|
$count++; |
548
|
|
|
} |
549
|
|
|
$query .= 'SET FOREIGN_KEY_CHECKS = 1;'; |
550
|
|
|
$this->getConnection()->query($query); |
551
|
|
|
$output->writeln('<info>Dropped database tables</info> <comment>' . $count . ' tables dropped</comment>'); |
552
|
|
|
} |
553
|
|
|
|
554
|
|
|
/** |
555
|
|
|
* @param OutputInterface $output |
556
|
|
|
*/ |
557
|
|
View Code Duplication |
public function createDatabase($output) |
|
|
|
|
558
|
|
|
{ |
559
|
|
|
$this->detectDbSettings($output); |
560
|
|
|
$db = $this->getConnection(); |
561
|
|
|
$db->query('CREATE DATABASE IF NOT EXISTS `' . $this->dbSettings['dbname'] . '`'); |
562
|
|
|
$output->writeln('<info>Created database</info> <comment>' . $this->dbSettings['dbname'] . '</comment>'); |
563
|
|
|
} |
564
|
|
|
|
565
|
|
|
/** |
566
|
|
|
* @param string $command example: 'VARIABLES', 'STATUS' |
567
|
|
|
* @param string|null $variable [optional] |
568
|
|
|
* |
569
|
|
|
* @return array |
570
|
|
|
*/ |
571
|
|
|
private function runShowCommand($command, $variable = null) |
572
|
|
|
{ |
573
|
|
|
$db = $this->getConnection(); |
574
|
|
|
|
575
|
|
|
if (null !== $variable) { |
576
|
|
|
$statement = $db->prepare( |
577
|
|
|
'SHOW /*!50000 GLOBAL */ ' . $command . ' LIKE :like', |
578
|
|
|
array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY) |
579
|
|
|
); |
580
|
|
|
$statement->execute( |
581
|
|
|
array(':like' => $variable) |
582
|
|
|
); |
583
|
|
|
} else { |
584
|
|
|
$statement = $db->query('SHOW /*!50000 GLOBAL */ ' . $command); |
585
|
|
|
} |
586
|
|
|
|
587
|
|
|
if ($statement) { |
588
|
|
|
/** @var array|string[] $result */ |
589
|
|
|
$result = $statement->fetchAll(PDO::FETCH_ASSOC); |
590
|
|
|
$return = array(); |
591
|
|
|
foreach ($result as $row) { |
592
|
|
|
$return[$row['Variable_name']] = $row['Value']; |
593
|
|
|
} |
594
|
|
|
|
595
|
|
|
return $return; |
596
|
|
|
} |
597
|
|
|
|
598
|
|
|
return array(); |
599
|
|
|
} |
600
|
|
|
|
601
|
|
|
/** |
602
|
|
|
* @param string|null $variable [optional] |
603
|
|
|
* |
604
|
|
|
* @return array |
605
|
|
|
*/ |
606
|
|
|
public function getGlobalVariables($variable = null) |
607
|
|
|
{ |
608
|
|
|
return $this->runShowCommand('VARIABLES', $variable); |
609
|
|
|
} |
610
|
|
|
|
611
|
|
|
/** |
612
|
|
|
* @param string|null $variable [optional] |
613
|
|
|
* |
614
|
|
|
* @return array |
615
|
|
|
*/ |
616
|
|
|
public function getGlobalStatus($variable = null) |
617
|
|
|
{ |
618
|
|
|
return $this->runShowCommand('STATUS', $variable); |
619
|
|
|
} |
620
|
|
|
|
621
|
|
|
/** |
622
|
|
|
* @return Application|BaseApplication |
623
|
|
|
*/ |
624
|
|
|
private function getApplication() |
625
|
|
|
{ |
626
|
|
|
$command = $this->getHelperSet()->getCommand(); |
627
|
|
|
|
628
|
|
|
if ($command) { |
629
|
|
|
$application = $command->getApplication(); |
630
|
|
|
} else { |
631
|
|
|
$application = new Application(); |
632
|
|
|
} |
633
|
|
|
|
634
|
|
|
return $application; |
635
|
|
|
} |
636
|
|
|
|
637
|
|
|
/** |
638
|
|
|
* small helper method to obtain an object of type OutputInterface |
639
|
|
|
* |
640
|
|
|
* @param OutputInterface|null $output |
641
|
|
|
* |
642
|
|
|
* @return OutputInterface |
643
|
|
|
*/ |
644
|
|
|
private function fallbackOutput(OutputInterface $output = null) |
645
|
|
|
{ |
646
|
|
|
if (null !== $output) { |
647
|
|
|
return $output; |
648
|
|
|
} |
649
|
|
|
|
650
|
|
|
if ($this->getHelperSet()->has('io')) { |
651
|
|
|
/** @var $helper IoHelper */ |
652
|
|
|
$helper = $this->getHelperSet()->get('io'); |
653
|
|
|
$output = $helper->getOutput(); |
654
|
|
|
} |
655
|
|
|
|
656
|
|
|
if (null === $output) { |
657
|
|
|
$output = new NullOutput(); |
658
|
|
|
} |
659
|
|
|
|
660
|
|
|
return $output; |
661
|
|
|
} |
662
|
|
|
} |
663
|
|
|
|
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.