GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Failed Conditions
Push — master ( f2da15...888a68 )
by Charlotte
05:28
created

src/Commands/StatementExecuteCommand.php (71 issues)

1
<?php
2
/**
3
 * Plasma Driver MySQL component
4
 * Copyright 2018 PlasmaPHP, All Rights Reserved
5
 *
6
 * Website: https://github.com/PlasmaPHP
7
 * License: https://github.com/PlasmaPHP/driver-mysql/blob/master/LICENSE
8
*/
9
10
namespace Plasma\Drivers\MySQL\Commands;
11
12
/**
13
 * Statement Execute command.
14
 * @internal
15
 */
16
class StatementExecuteCommand extends QueryCommand {
17
    /**
18
     * The identifier for this command.
19
     * @var int
20
     * @source
21
     */
22
    const COMMAND_ID = 0x17;
23
    
24
    /**
25
     * @var mixed
26
     */
27
    protected $id;
28
    
29
    /**
30
     * @var array
31
     */
32
    protected $params;
33
    
34
    /**
35
     * Constructor.
36
     * @param \Plasma\DriverInterface  $driver
37
     * @param mixed                    $id
38
     * @param string                   $query
39
     * @param array                    $params
40
     */
41
    function __construct(\Plasma\DriverInterface $driver, $id, string $query, array $params) {
42
        parent::__construct($driver, $query);
43
        
44
        $this->id = $id;
45
        $this->params = $params;
46
    }
47
    
48
    /**
49
     * Get the encoded message for writing to the database connection.
50
     * @return string
51
     */
52
    function getEncodedMessage(): string {
53
        $packet = \chr(static::COMMAND_ID);
54
        $packet .= \Plasma\BinaryBuffer::writeInt4($this->id);
55
        
56
        $packet .= "\0"; // Cursor type flag
57
        $packet .= \Plasma\BinaryBuffer::writeInt4(1); // Iteration count is always 1
58
        
59
        $paramCount = \count($this->params);
60
        
61
        $bitmapOffset = \strlen($packet);
62
        $packet .= \str_repeat("\0", (($paramCount + 7) >> 3));
63
        
64
        $bound = 0;
65
        
66
        $types = '';
67
        $values = '';
68
        
69
        foreach($this->params as $id => $param) {
70
            if($param === null) {
71
                $offset = $bitmapOffset + ($id >> 3);
72
                $packet[$offset] = $packet[$offset] | \chr((1 << ($id % 8)));
73
            } else {
74
                $bound = 1;
75
            }
76
            
77
            $unsigned = false;
78
            
79
            try {
80
                $manager = \Plasma\Types\TypeExtensionsManager::getManager('driver-mysql');
81
                $encode = $manager->encodeType($param);
82
                
83
                $unsigned = $encode->isUnsigned();
84
                $type = $encode->getSQLType();
85
                $value = $encode->getValue();
86
            } catch (\Plasma\Exception $e) {
87
                [ $unsigned, $type, $value ] = $this->stdEncodeValue($param);
88
            }
89
            
90
            $types .= \chr($type);
91
            $types .= ($unsigned ? "\x80" : "\0");
92
            
93
            $values .= $value;
94
        }
95
        
96
        $packet .= \chr($bound);
97
        
98
        if($bound) {
99
            $packet .= $types;
100
            $packet .= $values;
101
        }
102
        
103
        return $packet;
104
    }
105
    
106
    /**
107
     * Whether the sequence ID should be resetted.
108
     * @return bool
109
     */
110
    function resetSequence(): bool {
111
        return false;
112
    }
113
    
114
    /**
115
     * Parses the binary resultset row and returns the row.
116
     * @param \Plasma\ColumnDefinitionInterface  $column
117
     * @param \Plasma\BinaryBuffer               $buffer
0 ignored issues
show
Superfluous parameter comment
Loading history...
118
     * @return array
119
     */
120
    protected function parseResultsetRow(\Plasma\BinaryBuffer $buffer): array {
121
        //var_dump(unpack('C*', $buffer->getContents()));
122
        //$buffer = $buffer->read(1); // Skip first byte (header)
123
        
124
        $nullRow = array();
125
        $i = 0;
126
        
127
        /** @var \Plasma\ColumnDefinitionInterface  $column */
128
        foreach($this->fields as $column) { // Handle NULL-bitmap
129
            if((\ord($buffer[(($i + 2) >> 3)]) & (1 << (($i + 2) % 8))) !== 0) {
130
                $nullRow[$column->getName()] = null;
131
            }
132
            
133
            $i++;
134
        }
135
        
136
        $buffer->read(((\count($this->fields) + 9) >> 3)); // Remove NULL-bitmap
137
        $row = array();
138
        
139
        /** @var \Plasma\ColumnDefinitionInterface  $column */
140
        foreach($this->fields as $column) {
141
            if(\array_key_exists($columm->getName(), $nullRow)) {
142
                $row[$columm->getName()] = $nullRow[$columm->getName()];
143
                continue;
144
            }
145
            
146
            $value = $this->stdDecodeBinaryValue($column, $buffer);
147
            
148
            try {
149
                $strval = (string) $val;
150
                $value = $column->parseValue($strval);
151
            } catch (\Plasma\Exception $e) {
152
                /* Continue regardless of error */
153
            }
154
            
155
            $row[$column->getName()] = $value;
156
        }
157
        
158
        return $row;
159
    }
160
    
161
    /**
162
     * Standard encode value, if type extensions failed.
163
     * @param mixed  $param
164
     * @return array
165
     * @throws \Plasma\Exception
166
     */
167
    protected function stdEncodeValue($param): array {
168
        $unsigned = false;
169
        
170
        switch(\gettype($param)) {
171
            case 'boolean':
172
                $type = \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_TINY;
173
                $value = ($param ? "\x01" : "\0");
174
            break;
175
            case 'integer':
176
                if($param >= 0) {
177
                    $unsigned = true;
178
                }
179
                
180
                // TODO: Check if short, long or long long
181
                if($param >= 0 && $param < (1 << 15)) {
182
                    $type = \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_SHORT;
183
                    $value = \Plasma\BinaryBuffer::writeInt2($param);
184
                } elseif(\PHP_INT_SIZE === 4) {
185
                    $type = \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_LONG;
186
                    $value = \Plasma\BinaryBuffer::writeInt4($param);
187
                } else {
188
                    $type = \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_LONGLONG;
189
                    $value = \Plasma\BinaryBuffer::writeInt8($param);
190
                }
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
191
            break;
1 ignored issue
show
Case breaking statement indented incorrectly; expected 16 spaces, found 12
Loading history...
192
            case 'double':
193
                $type = \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_DOUBLE;
194
                $value = \Plasma\BinaryBuffer::writeFloat($param);
195
            break;
1 ignored issue
show
Case breaking statement indented incorrectly; expected 16 spaces, found 12
Loading history...
196
            case 'string':
197
                $type = \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_LONG_BLOB;
198
                
199
                $value = \Plasma\BinaryBuffer::writeInt4(\strlen($param));
200
                $value .= $param;
201
            break;
202
            case 'NULL':
203
                $type = \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_NULL;
204
                $value = '';
205
            break;
206
            default:
207
                throw new \Plasma\Exception('Unexpected type for binding parameter: '.\gettype($param));
208
            break;
209
        }
210
        
211
        return array($unsigned, $type, $value);
212
    }
213
    
214
    /**
215
     * Standard decode value, if type extensions failed.
216
     * @param \Plasma\ColumnDefinitionInterface  $column
217
     * @param \Plasma\BinaryBuffer               $buffer
218
     * @return mixed
219
     * @throws \Plasma\Exception
220
     */
221
    protected function stdDecodeBinaryValue(\Plasma\ColumnDefinitionInterface $column, \Plasma\BinaryBuffer $buffer) {
222
        $flags = $column->getFlags();
223
        
224
        switch(true) {
225
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_TINY) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
226
                $value = $buffer->readInt1();
227
                $value = $this->zeroFillInts($column, $value);
228
            break;
1 ignored issue
show
Case breaking statement indented incorrectly; expected 16 spaces, found 12
Loading history...
229
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_SHORT) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
230
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_YEAR) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
231
                $value = $buffer->readInt2();
