96 lines
3.4 KiB
PHP
96 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);
|
|
}
|
|
}
|