pub(crate) fn split_sql_commands(input: &str) -> Vec<String> {
let mut commands = Vec::new(); let mut current_command = String::new(); let mut in_single_quote = false; let mut in_double_quote = false;
for c in input.chars() {
match c {
'\'' if !in_double_quote => {
in_single_quote = !in_single_quote;
current_command.push(c);
}
'"' if !in_single_quote => {
in_double_quote = !in_double_quote;
current_command.push(c);
}
';' if !in_single_quote && !in_double_quote => {
if !current_command.trim().is_empty() {
commands.push(current_command.trim().to_string());
current_command.clear();
}
}
_ => current_command.push(c),
}
}
if !current_command.trim().is_empty() {
commands.push(current_command.trim().to_string());
}
commands
}
use crate::detect::{ColumnDef, TableDef};
pub(crate) fn find_column_or_unwrap<'t>(tabledef: &'t TableDef, name: &str) -> &'t ColumnDef {
let err = format!("Could not find column '{}' in the database", name);
tabledef
.columns()
.iter()
.find(|&c| c.name() == name)
.expect(&err)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_split_sql_commands() {
let input = "SELECT * FROM users; UPDATE users SET name = 'John; Doe' WHERE id = 1;";
let commands = split_sql_commands(input);
assert_eq!(
commands,
vec![
"SELECT * FROM users",
"UPDATE users SET name = 'John; Doe' WHERE id = 1"
]
);
}
#[test]
fn test_with_double_quotes() {
let input = "INSERT INTO users (name, email) VALUES (\"Jane; Doe\", 'jane@doe.com'); SELECT * FROM users;";
let commands = split_sql_commands(input);
assert_eq!(
commands,
vec![
"INSERT INTO users (name, email) VALUES (\"Jane; Doe\", 'jane@doe.com')",
"SELECT * FROM users"
]
);
}
#[test]
fn test_with_nested_quotes() {
let input = "INSERT INTO books (title, description) VALUES ('SQL; The \"Easy\" Way', 'A book for \"beginners\"; covers basics and more.'); SELECT id FROM books;";
let commands = split_sql_commands(input);
assert_eq!(
commands,
vec![
"INSERT INTO books (title, description) VALUES ('SQL; The \"Easy\" Way', 'A book for \"beginners\"; covers basics and more.')",
"SELECT id FROM books"
]
);
}
#[test]
fn test_empty_and_whitespace() {
let input = "SELECT * FROM users;; ; UPDATE users SET active = false WHERE last_login < '2023-01-01';";
let commands = split_sql_commands(input);
assert_eq!(
commands,
vec![
"SELECT * FROM users",
"UPDATE users SET active = false WHERE last_login < '2023-01-01'"
]
);
}
}