232
                $value = $this->zeroFillInts($column, $value);
233
            break;
1 ignored issue
show
Case breaking statement indented incorrectly; expected 16 spaces, found 12
Loading history...
234
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_INT24) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
235
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_LONG) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
236
                $value = $buffer->readInt4();
237
            
238
                if(($flags & \Plasma\Drivers\MySQL\FieldFlags::UNSIGNED_FLAG) !== 0 && \PHP_INT_SIZE <= 4) {
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
239
                    $value = \bcadd($value, '18446744073709551616');
240
                }
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
241
                
242
                $value = $this->zeroFillInts($column, $value);
243
            break;
1 ignored issue
show
Case breaking statement indented incorrectly; expected 16 spaces, found 12
Loading history...
244
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_LONGLONG) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
245
                $value = $buffer->readInt8();
246
                
247
                if(($flags & \Plasma\Drivers\MySQL\FieldFlags::UNSIGNED_FLAG) !== 0) {
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
248
                    $value = \bcadd($value, '18446744073709551616');
249
                } elseif(\PHP_INT_SIZE > 4) {
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
250
                    $value = (int) $value;
251
                }
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
252
                
253
                $value = $this->zeroFillInts($column, $value);
254
            break;
1 ignored issue
show
Case breaking statement indented incorrectly; expected 16 spaces, found 12
Loading history...
255
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_FLOAT) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
256
                $value = $buffer->readFloat();
