keelson_sqlite/
dialect.rs1use keelson_core::{Dialect, SqlWriter};
2
3#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
12pub struct Sqlite;
13
14impl Dialect for Sqlite {
15 fn write_arg(&self, w: &mut SqlWriter<'_>, position: usize) {
16 w.push_str("?");
17 w.push_str(&position.to_string());
18 }
19
20 fn write_quoted(&self, w: &mut SqlWriter<'_>, s: &str) {
26 w.push_str("\"");
27 if s.contains('"') {
28 w.push_str(&s.replace('"', "\"\""));
29 } else {
30 w.push_str(s);
31 }
32 w.push_str("\"");
33 }
34
35 fn write_named_arg(&self, w: &mut SqlWriter<'_>, name: &str) {
36 w.push_str(":");
37 w.push_str(name);
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44 use keelson_core::{Value, build, expr};
45
46 #[test]
47 fn placeholders_are_numbered_and_identifiers_are_double_quoted() {
48 let e = expr::Expr::join((expr::quote(("users", "id")), expr::arg(1i32)));
49 let (sql, args) = build(&Sqlite, &e).unwrap();
50 assert_eq!(sql, r#""users"."id" ?1"#);
51 assert_eq!(args, vec![Value::I32(1)]);
52 }
53
54 #[test]
55 fn an_embedded_quote_is_doubled() {
56 let (sql, _) = build(&Sqlite, &expr::quote(r#"we"ird"#)).unwrap();
57 assert_eq!(sql, r#""we""ird""#);
58 }
59
60 #[test]
63 fn named_arguments_are_supported_and_consume_no_position() {
64 let e = expr::Expr::join((expr::arg(1i32), expr::named("cutoff"), expr::arg(2i32)));
65 let (sql, args) = build(&Sqlite, &e).unwrap();
66 assert_eq!(sql, "?1 :cutoff ?2");
67 assert_eq!(args, vec![Value::I32(1), Value::I32(2)]);
68 }
69}