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 ( 888a68...c84b74 )
by Charlotte
05:53
created

src/Commands/PromiseCommand.php (1 issue)

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) {
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
            // Let the event loop read the stream buffer before resolving
52
            $this->driver->getLoop()->futureTick(function () {
53
                $this->deferred->resolve($this->resolveValue);
54
                $this->resolveValue = null;
55
            });
56
        });
57
    }
58
    
59
    /**
60
     * Get the encoded message for writing to the database connection.
61
     * @return string
62
     */
63
    abstract function getEncodedMessage(): string;
64
    
65
    /**
66
     * Get the promise.
67
     * @var \React\Promise\PromiseInterface
68
     */
69
    function getPromise(): \React\Promise\PromiseInterface {
70
        return $this->deferred->promise();
71
    }
72
    
73
    /**
74
     * Sets the parser state, if necessary. If not, return `-1`.
75
     * @return int
76
     */
77
    function setParserState(): int {
78
        return -1;
79
    }
80
    
81
    /**
82
     * Sets the command as completed. This state gets reported back to the user.
83
     * @return void
84
     */
85
    function onComplete(): void {
86
        $this->finished = true;
87
        $this->emit('end');
88
    }
89
    
90
    /**
91
     * Sets the command as errored. This state gets reported back to the user.
92
     * @param \Throwable  $throwable
93
     * @return void
94
     */
95
    function onError(\Throwable $throwable): void {
96
        $this->finished = true;
97
        
98
        if($this->resolveValue !== null) {
99
            // Let the event loop read the stream buffer and resolve the promise before emitting
100
            // Works around a race condition, where the promise resolves
101
            // after receiving an error response packet
102
            // and therefore the user misses the error event
103
            $this->driver->getLoop()->futureTick(function () use (&$throwable) {
104
                $this->emit('error', array($throwable));
105
            });
106
            
107
            return;
108
        }
109
        
110
        $this->emit('error', array($throwable));
111
    }
112
    
113
    /**
114
     * Sends the next received value into the command.
115
     * @param mixed  $value
116
     * @return void
117
     */
118
    abstract function onNext($value): void;
119
    
120
    /**
121
     * Whether the command has finished.
122
     * @return bool
123
     */
124
    function hasFinished(): bool {
125
        return $this->finished;
126
    }
127
    
128
    /**
129
     * Whether this command sets the connection as busy.
130
     * @return bool
131
     */
132
    function waitForCompletion(): bool {
133
        return true;
134
    }
135
    
136
    /**
137
     * Whether the sequence ID should be resetted.
138
     * @return bool
139
     */
140
    abstract function resetSequence(): bool;
141
    
142
    /**
143
     * Handles the column definitions of query commands on next caller.
144
     * @param \Plasma\BinaryBuffer                  $buffer
145
     * @param \Plasma\Drivers\MySQL\ProtocolParser  $parser
146
     * @return \Plasma\ColumnDefinitionInterface|null
147
     */
148
    function handleQueryOnNextCallerColumns(\Plasma\BinaryBuffer $buffer, \Plasma\Drivers\MySQL\ProtocolParser $parser): ?\Plasma\ColumnDefinitionInterface {
149
        if($this->fieldsCount === null) {
150
            $fieldCount = $buffer->readIntLength();
151
            
152
            if($fieldCount === 0x00) {
153
                $this->driver->getLoop()->futureTick(function () use (&$buffer, &$parser) {
154
                    $msg = new \Plasma\Drivers\MySQL\Messages\OkResponseMessage($parser);
155
                    $parser->handleMessage($buffer, $msg);
156
                });
157
                
158
                return null;
159
            } elseif($fieldCount === 0xFB) {
160
                // Handle it on future tick, so we can cleanly finish the buffer of this call
161
                $this->driver->getLoop()->futureTick(function () use (&$buffer, &$parser) {
162
                    $msg = new \Plasma\Drivers\MySQL\Messages\LocalInFileRequestMessage($parser);
163
                    $parser->handleMessage($buffer, $msg);
164
                });
165
                
166
                return null;
167
            } elseif($fieldCount === 0xFF) {
168
                $this->driver->getLoop()->futureTick(function () use (&$buffer, &$parser) {
169
                    $msg = new \Plasma\Drivers\MySQL\Messages\ErrResponseMessage($parser);
170
                    $parser->handleMessage($buffer, $msg);
171
                });
172
                
173
                return null;
174
            }
175
            
176
            $this->fieldsCount = $fieldCount;
177
            return null;
178
        }
179
        
180
        return static::parseColumnDefinition($buffer);
181
    }
