-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Expand file tree
/
Copy pathok.rs
More file actions
94 lines (76 loc) · 2.7 KB
/
ok.rs
File metadata and controls
94 lines (76 loc) · 2.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use bytes::{Buf, Bytes};
use crate::error::Error;
use crate::io::MySqlBufExt;
use crate::io::ProtocolDecode;
use crate::protocol::response::Status;
/// Indicates successful completion of a previous command sent by the client.
#[derive(Debug)]
pub struct OkPacket {
pub affected_rows: u64,
pub last_insert_id: u64,
pub status: Status,
pub warnings: u16,
}
impl ProtocolDecode<'_> for OkPacket {
fn decode_with(mut buf: Bytes, _: ()) -> Result<Self, Error> {
let header = buf.get_u8();
if header != 0 && header != 0xfe {
return Err(err_protocol!(
"expected 0x00 or 0xfe (OK_Packet) but found 0x{:02x}",
header
));
}
let affected_rows = buf.get_uint_lenenc()?;
let last_insert_id = buf.get_uint_lenenc()?;
if buf.remaining() < 4 {
return Err(err_protocol!(
"OK_Packet too short: expected at least 4 more bytes for status+warnings, got {}",
buf.remaining()
));
}
let status = Status::from_bits_truncate(buf.get_u16_le());
let warnings = buf.get_u16_le();
Ok(Self {
affected_rows,
last_insert_id,
status,
warnings,
})
}
}
#[test]
fn test_decode_ok_packet() {
const DATA: &[u8] = b"\x00\x00\x00\x02@\x00\x00";
let p = OkPacket::decode(DATA.into()).unwrap();
assert_eq!(p.affected_rows, 0);
assert_eq!(p.last_insert_id, 0);
assert_eq!(p.warnings, 0);
assert!(p.status.contains(Status::SERVER_STATUS_AUTOCOMMIT));
assert!(p.status.contains(Status::SERVER_SESSION_STATE_CHANGED));
}
#[test]
fn test_decode_ok_packet_with_info() {
// OK packet with 0xfe header and length >= 9 (with appended info)
const DATA: &[u8] = b"\xfe\x01\x00\x02\x00\x00\x00\x05\x09info data";
let p = OkPacket::decode(DATA.into()).unwrap();
assert_eq!(p.affected_rows, 1);
assert_eq!(p.last_insert_id, 0);
assert_eq!(p.warnings, 0);
assert!(p.status.contains(Status::SERVER_STATUS_AUTOCOMMIT));
}
#[test]
fn test_decode_ok_packet_with_extended_info() {
// OK packet with 0xfe header, affected rows, last insert id, and extended info
const DATA: &[u8] = b"\xfe\x05\x64\x02\x00\x01\x00\x0e\x14extended information";
let p = OkPacket::decode(DATA.into()).unwrap();
assert_eq!(p.affected_rows, 5);
assert_eq!(p.last_insert_id, 100);
assert_eq!(p.warnings, 1);
assert!(p.status.contains(Status::SERVER_STATUS_AUTOCOMMIT));
}
#[test]
fn test_decode_ok_packet_truncated() {
const DATA: &[u8] = b"\x00\x00\x00\x01";
let err = OkPacket::decode(DATA.into()).unwrap_err();
assert!(matches!(err, Error::Protocol(_)), "{err}");
}