Query::getParams()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 6
c 0
b 0
f 0
nc 3
nop 0
dl 0
loc 11
ccs 7
cts 7
cp 1
crap 3
rs 10
1
<?php
2
3
namespace mindplay\sql\model\query;
4
5
use mindplay\sql\framework\Statement;
6
use mindplay\sql\model\schema\Type;
7
use mindplay\sql\model\TypeProvider;
8
use UnexpectedValueException;
9
10
/**
11
 * Abstract base-class for all types of SQL Query models.
12
 */
13
abstract class Query implements Statement
14
{
15
    protected TypeProvider $types;
16
17
    /**
18
     * @var array<string,mixed> map where placeholder name => mixed value types
19
     */
20
    protected array $params = [];
21
22
    /**
23
     * @var array<string,Type|null> map where placeholder name => Type instance (or NULL)
24
     */
25
    protected array $param_types = [];
26
27
    /**
28
     * @param TypeProvider $types
29
     */
30 1
    public function __construct(TypeProvider $types)
31
    {
32 1
        $this->types = $types;
33
    }
34
35
    /**
36
     * Bind an individual placeholder name to a given value.
37
     *
38
     * The `$type` argument is optional for scalar types (string, int, float, bool, null) and arrays of scalar values.
39
     *
40
     * @param string           $name placeholder name
41
     * @param mixed            $value
42
     * @param Type|string|null $type Type instance, or Type class-name (or NULL for scalar types)
43
     *
44
     * @return $this
45
     */
46 1
    public function bind(string $name, mixed $value, Type|string|null $type = null): static
47
    {
48 1
        static $SCALAR_TYPES = [
49 1
            'integer' => true,
50 1
            'double'  => true,
51 1
            'string'  => true,
52 1
            'boolean' => true,
53 1
            'NULL'    => true,
54 1
        ];
55
56 1
        if ($type === null) {
57 1
            $value_type = gettype($value);
58
59 1
            if ($value_type === 'array') {
60 1
                foreach ($value as $element) {
61 1
                    $element_type = gettype($element);
62
63 1
                    if (! isset($SCALAR_TYPES[$element_type])) {
64 1
                        throw new UnexpectedValueException("unexpected array element type: {$element_type}");
65
                    }
66
                }
67
            } else {
68 1
                if (! isset($SCALAR_TYPES[$value_type])) {
69 1
                    throw new UnexpectedValueException("unexpected value type: {$value_type}");
70
                }
71
            }
72
        }
73
        
74 1
        $this->params[$name] = $value;
75
        
76 1
        $this->param_types[$name] = is_string($type)
77 1
            ? $this->types->getType($type)
78 1
            : $type; // assumes Type instance (or NULL)
79
        
80 1
        return $this;
81
    }
82
83
    /**
84
     * Applies a set of placeholder name/value pairs and binds them to individual placeholders.
85
     * 
86
     * This works for scalar values only (string, int, float, bool, null) and arrays of scalar values - to
87
     * bind values with `Type`-support, use the `bind()` method.
88
     * 
89
     * @see bind()
90
     *
91
     * @param array<string|int|float|bool|null|array<string|int|float|bool|null>> $params placeholder name/value pairs
92
     *
93
     * @return $this
94
     */
95 1
    public function apply(array $params): static
96
    {
97 1
        foreach ($params as $name => $value) {
98 1
            $this->bind($name, $value);
99
        }
100
        
101 1
        return $this;
102
    }
103
    
104
    /**
105
     * @inheritdoc
106
     */
107 1
    public function getParams(): array
108
    {
109 1
        $params = [];
110
111 1
        foreach ($this->params as $name => $value) {
112 1
            $params[$name] = isset($this->param_types[$name])
113 1
                ? $this->param_types[$name]->convertToSQL($value)
114 1
                : $value; // assume scalar value (or array of scalar values)
115
        }
116
117 1
        return $params;
118
    }
119
}
120