dm_database_parser_sqllog/parser/
record.rs

1//! Record 结构定义和相关方法
2//!
3//! Record 表示一条原始的日志记录,可能包含多行(起始行 + 继续行)。
4
5use crate::error::ParseError;
6use crate::sqllog::Sqllog;
7
8/// 表示一条完整的日志记录(可能包含多行)
9///
10/// 日志记录由一个起始行和零个或多个继续行组成。起始行包含时间戳和元数据,
11/// 继续行包含多行 SQL 语句的后续部分。
12///
13/// # 示例
14///
15/// ```
16/// use dm_database_parser_sqllog::{Record, parse_records_from_string};
17///
18/// 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 *
19/// FROM users
20/// WHERE id = 1"#;
21///
22/// let records = parse_records_from_string(log);
23/// assert_eq!(records.len(), 1);
24/// assert!(records[0].has_continuation_lines());
25/// assert_eq!(records[0].lines.len(), 3);
26/// ```
27#[derive(Debug, Clone, PartialEq)]
28pub struct Record {
29    /// 记录的所有行(第一行是起始行,后续行是继续行)
30    pub lines: Vec<String>,
31}
32
33impl Record {
34    /// 创建新的记录
35    ///
36    /// # 参数
37    ///
38    /// * `start_line` - 记录的起始行
39    pub fn new(start_line: String) -> Self {
40        Self {
41            lines: vec![start_line],
42        }
43    }
44
45    /// 添加继续行
46    ///
47    /// # 参数
48    ///
49    /// * `line` - 要添加的继续行
50    pub fn add_line(&mut self, line: String) {
51        self.lines.push(line);
52    }
53
54    /// 获取起始行
55    ///
56    /// # 返回
57    ///
58    /// 返回记录的第一行(起始行)
59    pub fn start_line(&self) -> &str {
60        &self.lines[0]
61    }
62
63    /// 获取所有行
64    ///
65    /// # 返回
66    ///
67    /// 返回包含所有行的切片
68    pub fn all_lines(&self) -> &[String] {
69        &self.lines
70    }
71
72    /// 获取完整的记录内容(所有行拼接)
73    ///
74    /// # 返回
75    ///
76    /// 返回所有行用换行符拼接后的字符串
77    pub fn full_content(&self) -> String {
78        self.lines.join("\n")
79    }
80
81    /// 判断是否有继续行
82    ///
83    /// # 返回
84    ///
85    /// 如果记录包含多行(有继续行)返回 `true`,否则返回 `false`
86    pub fn has_continuation_lines(&self) -> bool {
87        self.lines.len() > 1
88    }
89
90    /// 将 Record 解析为 Sqllog
91    ///
92    /// # 返回
93    ///
94    /// * `Ok(Sqllog)` - 解析成功
95    /// * `Err(ParseError)` - 解析失败
96    ///
97    /// # 示例
98    ///
99    /// ```
100    /// use dm_database_parser_sqllog::{Record, parse_records_from_string};
101    ///
102    /// let log = "2025-08-12 10:57:09.548 (EP[0] sess:123 thrd:456 user:alice trxid:789 stmt:999 appname:app) SELECT 1";
103    /// let records = parse_records_from_string(log);
104    /// let sqllog = records[0].parse_to_sqllog().unwrap();
105    ///
106    /// assert_eq!(sqllog.meta.username, "alice");
107    /// ```
108    pub fn parse_to_sqllog(&self) -> Result<Sqllog, ParseError> {
109        let lines: Vec<&str> = self.lines.iter().map(|s| s.as_str()).collect();
110        super::parse_functions::parse_record(&lines)
111    }
112}