Completed
Branch master (e178de)
by kacper
06:21
created

Event::consume()   C

Complexity

Conditions 14
Paths 25

Size

Total Lines 55
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 35
CRAP Score 14.9079

Importance

Changes 0
Metric Value
cc 14
eloc 35
nc 25
nop 0
dl 0
loc 55
ccs 35
cts 42
cp 0.8333
crap 14.9079
rs 6.7491
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace MySQLReplication\Event;
4
5
use MySQLReplication\BinaryDataReader\BinaryDataReader;
6
use MySQLReplication\BinaryDataReader\BinaryDataReaderException;
7
use MySQLReplication\BinLog\BinLogException;
8
use MySQLReplication\BinLog\BinLogServerInfo;
9
use MySQLReplication\BinLog\BinLogSocketConnect;
10
use MySQLReplication\Config\Config;
11
use MySQLReplication\Definitions\ConstEventType;
12
use MySQLReplication\Event\DTO\EventDTO;
13
use MySQLReplication\Event\DTO\FormatDescriptionEventDTO;
14
use MySQLReplication\Event\DTO\HeartbeatDTO;
15
use MySQLReplication\Event\DTO\QueryDTO;
16
use MySQLReplication\Event\RowEvent\RowEventFactory;
17
use MySQLReplication\Exception\MySQLReplicationException;
18
use MySQLReplication\JsonBinaryDecoder\JsonBinaryDecoderException;
19
use MySQLReplication\Socket\SocketException;
20
use Psr\SimpleCache\CacheInterface;
21
use Psr\SimpleCache\InvalidArgumentException;
22
use Symfony\Component\EventDispatcher\EventDispatcher;
23
24
/**
25
 * Class Event
26
 * @package MySQLReplication\Event
27
 */
