use forge::signal::compactor;
use once_cell::sync::Lazy;
use regex::Regex;
static CONN_NOISE_RE: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"(?m)^(mysql: \[Warning\]|Welcome to the MySQL|Your MySQL connection id|Server version:)[^\n]*\n?").unwrap()
});
#[allow(dead_code)]
static EMPTY_SET_RE: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?m)^Empty set \(\d+\.\d+ sec\)\n?").unwrap());
static ROWS_RE: Lazy<Regex> = Lazy::new(||
Regex::new(r"(?m)^\d+ rows? in set \(\d+\.\d+ sec\)").unwrap());
pub fn compress_mysql(raw: &str) -> String {
let cleaned = compactor::normalise(raw);
let s = CONN_NOISE_RE.replace_all(&cleaned, "");
let lines: Vec<&str> = s.lines().collect();
if lines.len() > 55 {
let row_count_line = lines.iter().rfind(|l| ROWS_RE.is_match(l));
let head = &lines[..2.min(lines.len())];
let body = &lines[2..52.min(lines.len())];
let omitted = lines.len().saturating_sub(52);
let mut out = head.join("\n");
out.push('\n');
out.push_str(&body.join("\n"));
out.push_str(&format!("\n... [{} more rows omitted] ...", omitted));
if let Some(rc) = row_count_line {
out.push('\n');
out.push_str(rc);
}
return out;
}
compactor::collapse_blanks(&s)
}
pub fn compress_mysqldump(raw: &str) -> String {
let cleaned = compactor::normalise(raw);
let kept: Vec<&str> = cleaned
.lines()
.filter(|l| {
let t = l.trim();
!(t.starts_with("-- Server version")
|| t.starts_with("-- Host:")
|| t.starts_with("-- Dump completed")
|| t.starts_with("-- MySQL dump")
|| t.starts_with("/*!"))
})
.collect();
kept.join("\n")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn strips_connection_warnings() {
let raw = "mysql: [Warning] Using a password on the command line interface can be insecure.\nid | name\n1 | foo\n1 row in set (0.00 sec)\n";
let out = compress_mysql(raw);
assert!(!out.contains("[Warning]"), "{out}");
assert!(out.contains("foo"), "{out}");
}
#[test]
fn truncates_large_result_set() {
let header = "+----+--------+\n| id | name |\n+----+--------+\n";
let rows: String = (0..60)
.map(|i| format!("| {i:2} | name{i:2} |\n"))
.collect();
let footer = "+----+--------+\n60 rows in set (0.01 sec)\n";
let raw = format!("{header}{rows}{footer}");
let out = compress_mysql(&raw);
assert!(out.contains("omitted"), "{out}");
}
}