Use order by to avoid problems when chunking finds a same item again...
Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
parent
0a0dbbdf15
commit
10d7cbb71f
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
namespace OC\Core\Command\Db;
|
namespace OC\Core\Command\Db;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\DBALException;
|
||||||
|
use Doctrine\DBAL\Schema\Table;
|
||||||
use OC\DB\MigrationService;
|
use OC\DB\MigrationService;
|
||||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||||
use \OCP\IConfig;
|
use \OCP\IConfig;
|
||||||
|
@ -271,24 +273,23 @@ class ConvertType extends Command implements CompletionAwareInterface {
|
||||||
/**
|
/**
|
||||||
* @param Connection $fromDB
|
* @param Connection $fromDB
|
||||||
* @param Connection $toDB
|
* @param Connection $toDB
|
||||||
* @param $table
|
* @param Table $table
|
||||||
* @param InputInterface $input
|
* @param InputInterface $input
|
||||||
* @param OutputInterface $output
|
* @param OutputInterface $output
|
||||||
* @suppress SqlInjectionChecker
|
* @suppress SqlInjectionChecker
|
||||||
*/
|
*/
|
||||||
protected function copyTable(Connection $fromDB, Connection $toDB, $table, InputInterface $input, OutputInterface $output) {
|
protected function copyTable(Connection $fromDB, Connection $toDB, Table $table, InputInterface $input, OutputInterface $output) {
|
||||||
if ($table === $toDB->getPrefix() . 'migrations') {
|
if ($table->getName() === $toDB->getPrefix() . 'migrations') {
|
||||||
$output->writeln('<comment>Skipping migrations table because it was already filled by running the migrations</comment>');
|
$output->writeln('<comment>Skipping migrations table because it was already filled by running the migrations</comment>');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$chunkSize = $input->getOption('chunk-size');
|
$chunkSize = $input->getOption('chunk-size');
|
||||||
|
|
||||||
$query = $fromDB->getQueryBuilder();
|
$query = $fromDB->getQueryBuilder();
|
||||||
$query->automaticTablePrefix(false);
|
$query->automaticTablePrefix(false);
|
||||||
$query->selectAlias($query->createFunction('COUNT(*)'), 'num_entries')
|
$query->selectAlias($query->createFunction('COUNT(*)'), 'num_entries')
|
||||||
->from($table);
|
->from($table->getName());
|
||||||
$result = $query->execute();
|
$result = $query->execute();
|
||||||
$count = $result->fetchColumn();
|
$count = $result->fetchColumn();
|
||||||
$result->closeCursor();
|
$result->closeCursor();
|
||||||
|
@ -306,12 +307,30 @@ class ConvertType extends Command implements CompletionAwareInterface {
|
||||||
$query = $fromDB->getQueryBuilder();
|
$query = $fromDB->getQueryBuilder();
|
||||||
$query->automaticTablePrefix(false);
|
$query->automaticTablePrefix(false);
|
||||||
$query->select('*')
|
$query->select('*')
|
||||||
->from($table)
|
->from($table->getName())
|
||||||
->setMaxResults($chunkSize);
|
->setMaxResults($chunkSize);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$orderColumns = $table->getPrimaryKeyColumns();
|
||||||
|
} catch (DBALException $e) {
|
||||||
|
$orderColumns = [];
|
||||||
|
}
|
||||||
|
foreach ($table->getIndexes() as $index) {
|
||||||
|
if ($index->isUnique()) {
|
||||||
|
$orderColumns = array_merge($orderColumns, $index->getUnquotedColumns());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$orderColumns = array_unique($orderColumns);
|
||||||
|
|
||||||
|
if (!empty($orderColumns)) {
|
||||||
|
foreach ($orderColumns as $column) {
|
||||||
|
$query->addOrderBy($column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$insertQuery = $toDB->getQueryBuilder();
|
$insertQuery = $toDB->getQueryBuilder();
|
||||||
$insertQuery->automaticTablePrefix(false);
|
$insertQuery->automaticTablePrefix(false);
|
||||||
$insertQuery->insert($table);
|
$insertQuery->insert($table->getName());
|
||||||
$parametersCreated = false;
|
$parametersCreated = false;
|
||||||
|
|
||||||
for ($chunk = 0; $chunk < $numChunks; $chunk++) {
|
for ($chunk = 0; $chunk < $numChunks; $chunk++) {
|
||||||
|
@ -329,7 +348,7 @@ class ConvertType extends Command implements CompletionAwareInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($row as $key => $value) {
|
foreach ($row as $key => $value) {
|
||||||
$type = $this->getColumnType($table, $key);
|
$type = $this->getColumnType($table->getName(), $key);
|
||||||
if ($type !== false) {
|
if ($type !== false) {
|
||||||
$insertQuery->setParameter($key, $value, $type);
|
$insertQuery->setParameter($key, $value, $type);
|
||||||
} else {
|
} else {
|
||||||
|
@ -365,11 +384,13 @@ class ConvertType extends Command implements CompletionAwareInterface {
|
||||||
|
|
||||||
protected function convertDB(Connection $fromDB, Connection $toDB, array $tables, InputInterface $input, OutputInterface $output) {
|
protected function convertDB(Connection $fromDB, Connection $toDB, array $tables, InputInterface $input, OutputInterface $output) {
|
||||||
$this->config->setSystemValue('maintenance', true);
|
$this->config->setSystemValue('maintenance', true);
|
||||||
|
$schema = $fromDB->createSchema();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// copy table rows
|
// copy table rows
|
||||||
foreach($tables as $table) {
|
foreach($tables as $table) {
|
||||||
$output->writeln($table);
|
$output->writeln($table);
|
||||||
$this->copyTable($fromDB, $toDB, $table, $input, $output);
|
$this->copyTable($fromDB, $toDB, $schema->getTable($table), $input, $output);
|
||||||
}
|
}
|
||||||
if ($input->getArgument('type') === 'pgsql') {
|
if ($input->getArgument('type') === 'pgsql') {
|
||||||
$tools = new \OC\DB\PgSqlTools($this->config);
|
$tools = new \OC\DB\PgSqlTools($this->config);
|
||||||
|
|
|
@ -34,7 +34,7 @@ class SchemaWrapper {
|
||||||
protected $schema;
|
protected $schema;
|
||||||
|
|
||||||
/** @var array */
|
/** @var array */
|
||||||
protected $tablesToDelete;
|
protected $tablesToDelete = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param IDBConnection $connection
|
* @param IDBConnection $connection
|
||||||
|
|
Loading…
Reference in New Issue