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
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

## 1.1.1 under development

- no changes in this release.
- Enh #301: Refactor `JsonExpressionBuilder` (@Tigrov)
- Enh #300: Refactor `ArrayExpressionBuilder` (@Tigrov)
- Enh #302: Refactor `ColumnSchema` (@Tigrov)
- Bug #302: Fix incorrect convert string value for BIT type (@Tigrov)

## 1.1.0 July 24, 2023

Expand Down
32 changes: 12 additions & 20 deletions src/Builder/ArrayExpressionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Yiisoft\Db\Pgsql\Builder;

use Traversable;
use Yiisoft\Db\Exception\Exception;
use Yiisoft\Db\Exception\InvalidArgumentException;
use Yiisoft\Db\Exception\InvalidConfigException;
Expand All @@ -19,7 +18,7 @@

use function implode;
use function in_array;
use function is_array;
use function is_iterable;
use function str_repeat;

/**
Expand All @@ -34,7 +33,7 @@ public function __construct(private QueryBuilderInterface $queryBuilder)
/**
* The Method builds the raw SQL from the expression that won't be additionally escaped or quoted.
*
* @param ExpressionInterface $expression The expression build.
* @param ArrayExpression $expression The expression build.
* @param array $params The binding parameters.
*
* @throws Exception
Expand All @@ -43,8 +42,6 @@ public function __construct(private QueryBuilderInterface $queryBuilder)
* @throws NotSupportedException
*
* @return string The raw SQL that won't be additionally escaped or quoted.
*
* @psalm-param ArrayExpression $expression
*/
public function build(ExpressionInterface $expression, array &$params = []): string
{
Expand All @@ -63,7 +60,7 @@ public function build(ExpressionInterface $expression, array &$params = []): str
/** @psalm-var string[] $placeholders */
$placeholders = $this->buildPlaceholders($expression, $params);

return 'ARRAY[' . implode(', ', $placeholders) . ']' . $this->getTypehint($expression);
return 'ARRAY[' . implode(', ', $placeholders) . ']' . $this->getTypeHint($expression);
}

