mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-11-05 11:48:24 +00:00
64 lines
2.4 KiB
PHP
64 lines
2.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Chill is a software for social workers
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Chill\Migrations\DocStore;
|
|
|
|
use Doctrine\DBAL\Schema\Schema;
|
|
use Doctrine\Migrations\AbstractMigration;
|
|
|
|
final class Version20251013094414 extends AbstractMigration
|
|
{
|
|
public function getDescription(): string
|
|
{
|
|
return 'DocStore: Enforce filename uniqueness on chill_doc.stored_object_version; clean duplicates and add partial unique index on filename (for new rows only).';
|
|
}
|
|
|
|
public function up(Schema $schema): void
|
|
{
|
|
// 1) Clean duplicates: for each (stored_object_id, filename, key, iv), keep only the last inserted row
|
|
// and delete all others. Use ROW_NUMBER over id DESC to define the last one.
|
|
$this->addSql(<<<'SQL'
|
|
WITH ranked AS (
|
|
SELECT id,
|
|
rank() OVER (
|
|
PARTITION BY stored_object_id, filename, "key"::jsonb, iv::jsonb
|
|
ORDER BY id DESC
|
|
) AS rn
|
|
FROM chill_doc.stored_object_version
|
|
)
|
|
DELETE FROM chill_doc.stored_object_version sov
|
|
USING ranked r
|
|
WHERE sov.id = r.id
|
|
AND r.rn > 1
|
|
SQL);
|
|
|
|
// 2) Create a partial unique index on filename that applies only to subsequently inserted rows.
|
|
// Per user's instruction, compute the cutoff using the stored_object_id sequence value.
|
|
$nextVal = (int) $this->connection->fetchOne("SELECT nextval('chill_doc.stored_object_version_id_seq')");
|
|
|
|
// Safety: if somehow sequence is not available, fallback to current max id from the table
|
|
if ($nextVal <= 0) {
|
|
$nextVal = (int) $this->connection->fetchOne('SELECT COALESCE(MAX(id), 0) FROM chill_doc.stored_object_version');
|
|
}
|
|
|
|
$this->addSql(sprintf(
|
|
'CREATE UNIQUE INDEX chill_doc_stored_object_version_unique_by_filename ON chill_doc.stored_object_version (filename) WHERE id > %d',
|
|
$nextVal
|
|
));
|
|
}
|
|
|
|
public function down(Schema $schema): void
|
|
{
|
|
// Drop the partial unique index; data cleanup is irreversible.
|
|
$this->addSql('DROP INDEX IF EXISTS chill_doc_stored_object_version_unique_by_filename');
|
|
}
|
|
}
|