Redesign leaderboard entities to support game periods and better match DTOs
This commit is contained in:
parent
579d2047d8
commit
dd4ee4579a
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version0007 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Redesign leaderboard tables to support game periods and better match DTOs';
|
||||
}
|
||||
|
||||
private function checkLeaderboardCount(): void
|
||||
{
|
||||
$sql = 'SELECT COUNT(*) FROM nexus_leaderboard';
|
||||
$leaderboardCount = $this->connection->executeQuery(sql: $sql)->fetchOne();
|
||||
$this->abortIf(
|
||||
condition: $leaderboardCount > 0,
|
||||
message: 'This migration can only be executed on empty leaderboard tables!',
|
||||
);
|
||||
}
|
||||
|
||||
public function preUp(Schema $schema): void
|
||||
{
|
||||
$this->checkLeaderboardCount();
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// create table nexus_leaderboard_category
|
||||
$this->addSql(
|
||||
<<<'SQL'
|
||||
CREATE TABLE nexus_leaderboard_category (
|
||||
id UUID NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
score_label TEXT NOT NULL,
|
||||
career BOOLEAN NOT NULL,
|
||||
PRIMARY KEY(id)
|
||||
)
|
||||
SQL
|
||||
);
|
||||
$this->addSql(
|
||||
'CREATE UNIQUE INDEX nexus_leaderboard_category_uniq ON nexus_leaderboard_category (name, career)'
|
||||
);
|
||||
$this->addSql("COMMENT ON COLUMN nexus_leaderboard_category.id IS '(DC2Type:uuid)'");
|
||||
|
||||
// update nexus_leaderboard table
|
||||
$this->addSql('DROP INDEX nexus_leaderboard_uniq');
|
||||
$this->addSql("ALTER TABLE nexus_leaderboard ADD category_id UUID NOT NULL");
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard ADD game_period_id INT NOT NULL');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard DROP title');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard DROP value_title');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard DROP career');
|
||||
$this->addSql("COMMENT ON COLUMN nexus_leaderboard.category_id IS '(DC2Type:uuid)'");
|
||||
$this->addSql(
|
||||
<<<'SQL'
|
||||
ALTER TABLE nexus_leaderboard ADD CONSTRAINT FK_2557F33F6140100F
|
||||
FOREIGN KEY (category_id) REFERENCES nexus_leaderboard_category (id)
|
||||
NOT DEFERRABLE INITIALLY IMMEDIATE
|
||||
SQL
|
||||
);
|
||||
$this->addSql(
|
||||
<<<'SQL'
|
||||
ALTER TABLE nexus_leaderboard ADD CONSTRAINT FK_2557F33F3E2DBBDC
|
||||
FOREIGN KEY (game_period_id) REFERENCES nexus_game_period (id)
|
||||
NOT DEFERRABLE INITIALLY IMMEDIATE
|
||||
SQL
|
||||
);
|
||||
$this->addSql('CREATE INDEX nexus_leaderboard_category_idx ON nexus_leaderboard (category_id)');
|
||||
$this->addSql('CREATE INDEX nexus_leaderboard_game_period_idx ON nexus_leaderboard (game_period_id)');
|
||||
$this->addSql('CREATE UNIQUE INDEX nexus_leaderboard_uniq ON nexus_leaderboard (category_id, game_period_id)');
|
||||
|
||||
// update nexus_leaderboard_entry table
|
||||
$this->addSql('DROP INDEX nexus_leaderboard_entry_uniq');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard_entry DROP CONSTRAINT nexus_leaderboard_entry_pkey');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard_entry DROP id');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard_entry DROP created_at');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard_entry DROP last_modified_at');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard_entry RENAME COLUMN value TO score');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard_entry ADD PRIMARY KEY (leaderboard_id, position)');
|
||||
}
|
||||
|
||||
public function preDown(Schema $schema): void
|
||||
{
|
||||
$this->checkLeaderboardCount();
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// update nexus_leaderboard_entry table
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard_entry DROP CONSTRAINT nexus_leaderboard_entry_pkey');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard_entry RENAME COLUMN score TO value');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard_entry ADD id UUID NOT NULL');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard_entry ADD created_at TIMESTAMP(0) WITH TIME ZONE NOT NULL');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard_entry ADD last_modified_at TIMESTAMP(0) WITH TIME ZONE NOT NULL');
|
||||
$this->addSql("COMMENT ON COLUMN nexus_leaderboard_entry.id IS '(DC2Type:uuid)'");
|
||||
$this->addSql("COMMENT ON COLUMN nexus_leaderboard_entry.created_at IS '(DC2Type:datetimetz_immutable)'");
|
||||
$this->addSql("COMMENT ON COLUMN nexus_leaderboard_entry.last_modified_at IS '(DC2Type:datetimetz_immutable)'");
|
||||
$this->addSql('CREATE UNIQUE INDEX nexus_leaderboard_entry_uniq ON nexus_leaderboard_entry (position)');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard_entry ADD PRIMARY KEY (id)');
|
||||
|
||||
// update nexus_leaderboard table
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard DROP category_id');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard DROP game_period_id');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard ADD title TEXT NOT NULL');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard ADD value_title TEXT NOT NULL');
|
||||
$this->addSql('ALTER TABLE nexus_leaderboard ADD career BOOLEAN NOT NULL');
|
||||
$this->addSql('CREATE UNIQUE INDEX nexus_leaderboard_uniq ON nexus_leaderboard (title)');
|
||||
|
||||
// drop table nexus_leaderboard_category
|
||||
$this->addSql('DROP TABLE nexus_leaderboard_category');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Contract\Doctrine\Entity;
|
||||
|
||||
use App\Contract\Entity\Nexus\GamePeriodInterface;
|
||||
|
||||
interface GamePeriodReferenceInterface
|
||||
{
|
||||
public function getGamePeriod(): ?GamePeriodInterface;
|
||||
|
||||
public function setGamePeriod(GamePeriodInterface $gamePeriod): void;
|
||||
}
|
|
@ -5,8 +5,9 @@ declare(strict_types=1);
|
|||
namespace App\Doctrine\Entity\Nexus;
|
||||
|
||||
use App\Contract\Doctrine\Entity\DatedEntityInterface;
|
||||
use App\Contract\Doctrine\Entity\GamePeriodReferenceInterface;
|
||||
use App\Contract\Doctrine\Entity\UuidPrimaryKeyInterface;
|
||||
use App\Contract\Entity\LeaderboardTypes;
|
||||
use App\Contract\Entity\Nexus\GamePeriodInterface;
|
||||
use App\Doctrine\Entity\DatedEntityTrait;
|
||||
use App\Doctrine\Entity\UuidPrimaryKeyTrait;
|
||||
use App\Doctrine\Repository\Nexus\LeaderboardRepository;
|
||||
|
@ -15,66 +16,49 @@ use Doctrine\ORM\Mapping as ORM;
|
|||
#[
|
||||
ORM\Entity(repositoryClass: LeaderboardRepository::class),
|
||||
ORM\Table(name: 'nexus_leaderboard'),
|
||||
ORM\UniqueConstraint(name: 'nexus_leaderboard_uniq', fields: ['title']),
|
||||
ORM\UniqueConstraint(name: 'nexus_leaderboard_uniq', fields: ['category', 'gamePeriod']),
|
||||
ORM\Index(fields: ['category'], name: 'nexus_leaderboard_category_idx'),
|
||||
ORM\Index(fields: ['gamePeriod'], name: 'nexus_leaderboard_game_period_idx'),
|
||||
]
|
||||
class Leaderboard implements UuidPrimaryKeyInterface, DatedEntityInterface
|
||||
class Leaderboard implements UuidPrimaryKeyInterface, GamePeriodReferenceInterface, DatedEntityInterface
|
||||
{
|
||||
use UuidPrimaryKeyTrait;
|
||||
use DatedEntityTrait;
|
||||
|
||||
#[ORM\Column(name: 'title', type: 'text', nullable: false)]
|
||||
private ?string $title = null;
|
||||
#[
|
||||
ORM\ManyToOne(targetEntity: LeaderboardCategory::class),
|
||||
ORM\JoinColumn(name: 'category_id', referencedColumnName: 'id', nullable: false),
|
||||
]
|
||||
private ?LeaderboardCategory $category = null;
|
||||
|
||||
#[ORM\Column(name: 'value_title', type: 'text', nullable: false)]
|
||||
private ?string $valueTitle = null;
|
||||
|
||||
#[ORM\Column(name: 'career', type: 'boolean', nullable: false)]
|
||||
private bool $career = false;
|
||||
#[
|
||||
ORM\ManyToOne(targetEntity: GamePeriod::class),
|
||||
ORM\JoinColumn(name: 'game_period_id', referencedColumnName: 'id', nullable: false),
|
||||
]
|
||||
protected ?GamePeriodInterface $gamePeriod = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->generateId();
|
||||
}
|
||||
|
||||
public function getTitle(): ?string
|
||||
public function getCategory(): ?LeaderboardCategory
|
||||
{
|
||||
return $this->title;
|
||||
return $this->category;
|
||||
}
|
||||
|
||||
public function setTitle(string $title): void
|
||||
public function setCategory(LeaderboardCategory $category): void
|
||||
{
|
||||
$this->title = $title;
|
||||
$this->category = $category;
|
||||
}
|
||||
|
||||
public function getValueTitle(): ?string
|
||||
public function getGamePeriod(): ?GamePeriodInterface
|
||||
{
|
||||
return $this->valueTitle;
|
||||
return $this->gamePeriod;
|
||||
}
|
||||
|
||||
public function setValueTitle(string $valueTitle): void
|
||||
public function setGamePeriod(GamePeriodInterface $gamePeriod): void
|
||||
{
|
||||
$this->valueTitle = $valueTitle;
|
||||
}
|
||||
|
||||
public function getType(): ?string
|
||||
{
|
||||
return $this->career ? LeaderboardTypes::CAREER : LeaderboardTypes::BREATH;
|
||||
}
|
||||
|
||||
public function setType(string $type): void
|
||||
{
|
||||
$this->career = LeaderboardTypes::CAREER === $type;
|
||||
}
|
||||
|
||||
public function getCareer(): bool
|
||||
{
|
||||
return $this->career;
|
||||
}
|
||||
|
||||
public function setCareer(bool $career): self
|
||||
{
|
||||
$this->career = $career;
|
||||
|
||||
return $this;
|
||||
$this->gamePeriod = $gamePeriod;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Doctrine\Entity\Nexus;
|
||||
|
||||
use App\Contract\Doctrine\Entity\UuidPrimaryKeyInterface;
|
||||
use App\Contract\Entity\LeaderboardTypes;
|
||||
use App\Doctrine\Entity\UuidPrimaryKeyTrait;
|
||||
use App\Doctrine\Repository\Nexus\LeaderboardCategoryRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[
|
||||
ORM\Entity(repositoryClass: LeaderboardCategoryRepository::class),
|
||||
ORM\Table(name: 'nexus_leaderboard_category'),
|
||||
ORM\UniqueConstraint(name: 'nexus_leaderboard_category_uniq', fields: ['name', 'career']),
|
||||
]
|
||||
class LeaderboardCategory implements UuidPrimaryKeyInterface
|
||||
{
|
||||
use UuidPrimaryKeyTrait;
|
||||
|
||||
#[ORM\Column(name: 'name', type: 'text', nullable: false)]
|
||||
private ?string $name = null;
|
||||
|
||||
#[ORM\Column(name: 'score_label', type: 'text', nullable: false)]
|
||||
private ?string $scoreLabel = null;
|
||||
|
||||
#[ORM\Column(name: 'career', type: 'boolean', nullable: false)]
|
||||
private bool $career = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->generateId();
|
||||
}
|
||||
|
||||
public function getName(): ?string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): void
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function getScoreLabel(): ?string
|
||||
{
|
||||
return $this->scoreLabel;
|
||||
}
|
||||
|
||||
public function setScoreLabel(string $scoreLabel): void
|
||||
{
|
||||
$this->scoreLabel = $scoreLabel;
|
||||
}
|
||||
|
||||
public function getType(): ?string
|
||||
{
|
||||
return $this->career ? LeaderboardTypes::CAREER : LeaderboardTypes::BREATH;
|
||||
}
|
||||
|
||||
public function setType(string $type): void
|
||||
{
|
||||
$this->career = LeaderboardTypes::CAREER === $type;
|
||||
}
|
||||
|
||||
public function getCareer(): bool
|
||||
{
|
||||
return $this->career;
|
||||
}
|
||||
|
||||
public function setCareer(bool $career): self
|
||||
{
|
||||
$this->career = $career;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -4,43 +4,34 @@ declare(strict_types=1);
|
|||
|
||||
namespace App\Doctrine\Entity\Nexus;
|
||||
|
||||
use App\Contract\Doctrine\Entity\DatedEntityInterface;
|
||||
use App\Contract\Doctrine\Entity\UuidPrimaryKeyInterface;
|
||||
use App\Doctrine\Entity\DatedEntityTrait;
|
||||
use App\Doctrine\Entity\UuidPrimaryKeyTrait;
|
||||
use App\Doctrine\Repository\Nexus\LeaderboardEntryRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[
|
||||
ORM\Entity(repositoryClass: LeaderboardEntryRepository::class),
|
||||
ORM\Table(name: 'nexus_leaderboard_entry'),
|
||||
ORM\UniqueConstraint(name: 'nexus_leaderboard_entry_uniq', fields: ['position']),
|
||||
ORM\Index(fields: ['leaderboard'], name: 'nexus_leaderboard_entry_leaderboard_idx'),
|
||||
]
|
||||
class LeaderboardEntry implements UuidPrimaryKeyInterface, DatedEntityInterface
|
||||
class LeaderboardEntry
|
||||
{
|
||||
use UuidPrimaryKeyTrait;
|
||||
use DatedEntityTrait;
|
||||
|
||||
#[
|
||||
ORM\Id,
|
||||
ORM\ManyToOne(targetEntity: Leaderboard::class),
|
||||
ORM\JoinColumn(name: 'leaderboard_id', referencedColumnName: 'id', nullable: false),
|
||||
]
|
||||
private ?Leaderboard $leaderboard = null;
|
||||
|
||||
#[
|
||||
ORM\Id,
|
||||
ORM\Column(name: 'position', type: 'integer', nullable: false),
|
||||
]
|
||||
private ?int $position = null;
|
||||
|
||||
#[ORM\Column(name: 'character_name', type: 'text', nullable: false)]
|
||||
private ?string $characterName = null;
|
||||
|
||||
#[ORM\Column(name: 'position', type: 'integer', nullable: false)]
|
||||
private ?int $position = null;
|
||||
|
||||
#[ORM\Column(name: 'value', type: 'integer', nullable: false)]
|
||||
private ?int $value = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->generateId();
|
||||
}
|
||||
#[ORM\Column(name: 'score', type: 'integer', nullable: false)]
|
||||
private ?int $score = null;
|
||||
|
||||
public function getLeaderboard(): ?Leaderboard
|
||||
{
|
||||
|
@ -52,16 +43,6 @@ class LeaderboardEntry implements UuidPrimaryKeyInterface, DatedEntityInterface
|
|||
$this->leaderboard = $leaderboard;
|
||||
}
|
||||
|
||||
public function getCharacterName(): ?string
|
||||
{
|
||||
return $this->characterName;
|
||||
}
|
||||
|
||||
public function setCharacterName(string $characterName): void
|
||||
{
|
||||
$this->characterName = $characterName;
|
||||
}
|
||||
|
||||
public function getPosition(): ?int
|
||||
{
|
||||
return $this->position;
|
||||
|
@ -72,13 +53,23 @@ class LeaderboardEntry implements UuidPrimaryKeyInterface, DatedEntityInterface
|
|||
$this->position = $position;
|
||||
}
|
||||
|
||||
public function getValue(): ?int
|
||||
public function getCharacterName(): ?string
|
||||
{
|
||||
return $this->value;
|
||||
return $this->characterName;
|
||||
}
|
||||
|
||||
public function setValue(int $value): void
|
||||
public function setCharacterName(string $characterName): void
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->characterName = $characterName;
|
||||
}
|
||||
|
||||
public function getScore(): ?int
|
||||
{
|
||||
return $this->score;
|
||||
}
|
||||
|
||||
public function setScore(int $score): void
|
||||
{
|
||||
$this->score = $score;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Doctrine\Repository\Nexus;
|
||||
|
||||
use App\Doctrine\Entity\Nexus\LeaderboardCategory;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @method LeaderboardCategory|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method LeaderboardCategory|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method LeaderboardCategory[] findAll()
|
||||
* @method LeaderboardCategory[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class LeaderboardCategoryRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, LeaderboardCategory::class);
|
||||
}
|
||||
}
|
Reference in New Issue