From ec7f72cbe4211dbddae66819803631d26793057d Mon Sep 17 00:00:00 2001 From: Sebastian Meyer Date: Sat, 6 Jan 2024 17:12:01 +0100 Subject: [PATCH] Handle records as entities --- src/Console/CsvImportCommand.php | 29 ++++++++++++------ src/Database.php | 50 ++++++++++++-------------------- src/Database/Record.php | 12 +++++++- 3 files changed, 49 insertions(+), 42 deletions(-) diff --git a/src/Console/CsvImportCommand.php b/src/Console/CsvImportCommand.php index 6a3f2bc..86c7dc1 100644 --- a/src/Console/CsvImportCommand.php +++ b/src/Console/CsvImportCommand.php @@ -95,6 +95,13 @@ class CsvImportCommand extends Command 'Name of the CSV column which holds the records\' sets list.', 'sets' ); + $this->addOption( + 'noValidation', + null, + InputOption::VALUE_NONE, + 'Omit content validation (improves performance for large record sets).', + false + ); parent::configure(); } @@ -117,6 +124,8 @@ class CsvImportCommand extends Command $arguments = $input->getArguments(); /** @var Format */ $format = Database::getInstance()->getEntityManager()->getReference(Format::class, $arguments['format']); + /** @var bool */ + $noValidation = $input->getOption('noValidation'); /** @var resource */ $file = fopen($arguments['file'], 'r'); @@ -129,23 +138,25 @@ class CsvImportCommand extends Command $progressIndicator = new ProgressIndicator($output, 'verbose', 200, ['⠏', '⠛', '⠹', '⢸', '⣰', '⣤', '⣆', '⡇']); $progressIndicator->start('Importing...'); - while ($record = fgetcsv($file)) { - Database::getInstance()->addOrUpdateRecord( - $record[$columns['idColumn']], + while ($row = fgetcsv($file)) { + $record = new Record( + $row[$columns['idColumn']], $format, - trim($record[$columns['contentColumn']]), - new DateTime($record[$columns['dateColumn']] ?? 'now'), - // TODO: Complete support for sets. - /* $record[$columns['setColumn']] ?? */ null, - true + null, + new DateTime($row[$columns['dateColumn']] ?? 'now') ); + if (strlen(trim($row[$columns['contentColumn']])) > 0) { + $record->setContent($row[$columns['contentColumn']], !$noValidation); + } + // TODO: Complete support for sets. + Database::getInstance()->addOrUpdateRecord($record, true); ++$count; $progressIndicator->advance(); $progressIndicator->setMessage((string) $count . ' done.'); // Flush to database if memory usage reaches 90% of available limit. - if (memory_get_usage() / $memoryLimit > 0.9) { + if ((memory_get_usage() / $memoryLimit) > 0.9) { Database::getInstance()->flush([Record::class]); } } diff --git a/src/Database.php b/src/Database.php index 7b54da3..c76c459 100644 --- a/src/Database.php +++ b/src/Database.php @@ -92,46 +92,32 @@ class Database /** * Add or update record. * - * @param string $identifier The record identifier - * @param Format $format The metadata prefix - * @param ?string $data The record's content - * @param ?DateTime $lastChanged The date of last change - * @param ?array $sets The record's associated sets + * @param Record $newRecord The record * @param bool $bulkMode Should we operate in bulk mode (no flush)? * * @return void */ - public function addOrUpdateRecord( - string $identifier, - Format $format, - ?string $data = null, - ?DateTime $lastChanged = null, - // TODO: Complete support for sets - ?array $sets, - bool $bulkMode = false - ): void + public function addOrUpdateRecord(Record $newRecord, bool $bulkMode = false): void { - $record = $this->entityManager->find(Record::class, ['identifier' => $identifier, 'format' => $format]); - if (!isset($data) && Configuration::getInstance()->deletedRecords === 'no') { - if (isset($record)) { - $this->entityManager->remove($record); + $oldRecord = $this->entityManager->find( + Record::class, + [ + 'identifier' => $newRecord->getIdentifier(), + 'format' => $newRecord->getFormat() + ] + ); + if (isset($oldRecord)) { + if ($newRecord->hasContent() || Configuration::getInstance()->deletedRecords !== 'no') { + $oldRecord->setContent($newRecord->getContent(), false); + $oldRecord->setLastChanged($newRecord->getLastChanged()); + // TODO: Add full set support. + } else { + $this->entityManager->remove($oldRecord); } } else { - if (isset($record)) { - try { - $record->setContent($data); - $record->setLastChanged($lastChanged); - } catch (ValidationFailedException $exception) { - throw $exception; - } - } else { - try { - $record = new Record($identifier, $format, $data, $lastChanged); - } catch (ValidationFailedException $exception) { - throw $exception; - } + if ($newRecord->hasContent() || Configuration::getInstance()->deletedRecords !== 'no') { + $this->entityManager->persist($newRecord); } - $this->entityManager->persist($record); } if (!$bulkMode) { $this->entityManager->flush(); diff --git a/src/Database/Record.php b/src/Database/Record.php index 4c8e0b0..61fa726 100644 --- a/src/Database/Record.php +++ b/src/Database/Record.php @@ -156,6 +156,16 @@ class Record return $this->sets->toArray(); } + /** + * Whether this record has any content. + * + * @return bool TRUE if content exists, FALSE otherwise + */ + public function hasContent(): bool + { + return isset($this->content); + } + /** * Remove record from set. * @@ -184,6 +194,7 @@ class Record public function setContent(?string $data = null, bool $validate = true): void { if (isset($data)) { + $data = trim($data); if ($validate) { try { $data = $this->validate($data); @@ -233,7 +244,6 @@ class Record */ protected function validate(string $xml): string { - $xml = trim($xml); $validator = Validation::createValidator(); $violations = $validator->validate( $xml,