Skip to content
Snippets Groups Projects
Verified Commit eed65e61 authored by Jiří Pudil's avatar Jiří Pudil
Browse files

Revert "Draft: Fixed parser for case where array contain list of composite types."

This reverts commit 1fcbe30a.
parent ffc50dea
No related branches found
No related tags found
1 merge request!40CompositeType: add explicit type cast to support composite values in WHERE clause
......@@ -106,7 +106,6 @@ final class ArrayType implements Type // @todo: There is implicit support for nu
$result = [];
$string = false;
$subObject = false;
$length = \strlen($value);
$item = '';
for ($i = $start + 1; $i < $length; $i++) {
......@@ -125,12 +124,7 @@ final class ArrayType implements Type // @todo: There is implicit support for nu
$subArrayStart = $i;
$this->parseArray($value, $i, $i);
$item = \substr($value, $subArrayStart, $i - $subArrayStart + 1);
} elseif ( ! $string && ! $subObject && $char === '(') {
// @todo: Not sure if this 100% covers all cases. It should run here full object parser and find where the object ends
// @todo: see few lines above how recursive arrays are handled...
$subObject = TRUE;
$item .= '(';
} elseif ( ! $string && ! $subObject && $char ===',') {
} elseif ( ! $string && $char ===',') {
$result[] = $item !== 'NULL' ? $item : null;
$item = '';
} elseif ( ! $string && $char === '"') {
......@@ -138,10 +132,7 @@ final class ArrayType implements Type // @todo: There is implicit support for nu
} elseif ($string && ($char === '"' || $char === "\\") && $value[$i - 1] === "\\") {
$item = \substr($item, 0, -1) . $char;
} elseif ($string && $char === '"' && $value[$i - 1] !== "\\") {
$string = FALSE;
} elseif (!$string && $subObject && $char === ')') {
$subObject = FALSE;
$item .= ')';
$string = false;
} else {
$item .= $char;
}
......
......@@ -11,7 +11,6 @@ use Grifart\Tables\Types\ArrayType;
use Grifart\Tables\Types\CompositeType;
use Grifart\Tables\Types\IntType;
use Grifart\Tables\Types\TextType;
use PhpParser\Node\Name;
use Tester\Assert;
use function Functional\map;
use function Grifart\ClassScaffolder\Definition\Types\resolve;
......@@ -54,3 +53,26 @@ $executeExpressionInDatabase = function(string $expression) use ($connection): s
Assert::same($theInput, $textArrayType->fromDatabase($dbResult));
})();
final class Version {
public function __construct(public int $major, public int $minor, public int $patch) {}
/** @return array{int,int,int} */
public function toArray(): array { return [$this->major, $this->minor, $this->patch]; }
}
/** @extends CompositeType<Version> */
final class VersionType extends CompositeType {
public function __construct() { parent::__construct(new NamedIdentifier('public', 'packageVersion'), new IntType(), new IntType(), new IntType() ); }
public function getPhpType(): PhpType { return resolve(Version::class); }
public function toDatabase(mixed $value): Literal { return $this->tupleToDatabase($value->toArray()); }
public function fromDatabase(mixed $value): Version { return new Version(...$this->tupleFromDatabase($value)); }
};
$compositeArrayType = ArrayType::of(new VersionType());
Assert::same('{(0,1,0),(1,0,0),(1,0,1)}::public."packageVersion"[]', $compositeArrayType->toDatabase([new Version(0,1,0), new Version(1,0,0), new Version(1,0,1)]));
/** @var callable(Version[] $versions):array<array{int,int,int}> $toTuples */
// scalar tuples are comparable with ===
$toTuples = static fn(array $versions): array => map($versions, static fn($version) => $version->toArray());
Assert::same(
$toTuples([new Version(0,1,0), new Version(1,0,0), new Version(1,0,1)]),
$toTuples($compositeArrayType->fromDatabase('{(0,1,0),(1,0,0),(1,0,1)}')),
);
<?php
declare(strict_types=1);
namespace Grifart\Tables\Tests\Types;
use Dibi\Literal;
use Grifart\ClassScaffolder\Definition\Types\Type as PhpType;
use Grifart\Tables\NamedIdentifier;
use Grifart\Tables\Types\ArrayType;
use Grifart\Tables\Types\CompositeType;
use Grifart\Tables\Types\IntType;
use Grifart\Tables\Types\TextType;
use PhpParser\Node\Name;
use Tester\Assert;
use function Functional\map;
use function Grifart\ClassScaffolder\Definition\Types\resolve;
use function Grifart\Tables\Tests\connect;
require __DIR__ . '/../bootstrap.php';
$connection = connect();
$executeExpressionInDatabase = function(string $expression) use ($connection): string {
$result = $connection->nativeQuery(sprintf("SELECT %s;", $expression))->fetchSingle();
\assert(is_string($result));
return $connection->nativeQuery(sprintf("SELECT %s;", $expression))->fetchSingle();
};
final class Version {
public function __construct(public int $major, public int $minor, public int $patch) {}
/** @return array{int,int,int} */
public function toArray(): array { return [$this->major, $this->minor, $this->patch]; }
}
/** @extends CompositeType<Version> */
final class VersionType extends CompositeType {
public function __construct() { parent::__construct(new NamedIdentifier('public', 'packageVersion'), new IntType(), new IntType(), new IntType() ); }
public function getPhpType(): PhpType { return resolve(Version::class); }
public function toDatabase(mixed $value): Literal { return $this->tupleToDatabase($value->toArray()); }
public function fromDatabase(mixed $value): Version { return new Version(...$this->tupleFromDatabase($value)); }
};
$theInput = [new Version(0,1,0), new Version(1,0,0), new Version(1,0,1)];
$compositeArrayType = ArrayType::of(new NamedIdentifier('public', 'packageVersion'), new VersionType());
Assert::same('ARRAY[ROW(0,1,0)::public."packageVersion",ROW(1,0,0)::public."packageVersion",ROW(1,0,1)::public."packageVersion"]::public."packageVersion"[]', (string) $compositeArrayType->toDatabase($theInput));
/** @var callable(Version[] $versions):array<array{int,int,int}> $toTuples */
// scalar tuples are comparable with ===
$toTuples = static fn(array $versions): array => map($versions, static fn($version) => $version->toArray());
Assert::same(
$toTuples($theInput),
$toTuples($compositeArrayType->fromDatabase('{(0,1,0),(1,0,0),(1,0,1)}')),
);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment