|
|
|
|
@ -4,52 +4,55 @@ declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
namespace Kartierung\Repository;
|
|
|
|
|
|
|
|
|
|
use Kartierung\Analyze\Exception\InvalidRepository;
|
|
|
|
|
use Kartierung\Attribute\Query;
|
|
|
|
|
use ReflectionClass;
|
|
|
|
|
use Kartierung\Analyze\RepositoryAnalyzer;
|
|
|
|
|
use Kartierung\Analyze\Result\RepositoryResult;
|
|
|
|
|
use Kartierung\Repository\ResolutionStrategy\ResolutionStrategyFactory;
|
|
|
|
|
use PDO;
|
|
|
|
|
|
|
|
|
|
class Repository
|
|
|
|
|
readonly class Repository
|
|
|
|
|
{
|
|
|
|
|
public function __construct(
|
|
|
|
|
private PDO $pdo
|
|
|
|
|
) {}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @template R of object
|
|
|
|
|
* @param class-string<R> $clazz
|
|
|
|
|
* @return R
|
|
|
|
|
* @noinspection PhpDocMissingThrowsInspection
|
|
|
|
|
*/
|
|
|
|
|
public function ofType(string $clazz): object
|
|
|
|
|
{
|
|
|
|
|
/** @noinspection PhpUnhandledExceptionInspection */
|
|
|
|
|
$refClass = new ReflectionClass($clazz);
|
|
|
|
|
$resolutionStrategyFactory = new ResolutionStrategyFactory();
|
|
|
|
|
$repoResult = (new RepositoryAnalyzer($resolutionStrategyFactory))->analyze($clazz);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var R of object
|
|
|
|
|
* @phpstan-ignore varTag.nativeType
|
|
|
|
|
*/
|
|
|
|
|
return new class($refClass) {
|
|
|
|
|
/**
|
|
|
|
|
* @param ReflectionClass<R> $refClass
|
|
|
|
|
*/
|
|
|
|
|
return new class($repoResult, $this->pdo) {
|
|
|
|
|
public function __construct(
|
|
|
|
|
private readonly ReflectionClass $refClass
|
|
|
|
|
private readonly RepositoryResult $repoResult,
|
|
|
|
|
private readonly PDO $pdo
|
|
|
|
|
) {}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $name
|
|
|
|
|
* @param string $methodName
|
|
|
|
|
* @param list<mixed> $arguments
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
|
|
|
|
public function __call(string $name, array $arguments): mixed
|
|
|
|
|
public function __call(string $methodName, array $arguments): mixed
|
|
|
|
|
{
|
|
|
|
|
$method = $this->refClass->getMethod($name);
|
|
|
|
|
$queryAttr = $method->getAttributes(Query::class);
|
|
|
|
|
$repoMethod = $this->repoResult->methods[$methodName];
|
|
|
|
|
|
|
|
|
|
if (count($queryAttr) !== 1) {
|
|
|
|
|
throw new InvalidRepository(
|
|
|
|
|
"Called method $name has an invalid number of Query attributes. Expected: 1"
|
|
|
|
|
);
|
|
|
|
|
$argCount = 0;
|
|
|
|
|
$callParams = [];
|
|
|
|
|
foreach ($repoMethod->parameters as $parameter) {
|
|
|
|
|
$callParams[$parameter->name] = $arguments[$argCount++];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return '';
|
|
|
|
|
$query = $repoMethod->createQuery($callParams);
|
|
|
|
|
|
|
|
|
|
return $query->execute($this->pdo);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|