dm_database_sqllog2db/
parser.rs1use crate::error::{Error, ParserError, Result};
4use log::{debug, info, warn};
5use std::path::{Path, PathBuf};
6
7#[derive(Debug)]
9pub struct SqllogParser {
10 path: PathBuf,
12}
13
14impl SqllogParser {
15 pub fn new(path: impl AsRef<Path>) -> Self {
17 Self {
18 path: path.as_ref().to_path_buf(),
19 }
20 }
21
22 #[must_use]
24 pub fn path(&self) -> &Path {
25 &self.path
26 }
27
28 pub fn log_files(&self) -> Result<Vec<PathBuf>> {
31 self.scan_log_files()
32 }
33
34 fn scan_log_files(&self) -> Result<Vec<PathBuf>> {
36 let path = &self.path;
37
38 if !path.exists() {
39 return Err(Error::Parser(ParserError::PathNotFound {
40 path: path.clone(),
41 }));
42 }
43
44 let mut log_files = Vec::new();
45
46 if path.is_file() {
47 info!("Parsing single log file: {}", path.display());
49 log_files.push(path.clone());
50 } else if path.is_dir() {
51 info!("Scanning log directory: {}", path.display());
53
54 let entries = std::fs::read_dir(path).map_err(|e| {
55 Error::Parser(ParserError::ReadDirFailed {
56 path: path.clone(),
57 reason: e.to_string(),
58 })
59 })?;
60
61 for entry in entries {
62 let entry = entry.map_err(|e| {
63 Error::Parser(ParserError::ReadDirFailed {
64 path: path.clone(),
65 reason: e.to_string(),
66 })
67 })?;
68
69 let entry_path = entry.path();
70
71 if entry_path.is_file() && entry_path.extension().is_some_and(|ext| ext == "log") {
73 debug!("Found log file: {}", entry_path.display());
74 log_files.push(entry_path);
75 }
76 }
77
78 if log_files.is_empty() {
79 warn!("No .log files found in directory {}", path.display());
80 } else {
81 info!("Found {} log files", log_files.len());
82 }
83 } else {
84 return Err(Error::Parser(ParserError::InvalidPath {
85 path: path.clone(),
86 reason: "既不是文件也不是目录".to_string(),
87 }));
88 }
89
90 Ok(log_files)
91 }
92}