/**
Expand All @@ -75,22 +72,20 @@ public function build(ExpressionInterface $expression, array &$params = []): str
* @throws InvalidArgumentException
* @throws InvalidConfigException
* @throws NotSupportedException
*
* @psalm-param ArrayExpression $expression
*/
protected function buildPlaceholders(ExpressionInterface $expression, array &$params): array
private function buildPlaceholders(ArrayExpression $expression, array &$params): array
{
$placeholders = [];

/** @psalm-var mixed $value */
$value = $expression->getValue();

if (!is_array($value) && !$value instanceof Traversable) {
if (!is_iterable($value)) {
return $placeholders;
}

if ($expression->getDimension() > 1) {
/** @psalm-var ExpressionInterface|int $item */
/** @psalm-var mixed $item */
foreach ($value as $item) {
$placeholders[] = $this->build($this->unnestArrayExpression($expression, $item), $params);
}
Expand All @@ -109,10 +104,9 @@ protected function buildPlaceholders(ExpressionInterface $expression, array &$pa

if ($item instanceof ExpressionInterface) {
$placeholders[] = $this->queryBuilder->buildExpression($item, $params);
continue;
} else {
$placeholders[] = $this->queryBuilder->bindParam($item, $params);
}

$placeholders[] = $this->queryBuilder->bindParam($item, $params);
}

return $placeholders;
Expand All @@ -126,7 +120,7 @@ private function unnestArrayExpression(ArrayExpression $expression, mixed $value
/**
* @return string The typecast expression based on {@see type}.
*/
protected function getTypeHint(ArrayExpression $expression): string
private function getTypeHint(ArrayExpression $expression): string
{
$type = $expression->getType();

Expand All @@ -135,10 +129,8 @@ protected function getTypeHint(ArrayExpression $expression): string
}

$dimension = $expression->getDimension();
$result = '::' . $type;
$result .= str_repeat('[]', $dimension);

return $result;
return '::' . $type . str_repeat('[]', $dimension);
}

/**
Expand All @@ -149,15 +141,15 @@ protected function getTypeHint(ArrayExpression $expression): string
*
* @return string The sub-query array expression.
*/
protected function buildSubqueryArray(string $sql, ArrayExpression $expression): string
private function buildSubqueryArray(string $sql, ArrayExpression $expression): string
{
return 'ARRAY(' . $sql . ')' . $this->getTypeHint($expression);
}

/**
* @return array|bool|ExpressionInterface|float|int|JsonExpression|string|null The cast value or expression.
*/
protected function typecastValue(
private function typecastValue(
ArrayExpression $expression,
array|bool|float|int|string|ExpressionInterface|null $value
): array|bool|float|int|string|JsonExpression|ExpressionInterface|null {
Expand Down
14 changes: 5 additions & 9 deletions src/Builder/JsonExpressionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function __construct(private QueryBuilderInterface $queryBuilder)
/**
* The Method builds the raw SQL from the $expression that won't be additionally escaped or quoted.
*
* @param ExpressionInterface $expression The expression to build.
* @param JsonExpression $expression The expression to build.
* @param array $params The binding parameters.
*
* @throws Exception
Expand All @@ -39,19 +39,15 @@ public function __construct(private QueryBuilderInterface $queryBuilder)
* @throws NotSupportedException
*
* @return string The raw SQL that won't be additionally escaped or quoted.
*
* @psalm-param JsonExpression $expression
*/
public function build(ExpressionInterface $expression, array &$params = []): string
{
/**
* @psalm-var array|mixed|QueryInterface $value
*/
/** @psalm-var mixed $value */
$value = $expression->getValue();

if ($value instanceof QueryInterface) {
[$sql, $params] = $this->queryBuilder->build($value, $params);
return "($sql)" . $this->getTypecast($expression);
return "($sql)" . $this->getTypeHint($expression);
}

if ($value instanceof ArrayExpression) {
Expand All @@ -60,13 +56,13 @@ public function build(ExpressionInterface $expression, array &$params = []): str
$placeholder = $this->queryBuilder->bindParam(Json::encode($value), $params);
}

return $placeholder . $this->getTypecast($expression);
return $placeholder . $this->getTypeHint($expression);
}

/**
* @return string The typecast expression based on {@see JsonExpression::getType()}.
*/
protected function getTypecast(JsonExpression $expression): string
private function getTypeHint(JsonExpression $expression): string
{
$type = $expression->getType();

Expand Down
21 changes: 10 additions & 11 deletions src/ColumnSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ final class ColumnSchema extends AbstractColumnSchema
*
* @param mixed $value input value
*
* @return mixed Converted value. This may also be an array containing the value as the first element and the PDO
* type as the second element.
* @return mixed Converted value.
*/
public function dbTypecast(mixed $value): mixed
{
Expand All @@ -87,7 +86,7 @@ public function dbTypecast(mixed $value): mixed

Schema::TYPE_BIT => is_int($value)
? str_pad(decbin($value), (int) $this->getSize(), '0', STR_PAD_LEFT)
: $this->typecast($value),
Comment thread
vjik marked this conversation as resolved.
: (string) $value,

default => $this->typecast($value),
};
Expand All @@ -111,15 +110,15 @@ public function phpTypecast(mixed $value): mixed
$value = $this->getArrayParser()->parse($value);
}

if (is_array($value)) {
array_walk_recursive($value, function (string|null &$val) {
/** @psalm-var mixed $val */
$val = $this->phpTypecastValue($val);
});
} else {
if (!is_array($value)) {
return null;
}

array_walk_recursive($value, function (mixed &$val) {
/** @psalm-var mixed $val */
$val = $this->phpTypecastValue($val);
});

return $value;
}

Expand All @@ -131,7 +130,7 @@ public function phpTypecast(mixed $value): mixed
*
* @throws JsonException
*/
protected function phpTypecastValue(mixed $value): mixed
private function phpTypecastValue(mixed $value): mixed
{
if ($value === null) {
return null;
Expand All @@ -152,7 +151,7 @@ protected function phpTypecastValue(mixed $value): mixed
/**
* Creates instance of ArrayParser.
*/
protected function getArrayParser(): ArrayParser
private function getArrayParser(): ArrayParser
{
return new ArrayParser();
}
Expand Down
9 changes: 9 additions & 0 deletions tests/ColumnSchemaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,13 @@ public function testNegativeDefaultValues()
$this->assertSame(-12345.6789, $tableSchema->getColumn('float_col')->getDefaultValue());
$this->assertSame(-33.22, $tableSchema->getColumn('numeric_col')->getDefaultValue());
}

public function testDbTypeCastBit()
{
$db = $this->getConnection(true);
$schema = $db->getSchema();
$tableSchema = $schema->getTableSchema('type');

$this->assertSame('01100100', $tableSchema->getColumn('bit_col')->dbTypecast('01100100'));
}
}
11 changes: 11 additions & 0 deletions tests/QueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,17 @@ public function testAlterColumn(): void
),
);

$this->assertSame(
<<<SQL
ALTER TABLE "foo1" ALTER COLUMN "bar" TYPE varchar(30), ADD UNIQUE ("bar")
SQL,
$qb->alterColumn(
'foo1',
'bar',
(new Column(SchemaInterface::TYPE_STRING, 30))->unique()
),
);

$db->close();
}

Expand Down