Files
ephub/migrations/Version20260913133131.php
T

56 lines
3.7 KiB
PHP

<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20260913133131 extends AbstractMigration
{
public function getDescription(): string
{
return 'Adds time ranges and recurring series to bookings, and drops the unique (resource, date) guard';
}
public function up(Schema $schema): void
{
$this->addSql('CREATE TABLE booking_series (id INT AUTO_INCREMENT NOT NULL, rule VARCHAR(255) NOT NULL, weekdays JSON NOT NULL, start_date DATE NOT NULL, end_date DATE NOT NULL, start_minute INT NOT NULL, end_minute INT NOT NULL, created_at DATETIME NOT NULL, user_id INT NOT NULL, resource_id INT NOT NULL, INDEX IDX_818A3AD3A76ED395 (user_id), INDEX IDX_818A3AD389329D25 (resource_id), PRIMARY KEY (id)) DEFAULT CHARACTER SET utf8mb4');
$this->addSql('ALTER TABLE booking_series ADD CONSTRAINT FK_818A3AD3A76ED395 FOREIGN KEY (user_id) REFERENCES `user` (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE booking_series ADD CONSTRAINT FK_818A3AD389329D25 FOREIGN KEY (resource_id) REFERENCES resource (id) ON DELETE RESTRICT');
// The unique index cannot express "no overlapping time range" -- and MariaDB has no
// exclusion constraints -- so the guard moves into BookingManager, which serialises on a
// SELECT ... FOR UPDATE of the resource row. This index makes that check cheap.
$this->addSql('ALTER TABLE booking DROP INDEX uniq_booking_resource_date, ADD INDEX idx_booking_resource_date (resource_id, date)');
// The defaults are what backfills existing rows: every booking made so far was a whole
// day, which is exactly 0..1440. They are dropped again immediately so the application
// stays the only thing that decides a booking's span.
$this->addSql('ALTER TABLE booking ADD start_minute INT NOT NULL DEFAULT 0, ADD end_minute INT NOT NULL DEFAULT 1440, ADD overridden TINYINT(1) NOT NULL DEFAULT 0, ADD series_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE booking ALTER COLUMN start_minute DROP DEFAULT');
$this->addSql('ALTER TABLE booking ALTER COLUMN end_minute DROP DEFAULT');
$this->addSql('ALTER TABLE booking ALTER COLUMN overridden DROP DEFAULT');
$this->addSql('ALTER TABLE booking ADD CONSTRAINT FK_E00CEDDE5278319C FOREIGN KEY (series_id) REFERENCES booking_series (id) ON DELETE SET NULL');
$this->addSql('CREATE INDEX idx_booking_user_date ON booking (user_id, date)');
$this->addSql('CREATE INDEX IDX_E00CEDDE5278319C ON booking (series_id)');
}
public function down(Schema $schema): void
{
// Note the down() is lossy by nature: restoring UNIQUE(resource_id, date) fails if any
// day holds two part-day bookings of the same resource, which is the whole point of this
// migration. Release those first if you really need to roll back.
$this->addSql('ALTER TABLE booking_series DROP FOREIGN KEY FK_818A3AD3A76ED395');
$this->addSql('ALTER TABLE booking_series DROP FOREIGN KEY FK_818A3AD389329D25');
$this->addSql('DROP TABLE booking_series');
$this->addSql('ALTER TABLE booking DROP INDEX idx_booking_resource_date, ADD UNIQUE INDEX uniq_booking_resource_date (resource_id, date)');
$this->addSql('ALTER TABLE booking DROP FOREIGN KEY FK_E00CEDDE5278319C');
$this->addSql('DROP INDEX idx_booking_user_date ON booking');
$this->addSql('DROP INDEX IDX_E00CEDDE5278319C ON booking');
$this->addSql('ALTER TABLE booking DROP start_minute, DROP end_minute, DROP overridden, DROP series_id');
}
}