Completed
Push — dev ( 854c84...23e5a8 )
by joanhey
01:06
created

QueryGenerator::update()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 2
dl 0
loc 16
rs 9.7333
c 0
b 0
f 0
1
<?php
2
/**
3
 * KumbiaPHP web & app Framework.
4
 *
5
 * LICENSE
6
 *
7
 * This source file is subject to the new BSD license that is bundled
8
 * with this package in the file LICENSE.txt.
9
 * It is also available through the world-wide-web at this URL:
10
 * http://wiki.kumbiaphp.com/Licencia
11
 * If you did not receive a copy of the license and are unable to
12
 * obtain it through the world-wide-web, please send an email
13
 * to [email protected] so we can send you a copy immediately.
14
 *
15
 * @category   Kumbia
16
 *
17
 * @copyright  2005 - 2016  Kumbia Team (http://www.kumbiaphp.com)
18
 * @license    http://wiki.kumbiaphp.com/Licencia     New BSD License
19
 */
20
namespace Kumbia\ActiveRecord;
21
22
/**
23
 * Generador de codigo SQL.
24
 */
25
class QueryGenerator
26
{
27
    /**
28
     * Construye una consulta select desde una lista de parametros.
29
     *
30
     *                       where: condiciones where
31
     *                       order: criterio de ordenamiento
32
     *                       fields: lista de campos
33
     *                       join: joins de tablas
34
     *                       group: agrupar campos
35
     *                       having: condiciones de grupo
36
     *                       limit: valor limit
37
     *                       offset: valor offset
38
     * @param  array     $params    parametros de consulta select
39
     * @param  string    $source
40
     * @param  string    $type
41
     * @return string
42
     */
43
    public static function select($source, $type, array $params)
44
    {
45
        $params = array_merge([
46
            'fields' => '*',
47
            'join'   => '',
48
            'limit'  => \null,
49
            'offset' => \null,
50
            'where'  => \null,
51
            'group'  => \null,
52
            'having' => \null,
53
            'order'  => \null
54
        ], $params);
55
56
        list($where, $group, $having, $order) = static::prepareParam($params);
57
        $sql                                  = "SELECT {$params['fields']} FROM $source {$params['join']} $where $group $having $order";
58
59
        if ( ! \is_null($params['limit']) || ! \is_null($params['offset'])) {
60
            $sql = self::query($type, 'limit', $sql, $params['limit'], $params['offset']);
61
        }
62
63
        return $sql;
64
    }
65
66
    /**
67
     * Permite construir el WHERE, GROUP BY, HAVING y ORDER BY de una consulta SQL
68
     * en base a los parámetros $params.
69
     *
70
     * @param  array   $params
71
     * @return array
72
     */
73
    protected static function prepareParam(array $params)
74
    {
75
        return [
76
            static::where($params['where']),
77
            static::group($params['group']),
78
            static::having($params['having']),
79
            static::order($params['order'])
80
        ];
81
    }
82
83
    /**
84
     * Genera una sentencia where.
85
     *
86
     * @param  string $where
87
     * @return string
88
     */
89
    protected static function where($where)
90
    {
91
        return empty($where) ? '' : "WHERE $where";
92
    }
93
94
    /**
95
     * Genera una sentencia GROUP.
96
     *
97
     * @param  string $group
98
     * @return string
99
     */
100
    protected static function group($group)
101
    {
102
        return empty($group) ? '' : "GROUP BY $group";
103
    }
104
105
    /**
106
     * Genera una sentencia HAVING.
107
     *
108
     * @param  string $having
109
     * @return string
110
     */
111
    protected static function having($having)
112
    {
113
        return empty($having) ? '' : "HAVING $having";
114
    }
115
116
    /**
117
     * Genera una sentencia ORDER BY.
118
     *
119
     * @param  string $order
120
     * @return string
121
     */
122
    protected static function order($order)
123
    {
124
        return empty($order) ? '' : "ORDER BY $order";
125
    }
126
127
    /**
128
     * Construye una consulta INSERT.
129
     *
130
     * @param  LiteRecord $model Modelo a actualizar
131
     * @param  array      $data  Datos pasados a la consulta preparada
132
     * @return string
133
     */
134
    public static function insert(LiteRecord $model, array &$data)
135
    {
136
        $meta    = $model::metadata();
137
        $data    = [];
138
        $columns = [];
139
        $values  = [];
140
141
        // Preparar consulta
142
        foreach ($meta->getFieldsList() as $field) {
143
            $columns[] = $field;
144
            static::insertField($field, $model, $data, $values);
145
        }
146
        $columns = \implode(',', $columns);
147
        $values  = \implode(',', $values);
148
        $source  = $model::getSource();
149
150
        return "INSERT INTO $source ($columns) VALUES ($values)";
151
    }
152
153
    /**
154
     * Agrega un campo a para generar una consulta preparada para un INSERT.
155
     *
156
     * @param  string     $field  Nombre del campo
157
     * @param  LiteRecord $model  valor del campo
158
     * @param  array      $data   array de datos
159
     * @param  array      $values array de valores
160
     * @return void
161
     */
162
    protected static function insertField($field, LiteRecord $model, array &$data, array &$values)
163
    {
164
        $meta        = $model::metadata();
165
        $withDefault = $meta->getWithDefault();
0 ignored issues
show
Unused Code introduced by
$withDefault is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
166
        $autoFields  = $meta->getAutoFields();
0 ignored issues
show
Unused Code introduced by
$autoFields is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
167
        if (self::haveValue($model, $field)) {
168
            $data[":$field"] = $model->$field;
169
            $values[]        = ":$field";
170
        } else {
171
//if (!\in_array($field, $withDefault) && !\in_array($field, $autoFields)) {
172
            $values[] = 'NULL';
173
        }
174
    }
175
176
    /**
177
     * Permite conocer si la columna debe definirse como nula.
178
     *
179
     * @param  LiteRecord $model
180
     * @param  string     $field
181
     * @return bool
182
     */
183
    protected static function haveValue(LiteRecord $model, $field)
184
    {
185
        return isset($model->$field) && $model->$field !== '';
186
    }
187
188
    /**
189
     * Construye una consulta UPDATE.
190
     *
191
     * @param  LiteRecord $model Modelo a actualizar
192
     * @param  array      $data  Datos pasados a la consulta preparada
193
     * @return string
194
     */
195
    public static function update(LiteRecord $model, array &$data)
196
    {
197
        $set = [];
198
        $pk  = $model::getPK();
199
        /*elimina la clave primaria*/
200
        $list = \array_diff($model::metadata()->getFieldsList(), [$pk]);
201
        foreach ($list as $field) {
202
            $value = isset($model->$field) ? $model->$field : \null;
203
            static::updateField($field, $value, $data, $set);
204
        }
205
        $set          = \implode(', ', $set);
206
        $source       = $model::getSource();
207
        $data[":$pk"] = $model->$pk;
208
209
        return "UPDATE $source SET $set WHERE $pk = :$pk";
210
    }
211
212
    /**
213
     * Generate SQL for DELETE sentence.
214
     *
215
     * @param  string $source source
216
     * @param  string $where  condition
217
     * @return string SQL
218
     */
219
    public static function deleteAll($source, $where)
220
    {
221
        return "DELETE FROM $source ".static::where($where);
222
    }
223
224
    /**
225
     * Generate SQL for COUNT sentence.
226
     *
227
     * @param  string $source source
228
     * @param  string $where  condition
229
     * @return string SQL
230
     */
231
    public static function count($source, $where)
232
    {
233
        return "SELECT COUNT(*) AS count FROM $source ".static::where($where);
234
    }
235
236
    /**
237
     * Agrega un campo a para generar una consulta preparada para un UPDATE.
238
     *
239
     * @param  string $field Nombre del campo
240
     * @param  mixed  $value valor
241
     * @param  array  $data  array de datos
242
     * @param  array  $set   array de valores
243
     * @return void
244
     */
245
    protected static function updateField($field, $value, array &$data, array &$set)
246
    {
247
        if ( ! empty($value)) {
248
            $data[":$field"] = $value;
249
            $set[]           = "$field = :$field";
250
        } else {
251
            $set[] = "$field = NULL";
252
        }
253
    }
254
255
    /**
256
     * Construye una consulta UPDATE.
257
     *
258
     * @todo ¿Hay que escapar los nombres de los campos?
259
     * @param  string      $model   nombre del modelo a actualizar
260
     * @param  array       $fields  campos a actualizar
261
     * @param  array       $data    Datos pasados a la consulta preparada
262
     * @param  string|null $where
263
     * @return string
264
     */
265
    public static function updateAll($model, array $fields, array &$data, $where)
266
    {
267
        $set = [];
268
        //$pk = $model::getPK();
269
        /*elimina la clave primaria*/
270
        foreach ($fields as $field => $value) {
271
            static::updateField($field, $value, $data, $set);
272
        }
273
        $set    = \implode(', ', $set);
274
        $source = $model::getSource();
275
        $where  = static::where($where);
276
277
        return "UPDATE $source SET $set $where";
278
    }
279
280
    /**
281
     * Ejecuta una consulta.
282
     *
283
     * @thow KumbiaException
284
     * @param  string  $type           tipo de driver
285
     * @param  string  $query_function nombre de funcion
286
     * @return mixed
287
     */
288
    public static function query($type, $query_function)
289
    {
290
        $query_function = "{$type}_{$query_function}";
291
292
        require_once __DIR__."/Query/{$query_function}.php";
293
294
        $args = \array_slice(\func_get_args(), 2);
295
296
        return \call_user_func_array(__NAMESPACE__."\\Query\\$query_function", $args);
297
    }
298
}
299