diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e1c86b858..fbde1d757d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ All notable changes to this project will be documented in this file. ### Added - OpenAPI spec +### Fixed + - Fixed some code inconsitencies regarding nullish groupIds and pollIds. + - Added share repair fix to repair steps after updates. + - Purge soft-deleted entries after the documented 12 hour undo window + ### Changes - Added salt to user name obfuscation - Support Nextcloud 31 diff --git a/lib/Command/Db/CleanMigrations.php b/lib/Command/Db/CleanMigrations.php index 59a3ce2145..d7e4cd1871 100644 --- a/lib/Command/Db/CleanMigrations.php +++ b/lib/Command/Db/CleanMigrations.php @@ -10,7 +10,7 @@ use Doctrine\DBAL\Schema\Schema; use OCA\Polls\Command\Command; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCP\IDBConnection; /** diff --git a/lib/Command/Db/CreateIndices.php b/lib/Command/Db/CreateIndices.php index ded37f53b3..5f77dfd9f4 100644 --- a/lib/Command/Db/CreateIndices.php +++ b/lib/Command/Db/CreateIndices.php @@ -10,7 +10,7 @@ use Doctrine\DBAL\Schema\Schema; use OCA\Polls\Command\Command; -use OCA\Polls\Db\V10\IndexManager; +use OCA\Polls\Db\V11\IndexManager; use OCP\IDBConnection; /** diff --git a/lib/Command/Db/FixDB.php b/lib/Command/Db/FixDB.php index 39c22437f3..0fc8b7e686 100644 --- a/lib/Command/Db/FixDB.php +++ b/lib/Command/Db/FixDB.php @@ -10,7 +10,7 @@ use Doctrine\DBAL\Schema\Schema; use OCA\Polls\Command\Command; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCP\IDBConnection; /** diff --git a/lib/Command/Db/Purge.php b/lib/Command/Db/Purge.php index 601146d8e4..caf839c629 100644 --- a/lib/Command/Db/Purge.php +++ b/lib/Command/Db/Purge.php @@ -9,7 +9,7 @@ namespace OCA\Polls\Command\Db; use OCA\Polls\Command\Command; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCP\IDBConnection; /** diff --git a/lib/Command/Db/Rebuild.php b/lib/Command/Db/Rebuild.php index 2f60bae621..109c4a21e7 100644 --- a/lib/Command/Db/Rebuild.php +++ b/lib/Command/Db/Rebuild.php @@ -9,8 +9,8 @@ namespace OCA\Polls\Command\Db; use Doctrine\DBAL\Schema\Schema; -use OCA\Polls\Db\V10\TableManager; -use OCA\Polls\Db\V10\IndexManager; +use OCA\Polls\Db\V11\TableManager; +use OCA\Polls\Db\V11\IndexManager; use OCA\Polls\Command\Command; use OCP\IDBConnection; diff --git a/lib/Command/Db/RemoveFKConstraints.php b/lib/Command/Db/RemoveFKConstraints.php index f49934592c..0f03865789 100644 --- a/lib/Command/Db/RemoveFKConstraints.php +++ b/lib/Command/Db/RemoveFKConstraints.php @@ -10,7 +10,7 @@ use Doctrine\DBAL\Schema\Schema; use OCA\Polls\Command\Command; -use OCA\Polls\Db\V10\IndexManager; +use OCA\Polls\Db\V11\IndexManager; use OCP\IDBConnection; /** diff --git a/lib/Command/Db/RemoveOptionalIndices.php b/lib/Command/Db/RemoveOptionalIndices.php index 7c837b3ab5..bc174d81d4 100644 --- a/lib/Command/Db/RemoveOptionalIndices.php +++ b/lib/Command/Db/RemoveOptionalIndices.php @@ -10,7 +10,7 @@ use Doctrine\DBAL\Schema\Schema; use OCA\Polls\Command\Command; -use OCA\Polls\Db\V10\IndexManager; +use OCA\Polls\Db\V11\IndexManager; use OCP\IDBConnection; /** diff --git a/lib/Command/Db/RemoveUniqueIndices.php b/lib/Command/Db/RemoveUniqueIndices.php index 59823277a1..efdcfdea42 100644 --- a/lib/Command/Db/RemoveUniqueIndices.php +++ b/lib/Command/Db/RemoveUniqueIndices.php @@ -10,7 +10,7 @@ use Doctrine\DBAL\Schema\Schema; use OCA\Polls\Command\Command; -use OCA\Polls\Db\V10\IndexManager; +use OCA\Polls\Db\V11\IndexManager; use OCP\IDBConnection; /** diff --git a/lib/Command/Db/ResetUniqueIndices.php b/lib/Command/Db/ResetUniqueIndices.php index becef1c923..4897a40ae4 100644 --- a/lib/Command/Db/ResetUniqueIndices.php +++ b/lib/Command/Db/ResetUniqueIndices.php @@ -10,7 +10,7 @@ use Doctrine\DBAL\Schema\Schema; use OCA\Polls\Command\Command; -use OCA\Polls\Db\V10\IndexManager; +use OCA\Polls\Db\V11\IndexManager; use OCP\IDBConnection; /** diff --git a/lib/Command/Db/ResetWatch.php b/lib/Command/Db/ResetWatch.php index 1c58e666b6..8b039fd298 100644 --- a/lib/Command/Db/ResetWatch.php +++ b/lib/Command/Db/ResetWatch.php @@ -10,10 +10,10 @@ use Doctrine\DBAL\Schema\Schema; use OCA\Polls\Command\Command; -use OCA\Polls\Db\V10\IndexManager; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\IndexManager; +use OCA\Polls\Db\V11\TableManager; use OCA\Polls\Db\Watch; -use OCA\Polls\Migration\V10\TableSchema; +use OCA\Polls\Migration\V11\TableSchema; use OCP\IDBConnection; /** diff --git a/lib/Cron/JanitorCron.php b/lib/Cron/JanitorCron.php index 321e9aecb2..35f323870e 100644 --- a/lib/Cron/JanitorCron.php +++ b/lib/Cron/JanitorCron.php @@ -16,7 +16,7 @@ use OCA\Polls\Db\OptionMapper; use OCA\Polls\Db\PollMapper; use OCA\Polls\Db\ShareMapper; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCA\Polls\Db\VoteMapper; use OCA\Polls\Model\Settings\AppSettings; use OCP\AppFramework\Utility\ITimeFactory; diff --git a/lib/Db/Share.php b/lib/Db/Share.php index 4123dec927..f51a942732 100644 --- a/lib/Db/Share.php +++ b/lib/Db/Share.php @@ -148,6 +148,7 @@ class Share extends EntityWithUser implements JsonSerializable { public function __construct() { $this->addType('pollId', 'integer'); + $this->addType('groupId', 'integer'); $this->addType('invitationSent', 'integer'); $this->addType('locked', 'integer'); $this->addType('reminderSent', 'integer'); @@ -204,7 +205,7 @@ public function getUser(): UserBase { * @throws InvalidShareTypeException */ public function getPollIdOrFail(): int { - if ($this->pollId === null) { + if (!$this->pollId) { throw new InvalidShareTypeException('Share is not associated with a poll'); } return $this->pollId; @@ -310,7 +311,7 @@ public function getLocale(): string { } public function getURL(): string { - if ($this->getPollId() === null) { + if (!$this->getPollId()) { return ''; } diff --git a/lib/Db/V10/DbManager.php b/lib/Db/V11/DbManager.php similarity index 99% rename from lib/Db/V10/DbManager.php rename to lib/Db/V11/DbManager.php index 426f4c8906..1507f9ff85 100644 --- a/lib/Db/V10/DbManager.php +++ b/lib/Db/V11/DbManager.php @@ -6,7 +6,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\Polls\Db\V10; +namespace OCA\Polls\Db\V11; use Doctrine\DBAL\Schema\Schema; use Exception; diff --git a/lib/Db/V10/IndexManager.php b/lib/Db/V11/IndexManager.php similarity index 99% rename from lib/Db/V10/IndexManager.php rename to lib/Db/V11/IndexManager.php index eeb034cb05..83e245ba83 100644 --- a/lib/Db/V10/IndexManager.php +++ b/lib/Db/V11/IndexManager.php @@ -6,12 +6,12 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\Polls\Db\V10; +namespace OCA\Polls\Db\V11; use Doctrine\DBAL\Schema\Exception\IndexAlreadyExists; use Doctrine\DBAL\Schema\Exception\IndexDoesNotExist; use Exception; -use OCA\Polls\Migration\V10\TableSchema; +use OCA\Polls\Migration\V11\TableSchema; use OCP\IConfig; use OCP\IDBConnection; use Psr\Log\LoggerInterface; diff --git a/lib/Db/V10/TableManager.php b/lib/Db/V11/TableManager.php similarity index 93% rename from lib/Db/V10/TableManager.php rename to lib/Db/V11/TableManager.php index 02c5451ea5..21874ff0f2 100644 --- a/lib/Db/V10/TableManager.php +++ b/lib/Db/V11/TableManager.php @@ -6,7 +6,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\Polls\Db\V10; +namespace OCA\Polls\Db\V11; use Doctrine\DBAL\Types\Type; use Exception; @@ -20,7 +20,7 @@ use OCA\Polls\Db\Watch; use OCA\Polls\Exceptions\PreconditionException; use OCA\Polls\Helper\Hash; -use OCA\Polls\Migration\V10\TableSchema; +use OCA\Polls\Migration\V11\TableSchema; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IConfig; use OCP\IDBConnection; @@ -154,8 +154,11 @@ public function createTable(string $tableName): array { foreach ($columns as $columnName => $columnDefinition) { if ($table->hasColumn($columnName)) { $column = $table->getColumn($columnName); - if (Type::lookupName($column->getType()) !== $columnDefinition['type']) { - $messages[] = 'Migrated type of ' . $table->getName() . '[\'' . $columnName . '\'] from ' . Type::lookupName($column->getType()) . ' to ' . $columnDefinition['type']; + // Use $column->getType()->getName() instead of the static Type::lookupName(): + // since Nextcloud 35, ISchemaWrapper no longer returns a raw + // Doctrine\DBAL\Types\Type but an OCP\DB\Schema wrapper - getName() works on both. + if ($column->getType()->getName() !== $columnDefinition['type']) { + $messages[] = 'Migrated type of ' . $table->getName() . '[\'' . $columnName . '\'] from ' . $column->getType()->getName() . ' to ' . $columnDefinition['type']; $column->setType(Type::getType($columnDefinition['type'])); } $column->setOptions($columnDefinition['options']); @@ -421,10 +424,34 @@ private function deleteDuplicates(string $table, array $columns):int { return 0; } + // NULL-safe comparison: a UNIQUE index never catches "duplicate" NULLs on + // its own. Where the schema declares a default, NULL and that default + // represent the same "unset" state (e.g. a nullish and an already + // normalized poll_id/group_id = 0 are the same logical value), so compare + // both sides through the declared default via COALESCE. Without a known + // default, fall back to treating two NULLs as equal. + $default = TableSchema::TABLES[$table][$column]['options']['default'] ?? null; + + if ($default !== null) { + $defaultType = is_int($default) ? IQueryBuilder::PARAM_INT : IQueryBuilder::PARAM_STR; + $columnsMatch = $qb->expr()->eq( + $qb->createFunction('COALESCE(t1.' . $column . ', ' . $qb->createNamedParameter($default, $defaultType) . ')'), + $qb->createFunction('COALESCE(t2.' . $column . ', ' . $qb->createNamedParameter($default, $defaultType) . ')') + ); + } else { + $columnsMatch = $qb->expr()->orX( + $qb->expr()->eq('t1.' . $column, 't2.' . $column), + $qb->expr()->andX( + $qb->expr()->isNull('t1.' . $column), + $qb->expr()->isNull('t2.' . $column) + ) + ); + } + if ($i > 0) { - $selection->andWhere($qb->expr()->eq('t1.' . $column, 't2.' . $column)); + $selection->andWhere($columnsMatch); } else { - $selection->where($qb->expr()->eq('t1.' . $column, 't2.' . $column)); + $selection->where($columnsMatch); } $i++; } diff --git a/lib/Listener/AddMissingIndicesListener.php b/lib/Listener/AddMissingIndicesListener.php index 6541b5823e..37b96795d9 100644 --- a/lib/Listener/AddMissingIndicesListener.php +++ b/lib/Listener/AddMissingIndicesListener.php @@ -8,7 +8,7 @@ namespace OCA\Polls\Listener; -use OCA\Polls\Migration\V10\TableSchema; +use OCA\Polls\Migration\V11\TableSchema; use OCP\DB\Events\AddMissingIndicesEvent; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; diff --git a/lib/Migration/FixVotes.php b/lib/Migration/FixVotes.php index 3bef50cf67..9958955c89 100644 --- a/lib/Migration/FixVotes.php +++ b/lib/Migration/FixVotes.php @@ -9,7 +9,7 @@ namespace OCA\Polls\Migration; use Doctrine\DBAL\Schema\Schema; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; diff --git a/lib/Migration/RepairSteps/CleanTables.php b/lib/Migration/RepairSteps/CleanTables.php index c9a87155fc..9c95f0f2ca 100644 --- a/lib/Migration/RepairSteps/CleanTables.php +++ b/lib/Migration/RepairSteps/CleanTables.php @@ -11,7 +11,7 @@ use Doctrine\DBAL\Schema\Schema; use Exception; use OCA\Polls\Db\Poll; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; @@ -42,9 +42,12 @@ public function run(IOutput $output):void { $this->tableManager->migrateShareLabels(); $this->tableManager->removeOrphaned(); $this->tableManager->deleteAllDuplicates(); + $this->tableManager->fixNullishShares(); + $this->tableManager->fixNullishPollGroupRelations(); $this->tableManager->tidyWatchTable(time()); } catch (Exception $e) { // Simply skip repair, if it breaks and rely on the next run + $output->warning('Polls - CleanTables repair step failed: ' . $e->getMessage()); } } } diff --git a/lib/Migration/RepairSteps/CreateIndices.php b/lib/Migration/RepairSteps/CreateIndices.php index d25147db48..9b9fbcd237 100644 --- a/lib/Migration/RepairSteps/CreateIndices.php +++ b/lib/Migration/RepairSteps/CreateIndices.php @@ -10,7 +10,7 @@ use Doctrine\DBAL\Schema\Schema; use OCA\Polls\Db\Share; -use OCA\Polls\Db\V10\IndexManager; +use OCA\Polls\Db\V11\IndexManager; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; diff --git a/lib/Migration/RepairSteps/CreateTables.php b/lib/Migration/RepairSteps/CreateTables.php index ba3e52550d..e6f0649bdd 100644 --- a/lib/Migration/RepairSteps/CreateTables.php +++ b/lib/Migration/RepairSteps/CreateTables.php @@ -9,7 +9,7 @@ namespace OCA\Polls\Migration\RepairSteps; use Doctrine\DBAL\Schema\Schema; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; diff --git a/lib/Migration/RepairSteps/CreateUniqueIndices.php b/lib/Migration/RepairSteps/CreateUniqueIndices.php index dba5a5c133..47b4e19fa3 100644 --- a/lib/Migration/RepairSteps/CreateUniqueIndices.php +++ b/lib/Migration/RepairSteps/CreateUniqueIndices.php @@ -8,7 +8,7 @@ namespace OCA\Polls\Migration\RepairSteps; -use OCA\Polls\Db\V10\IndexManager; +use OCA\Polls\Db\V11\IndexManager; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; diff --git a/lib/Migration/RepairSteps/DropOrphanedColumns.php b/lib/Migration/RepairSteps/DropOrphanedColumns.php index 871f7b5713..4a2da7b92a 100644 --- a/lib/Migration/RepairSteps/DropOrphanedColumns.php +++ b/lib/Migration/RepairSteps/DropOrphanedColumns.php @@ -9,7 +9,7 @@ namespace OCA\Polls\Migration\RepairSteps; use Doctrine\DBAL\Schema\Schema; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; diff --git a/lib/Migration/RepairSteps/DropOrphanedIndices.php b/lib/Migration/RepairSteps/DropOrphanedIndices.php index d3bba06e9a..3d8662c4cb 100644 --- a/lib/Migration/RepairSteps/DropOrphanedIndices.php +++ b/lib/Migration/RepairSteps/DropOrphanedIndices.php @@ -9,7 +9,7 @@ namespace OCA\Polls\Migration\RepairSteps; use Doctrine\DBAL\Schema\Schema; -use OCA\Polls\Db\V10\IndexManager; +use OCA\Polls\Db\V11\IndexManager; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; diff --git a/lib/Migration/RepairSteps/DropOrphanedTables.php b/lib/Migration/RepairSteps/DropOrphanedTables.php index ac4bdcf87f..2b9f00e508 100644 --- a/lib/Migration/RepairSteps/DropOrphanedTables.php +++ b/lib/Migration/RepairSteps/DropOrphanedTables.php @@ -9,7 +9,7 @@ namespace OCA\Polls\Migration\RepairSteps; use Doctrine\DBAL\Schema\Schema; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; diff --git a/lib/Migration/RepairSteps/FixNullish.php b/lib/Migration/RepairSteps/FixNullish.php index 00ce95bea7..67392de355 100644 --- a/lib/Migration/RepairSteps/FixNullish.php +++ b/lib/Migration/RepairSteps/FixNullish.php @@ -8,7 +8,7 @@ namespace OCA\Polls\Migration\RepairSteps; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; diff --git a/lib/Migration/RepairSteps/Install.php b/lib/Migration/RepairSteps/Install.php index f20e84b1bb..ebe7428899 100644 --- a/lib/Migration/RepairSteps/Install.php +++ b/lib/Migration/RepairSteps/Install.php @@ -8,7 +8,7 @@ namespace OCA\Polls\Migration\RepairSteps; -use OCA\Polls\Db\V10\IndexManager; +use OCA\Polls\Db\V11\IndexManager; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; diff --git a/lib/Migration/RepairSteps/MigratePublicToOpen.php b/lib/Migration/RepairSteps/MigratePublicToOpen.php index eb933c2cfc..4d5c81748c 100644 --- a/lib/Migration/RepairSteps/MigratePublicToOpen.php +++ b/lib/Migration/RepairSteps/MigratePublicToOpen.php @@ -8,7 +8,7 @@ namespace OCA\Polls\Migration\RepairSteps; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; diff --git a/lib/Migration/RepairSteps/RemoveIndices.php b/lib/Migration/RepairSteps/RemoveIndices.php index f799f4cfe2..248506ff38 100644 --- a/lib/Migration/RepairSteps/RemoveIndices.php +++ b/lib/Migration/RepairSteps/RemoveIndices.php @@ -9,7 +9,7 @@ namespace OCA\Polls\Migration\RepairSteps; use Doctrine\DBAL\Schema\Schema; -use OCA\Polls\Db\V10\IndexManager; +use OCA\Polls\Db\V11\IndexManager; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; diff --git a/lib/Migration/RepairSteps/RemoveObsoleteMigrations.php b/lib/Migration/RepairSteps/RemoveObsoleteMigrations.php index e52ba8a4e8..31e1d44674 100644 --- a/lib/Migration/RepairSteps/RemoveObsoleteMigrations.php +++ b/lib/Migration/RepairSteps/RemoveObsoleteMigrations.php @@ -9,7 +9,7 @@ namespace OCA\Polls\Migration\RepairSteps; use Doctrine\DBAL\Schema\Schema; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; diff --git a/lib/Migration/RepairSteps/SetLastInteraction.php b/lib/Migration/RepairSteps/SetLastInteraction.php index 47be56cccc..190f4c0950 100644 --- a/lib/Migration/RepairSteps/SetLastInteraction.php +++ b/lib/Migration/RepairSteps/SetLastInteraction.php @@ -8,7 +8,7 @@ namespace OCA\Polls\Migration\RepairSteps; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCA\Polls\Db\WatchMapper; use OCP\IDBConnection; use OCP\Migration\IOutput; diff --git a/lib/Migration/RepairSteps/UpdateHashes.php b/lib/Migration/RepairSteps/UpdateHashes.php index 7a9a368fcd..18734ae28a 100644 --- a/lib/Migration/RepairSteps/UpdateHashes.php +++ b/lib/Migration/RepairSteps/UpdateHashes.php @@ -8,7 +8,7 @@ namespace OCA\Polls\Migration\RepairSteps; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; diff --git a/lib/Migration/RepairSteps/UpdateInteraction.php b/lib/Migration/RepairSteps/UpdateInteraction.php index 1e0e1d1b20..1dda77283f 100644 --- a/lib/Migration/RepairSteps/UpdateInteraction.php +++ b/lib/Migration/RepairSteps/UpdateInteraction.php @@ -8,7 +8,7 @@ namespace OCA\Polls\Migration\RepairSteps; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; diff --git a/lib/Migration/V10/TableSchema.php b/lib/Migration/V11/TableSchema.php similarity index 99% rename from lib/Migration/V10/TableSchema.php rename to lib/Migration/V11/TableSchema.php index dcd5e5939b..5a70c5408e 100644 --- a/lib/Migration/V10/TableSchema.php +++ b/lib/Migration/V11/TableSchema.php @@ -6,7 +6,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -namespace OCA\Polls\Migration\V10; +namespace OCA\Polls\Migration\V11; use OCA\Polls\Db\Comment; use OCA\Polls\Db\Log; diff --git a/lib/Migration/Version080301Date20250822153002.php b/lib/Migration/Version080301Date20250822153002.php index 7db22b9f56..973e07eaf9 100644 --- a/lib/Migration/Version080301Date20250822153002.php +++ b/lib/Migration/Version080301Date20250822153002.php @@ -8,8 +8,8 @@ namespace OCA\Polls\Migration; -use OCA\Polls\Db\V10\IndexManager; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\IndexManager; +use OCA\Polls\Db\V11\TableManager; use OCP\DB\ISchemaWrapper; use OCP\IDBConnection; use OCP\Migration\IOutput; diff --git a/lib/Migration/Version080307Date20250826231102.php b/lib/Migration/Version080307Date20250826231102.php index e56af80340..2051d0929c 100644 --- a/lib/Migration/Version080307Date20250826231102.php +++ b/lib/Migration/Version080307Date20250826231102.php @@ -9,8 +9,8 @@ namespace OCA\Polls\Migration; use OCA\Polls\Db\Share; -use OCA\Polls\Db\V10\IndexManager; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\IndexManager; +use OCA\Polls\Db\V11\TableManager; use OCP\DB\ISchemaWrapper; use OCP\IDBConnection; use OCP\Migration\IOutput; @@ -71,7 +71,7 @@ public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array // fix nullish values in poll_id and group_id and set 0 in case of null $message = $this->tableManager->fixNullishShares(); - $this->logInfo($message, 'postMigration: '); + $this->logInfo($message, 'preMigration: '); $message = $this->tableManager->tidyWatchTable(time()); $this->logInfo($message, 'preMigration: '); diff --git a/lib/Migration/Version090000Date20260302212000.php b/lib/Migration/Version090000Date20260302212000.php index 0364118878..c1d551cc97 100644 --- a/lib/Migration/Version090000Date20260302212000.php +++ b/lib/Migration/Version090000Date20260302212000.php @@ -8,7 +8,7 @@ namespace OCA\Polls\Migration; -use OCA\Polls\Db\V10\TableManager; +use OCA\Polls\Db\V11\TableManager; use OCP\DB\ISchemaWrapper; use OCP\IDBConnection; use OCP\Migration\IOutput; diff --git a/lib/Migration/Version090200Date20260822163500.php b/lib/Migration/Version090200Date20260822163500.php new file mode 100644 index 0000000000..7b59eae164 --- /dev/null +++ b/lib/Migration/Version090200Date20260822163500.php @@ -0,0 +1,120 @@ +output = $output; + $this->logInfo('Prepare migration'); + + // Let the tableManager use its own live schema (not the target schema from + // $schemaClosure, which may not reflect the actual current DB state yet) + $this->tableManager->createSchema(); + + // remove duplicate shares (and other unique-constrained duplicates) first, + // while poll_id/group_id might still be nullish - NULL never blocks a + // duplicate insert, so this has to run before values get normalized to 0 + $message = $this->tableManager->deleteAllDuplicates(); + $this->logInfo($message, 'preMigration: '); + + // fix nullish values in poll_id and group_id and set 0 in case of null + $message = $this->tableManager->fixNullishShares(); + $this->logInfo($message, 'preMigration: '); + + $message = $this->tableManager->fixNullishPollGroupRelations(); + $this->logInfo($message, 'preMigration: '); + } + + /** + * This method is executing the actual schema change based on the definition of TableSchema + * $schemaClosure The `\Closure` returns an `ISchemaWrapper` + * @param IOutput $output + * @param \Closure $schemaClosure + * @param array $options + * @return ISchemaWrapper|null + */ + public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options): ?ISchemaWrapper { + $this->output = $output; + $this->schema = $schemaClosure(); + $this->tableManager->setConnection($this->connection); + $this->tableManager->setSchema($this->schema); + + $message = $this->tableManager->createTables(); + $this->logInfo($message, 'runMigration: '); + + if (!($this->schema instanceof ISchemaWrapper)) { + return null; + } + + return $this->schema; + } + + /** + * Logs the given message to the output. + * + * @param string|array $message The message to log, can be a string or an array of strings. + * @param string $prefix Optional prefix for the message, defaults to an empty string. + * @return void + */ + private function logInfo(string|array $message, string $prefix = ''): void { + if ($this->output) { + if (is_array($message)) { + foreach ($message as $msg) { + $this->output->info($prefix . 'Polls - ' . $msg); + } + } else { + $this->output->info($prefix . 'Polls - ' . $message); + } + } + } + +} diff --git a/lib/Service/ShareService.php b/lib/Service/ShareService.php index 21df9ed1a0..27edf7fd29 100644 --- a/lib/Service/ShareService.php +++ b/lib/Service/ShareService.php @@ -404,10 +404,10 @@ public function deleteByToken(string $token, bool $restore = false): Share { public function delete(Share $share, bool $restore = false): Share { $pollId = $share->getPollId(); $groupId = $share->getGroupId(); - if ($pollId === null && $groupId !== null) { + if (!$pollId && $groupId) { $this->pollGroupMapper->find($groupId) ->request(PollGroup::PERMISSION_POLL_GROUP_EDIT); - } elseif ($pollId !== null && $groupId === null) { + } elseif ($pollId && !$groupId) { $this->pollMapper->get($pollId) ->request(Poll::PERMISSION_POLL_EDIT); } @@ -416,7 +416,7 @@ public function delete(Share $share, bool $restore = false): Share { $this->shareMapper->update($share); // skip event when deleting a poll group share - if ($pollId !== null) { + if ($pollId) { $this->eventDispatcher->dispatchTyped(new ShareDeletedEvent($share)); } return $share; @@ -596,7 +596,7 @@ public function createShare(int $pollOrPollGroupId, UserBase $userGroup, string $share = $e->getShare(); } - if ($share->getPollId() !== null) { + if ($share->getPollId()) { $this->eventDispatcher->dispatchTyped(new ShareCreateEvent($share)); } return $share; @@ -783,9 +783,9 @@ private function createNewShare( if ($purpose === 'poll') { $this->share->setPollId($pollOrPollGroupId); - $this->share->setGroupId(null); + $this->share->setGroupId(0); } else { - $this->share->setPollId(null); + $this->share->setPollId(0); $this->share->setGroupId($pollOrPollGroupId); }