Files
RuDS/crates/bds-core/tests/orm_boundary.rs

61 lines
1.7 KiB
Rust

use std::fs;
use std::path::{Path, PathBuf};
const SQL_PREFIXES: &[&str] = &[
"\"SELECT ",
"\"INSERT ",
"\"UPDATE ",
"\"DELETE ",
"\"CREATE ",
"\"DROP ",
"\"ALTER ",
"\"SAVEPOINT ",
"\"RELEASE ",
"\"ROLLBACK ",
];
#[test]
fn application_queries_use_the_diesel_abstraction() {
let source_root = Path::new(env!("CARGO_MANIFEST_DIR")).join("src");
let mut rust_files = Vec::new();
collect_rust_files(&source_root, &mut rust_files);
let mut violations = Vec::new();
for path in rust_files {
// SQLite connection configuration and FTS5 virtual tables/MATCH have no
// representation in Diesel's typed query builder.
if path.ends_with("db/connection.rs") || path.ends_with("db/fts.rs") {
continue;
}
let source = fs::read_to_string(&path).unwrap();
for (line_index, line) in source.lines().enumerate() {
if SQL_PREFIXES.iter().any(|prefix| line.contains(prefix)) {
violations.push(format!(
"{}:{}: {}",
path.display(),
line_index + 1,
line.trim()
));
}
}
}
assert!(
violations.is_empty(),
"literal SQL escaped the backend boundary:\n{}",
violations.join("\n")
);
}
fn collect_rust_files(directory: &Path, files: &mut Vec<PathBuf>) {
for entry in fs::read_dir(directory).unwrap() {
let path = entry.unwrap().path();
if path.is_dir() {
collect_rust_files(&path, files);
} else if path.extension().is_some_and(|extension| extension == "rs") {
files.push(path);
}
}
}