From 850dfd5eb4a60d21cbf386483860ab860b676410 Mon Sep 17 00:00:00 2001 From: thrillfall Date: Tue, 24 Aug 2021 23:19:21 +0200 Subject: [PATCH] add guid to episode action and make it findable by it --- lib/Core/EpisodeAction/EpisodeActionSaver.php | 4 +- lib/Db/EpisodeAction/EpisodeActionEntity.php | 2 + lib/Db/EpisodeAction/EpisodeActionMapper.php | 33 +++++++---- .../EpisodeAction/EpisodeActionRepository.php | 5 +- lib/Db/EpisodeAction/EpisodeActionWriter.php | 2 - .../Version0004Date20210823115513.php | 27 +++++++++ .../EpisodeActionGuidMigrationTest.php | 59 +++++++++++++++++-- 7 files changed, 108 insertions(+), 24 deletions(-) create mode 100644 lib/Migration/Version0004Date20210823115513.php diff --git a/lib/Core/EpisodeAction/EpisodeActionSaver.php b/lib/Core/EpisodeAction/EpisodeActionSaver.php index b96cb20..195723c 100644 --- a/lib/Core/EpisodeAction/EpisodeActionSaver.php +++ b/lib/Core/EpisodeAction/EpisodeActionSaver.php @@ -33,7 +33,7 @@ class EpisodeActionSaver * * @return EpisodeActionEntity[] */ - public function saveEpisodeAction($data, string $userId): array + public function saveEpisodeAction(string $data, string $userId): array { $episodeActionEntities = []; @@ -77,7 +77,7 @@ class EpisodeActionSaver string $userId ): EpisodeActionEntity { - $idEpisodeActionEntityToUpdate = $this->episodeActionRepository->findByEpisode( + $idEpisodeActionEntityToUpdate = $this->episodeActionRepository->findByEpisodeIdentifier( $episodeActionEntity->getEpisode(), $userId )->getId(); diff --git a/lib/Db/EpisodeAction/EpisodeActionEntity.php b/lib/Db/EpisodeAction/EpisodeActionEntity.php index 013a896..2540642 100644 --- a/lib/Db/EpisodeAction/EpisodeActionEntity.php +++ b/lib/Db/EpisodeAction/EpisodeActionEntity.php @@ -15,6 +15,7 @@ class EpisodeActionEntity extends Entity implements JsonSerializable { protected $started; protected $total; protected $timestamp; + protected $guid; protected $userId; public function __construct() { @@ -26,6 +27,7 @@ class EpisodeActionEntity extends Entity implements JsonSerializable { 'id' => $this->id, 'podcast' => $this->podcast, 'episode' => $this->episode, + 'guid' => $this->guid, 'action' => $this->action, 'position' => $this->position, 'started' => $this->started, diff --git a/lib/Db/EpisodeAction/EpisodeActionMapper.php b/lib/Db/EpisodeAction/EpisodeActionMapper.php index 2d502e4..51aaf21 100644 --- a/lib/Db/EpisodeAction/EpisodeActionMapper.php +++ b/lib/Db/EpisodeAction/EpisodeActionMapper.php @@ -8,12 +8,15 @@ use OCP\AppFramework\Db\MultipleObjectsReturnedException; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; -class EpisodeActionMapper extends \OCP\AppFramework\Db\QBMapper { - public function __construct(IDBConnection $db) { +class EpisodeActionMapper extends \OCP\AppFramework\Db\QBMapper +{ + public function __construct(IDBConnection $db) + { parent::__construct($db, 'gpodder_episode_action', EpisodeActionEntity::class); } - public function findAll(\DateTime $sinceTimestamp, string $userId): array { + public function findAll(\DateTime $sinceTimestamp, string $userId): array + { $qb = $this->db->getQueryBuilder(); $qb->select('*') @@ -21,28 +24,34 @@ class EpisodeActionMapper extends \OCP\AppFramework\Db\QBMapper { ->where( $qb->expr()->gt('timestamp', $qb->createNamedParameter($sinceTimestamp, IQueryBuilder::PARAM_DATE)) ) - ->andWhere( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId)) + ->andWhere( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId)) - ); + ); return $this->findEntities($qb); } - public function findByEpisode(string $episode, string $userId) { + public function findByEpisodeIdentifier(string $episodeIdentifier, string $userId) : EpisodeActionEntity + { $qb = $this->db->getQueryBuilder(); $qb->select('*') ->from($this->getTableName()) ->where( - $qb->expr()->eq('episode', $qb->createNamedParameter($episode)) + $qb->expr()->orX( + $qb->expr()->eq('episode', $qb->createNamedParameter($episodeIdentifier)), + $qb->expr()->eq('guid', $qb->createNamedParameter($episodeIdentifier))) ) - ->andWhere( - $qb->expr()->eq('user_id', $qb->createNamedParameter($userId)) - ); + ->andWhere( + $qb->expr()->eq('user_id', $qb->createNamedParameter($userId)) + ); try { - return $this->findEntity($qb); + /** @var EpisodeActionEntity $episodeActionEntity*/ + $episodeActionEntity = $this->findEntity($qb); + + return $episodeActionEntity; } catch (DoesNotExistException $e) { } catch (MultipleObjectsReturnedException $e) { } diff --git a/lib/Db/EpisodeAction/EpisodeActionRepository.php b/lib/Db/EpisodeAction/EpisodeActionRepository.php index 2d4c247..e2a5577 100644 --- a/lib/Db/EpisodeAction/EpisodeActionRepository.php +++ b/lib/Db/EpisodeAction/EpisodeActionRepository.php @@ -17,7 +17,8 @@ class EpisodeActionRepository { return $this->episodeActionMapper->findAll($sinceTimestamp, $userId); } - public function findByEpisode(string $episode, string $userId): EpisodeActionEntity { - return $this->episodeActionMapper->findByEpisode($episode, $userId); + public function findByEpisodeIdentifier(string $identifier, string $userId): EpisodeActionEntity { + return $this->episodeActionMapper->findByEpisodeIdentifier($identifier, $userId); } + } diff --git a/lib/Db/EpisodeAction/EpisodeActionWriter.php b/lib/Db/EpisodeAction/EpisodeActionWriter.php index 6624a4c..2a09f5f 100644 --- a/lib/Db/EpisodeAction/EpisodeActionWriter.php +++ b/lib/Db/EpisodeAction/EpisodeActionWriter.php @@ -3,8 +3,6 @@ declare(strict_types=1); namespace OCA\GPodderSync\Db\EpisodeAction; -use Doctrine\DBAL\Exception\UniqueConstraintViolationException; - class EpisodeActionWriter { /** diff --git a/lib/Migration/Version0004Date20210823115513.php b/lib/Migration/Version0004Date20210823115513.php new file mode 100644 index 0000000..ce9735a --- /dev/null +++ b/lib/Migration/Version0004Date20210823115513.php @@ -0,0 +1,27 @@ +getTable('gpodder_episode_action'); + $table->addColumn('guid', Types::STRING, [ + 'length' => 500, + 'notnull' => false + ]); + + $table->addUniqueIndex(['guid', 'user_id'], 'gpodder_guid_user_id'); + + return $schema; + } +} diff --git a/tests/Integration/EpisodeActionGuidMigrationTest.php b/tests/Integration/EpisodeActionGuidMigrationTest.php index 9b36cee..c06deb8 100644 --- a/tests/Integration/EpisodeActionGuidMigrationTest.php +++ b/tests/Integration/EpisodeActionGuidMigrationTest.php @@ -4,7 +4,9 @@ declare(strict_types=1); namespace tests\Integration; use Doctrine\DBAL\Exception\UniqueConstraintViolationException; +use OCA\GPodderSync\Core\EpisodeAction\EpisodeActionReader; use OCA\GPodderSync\Db\EpisodeAction\EpisodeActionEntity; +use OCA\GPodderSync\Db\EpisodeAction\EpisodeActionRepository; use OCA\GPodderSync\Db\EpisodeAction\EpisodeActionWriter; use OCP\AppFramework\App; use Test\TestCase; @@ -17,12 +19,20 @@ class EpisodeActionGuidMigrationTest extends TestCase { use DatabaseTransaction; + private const USER_ID_0 = "user0@127.0.0.1"; + private \OCP\AppFramework\IAppContainer $container; + /** + * @var EpisodeActionWriter + */ + private $episodeActionWriter; + public function setUp(): void { parent::setUp(); $app = new App('gpoddersync'); $this->container = $app->getContainer(); + $this->episodeActionWriter = $this->container->get(EpisodeActionWriter::class); } /** @@ -37,9 +47,6 @@ class EpisodeActionGuidMigrationTest extends TestCase { self::expectException(UniqueConstraintViolationException::class); - /** @var EpisodeActionWriter $episodeActionWriter */ - $episodeActionWriter = $this->container->get('OCA\GPodderSync\Db\EpisodeAction\EpisodeActionWriter'); - $episodeActionEntity = new EpisodeActionEntity(); $episodeActionEntity->setPodcast("https://podcast_01.url"); $episodeActionEntity->setEpisode("https://episode_01.url"); @@ -48,10 +55,50 @@ class EpisodeActionGuidMigrationTest extends TestCase $episodeActionEntity->setStarted(0); $episodeActionEntity->setTotal(123); $episodeActionEntity->setTimestamp("Mon Aug 23 01:58:56 GMT+02:00 2021"); - $episodeActionEntity->setUserId("user0@127.0.0.1"); - $episodeActionWriter->save($episodeActionEntity); + $episodeActionEntity->setUserId(self::USER_ID_0); + $this->episodeActionWriter->save($episodeActionEntity); - $episodeActionWriter->save($episodeActionEntity); + //and save again + $this->episodeActionWriter->save($episodeActionEntity); + + } + + public function testFindEpisodeActionByEpisodeUrlAndThenGuid() + { + $episodeActionEntity = new EpisodeActionEntity(); + $episodeActionEntity->setPodcast("https://podcast_01.url"); + $episodeActionEntity->setEpisode("https://episode_01.url"); + $episodeActionEntity->setAction("PLAY"); + $episodeActionEntity->setPosition(5); + $episodeActionEntity->setStarted(0); + $episodeActionEntity->setTotal(123); + $episodeActionEntity->setTimestamp("Mon Aug 23 01:58:56 GMT+02:00 2021"); + $episodeActionEntity->setUserId(self::USER_ID_0); + $savedEpisodeActionEntity = $this->episodeActionWriter->save($episodeActionEntity); + + /** @var EpisodeActionRepository $episodeActionRepository */ + $episodeActionRepository = $this->container->get(EpisodeActionRepository::class); + + self::assertSame( + $savedEpisodeActionEntity->getId(), + $episodeActionRepository->findByEpisodeIdentifier($episodeActionEntity->getEpisode(), self::USER_ID_0)->getId() + ); + + //update same episode action again this time with guid + + $episodeActionEntityWithGuid = clone $episodeActionEntity; + $episodeActionEntityWithGuid->setGuid("guid:dadsaf4f4v"); + $savedEpisodeActionEntityWithGuid = $this->episodeActionWriter->update($episodeActionEntityWithGuid); + + self::assertSame( + $savedEpisodeActionEntityWithGuid->getId(), + $episodeActionRepository->findByEpisodeIdentifier($episodeActionEntityWithGuid->getEpisode(), self::USER_ID_0)->getId() + ); + + self::assertSame( + $savedEpisodeActionEntityWithGuid->getId(), + $episodeActionRepository->findByEpisodeIdentifier($episodeActionEntityWithGuid->getGuid(), self::USER_ID_0)->getId() + ); }