Passed
Push — master ( c4f127...730a00 )
by Sergei
24:33 queued 20:27
created

CompositeExpression::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

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