Skip to content

Commit

Permalink
feat: initial version of basic repository (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
priyadi authored Jun 20, 2024
1 parent facd1d6 commit 2334aaf
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* refactor: rename the term 'large' to 'basic'
* cleanup: Basic classes do not require soft and hard limits
* cleanup: orderBy should be non-empty-array
* feat: initial version of basic repository

## 0.3.0

Expand Down
4 changes: 4 additions & 0 deletions packages/collections-contracts/src/BasicRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@
*/
interface BasicRepository extends BasicReadableRepository, BasicRecollection
{
/**
* @param T $element
*/
public function remove(mixed $element): void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/collections package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Contracts\Collections\Exception;

class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
178 changes: 178 additions & 0 deletions packages/collections-orm/src/AbstractBasicRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/collections package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Collections\ORM;

use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Order;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\QueryBuilder;
use Rekalogika\Collections\ORM\Trait\QueryBuilderTrait;
use Rekalogika\Contracts\Collections\BasicRepository;
use Rekalogika\Contracts\Collections\Exception\NotFoundException;
use Rekalogika\Contracts\Collections\Exception\UnexpectedValueException;
use Rekalogika\Domain\Collections\Common\Configuration;
use Rekalogika\Domain\Collections\Common\CountStrategy;
use Rekalogika\Domain\Collections\Common\Trait\PageableTrait;

/**
* @template TKey of array-key
* @template T of object
* @implements BasicRepository<TKey,T>
*/
abstract class AbstractBasicRepository implements BasicRepository
{
/**
* @use QueryBuilderTrait<array-key,T>
*/
use QueryBuilderTrait;

/**
* @use PageableTrait<array-key,T>
*/
use PageableTrait;

private QueryBuilder $queryBuilder;

private ?int $count = 0;

/**
* @var non-empty-array<string,Order>
*/
private readonly array $orderBy;

/**
* @param null|array<string,Order>|string $orderBy
* @param int<1,max> $itemsPerPage
*/
public function __construct(
private EntityManagerInterface $entityManager,
array|string|null $orderBy = null,
private readonly int $itemsPerPage = 50,
private readonly CountStrategy $countStrategy = CountStrategy::Restrict,
) {
// handle orderBy

if ($orderBy === null) {
$orderBy = Configuration::$defaultOrderBy;
}

if (\is_string($orderBy)) {
$orderBy = [$orderBy => Order::Ascending];
}

if (empty($orderBy)) {
throw new UnexpectedValueException('The order by clause cannot be empty.');
}

$this->orderBy = $orderBy;

$criteria = Criteria::create()->orderBy($orderBy);
$this->queryBuilder = $this->createQueryBuilder('e')->addCriteria($criteria);
}

/**
* @param null|array<string,Order>|string $orderBy
* @param int<1,max> $itemsPerPage
*/
protected function with(
null|EntityManagerInterface $entityManager = null,
array|string|null $orderBy = null,
?int $itemsPerPage = null,
?CountStrategy $countStrategy = null,
): static {
// @phpstan-ignore-next-line
return new static(
entityManager: $entityManager ?? $this->entityManager,
orderBy: $orderBy ?? $this->orderBy,
itemsPerPage: $itemsPerPage ?? $this->itemsPerPage,
countStrategy: $countStrategy ?? $this->countStrategy,
);
}

//
// mandatory
//

/**
* @return class-string<T>
*/
abstract protected function getClass(): string;

//
// misc
//

//
// accessors for subclasses
//

final protected function getEntityManager(): EntityManagerInterface
{
return $this->entityManager;
}

final protected function createQueryBuilder(
string $alias,
?string $indexBy = null
): QueryBuilder {
return $this->getEntityManager()->createQueryBuilder()
->select($alias)
->from($this->getClass(), $alias, $indexBy);
}

//
// interface methods
//

public function getReference(int|string $key): object
{
return $this->getEntityManager()
->getReference($this->getClass(), $key)
?? throw new NotFoundException('Entity not found');
}

public function contains(mixed $element): bool
{
if (!\is_object($element)) {
return false;
}

return $this->getEntityManager()->contains($element);
}

public function containsKey(string|int $key): bool
{
return $this->get($key) !== null;
}

public function get(string|int $key): mixed
{
return $this->getEntityManager()->find($this->getClass(), $key);
}

public function getOrFail(string|int $key): mixed
{
return $this->get($key) ?? throw new NotFoundException('Entity not found');
}

public function add(mixed $element): void
{
$this->getEntityManager()->persist($element);
}

public function remove(mixed $element): void
{
$this->getEntityManager()->remove($element);
}
}
1 change: 1 addition & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
<file name="packages/collections-domain/src/BasicCriteriaRecollection.php" />
<file name="packages/collections-orm/src/QueryCollection.php" />
<file name="packages/collections-orm/src/QueryPageable.php" />
<file name="packages/collections-orm/src/AbstractBasicRepository.php" />
</errorLevel>
</UnsafeInstantiation>
<MoreSpecificReturnType>
Expand Down

0 comments on commit 2334aaf

Please sign in to comment.