dm_database_parser_sqllog/parser/
sqllog_parser.rs1use crate::error::ParseError;
6use crate::parser::record_parser::RecordParser;
7use crate::sqllog::Sqllog;
8use std::io::Read;
9
10pub struct SqllogParser<R: Read> {
35 record_parser: RecordParser<R>,
36}
37
38impl<R: Read> SqllogParser<R> {
39 pub fn new(reader: R) -> Self {
49 Self {
50 record_parser: RecordParser::new(reader),
51 }
52 }
53}
54
55impl<R: Read> Iterator for SqllogParser<R> {
56 type Item = Result<Sqllog, ParseError>;
57
58 fn next(&mut self) -> Option<Self::Item> {
59 match self.record_parser.next()? {
60 Ok(record) => Some(record.parse_to_sqllog()),
61 Err(e) => Some(Err(ParseError::FileNotFound {
62 path: e.to_string(),
63 })),
64 }
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71 use std::io::Cursor;
72
73 #[test]
74 fn test_sqllog_parser_basic() {
75 let input = "2025-08-12 10:57:09.548 (EP[0] sess:123 thrd:456 user:alice trxid:789 stmt:999 appname:app) SELECT 1\n";
76 let cursor = Cursor::new(input);
77 let parser = SqllogParser::new(cursor);
78
79 let results: Vec<_> = parser.collect();
80 assert_eq!(results.len(), 1);
81 assert!(results[0].is_ok());
82
83 let sqllog = results[0].as_ref().unwrap();
84 assert_eq!(sqllog.ts, "2025-08-12 10:57:09.548");
85 assert_eq!(sqllog.meta.username, "alice");
86 assert_eq!(sqllog.body, "SELECT 1");
87 }
88
89 #[test]
90 fn test_sqllog_parser_with_indicators() {
91 let input = "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.\n";
92 let cursor = Cursor::new(input);
93 let parser = SqllogParser::new(cursor);
94
95 let results: Vec<_> = parser.collect();
96 assert_eq!(results.len(), 1);
97 assert!(results[0].is_ok());
98
99 let sqllog = results[0].as_ref().unwrap();
100 assert!(sqllog.has_indicators());
101 assert_eq!(sqllog.execute_time(), Some(10.5));
102 assert_eq!(sqllog.row_count(), Some(100));
103 assert_eq!(sqllog.execute_id(), Some(12345));
104 }
105
106 #[test]
107 fn test_sqllog_parser_multiline() {
108 let input = r#"2025-08-12 10:57:09.548 (EP[0] sess:123 thrd:456 user:alice trxid:789 stmt:999 appname:app) SELECT *
109FROM users
110WHERE id = 1
111"#;
112 let cursor = Cursor::new(input);
113 let parser = SqllogParser::new(cursor);
114
115 let results: Vec<_> = parser.collect();
116 assert_eq!(results.len(), 1);
117 assert!(results[0].is_ok());
118
119 let sqllog = results[0].as_ref().unwrap();
120 assert!(sqllog.body.contains("SELECT *"));
121 assert!(sqllog.body.contains("FROM users"));
122 assert!(sqllog.body.contains("WHERE id = 1"));
123 }
124
125 #[test]
126 fn test_sqllog_parser_empty() {
127 let input = "";
128 let cursor = Cursor::new(input);
129 let parser = SqllogParser::new(cursor);
130
131 let results: Vec<_> = parser.collect();
132 assert_eq!(results.len(), 0);
133 }
134
135 #[test]
136 fn test_sqllog_parser_multiple_records() {
137 let input = r#"2025-08-12 10:57:09.548 (EP[0] sess:123 thrd:456 user:alice trxid:789 stmt:999 appname:app) SELECT 1
1382025-08-12 10:57:10.548 (EP[0] sess:124 thrd:457 user:bob trxid:790 stmt:1000 appname:app) SELECT 2
139"#;
140 let cursor = Cursor::new(input);
141 let parser = SqllogParser::new(cursor);
142
143 let results: Vec<_> = parser.collect();
144 assert_eq!(results.len(), 2);
145 assert!(results[0].is_ok());
146 assert!(results[1].is_ok());
147
148 assert_eq!(results[0].as_ref().unwrap().meta.username, "alice");
149 assert_eq!(results[1].as_ref().unwrap().meta.username, "bob");
150 }
151}