diff --git a/app/src/Command/TransmogrifyCommand.php b/app/src/Command/TransmogrifyCommand.php
index 07af147f5..ced9173c6 100644
--- a/app/src/Command/TransmogrifyCommand.php
+++ b/app/src/Command/TransmogrifyCommand.php
@@ -535,47 +535,72 @@ public function execute(Arguments $args, ConsoleIo $io) {
$metaTable->setUpgradeVersion($targetVersion, true);
foreach(array_keys($this->tables) as $t) {
- // If we were given a list of tables see if this table is in the list
+ // If the command line args include a list of tables skip this table
+ // if it is not in that list.
if(!empty($atables) && !in_array($t, $atables))
continue;
- $io->info(Inflector::classify($t) . "(" . $t . ")");
-
- // Run any pre processing functions for the table.
+ $io->info(message: sprintf("Transmogrifying table %s(%s)", Inflector::classify($t), $t));
+
+ // Find the maximum id in the inbound table and reset the sequence for the outbound
+ // table to be that value plus one so that as we process the rows any entirely new rows
+ // inserted (entirely new rows have no existing id and will be given the id by the
+ // auto sequence) do not have a primary key id that conflicts with an existing row
+ // from the inbound table.
+ $qualifiedTableName = $this->inconn->qualifyTableName($this->tables[$t]['source']);
+ $maxId = $this->inconn->fetchOne('SELECT MAX(id) FROM ' . $qualifiedTableName);
+ $maxId++;
+
+ $qualifiedTableName = $this->outconn->qualifyTableName($t);
+ $this->io->info("Resetting sequence for $qualifiedTableName to $maxId");
+
+ // Strictly speaking we should use prepared statements, but we control the
+ // data here, and also we're executing a maintenance operation (so query
+ // optimization is less important).
+ if($this->outconn->isMySQL()) {
+ $outsql = "ALTER TABLE $qualifiedTableName AUTO_INCREMENT = " . $maxId;
+ } else {
+ $outsql = "ALTER SEQUENCE " . $qualifiedTableName . "_id_seq RESTART WITH " . $maxId;
+ }
+ $this->outconn->executeQuery($outsql);
+ // Run any preprocessing functions for the table.
if(!empty($this->tables[$t]['preTable'])) {
$p = $this->tables[$t]['preTable'];
$this->$p();
}
- $qualifiedTableName = $this->inconn->qualifyTableName($this->tables[$t]['source']);
- $count = $this->inconn->fetchOne("SELECT COUNT(*) FROM " . $qualifiedTableName);
-
- $insql = "SELECT * FROM " . $qualifiedTableName . " ORDER BY id ASC";
- $stmt = $this->inconn->executeQuery($insql);
-
- // Check if the table contains data
+ // Check if the outbound table contains any rows and skip the table if it does.
$Model = $this->getTableLocator()->get($t);
if($Model->find()->count() > 0) {
$io->warning("Skipping Transmogrification. Table (" . $t . ") is not empty. Drop the database (or truncate) and start over.");
continue;
}
+ // Count the rows in the inbound table so that we can log the percentage processed.
+ $qualifiedTableName = $this->inconn->qualifyTableName($this->tables[$t]['source']);
+ $count = $this->inconn->fetchOne("SELECT COUNT(*) FROM " . $qualifiedTableName);
+
+ // Select all the rows from the inbound table.
+ $insql = "SELECT * FROM " . $qualifiedTableName . " ORDER BY id ASC";
+ $stmt = $this->inconn->executeQuery($insql);
+
$tally = 0;
$warns = 0;
$err = 0;
+ // Loop over each row from the inbound table.
while($row = $stmt->fetch()) {
if(!empty($row[ $this->tables[$t]['displayField'] ])) {
$io->verbose("$t " . $row[ $this->tables[$t]['displayField'] ]);
}
try {
- // Make a copy of the original data for any post processing followups
+ // Make a copy of the original data for any postprocessing followups.
$origRow = $row;
- // Run any pre processing functions for the row.
+ // Run any preprocessing functions for the row.
if(!empty($this->tables[$t]['preRow'])) {
$p = $this->tables[$t]['preRow'];
@@ -635,21 +660,6 @@ public function execute(Arguments $args, ConsoleIo $io) {
$io->out("(Warnings: " . $warns . ")");
$io->out("(Errors: " . $err . ")");
- // Reset sequence to next value after current max.
- $qualifiedTableName = $this->outconn->qualifyTableName($t);
- $max = $this->outconn->fetchOne('SELECT MAX(id) FROM ' . $qualifiedTableName);
- $max++;
- $this->io->info("Resetting sequence for $qualifiedTableName to $max");
-
- // Strictly speaking we should use prepared statements, but we control the
- // data here, and also we're executing a maintenance operation (so query
- // optimization is less important)
- if($this->outconn->isMySQL()) {
- $outsql = "ALTER TABLE $qualifiedTableName AUTO_INCREMENT = " . $max;
- } else {
- $outsql = "ALTER SEQUENCE " . $qualifiedTableName . "_id_seq RESTART WITH " . $max;
- }
- $this->outconn->executeQuery($outsql);
// Run any post processing functions for the table.
if(!empty($this->tables[$t]['postTable'])) {