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

PromiseCommand   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 269
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
eloc 98
dl 0
loc 269
ccs 0
cts 126
cp 0
rs 9.68
c 0
b 0
f 0
wmc 34

12 Methods

Rating   Name   Duplication   Size   Complexity  
A getPromise() 0 2 1
A setParserState() 0 2 1
A onComplete() 0 3 1
A handleQueryOnNextCaller() 0 11 3
C stdDecodeValue() 0 30 15
A __construct() 0 9 1
A parseColumnDefinition() 0 30 1
A parseResultsetRow() 0 19 3
A onError() 0 14 2
A hasFinished() 0 2 1
A handleQueryOnNextCallerColumns() 0 26 4
A waitForCompletion() 0 2 1
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
 * Abstract command which has a promise.
14
 * @internal
15
 */
16
abstract class PromiseCommand implements CommandInterface {
17
    use \Evenement\EventEmitterTrait;
18
    
19
    /**
20
     * @var \Plasma\DriverInterface
21
     */
22
    protected $driver;
23
    
24
    /**
25
     * @var \React\Promise\Deferred
26
     */
27
    protected $deferred;
28
    
29
    /**
30
     * @var mixed
31
     */
32
    protected $resolveValue;
33
    
34
    /**
35
     * @var bool
36
     */
37
    protected $finished = false;
38
    
39
    /**
40
     * Constructor.
41
     * @param \Plasma\DriverInterface  $driver
42
     */
43
    function __construct(\Plasma\DriverInterface $driver) {
0 ignored issues
show
Unused Code introduced by
The parameter $driver is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

43
    function __construct(/** @scrutinizer ignore-unused */ \Plasma\DriverInterface $driver) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
44
        $this->deferred = new \React\Promise\Deferred();
45
        
46
        $this->once('error', function (\Throwable $error) {
47
            $this->deferred->reject($error);
48
        });
49
        
50
        $this->once('end', function () {
51
            $this->deferred->resolve($this->resolveValue);
52
        });
53
    }
54
    
55
    /**
56
     * Get the encoded message for writing to the database connection.
57
     * @return string
58
     */
59
    abstract function getEncodedMessage(): string;
60
    
61
    /**
62
     * Get the promise.
63
     * @var \React\Promise\PromiseInterface
64
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
65
    function getPromise(): \React\Promise\PromiseInterface {
66
        return $this->deferred->promise();
67
    }
68
    
69
    /**
70
     * Sets the parser state, if necessary. If not, return `-1`.
71
     * @return int
72
     */
73
    function setParserState(): int {
74
        return -1;
75
    }
76
    
77
    /**
78
     * Sets the command as completed. This state gets reported back to the user.
79
     * @return void
80
     */
81
    function onComplete(): void {
82
        $this->finished = true;
83
        $this->emit('end');
84
    }
85
    
86
    /**
87
     * Sets the command as errored. This state gets reported back to the user.
88
     * @param \Throwable  $throwable
89
     * @return void
90
     */
91
    function onError(\Throwable $throwable): void {
92
        $this->finished = true;
93
        
94
        if($this->resolveValue !== null) {
95
            // Workaround for getting the promise resolved AFTER receiving and processing an error packet,
96
            // so we would miss the error packet
97
            $this->driver->getLoop()->futureTick(function () use ($throwable) {
98
                $this->emit('error', array($throwable));
99
            });
100
            
101
            return;
102
        }
103
        
104
        $this->emit('error', array($throwable));
105
    }
106
    
107
    /**
108
     * Sends the next received value into the command.
109
     * @param mixed  $value
110
     * @return void
111
     */
112
    abstract function onNext($value): void;
113
    
114
    /**
115
     * Whether the command has finished.
116
     * @return bool
117
     */
118
    function hasFinished(): bool {
119
        return $this->finished;
120
    }
121
    
122
    /**
123
     * Whether this command sets the connection as busy.
124
     * @return bool
125
     */
126
    function waitForCompletion(): bool {
127
        return true;
128
    }
129
    
130
    /**
131
     * Handles query commands on next caller.
132
     * @param \Plasma\Drivers\MySQL\ProtocolOnNextCaller  $value
133
     * @return void
134
     */
135
    function handleQueryOnNextCaller(\Plasma\Drivers\MySQL\ProtocolOnNextCaller $value): void {
136
        $buffer = $value->getBuffer();
137
        $parser = $value->getParser();
138
        
139
        if($this->resolveValue !== null) {
140
            $row = $this->parseResultsetRow($buffer);
141
            $this->emit('data', array($row));
142
        } else {
143
            $field = $this->handleQueryOnNextCallerColumns($buffer, $parser);
144
            if($field) {
1 ignored issue
show
introduced by
$field is of type Plasma\ColumnDefinition, thus it always evaluated to true.
Loading history...
145
                $this->fields[$field->getName()] = $field;
0 ignored issues
show
Bug Best Practice introduced by
The property fields does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
146
            }
147
        }
148
    }
149
    
150
    /**
151
     * Handles the column definitions of query commands on next caller.
152
     * @param \Plasma\BinaryBuffer                  $buffer
153
     * @param \Plasma\Drivers\MySQL\ProtocolParser  $parser
154
     * @return \Plasma\ColumnDefinitionInterface|null
155
     */
156
    function handleQueryOnNextCallerColumns(\Plasma\BinaryBuffer $buffer, \Plasma\Drivers\MySQL\ProtocolParser $parser): ?\Plasma\ColumnDefinitionInterface {
157
        if($this->fieldsCount === null) {
158
            $fieldCount = $buffer->readIntLength();
159
            
160
            if($fieldCount === 0xFB) {
161
                // Handle it on future tick, so we can cleanly finish the buffer of this call
162
                $this->driver->getLoop()->futureTick(function () use (&$buffer, &$parser) {
163
                    $localMsg = new \Plasma\Drivers\MySQL\Messages\LocalInFileRequestMessage($parser);
164
                    $parser->handleMessage($buffer, $localMsg);
165
                });
166
                
167
                return null;
168
            } elseif($fieldCount === 0x00) {
169
                $this->driver->getLoop()->futureTick(function () use (&$buffer, &$parser) {
170
                    $okMsg = new \Plasma\Drivers\MySQL\Messages\OkResponseMessage($parser);
171
                    $parser->handleMessage($buffer, $okMsg);
172
                });
173
                
174
                return null;
175
            }
176
            
177
            $this->fieldsCount = $fieldCount;
0 ignored issues
show
Bug Best Practice introduced by
The property fieldsCount does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
178
            return null;
179
        }
180
        
181
        return static::parseColumnDefinition($buffer);
182
    }
183
    
184
    /**
185
     * Parses the column definition.
186
     * @param \Plasma\BinaryBuffer  $buffer
187
     * @return \Plasma\ColumnDefinitionInterface
188
     */
189
    static function parseColumnDefinition(\Plasma\BinaryBuffer $buffer): \Plasma\ColumnDefinitionInterface {
190
        \Plasma\Drivers\MySQL\Messages\MessageUtility::debug('CD 5 bytes: '.implode(', ', unpack('C*', \substr($buffer->getContents(), 0, 5))));
191
        $buffer->readStringLength(); // catalog - always "def"
192
        $database = $buffer->readStringLength();
193
        
194
        $table = $buffer->readStringLength();
195
        $buffer->readStringLength(); // orgTable
196
        
197
        $name = $buffer->readStringLength();
198
        $buffer->readStringLength(); // orgName
199
        
200
        $buffer->read(1); // 0x0C
201
        
202
        $charset = $buffer->readInt2();
203
        $length = $buffer->readInt4();
204
        $type = $buffer->readInt1();
205
        $flags = $buffer->readInt2();
206
        $decimals = $buffer->readInt1();
207
        
208
        $buffer->read(2); // fillers
209
        
210
        /*if($this instanceof COM_FIELD_LIST) {
211
            $buffer->readStringLength();
212
        }*/
213
        
214
        $charset = \Plasma\Drivers\MySQL\CharacterSetFlags::CHARSET_MAP[$charset] ?? 'Unknown charset "'.$charset.'"';
215
        $type = \Plasma\Drivers\MySQL\FieldFlags::TYPE_MAP[$type] ?? 'Unknown type "'.$type.'"';
216
        $nullable = (($flags & \Plasma\Drivers\MySQL\FieldFlags::NOT_NULL_FLAG) === 0);
217
        
218
        return (new \Plasma\ColumnDefinition($database, $table, $name, $type, $charset, $length, $nullable, $flags, $decimals));
3 ignored issues
show
Bug introduced by
It seems like $name can also be of type null; however, parameter $name of Plasma\ColumnDefinition::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

218
        return (new \Plasma\ColumnDefinition($database, $table, /** @scrutinizer ignore-type */ $name, $type, $charset, $length, $nullable, $flags, $decimals));
Loading history...
Bug introduced by
It seems like $table can also be of type null; however, parameter $table of Plasma\ColumnDefinition::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

218
        return (new \Plasma\ColumnDefinition($database, /** @scrutinizer ignore-type */ $table, $name, $type, $charset, $length, $nullable, $flags, $decimals));
Loading history...
Bug introduced by
It seems like $database can also be of type null; however, parameter $database of Plasma\ColumnDefinition::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

218
        return (new \Plasma\ColumnDefinition(/** @scrutinizer ignore-type */ $database, $table, $name, $type, $charset, $length, $nullable, $flags, $decimals));
Loading history...
219
    }
220
    
221
    /**
222
     * Parses the text resultset row and returns the row.
223
     * @param \Plasma\ColumnDefinitionInterface  $column
0 ignored issues
show
Coding Style introduced by
Doc comment for parameter $column does not match actual variable name $buffer
Loading history...
224
     * @param \Plasma\BinaryBuffer               $buffer
0 ignored issues
show
Coding Style introduced by
Superfluous parameter comment
Loading history...
225
     * @return array
226
     */
227
    protected function parseResultsetRow(\Plasma\BinaryBuffer $buffer): array {
228
        $row = array();
229
        
230
        /** @var \Plasma\ColumnDefinitionInterface  $column */
231
        foreach($this->fields as $column) {
232
            $rawValue = $buffer->readStringLength();
233
            
234
            try {
235
                $value = \Plasma\Types\TypeExtensionsManager::getManager('driver-mysql')
236
                    ->decodeType($column->getType(), $rawValue)
237
                    ->getValue();
238
            } catch (\Plasma\Exception $e) {
239
                $value = $this->stdDecodeValue($column, $rawValue);
0 ignored issues
show
Bug introduced by
It seems like $rawValue can also be of type null; however, parameter $param of Plasma\Drivers\MySQL\Com...mmand::stdDecodeValue() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

239
                $value = $this->stdDecodeValue($column, /** @scrutinizer ignore-type */ $rawValue);
Loading history...
240
            }
241
            
242
            $row[$column->getName()] = $value;
243
        }
244
        
245
        return $row;
246
    }
247
    
248
    /**
249
     * Standard decode value, if type extensions failed.
250
     * @param \Plasma\ColumnDefinitionInterface  $column
251
     * @param string                             $param
252
     * @return mixed
253
     * @throws \Plasma\Exception
254
     */
255
    protected function stdDecodeValue(\Plasma\ColumnDefinitionInterface $column, string $param) {
256
        $flags = $column->getFlags();
257
        
258
        if($param !== null && ($flags & \Plasma\Drivers\MySQL\FieldFlags::ZEROFILL_FLAG) === 0) {
259
            switch($column->getType()) {
260
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_LONG:
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
261
                    if(($flags & \Plasma\Drivers\MySQL\FieldFlags::UNSIGNED_FLAG) === 0 || \PHP_INT_SIZE > 4) {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
262
                        $param = (int) $param;
263
                    }
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
264
                break;
1 ignored issue
show
Coding Style introduced by
Case breaking statement indented incorrectly; expected 20 spaces, found 16
Loading history...
265
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_LONGLONG:
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
266
                    if(($flags & \Plasma\Drivers\MySQL\FieldFlags::UNSIGNED_FLAG) === 0 && \PHP_INT_SIZE > 4) {
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
267
                        $param = (int) $param;
268
                    }
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 16 spaces, found 20
Loading history...
269
                break;
1 ignored issue
show
Coding Style introduced by
Case breaking statement indented incorrectly; expected 20 spaces, found 16
Loading history...
270
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_TINY:
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
271
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_SHORT:
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
272
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_INT24:
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
273
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_TIMESTAMP:
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
274
                    $param = (int) $param;
275
                break;
1 ignored issue
show
Coding Style introduced by
Case breaking statement indented incorrectly; expected 20 spaces, found 16
Loading history...
276
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_FLOAT:
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
277
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_DOUBLE:
1 ignored issue
show
Coding Style introduced by
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
278
                    $param = (float) $param;
279
                break;
1 ignored issue
show
Coding Style introduced by
Case breaking statement indented incorrectly; expected 20 spaces, found 16
Loading history...
280
                // Other types are taken as string
281
            }
282
        }
283
        
284
        return $param;
285
    }
286
}
287