add guid to episode action and make it findable by it
This commit is contained in:
parent
ae27f7cf34
commit
850dfd5eb4
@ -33,7 +33,7 @@ class EpisodeActionSaver
|
|||||||
*
|
*
|
||||||
* @return EpisodeActionEntity[]
|
* @return EpisodeActionEntity[]
|
||||||
*/
|
*/
|
||||||
public function saveEpisodeAction($data, string $userId): array
|
public function saveEpisodeAction(string $data, string $userId): array
|
||||||
{
|
{
|
||||||
$episodeActionEntities = [];
|
$episodeActionEntities = [];
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ class EpisodeActionSaver
|
|||||||
string $userId
|
string $userId
|
||||||
): EpisodeActionEntity
|
): EpisodeActionEntity
|
||||||
{
|
{
|
||||||
$idEpisodeActionEntityToUpdate = $this->episodeActionRepository->findByEpisode(
|
$idEpisodeActionEntityToUpdate = $this->episodeActionRepository->findByEpisodeIdentifier(
|
||||||
$episodeActionEntity->getEpisode(),
|
$episodeActionEntity->getEpisode(),
|
||||||
$userId
|
$userId
|
||||||
)->getId();
|
)->getId();
|
||||||
|
@ -15,6 +15,7 @@ class EpisodeActionEntity extends Entity implements JsonSerializable {
|
|||||||
protected $started;
|
protected $started;
|
||||||
protected $total;
|
protected $total;
|
||||||
protected $timestamp;
|
protected $timestamp;
|
||||||
|
protected $guid;
|
||||||
protected $userId;
|
protected $userId;
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
@ -26,6 +27,7 @@ class EpisodeActionEntity extends Entity implements JsonSerializable {
|
|||||||
'id' => $this->id,
|
'id' => $this->id,
|
||||||
'podcast' => $this->podcast,
|
'podcast' => $this->podcast,
|
||||||
'episode' => $this->episode,
|
'episode' => $this->episode,
|
||||||
|
'guid' => $this->guid,
|
||||||
'action' => $this->action,
|
'action' => $this->action,
|
||||||
'position' => $this->position,
|
'position' => $this->position,
|
||||||
'started' => $this->started,
|
'started' => $this->started,
|
||||||
|
@ -8,12 +8,15 @@ use OCP\AppFramework\Db\MultipleObjectsReturnedException;
|
|||||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||||
use OCP\IDBConnection;
|
use OCP\IDBConnection;
|
||||||
|
|
||||||
class EpisodeActionMapper extends \OCP\AppFramework\Db\QBMapper {
|
class EpisodeActionMapper extends \OCP\AppFramework\Db\QBMapper
|
||||||
public function __construct(IDBConnection $db) {
|
{
|
||||||
|
public function __construct(IDBConnection $db)
|
||||||
|
{
|
||||||
parent::__construct($db, 'gpodder_episode_action', EpisodeActionEntity::class);
|
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 = $this->db->getQueryBuilder();
|
||||||
|
|
||||||
$qb->select('*')
|
$qb->select('*')
|
||||||
@ -21,28 +24,34 @@ class EpisodeActionMapper extends \OCP\AppFramework\Db\QBMapper {
|
|||||||
->where(
|
->where(
|
||||||
$qb->expr()->gt('timestamp', $qb->createNamedParameter($sinceTimestamp, IQueryBuilder::PARAM_DATE))
|
$qb->expr()->gt('timestamp', $qb->createNamedParameter($sinceTimestamp, IQueryBuilder::PARAM_DATE))
|
||||||
)
|
)
|
||||||
->andWhere(
|
->andWhere(
|
||||||
$qb->expr()->eq('user_id', $qb->createNamedParameter($userId))
|
$qb->expr()->eq('user_id', $qb->createNamedParameter($userId))
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->findEntities($qb);
|
return $this->findEntities($qb);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function findByEpisode(string $episode, string $userId) {
|
public function findByEpisodeIdentifier(string $episodeIdentifier, string $userId) : EpisodeActionEntity
|
||||||
|
{
|
||||||
$qb = $this->db->getQueryBuilder();
|
$qb = $this->db->getQueryBuilder();
|
||||||
|
|
||||||
$qb->select('*')
|
$qb->select('*')
|
||||||
->from($this->getTableName())
|
->from($this->getTableName())
|
||||||
->where(
|
->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(
|
->andWhere(
|
||||||
$qb->expr()->eq('user_id', $qb->createNamedParameter($userId))
|
$qb->expr()->eq('user_id', $qb->createNamedParameter($userId))
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return $this->findEntity($qb);
|
/** @var EpisodeActionEntity $episodeActionEntity*/
|
||||||
|
$episodeActionEntity = $this->findEntity($qb);
|
||||||
|
|
||||||
|
return $episodeActionEntity;
|
||||||
} catch (DoesNotExistException $e) {
|
} catch (DoesNotExistException $e) {
|
||||||
} catch (MultipleObjectsReturnedException $e) {
|
} catch (MultipleObjectsReturnedException $e) {
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,8 @@ class EpisodeActionRepository {
|
|||||||
return $this->episodeActionMapper->findAll($sinceTimestamp, $userId);
|
return $this->episodeActionMapper->findAll($sinceTimestamp, $userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function findByEpisode(string $episode, string $userId): EpisodeActionEntity {
|
public function findByEpisodeIdentifier(string $identifier, string $userId): EpisodeActionEntity {
|
||||||
return $this->episodeActionMapper->findByEpisode($episode, $userId);
|
return $this->episodeActionMapper->findByEpisodeIdentifier($identifier, $userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace OCA\GPodderSync\Db\EpisodeAction;
|
namespace OCA\GPodderSync\Db\EpisodeAction;
|
||||||
|
|
||||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
|
||||||
|
|
||||||
class EpisodeActionWriter {
|
class EpisodeActionWriter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
27
lib/Migration/Version0004Date20210823115513.php
Normal file
27
lib/Migration/Version0004Date20210823115513.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace OCA\GPodderSync\Migration;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Doctrine\DBAL\Types\StringType;
|
||||||
|
use Doctrine\DBAL\Types\Types;
|
||||||
|
use OCP\DB\ISchemaWrapper;
|
||||||
|
use OCP\Migration\IOutput;
|
||||||
|
|
||||||
|
class Version0004Date20210823115513 extends \OCP\Migration\SimpleMigrationStep {
|
||||||
|
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
|
||||||
|
/** @var ISchemaWrapper $schema */
|
||||||
|
$schema = $schemaClosure();
|
||||||
|
|
||||||
|
$table = $schema->getTable('gpodder_episode_action');
|
||||||
|
$table->addColumn('guid', Types::STRING, [
|
||||||
|
'length' => 500,
|
||||||
|
'notnull' => false
|
||||||
|
]);
|
||||||
|
|
||||||
|
$table->addUniqueIndex(['guid', 'user_id'], 'gpodder_guid_user_id');
|
||||||
|
|
||||||
|
return $schema;
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,9 @@ declare(strict_types=1);
|
|||||||
namespace tests\Integration;
|
namespace tests\Integration;
|
||||||
|
|
||||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
||||||
|
use OCA\GPodderSync\Core\EpisodeAction\EpisodeActionReader;
|
||||||
use OCA\GPodderSync\Db\EpisodeAction\EpisodeActionEntity;
|
use OCA\GPodderSync\Db\EpisodeAction\EpisodeActionEntity;
|
||||||
|
use OCA\GPodderSync\Db\EpisodeAction\EpisodeActionRepository;
|
||||||
use OCA\GPodderSync\Db\EpisodeAction\EpisodeActionWriter;
|
use OCA\GPodderSync\Db\EpisodeAction\EpisodeActionWriter;
|
||||||
use OCP\AppFramework\App;
|
use OCP\AppFramework\App;
|
||||||
use Test\TestCase;
|
use Test\TestCase;
|
||||||
@ -17,12 +19,20 @@ class EpisodeActionGuidMigrationTest extends TestCase
|
|||||||
{
|
{
|
||||||
use DatabaseTransaction;
|
use DatabaseTransaction;
|
||||||
|
|
||||||
|
private const USER_ID_0 = "user0@127.0.0.1";
|
||||||
|
|
||||||
private \OCP\AppFramework\IAppContainer $container;
|
private \OCP\AppFramework\IAppContainer $container;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var EpisodeActionWriter
|
||||||
|
*/
|
||||||
|
private $episodeActionWriter;
|
||||||
|
|
||||||
public function setUp(): void {
|
public function setUp(): void {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
$app = new App('gpoddersync');
|
$app = new App('gpoddersync');
|
||||||
$this->container = $app->getContainer();
|
$this->container = $app->getContainer();
|
||||||
|
$this->episodeActionWriter = $this->container->get(EpisodeActionWriter::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,9 +47,6 @@ class EpisodeActionGuidMigrationTest extends TestCase
|
|||||||
{
|
{
|
||||||
self::expectException(UniqueConstraintViolationException::class);
|
self::expectException(UniqueConstraintViolationException::class);
|
||||||
|
|
||||||
/** @var EpisodeActionWriter $episodeActionWriter */
|
|
||||||
$episodeActionWriter = $this->container->get('OCA\GPodderSync\Db\EpisodeAction\EpisodeActionWriter');
|
|
||||||
|
|
||||||
$episodeActionEntity = new EpisodeActionEntity();
|
$episodeActionEntity = new EpisodeActionEntity();
|
||||||
$episodeActionEntity->setPodcast("https://podcast_01.url");
|
$episodeActionEntity->setPodcast("https://podcast_01.url");
|
||||||
$episodeActionEntity->setEpisode("https://episode_01.url");
|
$episodeActionEntity->setEpisode("https://episode_01.url");
|
||||||
@ -48,10 +55,50 @@ class EpisodeActionGuidMigrationTest extends TestCase
|
|||||||
$episodeActionEntity->setStarted(0);
|
$episodeActionEntity->setStarted(0);
|
||||||
$episodeActionEntity->setTotal(123);
|
$episodeActionEntity->setTotal(123);
|
||||||
$episodeActionEntity->setTimestamp("Mon Aug 23 01:58:56 GMT+02:00 2021");
|
$episodeActionEntity->setTimestamp("Mon Aug 23 01:58:56 GMT+02:00 2021");
|
||||||
$episodeActionEntity->setUserId("user0@127.0.0.1");
|
$episodeActionEntity->setUserId(self::USER_ID_0);
|
||||||
$episodeActionWriter->save($episodeActionEntity);
|
$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()
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user