misuzu/src/Changelog/ChangelogChangeTag.php

97 lines
3.4 KiB
PHP

<?php
namespace Misuzu\Changelog;
use JsonSerializable;
use Misuzu\DB;
class ChangelogChangeTagException extends ChangelogException {}
class ChangelogChangeTagNotFoundException extends ChangelogChangeTagException {}
class ChangelogChangeCreationFailedException extends ChangelogChangeTagException {}
class ChangelogChangeTag implements JsonSerializable {
// Database fields
private $change_id = -1;
private $tag_id = -1;
private $change = null;
private $tag = null;
public const TABLE = 'changelog_change_tags';
private const QUERY_SELECT = 'SELECT %1$s FROM `' . DB::PREFIX . self::TABLE . '` AS '. self::TABLE;
private const SELECT = '%1$s.`change_id`, %1$s.`tag_id`';
public function getChangeId(): int {
return $this->change_id < 1 ? -1 : $this->change_id;
}
public function getChange(): ChangelogChange {
if($this->change === null)
$this->change = ChangelogChange::byId($this->getChangeId());
return $this->change;
}
public function getTagId(): int {
return $this->tag_id < 1 ? -1 : $this->tag_id;
}
public function getTag(): ChangelogTag {
if($this->tag === null)
$this->tag = ChangelogTag::byId($this->getTagId());
return $this->tag;
}
public function jsonSerialize(): mixed {
return [
'change' => $this->getChangeId(),
'tag' => $this->getTagId(),
];
}
public static function create(ChangelogChange $change, ChangelogTag $tag, bool $return = false): ?self {
$createRelation = DB::prepare(
'REPLACE INTO `' . DB::PREFIX . self::TABLE . '` (`change_id`, `tag_id`)'
. ' VALUES (:change, :tag)'
)->bind('change', $change->getId())->bind('tag', $tag->getId());
if(!$createRelation->execute())
throw new ChangelogChangeCreationFailedException;
if(!$return)
return null;
return self::byExact($change, $tag);
}
public static function purgeChange(ChangelogChange $change): void {
DB::prepare(
'DELETE FROM `' . DB::PREFIX . self::TABLE . '` WHERE `change_id` = :change'
)->bind('change', $change->getId())->execute();
}
private static function countQueryBase(string $column): string {
return sprintf(self::QUERY_SELECT, sprintf('COUNT(%s.`%s`)', self::TABLE, $column));
}
public static function countByTag(ChangelogTag $tag): int {
return (int)DB::prepare(
self::countQueryBase('change_id')
. ' WHERE `tag_id` = :tag'
)->bind('tag', $tag->getId())->fetchColumn();
}
private static function byQueryBase(): string {
return sprintf(self::QUERY_SELECT, sprintf(self::SELECT, self::TABLE));
}
public static function byExact(ChangelogChange $change, ChangelogTag $tag): self {
$tag = DB::prepare(self::byQueryBase() . ' WHERE `tag_id` = :tag')
->bind('change', $change->getId())
->bind('tag', $tag->getId())
->fetchObject(self::class);
if(!$tag)
throw new ChangelogChangeTagNotFoundException;
return $tag;
}
public static function byChange(ChangelogChange $change): array {
return DB::prepare(
self::byQueryBase()
. ' WHERE `change_id` = :change'
)->bind('change', $change->getId())->fetchObjects(self::class);
}
}