257
            break;
1 ignored issue
show
Case breaking statement indented incorrectly; expected 16 spaces, found 12
Loading history...
258
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_DOUBLE) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
259
                $value = $buffer->readDouble();
260
            break;
1 ignored issue
show
Case breaking statement indented incorrectly; expected 16 spaces, found 12
Loading history...
261
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_DATE) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
262
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_NEWDATE) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
263
                $length = $buffer->readIntLength();
264
                if($length > 0) {
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
265
                    $year = $buffer->readInt2();
266
                    $month = $buffer->readInt1();
267
                    $day = $buffer->readInt1();
268
                    
269
                    $value = \sprintf('%d-%d-%d', $year, $month, $day);
270
                } else {
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
271
                    $value = '0000-00-00';
272
                }
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
273
            break;
1 ignored issue
show
Case breaking statement indented incorrectly; expected 16 spaces, found 12
Loading history...
274
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_DATETIME) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
275
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_TIMESTAMP) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
276
                $length = $buffer->readIntLength();
277
                if($length > 0) {
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
278
                    $year = $buffer->readInt2();
279
                    $month = $buffer->readInt1();
280
                    $day = $buffer->readInt1();
281
                    
282
                    if($length > 4) {
1 ignored issue
show
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
283
                        $hour = $buffer->readInt1();
284
                        $min = $buffer->readInt1();
285
                        $sec = $buffer->readInt1();
286
                    } else {
1 ignored issue
show
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
287
                        $hour = 0;
288
                        $min = 0;
289
                        $sec = 0;
290
                    }
1 ignored issue
show
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
291
                    
292
                    if($length > 7) {
1 ignored issue
show
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
293
                        $micro = $buffer->readInt4();
294
                    } else {
1 ignored issue
show
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
295
                        $micro = 0;
296
                    }
1 ignored issue
show
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
297
                    
298
                    $timestamp = (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_TIMESTAMP) !== 0);
299
                    
300
                    $micro = \str_pad($micro, 6, '0', \STR_PAD_LEFT);
