Completed
Push — master ( c28104...334f29 )
by Hong
06:55
created

SetTrait::setRaw()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
c 0
b 0
f 0
rs 9.4285
nc 3
cc 3
eloc 8
nop 2
1
<?php
2
/**
3
 * Phossa Project
4
 *
5
 * PHP version 5.4
6
 *
7
 * @category  Library
8
 * @package   Phossa2\Query
9
 * @copyright Copyright (c) 2016 phossa.com
10
 * @license   http://mit-license.org/ MIT License
11
 * @link      http://www.phossa.com/
12
 */
13
/*# declare(strict_types=1); */
14
15
namespace Phossa2\Query\Traits\Clause;
16
17
use Phossa2\Query\Interfaces\ClauseInterface;
18
use Phossa2\Query\Interfaces\Clause\SetInterface;
19
20
/**
21
 * SetTrait
22
 *
23
 * Implementation of SetInterface
24
 *
25
 * @package Phossa2\Query
26
 * @author  Hong Zhang <[email protected]>
27
 * @see     SetInterface
28
 * @version 2.0.0
29
 * @since   2.0.0 added
30
 */
31
trait SetTrait
32
{
33
    /**
34
     * data storage
35
     *
36
     * @var    array
37
     * @access protected
38
     */
39
    protected $set_data = [];
40
41
    /**
42
     * data row number
43
     *
44
     * @var    int
45
     * @access protected
46
     */
47
    protected $set_row = 0;
48
49
    /**
50
     * storage for col names
51
     *
52
     * @var    array
53
     * @access protected
54
     */
55
    protected $set_col = [];
56
57
    /**
58
     * {@inheritDoc}
59
     */
60
    public function set($col, $value = ClauseInterface::NO_VALUE)
61
    {
62
        if (is_array($col)) { // array provided
63
            return $this->setWithArrayData($col);
64
        }
65
        if (!isset($this->set_col[$col])) { // save col names
66
            $this->set_col[$col] = true;
67
        }
68
        if (ClauseInterface::NO_VALUE === $value) { // auto positionedParam
69
            $this->setSettings(['positionedParam' => true]);
70
        }
71
72
        $this->set_data[$this->set_row][$col] = $value;
73
        return $this;
74
    }
75
76
    /**
77
     * {@inheritDoc}
78
     */
79
    public function setRaw($col, $value = ClauseInterface::NO_VALUE)
80
    {
81
        if (ClauseInterface::NO_VALUE !== $value) {
82
            if (func_num_args() > 2) {
83
                $value = $this->getBuilder()
0 ignored issues
show
Bug introduced by
It seems like getBuilder() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
84
                    ->raw($value, (array) func_get_arg(2));
85
            } else {
86
                $value = $this->getBuilder()->raw($value);
0 ignored issues
show
Bug introduced by
It seems like getBuilder() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
87
            }
88
        }
89
        return $this->set($col, $value);
90
    }
91
92
    /**
93
     * Batch SET
94
     *
95
     * @param  array $data
96
     * @return $this
97
     * @access protected
98
     */
99
    protected function setWithArrayData(array $data)
100
    {
101
        if (isset($data[0])) { // multiple rows
102
            foreach ($data as $row) {
103
                $this->set($row);
104
            }
105
        } else { // multiple values
106
            foreach ($data as $col => $val) {
107
                $this->set($col, $val);
108
            }
109
            $this->set_row++;
110
        }
111
        return $this;
112
    }
113
114
    /**
115
     * Build SET
116
     *
117
     * @param  string $prefix
118
     * @param  array $settings
119
     * @return string
120
     * @access protected
121
     */
122
    protected function buildSet(
123
        /*# string */ $prefix,
124
        array $settings
125
    )/*# : array */ {
126
        if ('UPDATE' === $this->getType()) {
127
            return $this->buildUpdateSet($prefix, $settings);
128
        } else {
129
            return $this->buildInsertSet($prefix, $settings);
130
        }
131
    }
132
133
    /**
134
     * Build SET for INSERT
135
     *
136
     * @param  string $prefix
137
     * @param  array $settings
138
     * @return string
139
     * @access protected
140
     */
141
    protected function buildInsertSet(
142
        /*# string */ $prefix,
143
        array $settings
144
    )/*# : string */ {
145
        if (empty($this->set_data)) {
146
            return '';
147
        }
148
149
        $cols = [];
150
        foreach (array_keys($this->set_col) as $col) {
151
            $cols[] = $this->quote($col, $settings);
152
        }
153
        return $settings['seperator'] . '(' . join(', ', $cols) . ')';
154
    }
155
156
    /**
157
     * Build SET ... = ..., ... = ...
158
     *
159
     *
160
     * @param  string $prefix
161
     * @param  array $settings
162
     * @return string
163
     * @access protected
164
     */
165
    protected function buildUpdateSet(
166
        /*# string */ $prefix,
167
        array $settings
168
    )/*# : string */ {
169
        $result = [];
170
        foreach ($this->set_data[0] as $col => $val) {
171
            $result[] = $this->quote($col, $settings) . ' = ' .
172
                $this->processValue($val, $settings);
173
        }
174
        return $this->joinClause($prefix, ',', $result, $settings);
175
    }
176
177
    /**
178
     * Build VALUES ( ... )
179
     *
180
     * @param  string $prefix
181
     * @param  array $settings
182
     * @return string
183
     * @access protected
184
     */
185
    protected function buildValues(
186
        /*# string */ $prefix,
187
        array $settings
188
    )/*# : string */ {
189
        $rows = [];
190
        $cols = array_keys($this->set_col);
191
        foreach ($this->set_data as $num => $row) {
192
            $values = [];
193
            foreach ($cols as $col) {
194
                $values[] = isset($row[$col]) ?
195
                    $this->processValue($row[$col], $settings) :
196
                    $this->nullOrDefault($settings);
197
            }
198
            $rows[] = '(' . join(', ', $values) . ')';
199
        }
200
        return $this->joinClause($prefix, ',', $rows, $settings);
201
    }
202
203
    /**
204
     * Get NULL or DEFAULT for values base on the settings
205
     *
206
     * @param  array $settings
207
     * @return string
208
     * @access protected
209
     */
210
    protected function nullOrDefault(array $settings)/*# : string */
211
    {
212
        return $settings['useNullAsDefault'] ? 'NULL' : 'DEFAULT';
213
    }
214
215
    abstract public function setSettings(array $settings);
216
    abstract protected function getType()/*# : string */;
217
    abstract protected function &getClause(/*# string */ $clauseName)/*# : array */;
218
    abstract protected function processValue($value, array $settings, /*# bool */ $between = false)/*# : string */;
219
    abstract protected function joinClause(
220
        /*# : string */ $prefix,
221
        /*# : string */ $seperator,
222
        array $clause,
223
        array $settings
224
    )/*# : string */;
225
    abstract protected function quote(/*# string */ $str, array $settings)/*# : string */;
226
}
227