edgedb_query_builder/
lib.rs1pub enum Keyword {
2 Select {
3 table: String,
4 fields: Vec<String>
5 },
6 Insert {
7 table: String,
8 fields: Vec<(String, String)>,
9 },
10 Filter {
11 fields: Vec<(String, String)>,
12 }
13}
14
15pub struct Query {
17 pub keywords: Vec<Keyword>
18}
19
20impl Query {
21 pub fn new() -> Self {
23 Query { keywords: Vec::new() }
24 }
25 pub fn select<T: Into<String> + std::fmt::Display>(&mut self, table: T, values: Vec<T>) -> &mut Self {
28 self.keywords.push(Keyword::Select { table: table.into(), fields: values.iter().map(|e| e.to_string()).collect::<Vec<String>>() });
29 return self
30 }
31 pub fn filter(&mut self, fields: Vec<(String, String)>) -> &mut Self {
34 self.keywords.push(Keyword::Filter { fields });
35 return self
36 }
37 pub fn insert<T: Into<String> + std::fmt::Display>(&mut self, table: T, fields: Vec<(String, String)>) -> &mut Self {
40 self.keywords.push(Keyword::Insert { table: table.into(), fields });
41 return self
42 }
43 pub fn build(&self) -> String {
52 let mut query = String::new();
53 for keyword in &self.keywords {
54 match keyword {
55 Keyword::Select { table, fields } => {
56 query.push_str(&format!("select {table} {{ {} }}", fields.join(",")))
57 },
58 Keyword::Insert { table, fields } => {
59 query.push_str(&format!("insert {table} {{ {} }}", fields.iter().map(|f| format!("{} := \"{}\"", f.0, f.1)).collect::<Vec<String>>().join(",")))
60 }
61 Keyword::Filter { fields } => {
62 let mut filter_stmt = String::from("filter");
63 let filters = fields.iter().map(|f| format!(".{} = \"{}\"", f.0, f.1)).collect::<Vec<String>>().join("and");
64 filter_stmt.push_str(&filters);
65 query.push_str(&filter_stmt);
66 }
67 }
68 }
69 query.push(';');
70 return query
71 }
72}
73
74#[cfg(test)]
75mod query_tests {
76 #[test]
77 fn basic_query() {
78 let mut query = crate::Query::new();
79 query.select("movie".to_string(), vec!["title".to_string()]);
80
81 let query_str = query.build();
82
83 assert_eq!(query_str, String::from("select movie { title }"));
84 }
85}