Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions src/Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
use function iterator_to_array;

/** Maps objects to database operations */
final class Mapper extends AbstractMapper
class Mapper extends AbstractMapper
{
public readonly Db $db;

Expand Down Expand Up @@ -168,7 +168,7 @@ private function rawDelete(
$condition = $this->guessCondition($columns, $scope);

return $this->db
->deleteFrom($scope->name)
->deleteFrom($this->style->realName($scope->name))
->where($condition)
->exec();
}
Expand All @@ -179,7 +179,7 @@ private function rawUpdate(array $columns, Scope $scope): bool
$condition = $this->guessCondition($columns, $scope);

return $this->db
->update($scope->name)
->update($this->style->realName($scope->name))
->set($columns)
->where($condition)
->exec();
Expand All @@ -192,7 +192,7 @@ private function rawInsert(
object|null $entity = null,
): bool {
$result = $this->db
->insertInto($scope->name, array_keys($columns))
->insertInto($this->style->realName($scope->name), array_keys($columns))
->values(array_values($columns))
->exec();

Expand Down Expand Up @@ -362,18 +362,21 @@ private function parseScope(

//No parent scope means it's the first table in the query
if ($parentAlias === null) {
$sql->from($entity);
$sql->from($s->realName($entity));
if ($s->realName($entity) !== $alias) {
$sql->as($alias);
}

return;
}

if ($scope->required) {
$sql->innerJoin($entity);
$sql->innerJoin($s->realName($entity));
} else {
$sql->leftJoin($entity);
$sql->leftJoin($s->realName($entity));
}

if ($alias !== $entity) {
if ($s->realName($entity) !== $alias) {
$sql->as($alias);
}

Expand All @@ -396,9 +399,10 @@ private function isCompositionJoin(Scope $scope, string $entity, string $parent)
foreach ($scope->with as $child) {
$connected = $child->name;

$table = $this->style->realName($entity);
if (
$entity === $this->style->composed($parent, $connected)
|| $entity === $this->style->composed($connected, $parent)
$table === $this->style->composed($parent, $connected)
|| $table === $this->style->composed($connected, $parent)
) {
return true;
}
Expand Down
17 changes: 15 additions & 2 deletions tests/MapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ public function testNtoN(): void
{
$mapper = $this->mapper;
$comments = $mapper->fetchAll($mapper->comment([
$mapper->post([$mapper->post_category([$mapper->category(filter: 2)])]),
$mapper->post([$mapper->postCategory([$mapper->category(filter: 2)])]),
]));
$comment = current($comments);
$this->assertEquals(1, count($comments));
Expand All @@ -379,11 +379,24 @@ public function testNtoN(): void
public function testManyToManyReverse(): void
{
$mapper = $this->mapper;
$cat = $mapper->fetch($mapper->category([$mapper->post_category([$mapper->post(filter: 5)])]));
$cat = $mapper->fetch($mapper->category([$mapper->postCategory([$mapper->post(filter: 5)])]));
$this->assertEquals(2, $cat->id);
$this->assertEquals('Sample Category', $cat->name);
}

public function testFetchMultiWordEntityAsRoot(): void
{
// A multi-word root scope (postCategory → table post_category) must emit
// `FROM post_category AS postCategory`: realName differs from the PHP
// alias, so the root needs its own AS just like joined tables do.
$mapper = $this->mapper;
$junction = $mapper->fetch($mapper->postCategory(filter: 66));
// The fetch succeeding at all proves the alias was emitted: without the
// root AS the query would be `FROM post_category` while SELECT references
// an undefined `postCategory.id`.
$this->assertEquals(66, $junction->id);
}

public function testSimplePersist(): void
{
$mapper = $this->mapper;
Expand Down
Loading