Passed
Branch master (088cbb)
by kacper
05:31
created

Event::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 4
dl 0
loc 10
ccs 5
cts 5
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
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
32
    /**
33
     * @var BinLogSocketConnect
34
     */
35
    private $binLogSocketConnect;
36
    /**
37
     * @var RowEventFactory
38
     */
39
    private $rowEventFactory;
40
    /**
41
     * @var EventDispatcher
42
     */
43
    private $eventDispatcher;
44
    /**
45
     * @var CacheInterface
46
     */
47
    private $cache;
48
49
    /**
50
     * BinLogPack constructor.
51
     * @param BinLogSocketConnect $binLogSocketConnect
52
     * @param RowEventFactory $rowEventFactory
53
     * @param EventDispatcher $eventDispatcher
54
     * @param CacheInterface $cache
55
     */
56 55
    public function __construct(
57
        BinLogSocketConnect $binLogSocketConnect,
58
        RowEventFactory $rowEventFactory,
59
        EventDispatcher $eventDispatcher,
60
        CacheInterface $cache
61
    ) {
62 55
        $this->binLogSocketConnect = $binLogSocketConnect;
63 55
        $this->rowEventFactory = $rowEventFactory;
64 55
        $this->eventDispatcher = $eventDispatcher;
65 55
        $this->cache = $cache;
66 55
    }
67
68
    /**
69
     * @throws BinaryDataReaderException
70
     * @throws BinLogException
71
     * @throws EventException
72
     * @throws MySQLReplicationException
73
     * @throws JsonBinaryDecoderException
74
     * @throws InvalidArgumentException
75
     * @throws SocketException
76
     */
77 55
    public function consume()
78
    {
79 55
        $binaryDataReader = new BinaryDataReader($this->binLogSocketConnect->getResponse());
80
81
        // "ok" value on first byte continue
82 55
        $binaryDataReader->advance(1);
83
84
        // decode all events data
85 55
        $eventInfo = $this->createEventInfo($binaryDataReader);
86
87 55
        $eventDTO = null;
88
89
        // always parse table map event but propagate when needed (we need this for creating table cache)
90 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...
91 53
            $eventDTO = $this->rowEventFactory->makeRowEvent($binaryDataReader, $eventInfo)->makeTableMapDTO();
92 53
        }
93
94 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

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