Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 10 | class ImportCommand extends AbstractDatabaseCommand |
||
| 11 | { |
||
| 12 | protected function configure() |
||
| 13 | { |
||
| 14 | $this |
||
| 15 | ->setName('db:import') |
||
| 16 | ->addArgument('filename', InputArgument::OPTIONAL, 'Dump filename') |
||
| 17 | ->addOption('compression', 'c', InputOption::VALUE_REQUIRED, 'The compression of the specified file') |
||
| 18 | ->addOption('only-command', null, InputOption::VALUE_NONE, 'Print only mysql command. Do not execute') |
||
| 19 | ->addOption('only-if-empty', null, InputOption::VALUE_NONE, 'Imports only if database is empty') |
||
| 20 | ->addOption('optimize', null, InputOption::VALUE_NONE, 'Convert verbose INSERTs to short ones before import (not working with compression)') |
||
|
|
|||
| 21 | ->addOption('drop', null, InputOption::VALUE_NONE, 'Drop and recreate database before import') |
||
| 22 | ->addOption('drop-tables', null, InputOption::VALUE_NONE, 'Drop tables before import') |
||
| 23 | ->setDescription('Imports database with mysql cli client according to database defined in local.xml'); |
||
| 24 | |||
| 25 | $help = <<<HELP |
||
| 26 | Imports an SQL file with mysql cli client into current configured database. |
||
| 27 | |||
| 28 | You need to have MySQL client tools installed on your system. |
||
| 29 | HELP; |
||
| 30 | $this->setHelp($help); |
||
| 31 | |||
| 32 | } |
||
| 33 | |||
| 34 | /** |
||
| 35 | * @return bool |
||
| 36 | */ |
||
| 37 | public function isEnabled() |
||
| 41 | |||
| 42 | /** |
||
| 43 | * Optimize a dump by converting single INSERTs per line to INSERTs with multiple lines |
||
| 44 | * @param $fileName |
||
| 45 | * @return string temporary filename |
||
| 46 | */ |
||
| 47 | protected function optimize($fileName) |
||
| 48 | { |
||
| 49 | $in = fopen($fileName,'r'); |
||
| 50 | $result = tempnam(sys_get_temp_dir(), 'dump') . '.sql'; |
||
| 51 | $out = fopen($result, 'w'); |
||
| 52 | |||
| 53 | $currentTable = ''; |
||
| 54 | $maxlen = 8 * 1024 * 1024; // 8 MB |
||
| 55 | $len = 0; |
||
| 56 | while ($line = fgets($in)) { |
||
| 57 | if (strtolower(substr($line, 0, 11)) == 'insert into') { |
||
| 58 | preg_match('/^insert into `(.*)` \(.*\) values (.*);/i', $line, $m); |
||
| 59 | |||
| 60 | View Code Duplication | if (count($m) < 3) { // fallback for very long lines or other cases where the preg_match fails |
|
| 61 | if ($currentTable != '') { |
||
| 62 | fwrite($out, ";\n"); |
||
| 63 | } |
||
| 64 | fwrite($out, $line); |
||
| 65 | $currentTable = ''; |
||
| 66 | continue; |
||
| 67 | } |
||
| 68 | |||
| 69 | $table = $m[1]; |
||
| 70 | $values = $m[2]; |
||
| 71 | |||
| 72 | if ($table != $currentTable or ($len > $maxlen - 1000)) { |
||
| 73 | if ($currentTable != '') { |
||
| 74 | fwrite($out, ";\n\n"); |
||
| 75 | } |
||
| 76 | $currentTable = $table; |
||
| 77 | $insert = 'INSERT INTO `' . $table . '` VALUES ' . $values; |
||
| 78 | fwrite($out, $insert); |
||
| 79 | $len = strlen($insert); |
||
| 80 | } else { |
||
| 81 | fwrite($out, ',' . $values); |
||
| 82 | $len += strlen($values) + 1; |
||
| 83 | } |
||
| 84 | View Code Duplication | } else { |
|
| 85 | if ($currentTable != '') { |
||
| 86 | fwrite($out, ";\n"); |
||
| 87 | $currentTable = ''; |
||
| 88 | } |
||
| 89 | fwrite($out, $line); |
||
| 90 | } |
||
| 91 | |||
| 92 | } |
||
| 93 | fclose($in); |
||
| 94 | fclose($out); |
||
| 95 | |||
| 96 | return $result; |
||
| 97 | |||
| 98 | } |
||
| 99 | /** |
||
| 100 | * @param \Symfony\Component\Console\Input\InputInterface $input |
||
| 101 | * @param \Symfony\Component\Console\Output\OutputInterface $output |
||
| 102 | * @return int|void |
||
| 103 | */ |
||
| 104 | protected function execute(InputInterface $input, OutputInterface $output) |
||
| 105 | { |
||
| 106 | $this->detectDbSettings($output); |
||
| 107 | $this->writeSection($output, 'Import MySQL Database'); |
||
| 108 | $dbHelper = $this->getHelper('database'); |
||
| 109 | |||
| 110 | $fileName = $this->checkFilename($input); |
||
| 111 | |||
| 112 | $compressor = $this->getCompressor($input->getOption('compression')); |
||
| 113 | |||
| 114 | // create import command |
||
| 115 | $exec = $compressor->getDecompressingCommand( |
||
| 116 | 'mysql ' . $dbHelper->getMysqlClientToolConnectionString(), |
||
| 117 | $fileName |
||
| 118 | ); |
||
| 119 | if ($input->getOption('only-command')) { |
||
| 120 | $output->writeln($exec); |
||
| 121 | |||
| 122 | return; |
||
| 123 | } else { |
||
| 124 | if ($input->getOption('only-if-empty') |
||
| 125 | && count($dbHelper->getTables()) > 0 |
||
| 126 | ) { |
||
| 127 | $output->writeln('<comment>Skip import. Database is not empty</comment>'); |
||
| 128 | |||
| 129 | return; |
||
| 130 | } |
||
| 131 | } |
||
| 132 | |||
| 133 | if ($input->getOption('optimize')) { |
||
| 134 | if ($input->getOption('compression')) { |
||
| 135 | throw new \Exception('Options --compression and --optimize are not compatible'); |
||
| 136 | } |
||
| 137 | $output->writeln('<comment>Optimizing <info>' . $fileName . '</info> to temporary file'); |
||
| 138 | $fileName = $this->optimize($fileName); |
||
| 139 | } |
||
| 140 | |||
| 141 | if( $input->getOption('drop') ) { |
||
| 142 | $dbHelper->dropDatabase($output); |
||
| 143 | $dbHelper->createDatabase($output); |
||
| 144 | } |
||
| 145 | if( $input->getOption('drop-tables') ) { |
||
| 146 | $dbHelper->dropTables($output); |
||
| 147 | } |
||
| 148 | |||
| 149 | |||
| 150 | |||
| 151 | |||
| 152 | $this->doImport($output, $fileName, $exec); |
||
| 153 | |||
| 154 | if ($input->getOption('optimize')) { |
||
| 155 | unlink($fileName); |
||
| 156 | } |
||
| 157 | } |
||
| 158 | |||
| 159 | public function asText() { |
||
| 163 | |||
| 164 | /** |
||
| 165 | * @param InputInterface $input |
||
| 166 | * |
||
| 167 | * @return mixed |
||
| 168 | * @throws \InvalidArgumentException |
||
| 169 | */ |
||
| 170 | protected function checkFilename(InputInterface $input) |
||
| 178 | |||
| 179 | /** |
||
| 180 | * @param OutputInterface $output |
||
| 181 | * @param string $fileName |
||
| 182 | * @param string $exec |
||
| 183 | * |
||
| 184 | * @return void |
||
| 185 | */ |
||
| 186 | protected function doImport(OutputInterface $output, $fileName, $exec) |
||
| 200 | } |
||
| 201 |
Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.