Handle metadata formats as entities

This commit is contained in:
Sebastian Meyer 2024-01-06 16:24:01 +01:00
parent 60f41db284
commit 152bc9030f
3 changed files with 35 additions and 62 deletions

View File

@ -24,6 +24,7 @@ namespace OCC\OaiPmh2\Console;
use OCC\OaiPmh2\Configuration; use OCC\OaiPmh2\Configuration;
use OCC\OaiPmh2\Database; use OCC\OaiPmh2\Database;
use OCC\OaiPmh2\Database\Format;
use Symfony\Component\Console\Application; use Symfony\Component\Console\Application;
use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
@ -70,7 +71,8 @@ class UpdateFormatsCommand extends Command
} }
} }
try { try {
Database::getInstance()->addOrUpdateMetadataFormat($prefix, $format['namespace'], $format['schema']); $format = new Format($prefix, $format['namespace'], $format['schema']);
Database::getInstance()->addOrUpdateMetadataFormat($format);
++$added; ++$added;
$output->writeln([ $output->writeln([
sprintf( sprintf(
@ -91,7 +93,7 @@ class UpdateFormatsCommand extends Command
} }
foreach (array_keys($inDatabase) as $prefix) { foreach (array_keys($inDatabase) as $prefix) {
if (!in_array($prefix, array_keys($formats), true)) { if (!in_array($prefix, array_keys($formats), true)) {
if (Database::getInstance()->removeMetadataFormat($prefix)) { Database::getInstance()->removeMetadataFormat($inDatabase[$prefix]);
++$deleted; ++$deleted;
$output->writeln([ $output->writeln([
sprintf( sprintf(
@ -99,15 +101,6 @@ class UpdateFormatsCommand extends Command
$prefix $prefix
) )
]); ]);
} else {
$failure = true;
$output->writeln([
sprintf(
' [ERROR] Could not delete metadata format "%s". ',
$prefix
)
]);
}
} }
} }
/** @var Application */ /** @var Application */

View File

@ -73,32 +73,19 @@ class Database
/** /**
* Add or update metadata format. * Add or update metadata format.
* *
* @param string $prefix The metadata prefix * @param Format $newFormat The metadata format
* @param string $namespace The namespace URI
* @param string $schema The schema URL
* *
* @return void * @return void
*
* @throws ValidationFailedException
*/ */
public function addOrUpdateMetadataFormat(string $prefix, string $namespace, string $schema): void public function addOrUpdateMetadataFormat(Format $newFormat): void
{ {
$format = $this->entityManager->find(Format::class, $prefix); $oldFormat = $this->entityManager->find(Format::class, $newFormat->getPrefix());
if (isset($format)) { if (isset($oldFormat)) {
try { $oldFormat->setNamespace($newFormat->getNamespace());
$format->setNamespace($namespace); $oldFormat->setSchema($newFormat->getSchema());
$format->setSchema($schema);
} catch (ValidationFailedException $exception) {
throw $exception;
}
} else { } else {
try { $this->entityManager->persist($newFormat);
$format = new Format($prefix, $namespace, $schema);
} catch (ValidationFailedException $exception) {
throw $exception;
} }
}
$this->entityManager->persist($format);
$this->entityManager->flush(); $this->entityManager->flush();
} }
@ -212,10 +199,8 @@ class Database
$dql->select('format') $dql->select('format')
->from(Format::class, 'format', 'format.prefix'); ->from(Format::class, 'format', 'format.prefix');
if (isset($identifier)) { if (isset($identifier)) {
$dql->innerJoin( $dql->innerJoin(Record::class, 'record')
'format.records', ->where(
'record',
'WITH',
$dql->expr()->andX( $dql->expr()->andX(
$dql->expr()->eq('record.identifier', ':identifier'), $dql->expr()->eq('record.identifier', ':identifier'),
$dql->expr()->isNotNull('record.content') $dql->expr()->isNotNull('record.content')
@ -451,14 +436,12 @@ class Database
/** /**
* Remove metadata format and all associated records. * Remove metadata format and all associated records.
* *
* @param string $prefix The metadata prefix * @param Format $format The metadata format
* *
* @return bool TRUE on success or FALSE on failure * @return void
*/ */
public function removeMetadataFormat(string $prefix): bool public function removeMetadataFormat(Format $format): void
{ {
$format = $this->entityManager->find(Format::class, $prefix);
if (isset($format)) {
$repository = $this->entityManager->getRepository(Record::class); $repository = $this->entityManager->getRepository(Record::class);
$criteria = Criteria::create()->where(Criteria::expr()->eq('format', $format)); $criteria = Criteria::create()->where(Criteria::expr()->eq('format', $format));
$records = $repository->matching($criteria); $records = $repository->matching($criteria);
@ -468,10 +451,6 @@ class Database
$this->entityManager->remove($format); $this->entityManager->remove($format);
$this->entityManager->flush(); $this->entityManager->flush();
$this->pruneOrphanSets(); $this->pruneOrphanSets();
return true;
} else {
return false;
}
} }
/** /**

View File

@ -51,7 +51,7 @@ class Record
* The associated format. * The associated format.
*/ */
#[ORM\Id] #[ORM\Id]
#[ORM\ManyToOne(targetEntity: Format::class, inversedBy: 'records')] #[ORM\ManyToOne(targetEntity: Format::class)]
#[ORM\JoinColumn(name: 'format', referencedColumnName: 'prefix')] #[ORM\JoinColumn(name: 'format', referencedColumnName: 'prefix')]
private Format $format; private Format $format;
@ -72,7 +72,7 @@ class Record
* *
* @var Collection<string, Set> * @var Collection<string, Set>
*/ */
#[ORM\ManyToMany(targetEntity: Set::class, inversedBy: 'records', indexBy: 'spec')] #[ORM\ManyToMany(targetEntity: Set::class, inversedBy: 'records', indexBy: 'spec', cascade: ['persist'])]
#[ORM\JoinTable(name: 'records_sets')] #[ORM\JoinTable(name: 'records_sets')]
#[ORM\JoinColumn(name: 'record_identifier', referencedColumnName: 'identifier')] #[ORM\JoinColumn(name: 'record_identifier', referencedColumnName: 'identifier')]
#[ORM\JoinColumn(name: 'record_format', referencedColumnName: 'format')] #[ORM\JoinColumn(name: 'record_format', referencedColumnName: 'format')]
@ -184,7 +184,6 @@ class Record
public function setContent(?string $data = null, bool $validate = true): void public function setContent(?string $data = null, bool $validate = true): void
{ {
if (isset($data)) { if (isset($data)) {
$data = trim($data);
if ($validate) { if ($validate) {
try { try {
$data = $this->validate($data); $data = $this->validate($data);
@ -234,11 +233,13 @@ class Record
*/ */
protected function validate(string $xml): string protected function validate(string $xml): string
{ {
$xml = trim($xml);
$validator = Validation::createValidator(); $validator = Validation::createValidator();
$violations = $validator->validate( $violations = $validator->validate(
$xml, $xml,
[ [
new Assert\Type('string'), new Assert\Type('string'),
// TODO: Validate well-formed XML.
new Assert\NotBlank() new Assert\NotBlank()
] ]
); );