diff --git a/.travis.yml b/.travis.yml index 7a31ea3..a22ed5c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,11 @@ php: - 5.6 - 7.0 - 7.1 + - 7.2 env: - DB=mysql57 - DB=mysql56 + - DB=mariadb cache: apt: true @@ -20,25 +22,23 @@ sudo: required before_script: - "sudo /etc/init.d/mysql stop || true" - - "sudo apt-get remove mysql* -y" + - "sudo apt-get remove mysql* -y --purge" - "if [ $DB = 'mysql57' ]; then echo deb http://repo.mysql.com/apt/ubuntu/ trusty mysql-5.7 | sudo tee /etc/apt/sources.list.d/mysql.list; sudo apt-get update; sudo apt-get install mysql-server -y --allow-unauthenticated; fi" - "if [ $DB = 'mysql56' ]; then echo deb http://repo.mysql.com/apt/ubuntu/ trusty mysql-5.6 | sudo tee /etc/apt/sources.list.d/mysql.list; sudo apt-get update; sudo apt-get install mysql-server -y --allow-unauthenticated; fi" - - "sudo mysql_upgrade" + - "if [ $DB = 'mariadb' ]; then sudo rm -rf /var/lib/mysql /etc/mysql; echo deb http://ftp.hosteurope.de/mirror/mariadb.org/repo/10.3/ubuntu trusty main | sudo tee /etc/apt/sources.list.d/mysql.list; sudo apt-get update; sudo apt-get install mariadb-server-10.3 -y --allow-unauthenticated; fi" + - "sudo mysql_upgrade --force" # Config - "echo '[mysqld]' | sudo tee /etc/mysql/conf.d/replication.cnf" - "echo 'log-bin=mysql-bin' | sudo tee -a /etc/mysql/conf.d/replication.cnf" - "echo 'server-id=1' | sudo tee -a /etc/mysql/conf.d/replication.cnf" - "echo 'binlog-format = row' | sudo tee -a /etc/mysql/conf.d/replication.cnf" + - "cat /etc/mysql/conf.d/replication.cnf" - # Enable GTID - - "echo '[mysqld]' | sudo tee /etc/mysql/conf.d/gtid.cnf" - - "echo 'gtid_mode=ON' | sudo tee -a /etc/mysql/conf.d/gtid.cnf" - - "echo 'enforce_gtid_consistency' | sudo tee -a /etc/mysql/conf.d/gtid.cnf" - - "echo 'binlog_format=ROW' | sudo tee -a /etc/mysql/conf.d/gtid.cnf" - - "echo 'log_slave_updates' | sudo tee -a /etc/mysql/conf.d/gtid.cnf" + # Enable GTID (only for mysql 5.*) + - "if [ $DB != 'mariadb' ]; then echo '[mysqld]' | sudo tee /etc/mysql/conf.d/gtid.cnf; echo 'gtid_mode=ON' | sudo tee -a /etc/mysql/conf.d/gtid.cnf; echo 'enforce_gtid_consistency' | sudo tee -a /etc/mysql/conf.d/gtid.cnf; echo 'binlog_format=ROW' | sudo tee -a /etc/mysql/conf.d/gtid.cnf; echo 'log_slave_updates' | sudo tee -a /etc/mysql/conf.d/gtid.cnf; cat /etc/mysql/conf.d/gtid.cnf; fi" - # Start mysql (avoid errors to have logs) + # Start mysql (avoid errors to have logs)/var/lib/mysql - "sudo /etc/init.d/mysql restart || true" - "sudo tail -1000 /var/log/syslog" @@ -49,6 +49,7 @@ before_script: - if [ $DB = 'mysql56' ]; then echo "USE mysql;\nUPDATE user SET password=PASSWORD('root') WHERE user='root';\nFLUSH PRIVILEGES;\n" | mysql -u root; fi - if [ $DB = 'mysql57' ]; then echo "USE mysql;\nUPDATE user SET authentication_string=PASSWORD('root') WHERE user='root';\nFLUSH PRIVILEGES;\n" | mysql -u root; fi + - if [ $DB = 'mariadb' ]; then echo "USE mysql;\nUPDATE user SET password=PASSWORD('root') WHERE User='root';\nFLUSH PRIVILEGES;\n" | mysql -u root; fi install: travis_retry composer install --no-interaction --prefer-source; diff --git a/CHANGELOG.md b/CHANGELOG.md index b2c4b89..d824902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ # Release Notes +## v5.0.1 (2018-05-29) +- Added tests now include php 7.2 and MariaDb 10.3 +- Added truncate table test (#37) +- Added MariaDb events ids to const +- Added filtering dummy events generated by MariaDB +- Added missing throws in BasicTest + ## v5.0.0 (2018-04-27) - Removed unused classes from code and merged some classes to one class - Added ability in MySQLReplicationFactory to provide implementations interfaces in constructor. This will give ability to replace default classes to your own diff --git a/src/MySQLReplication/Definitions/ConstEventType.php b/src/MySQLReplication/Definitions/ConstEventType.php index 72a6198..5b9a89b 100644 --- a/src/MySQLReplication/Definitions/ConstEventType.php +++ b/src/MySQLReplication/Definitions/ConstEventType.php @@ -61,5 +61,16 @@ class ConstEventType const DELETE_ROWS_EVENT_V2 = 32; // mariadb + // https://github.com/MariaDB/server/blob/10.4/sql/log_event.h + const MARIA_BINLOG_CHECKPOINT_EVENT = 161; const MARIA_GTID_EVENT = 162; -} + const MARIA_GTID_LIST_EVENT = 163; + const MARIA_START_ENCRYPTION_EVENT = 164; + const MARIA_QUERY_COMPRESSED_EVENT = 165; + const MARIA_WRITE_ROWS_COMPRESSED_EVENT_V1 = 166; + const MARIA_UPDATE_ROWS_COMPRESSED_EVENT_V1 = 167; + const MARIA_DELETE_ROWS_COMPRESSED_EVENT_V1 = 168; + const MARIA_WRITE_ROWS_COMPRESSED_EVENT = 169; + const MARIA_UPDATE_ROWS_COMPRESSED_EVENT = 170; + const MARIA_DELETE_ROWS_COMPRESSED_EVENT = 171; +} \ No newline at end of file diff --git a/src/MySQLReplication/Event/Event.php b/src/MySQLReplication/Event/Event.php index 9d36302..645f893 100644 --- a/src/MySQLReplication/Event/Event.php +++ b/src/MySQLReplication/Event/Event.php @@ -5,12 +5,14 @@ use MySQLReplication\BinaryDataReader\BinaryDataReader; use MySQLReplication\BinaryDataReader\BinaryDataReaderException; use MySQLReplication\BinLog\BinLogException; +use MySQLReplication\BinLog\BinLogServerInfo; use MySQLReplication\BinLog\BinLogSocketConnect; use MySQLReplication\Config\Config; use MySQLReplication\Definitions\ConstEventType; use MySQLReplication\Event\DTO\EventDTO; use MySQLReplication\Event\DTO\FormatDescriptionEventDTO; use MySQLReplication\Event\DTO\HeartbeatDTO; +use MySQLReplication\Event\DTO\QueryDTO; use MySQLReplication\Event\RowEvent\RowEventFactory; use MySQLReplication\Exception\MySQLReplicationException; use MySQLReplication\JsonBinaryDecoder\JsonBinaryDecoderException; @@ -25,6 +27,8 @@ */ class Event { + const MARIADB_DUMMY_QUERY = '# Dum'; + /** * @var BinLogSocketConnect */ @@ -111,7 +115,9 @@ public function consume() } else if (ConstEventType::GTID_LOG_EVENT === $eventInfo->getType()) { $eventDTO = (new GtidEvent($eventInfo, $binaryDataReader))->makeGTIDLogDTO(); } else if (ConstEventType::QUERY_EVENT === $eventInfo->getType()) { - $eventDTO = (new QueryEvent($eventInfo, $binaryDataReader))->makeQueryDTO(); + $eventDTO = $this->filterDummyMariaDbEvents( + (new QueryEvent($eventInfo, $binaryDataReader))->makeQueryDTO() + ); } else if (ConstEventType::MARIA_GTID_EVENT === $eventInfo->getType()) { $eventDTO = (new MariaDbGtidEvent($eventInfo, $binaryDataReader))->makeMariaDbGTIDLogDTO(); } else if (ConstEventType::FORMAT_DESCRIPTION_EVENT === $eventInfo->getType()) { @@ -141,6 +147,19 @@ private function createEventInfo(BinaryDataReader $binaryDataReader) ); } + /** + * @param QueryDTO $queryDTO + * @return QueryDTO|null + */ + private function filterDummyMariaDbEvents(QueryDTO $queryDTO) + { + if (BinLogServerInfo::isMariaDb() && false !== strpos($queryDTO->getQuery(), self::MARIADB_DUMMY_QUERY)) { + return null; + } + + return $queryDTO; + } + /** * @param EventDTO $eventDTO */ diff --git a/tests/Integration/BasicTest.php b/tests/Integration/BasicTest.php index 9167eff..c28041c 100644 --- a/tests/Integration/BasicTest.php +++ b/tests/Integration/BasicTest.php @@ -2,6 +2,9 @@ namespace MySQLReplication\Tests\Integration; +use Doctrine\DBAL\DBALException; +use MySQLReplication\BinLog\BinLogException; +use MySQLReplication\Config\ConfigException; use MySQLReplication\Definitions\ConstEventType; use MySQLReplication\Event\DTO\DeleteRowsDTO; use MySQLReplication\Event\DTO\QueryDTO; @@ -9,6 +12,10 @@ use MySQLReplication\Event\DTO\UpdateRowsDTO; use MySQLReplication\Event\DTO\WriteRowsDTO; use MySQLReplication\Event\DTO\XidDTO; +use MySQLReplication\Exception\MySQLReplicationException; +use MySQLReplication\Gtid\GtidException; +use MySQLReplication\Socket\SocketException; +use Psr\SimpleCache\InvalidArgumentException; /** * Class BasicTest @@ -18,6 +25,9 @@ class BasicTest extends BaseTest { /** * @test + * @throws DBALException + * @throws InvalidArgumentException + * @throws MySQLReplicationException */ public function shouldGetDeleteEvent() { @@ -41,6 +51,9 @@ public function shouldGetDeleteEvent() /** * @test + * @throws DBALException + * @throws InvalidArgumentException + * @throws MySQLReplicationException */ public function shouldGetUpdateEvent() { @@ -66,6 +79,9 @@ public function shouldGetUpdateEvent() /** * @test + * @throws DBALException + * @throws InvalidArgumentException + * @throws MySQLReplicationException */ public function shouldGetWriteEventDropTable() { @@ -73,7 +89,6 @@ public function shouldGetWriteEventDropTable() $this->connection->exec('INSERT INTO `test` VALUES (1)'); $this->connection->exec($dropExpected = 'DROP TABLE `test`'); - /** @var QueryDTO $event */ $event = $this->getEvent(); self::assertInstanceOf(QueryDTO::class, $event); @@ -103,6 +118,9 @@ public function shouldGetWriteEventDropTable() /** * @test + * @throws DBALException + * @throws InvalidArgumentException + * @throws MySQLReplicationException */ public function shouldGetQueryEventCreateTable() { @@ -118,6 +136,13 @@ public function shouldGetQueryEventCreateTable() /** * @test + * @throws BinLogException + * @throws ConfigException + * @throws DBALException + * @throws GtidException + * @throws InvalidArgumentException + * @throws MySQLReplicationException + * @throws SocketException */ public function shouldDropColumn() { @@ -146,6 +171,13 @@ public function shouldDropColumn() /** * @test + * @throws BinLogException + * @throws ConfigException + * @throws DBALException + * @throws GtidException + * @throws InvalidArgumentException + * @throws MySQLReplicationException + * @throws SocketException */ public function shouldFilterEvents() { @@ -168,6 +200,13 @@ public function shouldFilterEvents() /** * @test + * @throws DBALException + * @throws BinLogException + * @throws ConfigException + * @throws MySQLReplicationException + * @throws GtidException + * @throws SocketException + * @throws InvalidArgumentException */ public function shouldFilterTables() { @@ -197,4 +236,36 @@ public function shouldFilterTables() self::assertEquals($expectedTable, $event->getTableMap()->getTable()); self::assertEquals($expectedValue, $event->getValues()[0]['data']); } + + /** + * @test + * @throws DBALException + * @throws InvalidArgumentException + * @throws MySQLReplicationException + */ + public function shouldTruncateTable() + { + $this->disconnect(); + + $this->configBuilder->withEventsOnly( + [ConstEventType::QUERY_EVENT] + ); + + $this->connect(); + + self::assertInstanceOf(QueryDTO::class, $this->getEvent()); + self::assertInstanceOf(QueryDTO::class, $this->getEvent()); + + $this->connection->exec('CREATE TABLE test_truncate_column (id INTEGER(11), data VARCHAR(50))'); + $this->connection->exec('INSERT INTO test_truncate_column VALUES (1, \'A value\')'); + $this->connection->exec('TRUNCATE TABLE test_truncate_column'); + + /** @var QueryDTO $event */ + $event = $this->getEvent(); + self::assertSame('CREATE TABLE test_truncate_column (id INTEGER(11), data VARCHAR(50))', $event->getQuery()); + $event = $this->getEvent(); + self::assertSame('BEGIN', $event->getQuery()); + $event = $this->getEvent(); + self::assertSame('TRUNCATE TABLE test_truncate_column', $event->getQuery()); + } } \ No newline at end of file