mirror of
https://github.com/shlinkio/shlink.git
synced 2026-03-08 16:23:12 +08:00
Added locking to short URL creation when checking if URL exists
This commit is contained in:
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\Repository;
|
||||
|
||||
use Doctrine\DBAL\LockMode;
|
||||
use Doctrine\ORM\Query\Expr\Join;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository;
|
||||
@@ -11,6 +12,7 @@ use Happyr\DoctrineSpecification\Specification\Specification;
|
||||
use Shlinkio\Shlink\Common\Doctrine\Type\ChronosDateTimeType;
|
||||
use Shlinkio\Shlink\Common\Util\DateRange;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlsOrdering;
|
||||
use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl;
|
||||
@@ -180,12 +182,24 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU
|
||||
return $qb->getQuery()->getOneOrNullResult();
|
||||
}
|
||||
|
||||
public function shortCodeIsInUse(string $slug, ?string $domain = null, ?Specification $spec = null): bool
|
||||
public function shortCodeIsInUse(ShortUrlIdentifier $identifier, ?Specification $spec = null): bool
|
||||
{
|
||||
$qb = $this->createFindOneQueryBuilder($slug, $domain, $spec);
|
||||
$qb->select('COUNT(DISTINCT s.id)');
|
||||
return $this->doShortCodeIsInUse($identifier, $spec, null);
|
||||
}
|
||||
|
||||
return ((int) $qb->getQuery()->getSingleScalarResult()) > 0;
|
||||
public function shortCodeIsInUseWithLock(ShortUrlIdentifier $identifier, ?Specification $spec = null): bool
|
||||
{
|
||||
return $this->doShortCodeIsInUse($identifier, $spec, LockMode::PESSIMISTIC_WRITE);
|
||||
}
|
||||
|
||||
private function doShortCodeIsInUse(ShortUrlIdentifier $identifier, ?Specification $spec, ?int $lockMode): bool
|
||||
{
|
||||
$qb = $this->createFindOneQueryBuilder($identifier->shortCode(), $identifier->domain(), $spec);
|
||||
$qb->select('s.id');
|
||||
|
||||
$query = $qb->getQuery()->setLockMode($lockMode);
|
||||
|
||||
return $query->getOneOrNullResult() !== null;
|
||||
}
|
||||
|
||||
private function createFindOneQueryBuilder(string $slug, ?string $domain, ?Specification $spec): QueryBuilder
|
||||
|
||||
@@ -9,6 +9,7 @@ use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepositoryInterfa
|
||||
use Happyr\DoctrineSpecification\Specification\Specification;
|
||||
use Shlinkio\Shlink\Common\Util\DateRange;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlsOrdering;
|
||||
use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl;
|
||||
@@ -36,7 +37,9 @@ interface ShortUrlRepositoryInterface extends ObjectRepository, EntitySpecificat
|
||||
|
||||
public function findOne(string $shortCode, ?string $domain = null, ?Specification $spec = null): ?ShortUrl;
|
||||
|
||||
public function shortCodeIsInUse(string $slug, ?string $domain, ?Specification $spec = null): bool;
|
||||
public function shortCodeIsInUse(ShortUrlIdentifier $identifier, ?Specification $spec = null): bool;
|
||||
|
||||
public function shortCodeIsInUseWithLock(ShortUrlIdentifier $identifier, ?Specification $spec = null): bool;
|
||||
|
||||
public function findOneMatching(ShortUrlMeta $meta): ?ShortUrl;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user