vitess.io/vitess@v0.16.2/go/mysql/binlog_event_filepos.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package mysql
    18  
    19  import (
    20  	"encoding/binary"
    21  	"fmt"
    22  )
    23  
    24  // filePosBinlogEvent wraps a raw packet buffer and provides methods to examine
    25  // it by implementing BinlogEvent. Some methods are pulled in from binlogEvent.
    26  type filePosBinlogEvent struct {
    27  	binlogEvent
    28  	semiSyncAckRequested bool
    29  }
    30  
    31  // newFilePosBinlogEventWithSemiSyncInfo creates a BinlogEvent from given byte array
    32  func newFilePosBinlogEventWithSemiSyncInfo(buf []byte, semiSyncAckRequested bool) *filePosBinlogEvent {
    33  	return &filePosBinlogEvent{binlogEvent: binlogEvent(buf), semiSyncAckRequested: semiSyncAckRequested}
    34  }
    35  
    36  // newFilePosBinlogEvent creates a BinlogEvent from given byte array
    37  func newFilePosBinlogEvent(buf []byte) *filePosBinlogEvent {
    38  	return &filePosBinlogEvent{binlogEvent: binlogEvent(buf)}
    39  }
    40  
    41  func (*filePosBinlogEvent) GTID(BinlogFormat) (GTID, bool, error) {
    42  	return nil, false, nil
    43  }
    44  
    45  // IsSemiSyncAckRequested implements BinlogEvent.IsSemiSyncAckRequested().
    46  func (ev *filePosBinlogEvent) IsSemiSyncAckRequested() bool {
    47  	return ev.semiSyncAckRequested
    48  }
    49  
    50  func (*filePosBinlogEvent) IsGTID() bool {
    51  	return false
    52  }
    53  
    54  func (*filePosBinlogEvent) PreviousGTIDs(BinlogFormat) (Position, error) {
    55  	return Position{}, fmt.Errorf("filePos should not provide PREVIOUS_GTIDS_EVENT events")
    56  }
    57  
    58  // StripChecksum implements BinlogEvent.StripChecksum().
    59  func (ev *filePosBinlogEvent) StripChecksum(f BinlogFormat) (BinlogEvent, []byte, error) {
    60  	switch f.ChecksumAlgorithm {
    61  	case BinlogChecksumAlgOff, BinlogChecksumAlgUndef:
    62  		// There is no checksum.
    63  		return ev, nil, nil
    64  	default:
    65  		// Checksum is the last 4 bytes of the event buffer.
    66  		data := ev.Bytes()
    67  		length := len(data)
    68  		checksum := data[length-4:]
    69  		data = data[:length-4]
    70  		return newFilePosBinlogEvent(data), checksum, nil
    71  	}
    72  }
    73  
    74  // nextPosition returns the next file position of the binlog.
    75  // If no information is available, it returns 0.
    76  func (ev *filePosBinlogEvent) nextPosition(f BinlogFormat) int {
    77  	if f.HeaderLength <= 13 {
    78  		// Dead code. This is just a failsafe.
    79  		return 0
    80  	}
    81  	return int(binary.LittleEndian.Uint32(ev.Bytes()[13:17]))
    82  }
    83  
    84  // rotate implements BinlogEvent.Rotate().
    85  //
    86  // Expected format (L = total length of event data):
    87  //
    88  //	# bytes  field
    89  //	8        position
    90  //	8:L      file
    91  func (ev *filePosBinlogEvent) rotate(f BinlogFormat) (int, string) {
    92  	data := ev.Bytes()[f.HeaderLength:]
    93  	pos := binary.LittleEndian.Uint64(data[0:8])
    94  	file := data[8:]
    95  	return int(pos), string(file)
    96  }
    97  
    98  //----------------------------------------------------------------------------
    99  
   100  // filePosQueryEvent is a fake begin event.
   101  type filePosQueryEvent struct {
   102  	query string
   103  	filePosFakeEvent
   104  }
   105  
   106  func newFilePosQueryEvent(query string, ts uint32) filePosQueryEvent {
   107  	return filePosQueryEvent{
   108  		query: query,
   109  		filePosFakeEvent: filePosFakeEvent{
   110  			timestamp: ts,
   111  		},
   112  	}
   113  }
   114  
   115  func (ev filePosQueryEvent) IsQuery() bool {
   116  	return true
   117  }
   118  
   119  func (ev filePosQueryEvent) Query(BinlogFormat) (Query, error) {
   120  	return Query{
   121  		SQL: ev.query,
   122  	}, nil
   123  }
   124  
   125  func (ev filePosQueryEvent) StripChecksum(f BinlogFormat) (BinlogEvent, []byte, error) {
   126  	return ev, nil, nil
   127  }
   128  
   129  func (ev filePosQueryEvent) Bytes() []byte {
   130  	return []byte{}
   131  }
   132  
   133  //----------------------------------------------------------------------------
   134  
   135  // filePosFakeEvent is the base class for fake events.
   136  type filePosFakeEvent struct {
   137  	timestamp uint32
   138  }
   139  
   140  func (ev filePosFakeEvent) NextPosition() uint32 {
   141  	return 0
   142  }
   143  
   144  func (ev filePosFakeEvent) IsValid() bool {
   145  	return true
   146  }
   147  
   148  func (ev filePosFakeEvent) IsFormatDescription() bool {
   149  	return false
   150  }
   151  
   152  func (ev filePosFakeEvent) IsQuery() bool {
   153  	return false
   154  }
   155  
   156  func (ev filePosFakeEvent) IsXID() bool {
   157  	return false
   158  }
   159  
   160  func (ev filePosFakeEvent) IsStop() bool {
   161  	return false
   162  }
   163  
   164  func (ev filePosFakeEvent) IsSemiSyncAckRequested() bool {
   165  	return false
   166  }
   167  
   168  func (ev filePosFakeEvent) IsGTID() bool {
   169  	return false
   170  }
   171  
   172  func (ev filePosFakeEvent) IsRotate() bool {
   173  	return false
   174  }
   175  
   176  func (ev filePosFakeEvent) IsIntVar() bool {
   177  	return false
   178  }
   179  
   180  func (ev filePosFakeEvent) IsRand() bool {
   181  	return false
   182  }
   183  
   184  func (ev filePosFakeEvent) IsPreviousGTIDs() bool {
   185  	return false
   186  }
   187  
   188  func (ev filePosFakeEvent) IsHeartbeat() bool {
   189  	return false
   190  }
   191  
   192  func (ev filePosFakeEvent) IsTableMap() bool {
   193  	return false
   194  }
   195  
   196  func (ev filePosFakeEvent) IsWriteRows() bool {
   197  	return false
   198  }
   199  
   200  func (ev filePosFakeEvent) IsUpdateRows() bool {
   201  	return false
   202  }
   203  
   204  func (ev filePosFakeEvent) IsDeleteRows() bool {
   205  	return false
   206  }
   207  
   208  func (ev filePosFakeEvent) Timestamp() uint32 {
   209  	return ev.timestamp
   210  }
   211  
   212  func (ev filePosFakeEvent) Format() (BinlogFormat, error) {
   213  	return BinlogFormat{}, nil
   214  }
   215  
   216  func (ev filePosFakeEvent) GTID(BinlogFormat) (GTID, bool, error) {
   217  	return nil, false, nil
   218  }
   219  
   220  func (ev filePosFakeEvent) Query(BinlogFormat) (Query, error) {
   221  	return Query{}, nil
   222  }
   223  
   224  func (ev filePosFakeEvent) IntVar(BinlogFormat) (byte, uint64, error) {
   225  	return 0, 0, nil
   226  }
   227  
   228  func (ev filePosFakeEvent) Rand(BinlogFormat) (uint64, uint64, error) {
   229  	return 0, 0, nil
   230  }
   231  
   232  func (ev filePosFakeEvent) PreviousGTIDs(BinlogFormat) (Position, error) {
   233  	return Position{}, nil
   234  }
   235  
   236  func (ev filePosFakeEvent) TableID(BinlogFormat) uint64 {
   237  	return 0
   238  }
   239  
   240  func (ev filePosFakeEvent) TableMap(BinlogFormat) (*TableMap, error) {
   241  	return nil, nil
   242  }
   243  
   244  func (ev filePosFakeEvent) Rows(BinlogFormat, *TableMap) (Rows, error) {
   245  	return Rows{}, nil
   246  }
   247  
   248  func (ev filePosFakeEvent) NextLogFile(BinlogFormat) (string, uint64, error) {
   249  	return "", 0, nil
   250  }
   251  
   252  func (ev filePosFakeEvent) IsPseudo() bool {
   253  	return false
   254  }
   255  
   256  func (ev filePosFakeEvent) IsCompressed() bool {
   257  	return false
   258  }
   259  
   260  func (ev filePosFakeEvent) Bytes() []byte {
   261  	return []byte{}
   262  }
   263  
   264  //----------------------------------------------------------------------------
   265  
   266  // filePosGTIDEvent is a fake GTID event for filePos.
   267  type filePosGTIDEvent struct {
   268  	filePosFakeEvent
   269  	gtid filePosGTID
   270  }
   271  
   272  func newFilePosGTIDEvent(file string, pos int, timestamp uint32) filePosGTIDEvent {
   273  	return filePosGTIDEvent{
   274  		filePosFakeEvent: filePosFakeEvent{
   275  			timestamp: timestamp,
   276  		},
   277  		gtid: filePosGTID{
   278  			file: file,
   279  			pos:  pos,
   280  		},
   281  	}
   282  }
   283  
   284  func (ev filePosGTIDEvent) IsGTID() bool {
   285  	return true
   286  }
   287  
   288  func (ev filePosGTIDEvent) StripChecksum(f BinlogFormat) (BinlogEvent, []byte, error) {
   289  	return ev, nil, nil
   290  }
   291  
   292  func (ev filePosGTIDEvent) GTID(BinlogFormat) (GTID, bool, error) {
   293  	return ev.gtid, false, nil
   294  }