Completed
Push — master ( f5e5fb...7d0a28 )
by Rasmus
02:24
created

Query::bind()   C

Complexity

Conditions 7
Paths 8

Size

Total Lines 36
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 7

Importance

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