Completed
Push — master ( f707f5...a08928 )
by Rasmus
02:27
created

Query::bind()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 34
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 34
ccs 15
cts 15
cp 1
rs 8.439
cc 6
eloc 21
nc 6
nop 3
crap 6
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
        $value_type = gettype($value);
60
61 1
        if ($value_type === 'array') {
62 1
            foreach ($value as $item) {
63 1
                $item_type = gettype($item);
64
65 1
                if (! isset($SCALAR_TYPES[$item_type])) {
66 1
                    throw new UnexpectedValueException("unexpected item type in array: {$item_type}");
67
                }
68
            }
69
        } else {
70 1
            if (! isset($SCALAR_TYPES[$value_type])) {
71 1
                throw new UnexpectedValueException("unexpected value type: {$value_type}");
72
            }
73
        }
74
75 1
        $this->params[$name] = $value;
76
77 1
        $this->param_types[$name] = is_string($type)
78 1
            ? $this->types->getType($type)
79 1
            : $type; // assumes Type instance (or NULL)
80
81 1
        return $this;
82
    }
83
84
    /**
85
     * Applies a set of placeholder name/value pairs and binds them to individual placeholders.
86
     * 
87
     * This works for scalar values only (string, int, float, bool, null) and arrays of scalar values - to
88
     * bind values with `Type`-support, use the `bind()` method.
89
     * 
90
     * @see bind()
91
     *
92
     * @param array $params placeholder name/value pairs
93
     *
94
     * @return $this
95
     */
96 1
    public function apply(array $params)
97
    {
98 1
        foreach ($params as $name => $value) {
99 1
            $this->bind($name, $value);
100
        }
101
        
102 1
        return $this;
103
    }
104
    
105
    /**
106
     * @inheritdoc
107
     */
108 1
    public function getParams()
109
    {
110 1
        $params = [];
111
112 1
        foreach ($this->params as $name => $value) {
113 1
            $params[$name] = isset($this->param_types[$name])
114 1
                ? $this->param_types[$name]->convertToSQL($value)
115 1
                : $value; // assume scalar value (or array of scalar values)
116
        }
117
118 1
        return $params;
119
    }
120
}
121