Passed
Push — rename-composite-to-structured... ( b1c502 )
by Sergei
04:30
created

StructuredExpression::getColumns()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Pgsql\Structured;
6
7
use Traversable;
8
use Yiisoft\Db\Expression\ExpressionInterface;
9
use Yiisoft\Db\Schema\ColumnSchemaInterface;
10
11
/**
12
 * Represents a structured type SQL expression.
13
 *
14
 * @see https://en.wikipedia.org/wiki/Structured_type
15
 *
16
 * For example:
17
 *
18
 * ```php
19
 * new StructuredExpression(['price' => 10, 'currency_code' => 'USD']);
20
 * ```
21
 *
22
 * Will be encoded to `ROW(10, USD)`
23
 */
24
class StructuredExpression implements ExpressionInterface
25
{
26
    /**
27
     * @param ColumnSchemaInterface[] $columns
28
     * @psalm-param array<string, ColumnSchemaInterface> $columns
29
     */
30 10
    public function __construct(
31
        private mixed $value,
32
        private string|null $type = null,
33
        private array $columns = [],
34
    ) {
35 10
    }
36
37
    /**
38
     * The structured type name.
39
     *
40
     * Defaults to `null` which means the type is not explicitly specified.
41
     *
42
     * Note that in the case where a type is not specified explicitly and DBMS cannot guess it from the context,
43
     * SQL error will be raised.
44
     */
45 9
    public function getType(): string|null
46
    {
47 9
        return $this->type;
48
    }
49
50
    /**
51
     * The structured type columns that are used for value normalization and type casting.
52
     *
53
     * @return ColumnSchemaInterface[]
54
     */
55 7
    public function getColumns(): array
56
    {
57 7
        return $this->columns;
58
    }
59
60
    /**
61
     * The content of the structured type. It can be represented as an associative array of structured type column names
62
     * and values.
63
     */
64 11
    public function getValue(): mixed
65
    {
66 11
        return $this->value;
67
    }
68
69
    /**
70
     * Sorted values according to the order of structured type columns,
71
     * indexed keys are replaced with column names,
72
     * missing elements are filled in with default values,
73
     * excessive elements are removed.
74
     */
75 17
    public function getNormalizedValue(): mixed
76
    {
77 17
        if (empty($this->columns) || !is_iterable($this->value)) {
78 8
            return $this->value;
79
        }
80
81 9
        $normalized = [];
82 9
        $value = $this->value;
83 9
        $columnsNames = array_keys($this->columns);
84
85 9
        if ($value instanceof Traversable) {
86 2
            $value = iterator_to_array($value);
87
        }
88
89 9
        foreach ($columnsNames as $i => $columnsName) {
90 9
            $normalized[$columnsName] = match (true) {
91 9
                array_key_exists($columnsName, $value) => $value[$columnsName],
92 9
                array_key_exists($i, $value) => $value[$i],
93 9
                default => $this->columns[$columnsName]->getDefaultValue(),
94 9
            };
95
        }
96
97 9
        return $normalized;
98
    }
99
}
100