/** * @param SqlDumperContext $context * @param Table[] $tables */ private function dumpTables(SqlDumperContext $context, array $tables) { $progress = $context->getProgressBarHelper()->createProgressBar(count($tables)); $contentsDumper = new TableContentsDumper($context); foreach ($tables as $table) { $contentsDumper->dumpTable($table, $context->getConfig()->getTableConfig($table->getName())); $progress->advance(); } $progress->finish(); $context->getLogger()->info('Dump finished'); }
/** * Dumps the contents of a single table. * * @param Table $table * @param TableConfiguration $tableConfig */ private function dumpTableContent(Table $table, TableConfiguration $tableConfig) { // Ensure connection is still open (to prevent for example "MySQL server has gone" errors) $this->connectionHandler->reconnectIfNecessary(); // The PDO instance is used to quote the dumped values. $pdo = $this->connectionHandler->getPdo(); $tableName = $table->getName(); $quotedTableName = $table->getQuotedName($this->connectionHandler->getPlatform()); $insertColumns = null; $harvestColumns = $tableConfig->getColumnsToHarvest(); // The buffer is used to create combined SQL statements. $maxBufferSize = $this->context->getConfig()->getOutputConfig()->getRowsPerStatement(); $bufferCount = 0; // number of rows in buffer $buffer = array(); // array to buffer rows $rowCount = $this->dataLoader->countRows($tableConfig, $table, $this->harvestedValues); $result = $this->dataLoader->executeSelectQuery($tableConfig, $table, $this->harvestedValues); $this->logger->info(sprintf('Dumping table %s (%d rows)', $table->getName(), $rowCount)); $progress = $this->context->getProgressBarHelper()->createProgressBar($rowCount, OutputInterface::VERBOSITY_VERY_VERBOSE); foreach ($result as $row) { /* * The following code (in this loop) will be executed for each dumped row! * Performance in this place is essential! */ foreach ($harvestColumns as $harvestColumn) { if (!isset($row[$harvestColumn])) { throw new InvalidArgumentException(sprintf('Trying to collect value of column %s in table %s which does not exist.', $harvestColumn, $tableName)); } $this->harvestedValues[$tableName][$harvestColumn][] = $row[$harvestColumn]; } // Quote all values in the row. $context = $row; foreach ($row as $key => $value) { $value = $this->dataConverter->convert($tableName . '.' . $key, $value, $context); if (is_null($value)) { $value = 'NULL'; } else { $value = $pdo->quote($value); } $row[$key] = $value; } if ($insertColumns === null) { // As custom queries can be defined to select the data, the column order in the insert statement // depends on the actual result set. $insertColumns = $this->extractInsertColumns(array_keys($row)); } $buffer[] = '(' . implode(', ', $row) . ')'; $bufferCount++; if ($bufferCount >= $maxBufferSize) { $query = 'INSERT INTO ' . $quotedTableName . ' (' . $insertColumns . ')' . ' VALUES ' . implode(', ', $buffer) . ';'; $this->dumpOutput->writeln($query); $progress->advance($bufferCount); $buffer = array(); $bufferCount = 0; } } if ($bufferCount > 0) { // Dump the final buffer. $query = 'INSERT INTO ' . $quotedTableName . ' (' . $insertColumns . ')' . ' VALUES ' . implode(', ', $buffer) . ';'; $this->dumpOutput->writeln($query); } $progress->finish(); }