dm_database_parser_sqllog/sqllog.rs
1//! SQL 日志数据结构定义
2//!
3//! 定义了解析后的 SQL 日志记录的数据结构。
4
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7
8/// SQL 日志记录
9///
10/// 表示一条完整的 SQL 日志记录,包含时间戳、元数据、SQL 语句体和可选的性能指标。
11///
12/// # 示例
13///
14/// ```
15/// use dm_database_parser_sqllog::parse_sqllogs_from_string;
16///
17/// let log = r#"2025-08-12 10:57:09.548 (EP[0] sess:123 thrd:456 user:alice trxid:789 stmt:999 appname:app) SELECT 1"#;
18/// let results = parse_sqllogs_from_string(log);
19///
20/// if let Ok(sqllog) = &results[0] {
21/// assert_eq!(sqllog.ts, "2025-08-12 10:57:09.548");
22/// assert_eq!(sqllog.meta.username, "alice");
23/// assert_eq!(sqllog.body, "SELECT 1");
24/// }
25/// ```
26#[derive(Debug, Clone, PartialEq, Default)]
27#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
28pub struct Sqllog {
29 /// 时间戳,格式为 "YYYY-MM-DD HH:MM:SS.mmm"
30 pub ts: String,
31
32 /// 元数据部分,包含会话信息、用户信息等
33 pub meta: MetaParts,
34
35 /// SQL 语句体
36 pub body: String,
37
38 /// 可选的性能指标信息
39 pub indicators: Option<IndicatorsParts>,
40}
41
42/// 元数据部分
43///
44/// 包含日志记录的所有元数据字段,如会话 ID、用户名等。
45#[derive(Debug, Clone, PartialEq, Default)]
46#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
47pub struct MetaParts {
48 /// EP(Execution Point)编号,范围 0-255
49 pub ep: u8,
50
51 /// 会话 ID
52 pub sess_id: String,
53
54 /// 线程 ID
55 pub thrd_id: String,
56
57 /// 用户名
58 pub username: String,
59
60 /// 事务 ID
61 pub trxid: String,
62
63 /// 语句 ID
64 pub statement: String,
65
66 /// 应用程序名称
67 pub appname: String,
68
69 /// 客户端 IP 地址(可选)
70 pub client_ip: String,
71}
72
73/// 性能指标部分
74///
75/// 包含 SQL 执行的性能指标,如执行时间、影响行数等。
76///
77/// # 示例
78///
79/// ```
80/// use dm_database_parser_sqllog::parse_sqllogs_from_string;
81///
82/// let log = r#"2025-08-12 10:57:09.548 (EP[0] sess:123 thrd:456 user:alice trxid:789 stmt:999 appname:app) SELECT 1 EXECTIME: 10.5(ms) ROWCOUNT: 100(rows) EXEC_ID: 12345."#;
83/// let results = parse_sqllogs_from_string(log);
84///
85/// if let Ok(sqllog) = &results[0] {
86/// if let Some(indicators) = &sqllog.indicators {
87/// assert_eq!(indicators.execute_time, 10.5);
88/// assert_eq!(indicators.row_count, 100);
89/// assert_eq!(indicators.execute_id, 12345);
90/// }
91/// }
92/// ```
93#[derive(Debug, Clone, Copy, PartialEq, Default)]
94#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
95pub struct IndicatorsParts {
96 /// 执行时间(毫秒)
97 pub execute_time: f32,
98
99 /// 影响的行数
100 pub row_count: u32,
101
102 /// 执行 ID
103 pub execute_id: i64,
104}
105
106impl Sqllog {
107 /// 判断是否有性能指标信息
108 ///
109 /// # 返回
110 ///
111 /// 如果存在性能指标返回 `true`,否则返回 `false`
112 #[inline]
113 pub fn has_indicators(&self) -> bool {
114 self.indicators.is_some()
115 }
116
117 /// 获取执行时间(毫秒)
118 ///
119 /// # 返回
120 ///
121 /// 如果存在性能指标返回执行时间,否则返回 `None`
122 #[inline]
123 pub fn execute_time(&self) -> Option<f32> {
124 self.indicators.map(|i| i.execute_time)
125 }
126
127 /// 获取影响行数
128 ///
129 /// # 返回
130 ///
131 /// 如果存在性能指标返回影响行数,否则返回 `None`
132 #[inline]
133 pub fn row_count(&self) -> Option<u32> {
134 self.indicators.map(|i| i.row_count)
135 }
136
137 /// 获取执行 ID
138 ///
139 /// # 返回
140 ///
141 /// 如果存在性能指标返回执行 ID,否则返回 `None`
142 #[inline]
143 pub fn execute_id(&self) -> Option<i64> {
144 self.indicators.map(|i| i.execute_id)
145 }
146}
147
148impl MetaParts {
149 /// 判断是否有客户端 IP 信息
150 ///
151 /// # 返回
152 ///
153 /// 如果存在客户端 IP 返回 `true`,否则返回 `false`
154 #[inline]
155 pub fn has_client_ip(&self) -> bool {
156 !self.client_ip.is_empty()
157 }
158}