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

@ -14,7 +14,7 @@ use PDOStatement;
readonly class FindAll implements ResolutionStrategy 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 { return new LazyQuery(function (PDO $pdo) use ($method): array {
/** @var class-string $entityFqcn */ /** @var class-string $entityFqcn */

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

@ -14,5 +14,5 @@ interface ResolutionStrategy
* @param array<string, mixed> $parameters * @param array<string, mixed> $parameters
* @return LazyQuery * @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 class SaveEntity implements ResolutionStrategy
{ {
public function execute(RepositoryMethod $method, array $parameters): LazyQuery public function createQuery(RepositoryMethod $method, array $parameters): LazyQuery
{ {
return new LazyQuery( return new LazyQuery(
function (PDO $pdo) { function (PDO $pdo) {

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

@ -10,9 +10,14 @@ use PDO;
readonly class LazyQuery readonly class LazyQuery
{ {
/** /**
* @param (Closure(PDO): mixed) $execute * @param (Closure(PDO): mixed) $queryCall
*/ */
public function __construct( 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\ArrayType;
use Kartierung\Analyze\Result\Type\PrimitiveType; use Kartierung\Analyze\Result\Type\PrimitiveType;
use Kartierung\FullEntity; use Kartierung\FullEntity;
use Kartierung\PropertyPropagatedEntity;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
class EntityAnalyzerTest extends TestCase class EntityAnalyzerTest extends TestCase
@ -22,7 +21,7 @@ class EntityAnalyzerTest extends TestCase
$entity = FullEntity::class; $entity = FullEntity::class;
// When // When
$result = (new EntityAnalyzer(FullEntity::class))->analyze(); $result = (new EntityAnalyzer($entity))->analyze();
// Then // Then
$this->assertEquals('simple-table', $result->tableName); $this->assertEquals('simple-table', $result->tableName);

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

Loading…
Cancel
Save