182
    
183
    /**
184
     * Parses the column definition.
185
     * @param \Plasma\BinaryBuffer  $buffer
186
     * @return \Plasma\ColumnDefinitionInterface
187
     */
188
    static function parseColumnDefinition(\Plasma\BinaryBuffer $buffer): \Plasma\ColumnDefinitionInterface {
189
        $buffer->readStringLength(); // catalog - always "def"
190
        $database = $buffer->readStringLength();
191
        
192
        $table = $buffer->readStringLength();
193
        $buffer->readStringLength(); // orgTable
194
        
195
        $name = $buffer->readStringLength();
196
        $buffer->readStringLength(); // orgName
197
        
198
        $buffer->read(1); // 0x0C
199
        
200
        $charset = $buffer->readInt2();
201
        $length = $buffer->readInt4();
202
        $type = $buffer->readInt1();
203
        $flags = $buffer->readInt2();
204
        $decimals = $buffer->readInt1();
205
        
206
        $buffer->read(2); // fillers
207
        
208
        /*if($this instanceof COM_FIELD_LIST) {
209
            $buffer->readStringLength();
210
        }*/
211
        
212
        $charset = \Plasma\Drivers\MySQL\CharacterSetFlags::CHARSET_MAP[$charset] ?? 'Unknown charset "'.$charset.'"';
213
        $type = \Plasma\Drivers\MySQL\FieldFlags::TYPE_MAP[$type] ?? 'Unknown type "'.$type.'"';
214
        $nullable = (($flags & \Plasma\Drivers\MySQL\FieldFlags::NOT_NULL_FLAG) === 0);
215
        
216
        return (new \Plasma\ColumnDefinition($database, $table, $name, $type, $charset, $length, $nullable, $flags, $decimals));
217
    }
218
    
219
    /**
220
     * Parses the text resultset row and returns the row.
221
     * @param \Plasma\ColumnDefinitionInterface  $column
222
     * @param \Plasma\BinaryBuffer               $buffer
223
     * @return array
224
     */
225
    protected function parseResultsetRow(\Plasma\BinaryBuffer $buffer): array {
226
        $row = array();
227
        
228
        /** @var \Plasma\ColumnDefinitionInterface  $column */
229
        foreach($this->fields as $column) {
230
            $rawValue = $buffer->readStringLength();
231
            
232
            try {
233
                $value = \Plasma\Types\TypeExtensionsManager::getManager('driver-mysql')
234
                    ->decodeType($column->getType(), $rawValue)
235
                    ->getValue();
236
            } catch (\Plasma\Exception $e) {
237
                $value = $this->stdDecodeValue($column, $rawValue);
238
            }
239
            
240
            $row[$column->getName()] = $value;
241
        }
242
        
243
        return $row;
244
    }
245
    
246
    /**
247
     * Standard decode value, if type extensions failed.
248
     * @param \Plasma\ColumnDefinitionInterface  $column
249
     * @param string                             $param
250
     * @return mixed
251
     * @throws \Plasma\Exception
252
     */
253
    protected function stdDecodeValue(\Plasma\ColumnDefinitionInterface $column, string $param) {
254
        $flags = $column->getFlags();
255
        
256
        if($param !== null && ($flags & \Plasma\Drivers\MySQL\FieldFlags::ZEROFILL_FLAG) === 0) {
257
            switch($column->getType()) {
258
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_LONG:
259
                    if(($flags & \Plasma\Drivers\MySQL\FieldFlags::UNSIGNED_FLAG) === 0 || \PHP_INT_SIZE > 4) {
260
                        $param = (int) $param;
261
                    }
262
                break;
263
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_LONGLONG:
264
                    if(($flags & \Plasma\Drivers\MySQL\FieldFlags::UNSIGNED_FLAG) === 0 && \PHP_INT_SIZE > 4) {
265
                        $param = (int) $param;
266
                    }
267
                break;
268
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_TINY:
269
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_SHORT:
270
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_INT24:
271
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_TIMESTAMP:
272
                    $param = (int) $param;
273
                break;
274
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_FLOAT:
275
                case \Plasma\Drivers\MySQL\FieldFlags::FIELD_TYPE_DOUBLE:
1 ignored issue
show
Line indented incorrectly; expected 12 spaces, found 16
Loading history...
276
                    $param = (float) $param;
277
                break;
278
                // Other types are taken as string
279
            }
280
        }
281
        
282
        return $param;
283
    }
284
}
285