github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/pkg/binlog/event/dml_test.go (about) 1 // Copyright 2019 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package event 15 16 import ( 17 "fmt" 18 "testing" 19 20 gmysql "github.com/go-mysql-org/go-mysql/mysql" 21 "github.com/go-mysql-org/go-mysql/replication" 22 "github.com/pingcap/tiflow/dm/pkg/gtid" 23 "github.com/stretchr/testify/require" 24 ) 25 26 func TestGenDMLEvent(t *testing.T) { 27 t.Parallel() 28 var ( 29 serverID uint32 = 101 30 latestPos uint32 = 123 31 xid uint64 = 10 32 ) 33 34 // test INSERT/UPDATE for MySQL 35 flavor := gmysql.MySQLFlavor 36 gSetStr := "03fc0263-28c7-11e7-a653-6c0b84d59f30:123" 37 latestGTID, err := gtid.ParserGTID(flavor, gSetStr) 38 require.Nil(t, err) 39 40 // empty data 41 result, err := GenDMLEvents(flavor, serverID, latestPos, latestGTID, replication.WRITE_ROWS_EVENTv2, xid, nil, true, false, 0) 42 require.NotNil(t, err) 43 require.Nil(t, result) 44 45 // single INSERT without batch 46 insertRows1 := make([][]interface{}, 0, 1) 47 insertRows1 = append(insertRows1, []interface{}{int32(11), "string column value"}) 48 insertDMLData := []*DMLData{ 49 { 50 TableID: 11, 51 Schema: "db1", 52 Table: "tbl1", 53 ColumnType: []byte{gmysql.MYSQL_TYPE_LONG, gmysql.MYSQL_TYPE_STRING}, 54 Rows: insertRows1, 55 }, 56 } 57 eventType := replication.WRITE_ROWS_EVENTv2 58 result, err = GenDMLEvents(flavor, serverID, latestPos, latestGTID, eventType, xid, insertDMLData, true, false, 0) 59 require.Nil(t, err) 60 require.NotNil(t, result) 61 require.Len(t, result.Events, 3+2*len(insertDMLData)) 62 // simply check here, more check did in `event_test.go` 63 require.Equal(t, eventType, result.Events[3].Header.EventType) 64 require.Equal(t, latestPos+uint32(len(result.Data)), result.LatestPos) 65 require.Equal(t, "03fc0263-28c7-11e7-a653-6c0b84d59f30:124", result.LatestGTID.String()) 66 67 latestPos = result.LatestPos // update latest pos 68 latestGTID = result.LatestGTID 69 xid++ 70 71 // multi INSERT with batch 72 insertRows2 := make([][]interface{}, 0, 2) 73 insertRows2 = append(insertRows2, []interface{}{int32(101), "string column value a"}, []interface{}{int32(102), "string column value b"}) 74 insertDMLData = append(insertDMLData, &DMLData{ 75 TableID: 12, 76 Schema: "db2", 77 Table: "tbl2", 78 ColumnType: []byte{gmysql.MYSQL_TYPE_LONG, gmysql.MYSQL_TYPE_STRING}, 79 Rows: insertRows2, 80 }) 81 result, err = GenDMLEvents(flavor, serverID, latestPos, latestGTID, replication.WRITE_ROWS_EVENTv2, xid, insertDMLData, true, false, 0) 82 require.Nil(t, err) 83 require.NotNil(t, result) 84 require.Len(t, result.Events, 3+2*len(insertDMLData)) // 2 more events for insertRows2 85 require.Equal(t, eventType, result.Events[3+2].Header.EventType) 86 require.Equal(t, latestPos+uint32(len(result.Data)), result.LatestPos) 87 require.Equal(t, "03fc0263-28c7-11e7-a653-6c0b84d59f30:125", result.LatestGTID.String()) 88 89 latestPos = result.LatestPos // update latest pos 90 latestGTID = result.LatestGTID 91 xid++ 92 93 // single UPDATE 94 updateRows := make([][]interface{}, 0, 2) 95 updateRows = append(updateRows, []interface{}{int32(21), "old string"}, []interface{}{int32(21), "new string"}) 96 updateDMLData := []*DMLData{ 97 { 98 TableID: 21, 99 Schema: "db3", 100 Table: "tbl3", 101 ColumnType: []byte{gmysql.MYSQL_TYPE_LONG, gmysql.MYSQL_TYPE_STRING}, 102 Rows: updateRows, 103 }, 104 } 105 eventType = replication.UPDATE_ROWS_EVENTv2 106 result, err = GenDMLEvents(flavor, serverID, latestPos, latestGTID, eventType, xid, updateDMLData, true, false, 0) 107 require.Nil(t, err) 108 require.NotNil(t, result) 109 require.Len(t, result.Events, 3+2*len(updateDMLData)) 110 require.Equal(t, eventType, result.Events[3].Header.EventType) 111 require.Equal(t, latestPos+uint32(len(result.Data)), result.LatestPos) 112 require.Equal(t, "03fc0263-28c7-11e7-a653-6c0b84d59f30:126", result.LatestGTID.String()) 113 114 latestPos = result.LatestPos // update latest pos 115 xid++ 116 117 // test DELETE for MariaDB 118 flavor = gmysql.MariaDBFlavor 119 gSetStr = fmt.Sprintf("1-%d-3", serverID) 120 latestGTID, err = gtid.ParserGTID(flavor, gSetStr) 121 require.Nil(t, err) 122 123 // single DELETE 124 deleteRows := make([][]interface{}, 0, 1) 125 deleteRows = append(deleteRows, []interface{}{int32(31), "string a"}) 126 deleteDMLData := []*DMLData{ 127 { 128 TableID: 31, 129 Schema: "db4", 130 Table: "tbl4", 131 ColumnType: []byte{gmysql.MYSQL_TYPE_LONG, gmysql.MYSQL_TYPE_STRING}, 132 Rows: deleteRows, 133 }, 134 } 135 eventType = replication.DELETE_ROWS_EVENTv2 136 result, err = GenDMLEvents(flavor, serverID, latestPos, latestGTID, eventType, xid, deleteDMLData, true, false, 0) 137 require.Nil(t, err) 138 require.NotNil(t, result) 139 require.Len(t, result.Events, 3+2*len(deleteDMLData)) 140 require.Equal(t, eventType, result.Events[3].Header.EventType) 141 require.Equal(t, latestPos+uint32(len(result.Data)), result.LatestPos) 142 require.Equal(t, fmt.Sprintf("1-%d-4", serverID), result.LatestGTID.String()) 143 }