Completed
Push — master ( 1efb78...46dbb7 )
by Hong
03:27
created

SetTrait::setWithArrayData()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 9
nc 3
nop 1
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
use Phossa2\Query\Misc\Template;
20
21
/**
22
 * SetTrait
23
 *
24
 * Implementation of SetInterface
25
 *
26
 * @package Phossa2\Query
27
 * @author  Hong Zhang <[email protected]>
28
 * @see     SetInterface
29
 * @version 2.0.0
30
 * @since   2.0.0 added
31
 */
32
trait SetTrait
33
{
34
    use AbstractTrait;
35
36
    /**
37
     * data storage
38
     *
39
     * @var    array
40
     * @access protected
41
     */
42
    protected $set_data = [];
43
44
    /**
45
     * data row number
46
     *
47
     * @var    int
48
     * @access protected
49
     */
50
    protected $set_row = 0;
51
52
    /**
53
     * storage for col names
54
     *
55
     * @var    array
56
     * @access protected
57
     */
58
    protected $set_col = [];
59
60
    /**
61
     * {@inheritDoc}
62
     */
63
    public function set($col, $value = ClauseInterface::NO_VALUE)
64
    {
65
        if (is_array($col)) { // array provided
66
            return $this->setWithArrayData($col);
67
        }
68
        if (!isset($this->set_col[$col])) { // save col names
69
            $this->set_col[$col] = true;
70
        }
71
        $this->set_data[$this->set_row][$col] = $value;
72
        return $this;
73
    }
74
75
    /**
76
     * {@inheritDoc}
77
     */
78
    public function setRaw(/*# string */ $col, $value = ClauseInterface::NO_VALUE)
79
    {
80
        if (ClauseInterface::NO_VALUE !== $value) {
81
            if (func_num_args() > 2) {
82
                $value = $this->getBuilder()
83
                    ->raw($value, (array) func_get_arg(2));
84
            } else {
85
                $value = $this->getBuilder()->raw($value);
86
            }
87
        }
88
        return $this->set((string) $col, $value);
89
    }
90
91
    /**
92
     * {@inheritDoc}
93
     */
94
    public function setTpl(/*# string */ $col, /*# string */ $template, $field)
95
    {
96
        if (func_num_args() > 3) {
97
            $template = $this->getBuilder()
98
                ->raw($template, (array) func_get_arg(3));
99
        }
100
        return $this->set($col, new Template($template, $field));
101
    }
102
103
    /**
104
     * Batch SET
105
     *
106
     * @param  array $data
107
     * @return $this
108
     * @access protected
109
     */
110
    protected function setWithArrayData(array $data)
111
    {
112
        if (isset($data[0])) { // multiple rows
113
            foreach ($data as $row) {
114
                $this->set($row);
115
            }
116
        } elseif (!empty($data)) { // multiple values
117
            foreach ($data as $col => $val) {
118
                $this->set($col, $val);
119
            }
120
            $this->set_row++;
121
        }
122
        return $this;
123
    }
124
125
    /**
126
     * Build SET
127
     *
128
     * @param  string $prefix
129
     * @param  array $settings
130
     * @return string
131
     * @access protected
132
     */
133
    protected function buildSet(
134
        /*# string */ $prefix,
135
        array $settings
136
    )/*# : array */ {
137
        if ('UPDATE' === $this->getType()) {
138
            return $this->buildUpdateSet($prefix, $settings);
139
        } else {
140
            return $this->buildInsertSet($prefix, $settings);
141
        }
142
    }
143
144
    /**
145
     * Build SET for INSERT
146
     *
147
     * @param  string $prefix
148
     * @param  array $settings
149
     * @return string
150
     * @access protected
151
     */
152
    protected function buildInsertSet(
153
        /*# string */ $prefix,
154
        array $settings
155
    )/*# : string */ {
156
        if (empty($this->set_data)) {
157
            return '';
158
        }
159
160
        $cols = [];
161
        foreach (array_keys($this->set_col) as $col) {
162
            $cols[] = $this->quote($col, $settings);
163
        }
164
        return $settings['seperator'] . '(' . join(', ', $cols) . ')';
165
    }
166
167
    /**
168
     * Build SET ... = ..., ... = ...
169
     *
170
     *
171
     * @param  string $prefix
172
     * @param  array $settings
173
     * @return string
174
     * @access protected
175
     */
176
    protected function buildUpdateSet(
177
        /*# string */ $prefix,
178
        array $settings
179
    )/*# : string */ {
180
        $result = [];
181
        foreach ($this->set_data[0] as $col => $val) {
182
            if (ClauseInterface::NO_VALUE === $val) {
183
                $result[] = $col;
184
            } else {
185
                $result[] = $this->quote($col, $settings) . ' = ' .
186
                    $this->processValue($val, $settings);
187
            }
188
        }
189
        return $this->joinClause($prefix, ',', $result, $settings);
190
    }
191
192
    /**
193
     * Build VALUES ( ... )
194
     *
195
     * @param  string $prefix
196
     * @param  array $settings
197
     * @return string
198
     * @access protected
199
     */
200
    protected function buildValues(
201
        /*# string */ $prefix,
202
        array $settings
203
    )/*# : string */ {
204
        $rows = [];
205
        $cols = array_keys($this->set_col);
206
        foreach ($this->set_data as $num => $row) {
207
            $values = [];
208
            foreach ($cols as $col) {
209
                $values[] = isset($row[$col]) ?
210
                    $this->processValue($row[$col], $settings) :
211
                    $this->nullOrDefault($settings);
212
            }
213
            $rows[] = '(' . join(', ', $values) . ')';
214
        }
215
        return $this->joinClause($prefix, ',', $rows, $settings);
216
    }
217
218
    /**
219
     * Get NULL or DEFAULT for values base on the settings
220
     *
221
     * @param  array $settings
222
     * @return string
223
     * @access protected
224
     */
225
    protected function nullOrDefault(array $settings)/*# : string */
226
    {
227
        return $settings['useNullAsDefault'] ? 'NULL' : 'DEFAULT';
228
    }
229
}
230