tie together Repository factory class and execution of queries

master
Josha von Gizycki 2 weeks ago
parent 94f5bcb2a1
commit 3a5a4c7a5c

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Kartierung\Analyze\Result;
use Kartierung\Repository\ResolutionStrategy\ResolutionStrategy;
use Kartierung\Sql\LazyQuery;
readonly class RepositoryMethod
{
@ -25,4 +26,12 @@ readonly class RepositoryMethod
{
return str_starts_with($this->returnType, '?');
}
/**
* @param array<string, mixed> $parameters
*/
public function createQuery(array $parameters): LazyQuery
{
return $this->resolutionStrategy->createQuery($this, $parameters);
}
}

@ -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);
}
};
}

@ -10,7 +10,7 @@ use PDO;
class DeleteEntity implements ResolutionStrategy
{
public function execute(RepositoryMethod $method, array $parameters): LazyQuery
public function createQuery(RepositoryMethod $method, array $parameters): LazyQuery
{
return new LazyQuery(
function (PDO $pdo) {

@ -14,7 +14,7 @@ use PDOStatement;
readonly class FindAll implements ResolutionStrategy
{
public function execute(RepositoryMethod $method, array $parameters): LazyQuery
public function createQuery(RepositoryMethod $method, array $parameters): LazyQuery
{
return new LazyQuery(function (PDO $pdo) use ($method): array {
/** @var class-string $entityFqcn */

@ -10,7 +10,7 @@ use PDO;
class FindById implements ResolutionStrategy
{
public function execute(RepositoryMethod $method, array $parameters): LazyQuery
public function createQuery(RepositoryMethod $method, array $parameters): LazyQuery
{
return new LazyQuery(
function (PDO $pdo) {

@ -14,5 +14,5 @@ interface ResolutionStrategy
* @param array<string, mixed> $parameters
* @return LazyQuery
*/
public function execute(RepositoryMethod $method, array $parameters): LazyQuery;
public function createQuery(RepositoryMethod $method, array $parameters): LazyQuery;
}

@ -10,7 +10,7 @@ use PDO;
class SaveEntity implements ResolutionStrategy
{
public function execute(RepositoryMethod $method, array $parameters): LazyQuery
public function createQuery(RepositoryMethod $method, array $parameters): LazyQuery
{
return new LazyQuery(
function (PDO $pdo) {

@ -10,7 +10,7 @@ use PDO;
class UserDefinedQuery implements ResolutionStrategy
{
public function execute(RepositoryMethod $method, array $parameters): LazyQuery
public function createQuery(RepositoryMethod $method, array $parameters): LazyQuery
{
return new LazyQuery(
function (PDO $pdo) {

@ -10,9 +10,14 @@ use PDO;
readonly class LazyQuery
{
/**
* @param (Closure(PDO): mixed) $execute
* @param (Closure(PDO): mixed) $queryCall
*/
public function __construct(
public Closure $execute
private Closure $queryCall
) {}
public function execute(PDO $pdo): mixed
{
return $this->queryCall->__invoke($pdo);
}
}

@ -11,7 +11,6 @@ use Kartierung\Analyze\Result\FieldAccess;
use Kartierung\Analyze\Result\Type\ArrayType;
use Kartierung\Analyze\Result\Type\PrimitiveType;
use Kartierung\FullEntity;
use Kartierung\PropertyPropagatedEntity;
use PHPUnit\Framework\TestCase;
class EntityAnalyzerTest extends TestCase
@ -22,7 +21,7 @@ class EntityAnalyzerTest extends TestCase
$entity = FullEntity::class;
// When
$result = (new EntityAnalyzer(FullEntity::class))->analyze();
$result = (new EntityAnalyzer($entity))->analyze();
// Then
$this->assertEquals('simple-table', $result->tableName);

@ -35,7 +35,7 @@ class FindAllTest extends TestCase
public function testSelectsData(): void
{
// Given
$query = (new FindAll())->execute(
$query = (new FindAll())->createQuery(
method: new RepositoryMethod(
query: '',
returnType: '',
@ -48,10 +48,17 @@ class FindAllTest extends TestCase
);
// When
$result = $query->execute->__invoke($this->pdo);
$result = $query->execute($this->pdo);
// Then
$this->assertNotEmpty($result);
$this->assertEquals(
[
new SimpleEntity(1, 'dings'),
new SimpleEntity(2, 'bumms')
],
$result
);
}
}

Loading…
Cancel
Save