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
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
},
"autoload-dev": {
"psr-4": {
"Respect\\Relational\\": "tests/"
"Respect\\Relational\\": ["tests/", "tests/Stubs/"],
"Respect\\Relational\\OtherEntity\\": "tests/Stubs/OtherEntity/"
}
},
"scripts": {
Expand Down
9 changes: 2 additions & 7 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,9 @@
<file>src/</file>
<file>tests/</file>

<rule ref="Respect">
<!-- Deferred: test files have inline stub classes and snake_case conventions -->
<exclude name="PSR1.Classes.ClassDeclaration.MultipleClasses" />
<exclude name="Squiz.Classes.ClassFileName.NoMatch" />
<exclude name="SlevomatCodingStandard.Namespaces.RequireOneNamespaceInFile.MoreNamespacesInFile" />
</rule>
<rule ref="Respect" />

<!-- Deferred: test stubs use snake_case properties matching DB columns -->
<!-- Test code and stub entities use snake_case properties matching DB columns -->
<rule ref="Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps">
<exclude-pattern>tests/</exclude-pattern>
</rule>
Expand Down
1 change: 0 additions & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ parameters:
- message: '/Access to an undefined property Respect\\Relational\\Mapper::\$\w+\./'
- message: '/Unsafe usage of new static\(\)\./'
- message: '/Cannot unset property .+ because it might have hooks in a subclass\./'
- message: '/Array has \d+ duplicate keys/'
-
message: '/Parameter #1 .+ of class Respect\\Relational\\Mapper constructor expects .+, string given\./'
path: tests/MapperTest.php
153 changes: 97 additions & 56 deletions src/Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,30 @@ public function getDb(): Db
return $this->db;
}

public function fetch(Collection $collection, mixed $extra = null): mixed
{
$statement = $this->createStatement($collection, $extra);
$hydrated = $this->fetchHydrated($collection, $statement);
if (!$hydrated) {
return false;
}

return $this->parseHydrated($hydrated);
}

/** @return array<int, mixed> */
public function fetchAll(Collection $collection, mixed $extra = null): array
{
$statement = $this->createStatement($collection, $extra);
$entities = [];

while ($hydrated = $this->fetchHydrated($collection, $statement)) {
$entities[] = $this->parseHydrated($hydrated);
}

return $entities;
}

public function persist(object $object, Collection $onCollection): bool
{
$next = $onCollection->getNext();
Expand Down Expand Up @@ -268,22 +292,6 @@ protected function checkNewIdentity(object $entity, Collection $collection): boo
return true;
}

protected function createStatement(
Collection $collection,
mixed $withExtra = null,
): PDOStatement {
$query = $this->generateQuery($collection);

if ($withExtra instanceof Sql) {
$query->appendQuery($withExtra);
}

$statement = $this->db->prepare((string) $query, PDO::FETCH_NUM);
$statement->execute($query->getParams());

return $statement;
}

protected function generateQuery(Collection $collection): Sql
{
$collections = iterator_to_array(
Expand Down Expand Up @@ -499,28 +507,6 @@ protected function hasComposition(string $entity, string|null $next, string|null
|| $entity === $s->composed($next, $parent);
}

protected function fetchSingle(
Collection $collection,
PDOStatement $statement,
): SplObjectStorage|false {
$name = $collection->getName();
$entityName = $name;
$row = $statement->fetch(PDO::FETCH_OBJ);

if (!$row) {
return false;
}

if ($this->typable($collection)) {
$entityName = $this->inferGet($row, $this->getType($collection));
}

$entities = new SplObjectStorage();
$entities[$this->transformSingleRow($row, $entityName)] = $collection;

return $entities;
}

protected function getNewEntityByName(string $entityName): object
{
$entityName = $this->getStyle()->styledName($entityName);
Expand Down Expand Up @@ -571,24 +557,6 @@ protected function inferGet(object &$object, string $prop): mixed
}
}

protected function fetchMulti(
Collection $collection,
PDOStatement $statement,
): SplObjectStorage|false {
$entities = [];
$row = $statement->fetch(PDO::FETCH_NUM);

if (!$row) {
return false;
}

$this->postHydrate(
$entities = $this->createEntities($row, $statement, $collection),
);

return $entities;
}

/** @param array<int, mixed> $row */
protected function createEntities(
array $row,
Expand Down Expand Up @@ -709,4 +677,77 @@ protected function getAllProperties(object $object): array

return $cols;
}

private function parseHydrated(SplObjectStorage $hydrated): mixed
{
$this->tracked->addAll($hydrated);
$hydrated->rewind();

return $hydrated->current();
}

private function fetchHydrated(Collection $collection, PDOStatement $statement): SplObjectStorage|false
{
if (!$collection->hasMore()) {
return $this->fetchSingle($collection, $statement);
}

return $this->fetchMulti($collection, $statement);
}

private function createStatement(
Collection $collection,
mixed $withExtra = null,
): PDOStatement {
$query = $this->generateQuery($collection);

if ($withExtra instanceof Sql) {
$query->appendQuery($withExtra);
}

$statement = $this->db->prepare((string) $query, PDO::FETCH_NUM);
$statement->execute($query->getParams());

return $statement;
}

private function fetchSingle(
Collection $collection,
PDOStatement $statement,
): SplObjectStorage|false {
$name = $collection->getName();
$entityName = $name;
$row = $statement->fetch(PDO::FETCH_OBJ);

if (!$row) {
return false;
}

if ($this->typable($collection)) {
$entityName = $this->inferGet($row, $this->getType($collection));
}

$entities = new SplObjectStorage();
$entities[$this->transformSingleRow($row, $entityName)] = $collection;

return $entities;
}

private function fetchMulti(
Collection $collection,
PDOStatement $statement,
): SplObjectStorage|false {
$entities = [];
$row = $statement->fetch(PDO::FETCH_NUM);

if (!$row) {
return false;
}

$this->postHydrate(
$entities = $this->createEntities($row, $statement, $collection),
);

return $entities;
}
}
25 changes: 0 additions & 25 deletions tests/DbTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,28 +123,3 @@ protected function tearDown(): void
unset($this->object);
}
}

class TestFetchingClass
{
public int|null $testa = null;

public string|null $testb = null;

public int|null $testez = null;
}

class TestFetchingInto
{
public int|null $testa = null;

public string|null $testb = null;

public int|null $testez = null;
}

class TestFetchingClassArgs
{
public function __construct(public string|null $testd = null)
{
}
}
Loading
Loading