implement update case for SaveEntity

master
Josha von Gizycki 2 days ago
parent 21a93966d7
commit 8d86f09feb

@ -21,4 +21,12 @@ readonly class EntityResult
public array $fields, public array $fields,
public EntityField $idField public EntityField $idField
) {} ) {}
/**
* @return list<EntityField>
*/
public function fieldsWithoutId(): array
{
return array_filter($this->fields, static fn(EntityField $field) => !$field->isIdField);
}
} }

@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace Kartierung\Repository\ResolutionStrategy\Execution;
use Kartierung\Analyze\Result\EntityField;
use Kartierung\Analyze\Result\EntityResult;
use Kartierung\Repository\InvalidCall;
use PDO;
readonly class UpdateEntity
{
public function __construct(
private PDO $pdo
) {}
/**
* @param EntityResult<object> $entityResult
* @param array<string, mixed> $data
* @return object
*/
public function update(EntityResult $entityResult, array $data): object
{
$pairs = implode(', ', array_map(
static fn(EntityField $field) => "$field->columnName = ?",
$entityResult->fieldsWithoutId()
));
$idWhere = $entityResult->idField->columnName . ' = ?';
$params = array_map(
static fn(EntityField $field) => $data[$field->columnName] ?? null,
$entityResult->fieldsWithoutId()
);
$id = $data[$entityResult->idField->columnName] ?? null;
$params[] = $id;
// reindex keys for pdo
$params = array_values($params);
$sql = "UPDATE $entityResult->tableName SET $pairs WHERE $idWhere";
$prepStmt = $this->pdo->prepare($sql);
$success = $prepStmt->execute($params);
if (!$success) {
throw new InvalidCall(
"Database reports failed updated statement."
);
}
$rows = $prepStmt->rowCount();
if ($rows !== 1) {
throw new InvalidCall(
"Database returns $rows affected. Exactly 1 expected."
);
}
$entity = (new SelectEntityById($this->pdo))->select($entityResult, $id);
if (!$entity) {
throw new InvalidCall(
"Entity of type $entityResult->classFqcn with id $id can not be selected."
);
}
return $entity;
}
}

@ -10,6 +10,7 @@ use Kartierung\Analyze\Result\RepositoryMethod;
use Kartierung\Analyze\Result\RepositoryMethodParameter; use Kartierung\Analyze\Result\RepositoryMethodParameter;
use Kartierung\Repository\InvalidCall; use Kartierung\Repository\InvalidCall;
use Kartierung\Repository\ResolutionStrategy\Execution\InsertEntity; use Kartierung\Repository\ResolutionStrategy\Execution\InsertEntity;
use Kartierung\Repository\ResolutionStrategy\Execution\UpdateEntity;
use Kartierung\Sql\LazyQuery; use Kartierung\Sql\LazyQuery;
use PDO; use PDO;
@ -18,7 +19,7 @@ class SaveEntity implements ResolutionStrategy
public function createQuery(RepositoryMethod $method, array $parameters): LazyQuery public function createQuery(RepositoryMethod $method, array $parameters): LazyQuery
{ {
return new LazyQuery( return new LazyQuery(
function (PDO $pdo) use ($method, $parameters): object|int { function (PDO $pdo) use ($method, $parameters): object {
/** @var RepositoryMethodParameter $firstDeclaredParam */ /** @var RepositoryMethodParameter $firstDeclaredParam */
$firstDeclaredParam = array_first($method->parameters); $firstDeclaredParam = array_first($method->parameters);
/** @var object $firstParam */ /** @var object $firstParam */
@ -39,7 +40,7 @@ class SaveEntity implements ResolutionStrategy
$entityData = (new EntityToDataMapper())->byColumnName($entityResult, $firstParam); $entityData = (new EntityToDataMapper())->byColumnName($entityResult, $firstParam);
if ($this->hasIdValue($entityResult, $entityData)) { if ($this->hasIdValue($entityResult, $entityData)) {
return $this->update(); return $this->update($pdo, $entityResult, $entityData);
} }
return $this->insert($pdo, $entityResult, $entityData); return $this->insert($pdo, $entityResult, $entityData);
@ -47,9 +48,15 @@ class SaveEntity implements ResolutionStrategy
); );
} }
private function update(): int /**
* @param PDO $pdo
* @param EntityResult<object> $entityResult
* @param array<string, mixed> $data
* @return object
*/
private function update(PDO $pdo, EntityResult $entityResult, array $data): object
{ {
return 0; return (new UpdateEntity($pdo))->update($entityResult, $data);
} }
/** /**

@ -7,6 +7,7 @@ namespace Kartierung\Repository\ResolutionStrategy;
use Kartierung\Analyze\Result\ParameterFunction; use Kartierung\Analyze\Result\ParameterFunction;
use Kartierung\Analyze\Result\RepositoryMethod; use Kartierung\Analyze\Result\RepositoryMethod;
use Kartierung\Analyze\Result\RepositoryMethodParameter; use Kartierung\Analyze\Result\RepositoryMethodParameter;
use PDO;
use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\Group;
class SaveEntityTest extends SqliteBaseCase class SaveEntityTest extends SqliteBaseCase
@ -29,7 +30,7 @@ class SaveEntityTest extends SqliteBaseCase
} }
#[Group('integration')] #[Group('integration')]
public function testSelectsData(): void public function testCreatesNewEntity(): void
{ {
// Given // Given
$strategy = new SaveEntity(); $strategy = new SaveEntity();
@ -57,6 +58,51 @@ class SaveEntityTest extends SqliteBaseCase
// Then // Then
$this->assertInstanceOf(SimpleEntity::class, $result); $this->assertInstanceOf(SimpleEntity::class, $result);
$this->assertNotNull($result->intcol); $this->assertNotNull($result->intcol);
$this->assertNotSame($result, $entity);
$stmt = $this->getPdo()->query("SELECT COUNT(*) c FROM SimpleEntity");
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$this->assertEquals(3, $row['c'], 'Three rows expected');
}
#[Group('integration')]
public function testUpdatesEntity(): void
{
// Given
$strategy = new SaveEntity();
$method = new RepositoryMethod(
query: '',
returnType: '',
returnsNullable: true,
returnListType: '',
name: '',
parameters: [
new RepositoryMethodParameter(
name: '',
type: SimpleEntity::class,
function: ParameterFunction::STATEMENT_PARAMETER
)
],
resolutionStrategy: $strategy
);
$entity = new SimpleEntity(1, 'foobar');
$query = $method->createQuery([$entity]);
// When
$result = $query->execute($this->getPdo());
// Then
$this->assertInstanceOf(SimpleEntity::class, $result);
$this->assertNotSame($result, $entity);
$this->assertEquals($entity, $result);
$stmt = $this->getPdo()->query("SELECT COUNT(*) c FROM SimpleEntity");
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$this->assertEquals(2, $row['c'], 'Three rows expected');
$stmt = $this->getPdo()->query('SELECT stringcol c FROM SimpleEntity WHERE intcol = 1');
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$this->assertEquals('foobar', $row['c']);
} }
} }

Loading…
Cancel
Save