diff --git a/migrations/Version20190902140506.php b/migrations/Version20190902140506.php index 38939b5b..bbccf829 100644 --- a/migrations/Version20190902140506.php +++ b/migrations/Version20190902140506.php @@ -69,6 +69,12 @@ final class Version20190902140506 extends AbstractMultiPlatformMigration //For attachments $this->addSql('DELETE FROM `attachements` WHERE attachements.class_name = "Part" AND (SELECT COUNT(parts.id) FROM parts WHERE parts.id = attachements.element_id) = 0;'); + //Add perms_labels column to groups table if not existing (it was not created in certain legacy versions) + //This prevents the migration failing (see https://github.com/Part-DB/Part-DB-server/issues/366 and https://github.com/Part-DB/Part-DB-server/issues/67) + if (!$this->doesColumnExist('groups', 'perms_labels')) { + $this->addSql('ALTER TABLE `groups` ADD `perms_labels` SMALLINT NOT NULL AFTER `perms_tools`'); + } + /************************************************************************************************************** * Doctrine generated SQL **************************************************************************************************************/ diff --git a/src/Migration/AbstractMultiPlatformMigration.php b/src/Migration/AbstractMultiPlatformMigration.php index 54e3b529..f577e9f4 100644 --- a/src/Migration/AbstractMultiPlatformMigration.php +++ b/src/Migration/AbstractMultiPlatformMigration.php @@ -132,6 +132,24 @@ abstract class AbstractMultiPlatformMigration extends AbstractMigration return $result > 0; } + /** + * Checks if a column exists in a table. + * @return bool Returns true, if the column exists + * @throws Exception + */ + public function doesColumnExist(string $table, string $column_name): bool + { + $db_type = $this->getDatabaseType(); + if ($db_type !== 'mysql') { + throw new \RuntimeException('This method is only supported for MySQL/MariaDB databases!'); + } + + $sql = "SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = '$table' AND COLUMN_NAME = '$column_name'"; + $result = (int) $this->connection->fetchOne($sql); + + return $result > 0; + } + /** * Returns the database type of the used database. * @return string|null Returns 'mysql' for MySQL/MariaDB and 'sqlite' for SQLite. Returns null if unknown type