#[must_use]
pub fn with_limit_offset(sql: &str, limit: usize, offset: u64) -> String {
let trimmed = sql.trim_end();
let inner = trimmed.strip_suffix(';').unwrap_or(trimmed).trim_end();
format!("SELECT * FROM ({inner}\n) AS paginated LIMIT {limit} OFFSET {offset}")
}
#[cfg(test)]
mod tests {
use super::with_limit_offset;
#[test]
fn injects_limit_offset_and_alias() {
assert_eq!(
with_limit_offset("SELECT id FROM users ORDER BY id", 3, 0),
"SELECT * FROM (SELECT id FROM users ORDER BY id\n) AS paginated LIMIT 3 OFFSET 0",
);
}
#[test]
fn emits_requested_limit_and_offset() {
let wrapped = with_limit_offset("SELECT 1", 11, 50);
assert!(wrapped.contains(" LIMIT 11 OFFSET 50"), "got: {wrapped}");
}
#[test]
fn strips_trailing_semicolon_and_whitespace() {
let expected = "SELECT * FROM (SELECT 1\n) AS paginated LIMIT 2 OFFSET 0";
for input in ["SELECT 1", "SELECT 1;", "SELECT 1 ;", "SELECT 1; ", "SELECT 1 "] {
assert_eq!(with_limit_offset(input, 2, 0), expected, "input = {input:?}");
}
}
#[test]
fn survives_trailing_line_comment() {
assert_eq!(
with_limit_offset("SELECT 1 -- count rows", 6, 0),
"SELECT * FROM (SELECT 1 -- count rows\n) AS paginated LIMIT 6 OFFSET 0",
);
}
}