301
                    $micro = ($timestamp ? $micro : \number_format($micro, 0, '', ' '));
302
                    
303
                    $value = \sprintf('%d-%d-%d %d:%d:%d'.($micro > 0 ? '.%s' : ''), $year, $month, $day, $hour, $min, $sec, $micro);
304
                    
305
                    if($timestamp) {
1 ignored issue
show
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
306
                        $value = \DateTime::createFromFormat('Y-m-d H:i:s'.($micro > 0 ? '.u' : ''), $value)->getTimestamp();
307
                    }
1 ignored issue
show
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
308
                } else {
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
309
                    $value = '0000-00-00 00:00:00.000 000';
310
                }
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
311
            break;
1 ignored issue
show
Case breaking statement indented incorrectly; expected 16 spaces, found 12
Loading history...
312
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_TIME) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
313
                $length = $buffer->readIntLength();
314
                if($length > 0) {
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
315
                    $sign = $buffer->readInt1();
316
                    $days = $buffer->readInt4();
317
                    
318
                    if($sign === 1) {
1 ignored issue
show
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
319
                        $days *= -1;
320
                    }
1 ignored issue
show
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
321
                    
322
                    $hour = $buffer->readInt1();
323
                    $min = $buffer->readInt1();
324
                    $sec = $buffer->readInt1();
325
                    
326
                    if($length > 8) {
1 ignored issue
show
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
327
                        $micro = $buffer->readInt4();
328
                    } else {
1 ignored issue
show
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
329
                        $micro = 0;
330
                    }
1 ignored issue
show
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
331
                    
332
                    $micro = \str_pad($micro, 6, '0', \STR_PAD_LEFT);
333
                    $micro = \number_format($micro, 0, '', ' ');
334
                    
335
                    $value = \sprintf('%dd %d:%d:%d'.($micro > 0 ? '.%s' : ''), $days, $hour, $min, $sec, $micro);
336
                } else {
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
337
                    $value = '0d 00:00:00';
338
                }
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
339
            break;
1 ignored issue
show
Case breaking statement indented incorrectly; expected 16 spaces, found 12
Loading history...
340
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_STRING) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
341
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_VARCHAR) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
342
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_VAR_STRING) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
343
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_ENUM) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
344
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_SET) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
345
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_LONG_BLOB) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
346
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_MEDIUM_BLOB) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
347
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_BLOB) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
348
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_TINY_BLOB) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
349
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_GEOMETRY) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
350
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_BIT) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
351
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_DECIMAL) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
352
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_NEWDECIMAL) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
353
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_JSON) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
354
                $value = $buffer->readStringLength();
355
            break;
1 ignored issue
show
Case breaking statement indented incorrectly; expected 16 spaces, found 12
Loading history...
356
            case (($flags & \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_NULL) !== 0):
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
357
                $value = null;
358
            break;
1 ignored issue
show
Case breaking statement indented incorrectly; expected 16 spaces, found 12
Loading history...
359
            default:
1 ignored issue
show
Line indented incorrectly; expected 8 spaces, found 12
Loading history...
360
                throw new \InvalidArgumentException('Unknown column type (flags: '.$flags.', type: '.$column->getType().')');
361
            break;
362
        }
363
        
364
        return $value;
365
    }
366
    
367
    /**
368
     * @param \Plasma\ColumnDefinitionInterface  $column
369
     * @param string|int                         $value
370
     * @return string|int
371
     */
372
    protected function zeroFillInts(\Plasma\ColumnDefinitionInterface $column, $value) {
373
        $flags = $column->getFlags();
374
        
375
        if(($flags & \Plasma\Drivers\MySQL\FieldFlags::ZEROFILL_FLAG) !== 0) {
376
            $value = \str_pad(((string) $value), $column->getLength(), '0', \STR_PAD_LEFT);
377
        }
378
        
379
        return $value;
380
    }
381
}
382