mysql_common/binlog/events/
rotate_event.rs

1// Copyright (c) 2021 Anatoly Ikorsky
2//
3// Licensed under the Apache License, Version 2.0
4// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
5// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. All files in the project carrying such notice may not be copied,
7// modified, or distributed except according to those terms.
8
9use std::{borrow::Cow, cmp::min, io};
10
11use saturating::Saturating as S;
12
13use crate::{
14    binlog::{
15        consts::{BinlogVersion, EventType},
16        BinlogCtx, BinlogEvent, BinlogStruct,
17    },
18    io::ParseBuf,
19    misc::raw::{bytes::EofBytes, int::*, RawBytes},
20    proto::{MyDeserialize, MySerialize},
21};
22
23use super::BinlogEventHeader;
24
25/// The rotate event is added to the binlog as last event
26/// to tell the reader what binlog to request next.
27#[derive(Debug, Clone, Eq, PartialEq, Hash)]
28pub struct RotateEvent<'a> {
29    // post-header
30    /// Only available if binlog version > 1 (zero otherwise).
31    position: RawInt<LeU64>,
32
33    // payload
34    /// Name of the next binlog.
35    name: RawBytes<'a, EofBytes>,
36}
37
38impl<'a> RotateEvent<'a> {
39    pub fn new(position: u64, name: impl Into<Cow<'a, [u8]>>) -> Self {
40        Self {
41            position: RawInt::new(position),
42            name: RawBytes::new(name),
43        }
44    }
45
46    /// Sets the `position` field value.
47    pub fn with_position(mut self, position: u64) -> Self {
48        self.position = RawInt::new(position);
49        self
50    }
51
52    /// Sets the `name` field value.
53    pub fn with_name(mut self, name: impl Into<Cow<'a, [u8]>>) -> Self {
54        self.name = RawBytes::new(name);
55        self
56    }
57
58    /// Returns the position within the binary log to rotate to.
59    pub fn position(&self) -> u64 {
60        self.position.0
61    }
62
63    /// Returns raw name of the binlog to rotate to.
64    pub fn name_raw(&'a self) -> &'a [u8] {
65        self.name.as_bytes()
66    }
67
68    /// Returns name of the binlog to rotate to as a string (lossy converted).
69    pub fn name(&'a self) -> Cow<'a, str> {
70        self.name.as_str()
71    }
72
73    /// Returns true if it's a fake [`RotateEvent`] (its log postion is `0`).
74    pub fn is_fake(&self) -> bool {
75        self.position() == 0
76    }
77
78    pub fn into_owned(self) -> RotateEvent<'static> {
79        RotateEvent {
80            position: self.position,
81            name: self.name.into_owned(),
82        }
83    }
84}
85
86impl<'de> MyDeserialize<'de> for RotateEvent<'de> {
87    const SIZE: Option<usize> = None;
88    type Ctx = BinlogCtx<'de>;
89
90    fn deserialize(_ctx: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
91        Ok(Self {
92            position: buf.parse(())?,
93            name: buf.parse(())?,
94        })
95    }
96}
97
98impl MySerialize for RotateEvent<'_> {
99    fn serialize(&self, buf: &mut Vec<u8>) {
100        self.position.serialize(&mut *buf);
101        self.name.serialize(&mut *buf);
102    }
103}
104
105impl<'a> BinlogEvent<'a> for RotateEvent<'a> {
106    const EVENT_TYPE: EventType = EventType::ROTATE_EVENT;
107}
108
109impl<'a> BinlogStruct<'a> for RotateEvent<'a> {
110    fn len(&self, _version: BinlogVersion) -> usize {
111        let mut len = S(0);
112
113        len += S(8);
114        len += S(self.name.0.len());
115
116        min(len.0, u32::MAX as usize - BinlogEventHeader::LEN)
117    }
118}