Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
bohanyang committed Jul 20, 2023
1 parent 3b3672c commit 5478bf6
Show file tree
Hide file tree
Showing 3 changed files with 239 additions and 0 deletions.
12 changes: 12 additions & 0 deletions packages/mango/Doctrine/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,18 @@ public function fetchOne(): mixed
return $this->convertResultToPHPValue('c0', $values[0]);
}


public function fetchOneWithDefault(mixed $value): mixed
{
$values = $this->getQueryResult()->fetchFirstColumn();

if ($values === []) {
return $value;
}

return $this->convertResultToPHPValue('c0', $values[0]);
}

public function getBuilder(): QueryBuilder
{
return $this->builder;
Expand Down
210 changes: 210 additions & 0 deletions packages/mango/Query/QueryResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
<?php

declare(strict_types=1);

namespace Manyou\Mango\Query;

use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Result;
use LogicException;
use RuntimeException;

use function array_keys;

class QueryResult
{
private ?string $key0;

private ?string $key1;

/** @param array<string, ResultColumnMetadata> $metadata */
public function __construct(
private AbstractPlatform $platform,
private Result $result,
private array $metadata,
) {
$keys = array_keys($metadata);
$this->key0 = $keys[0] ?? null;
$this->key1 = $keys[1] ?? null;
}

private function requireOneColumn(): void
{
if ($this->key0 === null) {
throw new LogicException('The method requires at least one column in each result.');
}
}

private function requireTwoColumns(): void
{
if ($this->key0 === null || $this->key1 === null) {
throw new LogicException('The method requires at least two columns in each result.');
}
}

private function convertResultToPHPValue(string $key, mixed $value)
{
$metadata = $this->metadata[$key];

return $metadata->type->convertToPHPValue($value, $this->platform);
}

private function convertResultRow(array $row): array
{
$results = [];
foreach ($row as $key => $value) {
$metadata = $this->metadata[$key];
$value = $this->convertResultToPHPValue($key, $value);

$results[$metadata->group][$metadata->name] = $value;
}

return $results;
}

private function convertResultRowFlat(array $row): array
{
$results = [];
foreach ($row as $key => $value) {
$metadata = $this->metadata[$key];
$value = $this->convertResultToPHPValue($key, $value);

$results[$metadata->name] = $value;
}

return $results;
}

public function fetchAssociative(): array|false
{
if (false !== $row = $this->result->fetchAssociative()) {
return $this->convertResultRow($row);
}

return $row;
}

public function fetchAssociativeFlat(): array|false
{
if (false !== $row = $this->result->fetchAssociative()) {
return $this->convertResultRowFlat($row);
}

return $row;
}

public function fetchAllAssociative(): array
{
$rows = $this->result->fetchAllAssociative();

foreach ($rows as $i => $row) {
$rows[$i] = $this->convertResultRow($row);
}

return $rows;
}

public function fetchAllAssociativeFlat(): array
{
$rows = $this->result->fetchAllAssociative();

foreach ($rows as $i => $row) {
$rows[$i] = $this->convertResultRowFlat($row);
}

return $rows;
}

public function fetchAllKeyValue(): array
{
$this->requireTwoColumns();

$rows = $this->result->fetchAllAssociative();

$results = [];
foreach ($rows as $row) {
$key = $this->convertResultToPHPValue($this->key0, $row[$this->key0]);
$value = $this->convertResultToPHPValue($this->key1, $row[$this->key1]);

$results[$key] = $value;
}

return $results;
}

public function fetchAllAssociativeIndexed(): array
{
$this->requireTwoColumns();

$rows = $this->result->fetchAllAssociative();

$results = [];
foreach ($rows as $row) {
$key = $this->convertResultToPHPValue($this->key0, $row[$this->key0]);
unset($row[$this->key0]);

$results[$key] = $this->convertResultRowFlat($row);
}

return $results;
}

public function fetchAllAssociativeGrouped(): array
{
$this->requireTwoColumns();

$rows = $this->result->fetchAllAssociative();

$keys = [];
$results = [];
foreach ($rows as $row) {
$key = $keys[$row[$this->key0]] ??= $this->convertResultToPHPValue($this->key0, $row[$this->key0]);
unset($row[$this->key0]);

$results[$key][] = $this->convertResultRowFlat($row);
}

return $results;
}

public function fetchColumnGrouped(): array
{
$this->requireTwoColumns();

$rows = $this->result->fetchAllAssociative();

$keys = [];
$results = [];
foreach ($rows as $row) {
$key = $keys[$row[$this->key0]] ??= $this->convertResultToPHPValue($this->key0, $row[$this->key0]);

$results[$key][] = $this->convertResultToPHPValue($this->key1, $row[$this->key1]);
}

return $results;
}

public function fetchFirstColumn(): array
{
$this->requireOneColumn();
$values = $this->result->fetchFirstColumn();

foreach ($values as $i => $value) {
$values[$i] = $this->convertResultToPHPValue($this->key0, $value);
}

return $values;
}

public function fetchOne(): mixed
{
$this->requireOneColumn();
$values = $this->result->fetchFirstColumn();

if ($values === []) {
throw new RuntimeException('No result found.');
}

return $this->convertResultToPHPValue($this->key0, $values[0]);
}
}
17 changes: 17 additions & 0 deletions packages/mango/Query/ResultColumnMetadata.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace Manyou\Mango\Query;

use Doctrine\DBAL\Types\Type;

class ResultColumnMetadata
{
public function __construct(
public readonly string $group,
public readonly string $name,
public readonly Type $type,
) {
}
}

0 comments on commit 5478bf6

Please sign in to comment.