28
class Event
29
{
30
    const MARIADB_DUMMY_QUERY = '# Dum';
31
    const EOF_HEADER_VALUE = 254;
32
33
    /**
34
     * @var BinLogSocketConnect
35
     */
36
    private $binLogSocketConnect;
37
    /**
38
     * @var RowEventFactory
39
     */
40
    private $rowEventFactory;
41
    /**
42
     * @var EventDispatcher
43
     */
44
    private $eventDispatcher;
45
    /**
46
     * @var CacheInterface
47
     */
48
    private $cache;
49
50
    /**
51
     * BinLogPack constructor.
52
     * @param BinLogSocketConnect $binLogSocketConnect
53
     * @param RowEventFactory $rowEventFactory
54
     * @param EventDispatcher $eventDispatcher
55
     * @param CacheInterface $cache
56
     */
57 55
    public function __construct(
58
        BinLogSocketConnect $binLogSocketConnect,
59
        RowEventFactory $rowEventFactory,
60
        EventDispatcher $eventDispatcher,
61
        CacheInterface $cache
62
    ) {
63 55
        $this->binLogSocketConnect = $binLogSocketConnect;
64 55
        $this->rowEventFactory = $rowEventFactory;
65 55
        $this->eventDispatcher = $eventDispatcher;
66 55
        $this->cache = $cache;
67 55
    }
68
69
    /**
70
     * @throws BinaryDataReaderException
71
     * @throws BinLogException
72
     * @throws EventException
73
     * @throws MySQLReplicationException
74
     * @throws JsonBinaryDecoderException
75
     * @throws InvalidArgumentException
76
     * @throws SocketException
77
     */
78 55
    public function consume()
79
    {
80 55
        $binaryDataReader = new BinaryDataReader($this->binLogSocketConnect->getResponse());
81
82
        // check EOF_Packet -> https://dev.mysql.com/doc/internals/en/packet-EOF_Packet.html
83 55
        if (self::EOF_HEADER_VALUE === $binaryDataReader->readUInt8()) {
84
            return;
85
        }
86
87
        // decode all events data
88 55
        $eventInfo = $this->createEventInfo($binaryDataReader);
89
90 55
        $eventDTO = null;
91
92
        // always parse table map event but propagate when needed (we need this for creating table cache)
93 55
        if (ConstEventType::TABLE_MAP_EVENT === $eventInfo->getType()) {
0 ignored issues
show
introduced by
The condition MySQLReplication\Definit...= $eventInfo->getType() is always false.
Loading history...
94 53
            $eventDTO = $this->rowEventFactory->makeRowEvent($binaryDataReader, $eventInfo)->makeTableMapDTO();
95 53
        }
96
97 55
        if (!Config::checkEvent($eventInfo->getType())) {
0 ignored issues
show
Bug introduced by
$eventInfo->getType() of type string is incompatible with the type integer expected by parameter $type of MySQLReplication\Config\Config::checkEvent(). ( Ignorable by Annotation )

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

97
        if (!Config::checkEvent(/** @scrutinizer ignore-type */ $eventInfo->getType())) {
Loading history...
98 4
            return;
99
        }
100
101 55
        if (in_array(
102 55
            $eventInfo->getType(), [ConstEventType::UPDATE_ROWS_EVENT_V1, ConstEventType::UPDATE_ROWS_EVENT_V2], true
103 55
        )) {
104 1
            $eventDTO = $this->rowEventFactory->makeRowEvent($binaryDataReader, $eventInfo)->makeUpdateRowsDTO();
105 55
        } else if (in_array(
106 55
            $eventInfo->getType(), [ConstEventType::WRITE_ROWS_EVENT_V1, ConstEventType::WRITE_ROWS_EVENT_V2], true
107 55
        )) {
108 52
            $eventDTO = $this->rowEventFactory->makeRowEvent($binaryDataReader, $eventInfo)->makeWriteRowsDTO();
109 55
        } else if (in_array(
110 55
            $eventInfo->getType(), [ConstEventType::DELETE_ROWS_EVENT_V1, ConstEventType::DELETE_ROWS_EVENT_V2], true
111 55
        )) {
112 1
            $eventDTO = $this->rowEventFactory->makeRowEvent($binaryDataReader, $eventInfo)->makeDeleteRowsDTO();
113 55
        } else if (ConstEventType::XID_EVENT === $eventInfo->getType()) {
0 ignored issues
show
introduced by
The condition MySQLReplication\Definit...= $eventInfo->getType() is always false.
Loading history...
114 3
            $eventDTO = (new XidEvent($eventInfo, $binaryDataReader))->makeXidDTO();
115 55
        } else if (ConstEventType::ROTATE_EVENT === $eventInfo->getType()) {
0 ignored issues
show
introduced by
The condition MySQLReplication\Definit...= $eventInfo->getType() is always false.
Loading history...
116
            $this->cache->clear();
117
            $eventDTO = (new RotateEvent($eventInfo, $binaryDataReader))->makeRotateEventDTO();
118 55
        } else if (ConstEventType::GTID_LOG_EVENT === $eventInfo->getType()) {
0 ignored issues
show
introduced by
The condition MySQLReplication\Definit...= $eventInfo->getType() is always false.
Loading history...
119
            $eventDTO = (new GtidEvent($eventInfo, $binaryDataReader))->makeGTIDLogDTO();
120 55
        } else if (ConstEventType::QUERY_EVENT === $eventInfo->getType()) {
0 ignored issues
show
introduced by
The condition MySQLReplication\Definit...= $eventInfo->getType() is always false.
Loading history...
121 55
            $eventDTO = $this->filterDummyMariaDbEvents(
122 55
                (new QueryEvent($eventInfo, $binaryDataReader))->makeQueryDTO()
123 55
            );
124 55
        } else if (ConstEventType::MARIA_GTID_EVENT === $eventInfo->getType()) {
0 ignored issues
show
introduced by
The condition MySQLReplication\Definit...= $eventInfo->getType() is always false.
Loading history...
125
            $eventDTO = (new MariaDbGtidEvent($eventInfo, $binaryDataReader))->makeMariaDbGTIDLogDTO();
126 55
        } else if (ConstEventType::FORMAT_DESCRIPTION_EVENT === $eventInfo->getType()) {
0 ignored issues
show
introduced by
The condition MySQLReplication\Definit...= $eventInfo->getType() is always false.
Loading history...
127 55
            $eventDTO = new FormatDescriptionEventDTO($eventInfo);
128 55
        } else if (ConstEventType::HEARTBEAT_LOG_EVENT === $eventInfo->getType()) {
0 ignored issues
show
introduced by
The condition MySQLReplication\Definit...= $eventInfo->getType() is always false.
Loading history...
129
            $eventDTO = new HeartbeatDTO($eventInfo);
130
        }
131
132 55
        $this->dispatch($eventDTO);
133 55
    }
134
135
    /**
136
     * @param BinaryDataReader $binaryDataReader
137
     * @return EventInfo
138
     */
139 55
    private function createEventInfo(BinaryDataReader $binaryDataReader)
140
    {
141 55
        return new EventInfo(
142 55
            $binaryDataReader->readInt32(),
143 55
            $binaryDataReader->readUInt8(),
144 55
            $binaryDataReader->readInt32(),
145 55
            $binaryDataReader->readInt32(),
146 55
            $binaryDataReader->readInt32(),
147 55
            $binaryDataReader->readUInt16(),
148 55
            $this->binLogSocketConnect->getCheckSum(),
149 55
            $this->binLogSocketConnect->getBinLogCurrent()
150 55
        );
151
    }
152
153
    /**
154
     * @param QueryDTO $queryDTO
155
     * @return QueryDTO|null
156
     */
157 55
    private function filterDummyMariaDbEvents(QueryDTO $queryDTO)
158
    {
159 55
        if (BinLogServerInfo::isMariaDb() && false !== strpos($queryDTO->getQuery(), self::MARIADB_DUMMY_QUERY)) {
160
            return null;
161
        }
162
163 55
        return $queryDTO;
164
    }
165
166
    /**
167
     * @param EventDTO $eventDTO
168
     */
169 55
    private function dispatch(EventDTO $eventDTO = null)
170
    {
171 55
        if (null !== $eventDTO) {
172 55
            $this->eventDispatcher->dispatch($eventDTO->getType(), $eventDTO);
173 55
        }
174 55
    }
175
}
176