A tool to compile SQL to Elasticsearch queries
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

compiler.rs 2.2KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. use serde_json::{json, Value};
  2. use std::fmt::{Display, Formatter};
  3. use crate::error::KappeError;
  4. use crate::parser::{Field, Identifier, Select};
  5. #[derive(Debug, PartialEq)]
  6. pub struct Query {
  7. pub source: Identifier,
  8. pub body: Value,
  9. }
  10. impl Query {
  11. pub fn new(source: Identifier, body: Value) -> Self {
  12. Self { source, body }
  13. }
  14. }
  15. impl Display for Query {
  16. fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
  17. let header = format!("GET /{}/_search", self.source.name);
  18. let body = match serde_json::to_string_pretty(&self.body) {
  19. Ok(body) => body,
  20. Err(_) => return Err(std::fmt::Error {}),
  21. };
  22. write!(f, "{}\n{}", header, body)
  23. }
  24. }
  25. pub fn compile(expr: Select) -> Result<Query, KappeError> {
  26. let field_names: Vec<Value> = expr
  27. .fields
  28. .iter()
  29. .map(|f| match f {
  30. Field::Star => Value::String("*".to_string()),
  31. Field::Named(name) => Value::String(name.clone()),
  32. })
  33. .collect();
  34. let body = json!({
  35. "query": { "match_all":{} },
  36. "_source": Value::Array(field_names)
  37. });
  38. Ok(Query::new(expr.source, body))
  39. }
  40. #[cfg(test)]
  41. mod tests {
  42. use super::*;
  43. use crate::lexer::scan;
  44. use crate::parser::parse;
  45. fn _compile(input: &str) -> Result<Query, KappeError> {
  46. let tokens = scan(input).unwrap();
  47. let select = parse(tokens).unwrap();
  48. compile(select)
  49. }
  50. #[test]
  51. fn it_compiles_a_simple_select() {
  52. assert_eq!(
  53. _compile("SELECT * FROM bar").unwrap(),
  54. Query::new(
  55. Identifier::new("bar"),
  56. json!({
  57. "query": {
  58. "match_all": {}
  59. },
  60. "_source": ["*"]
  61. })
  62. )
  63. )
  64. }
  65. #[test]
  66. fn it_compiles_a_select_with_specific_fields() {
  67. assert_eq!(
  68. _compile("SELECT foo FROM bar").unwrap(),
  69. Query::new(
  70. Identifier::new("bar"),
  71. json!({
  72. "query": {
  73. "match_all": {}
  74. },
  75. "_source": ["foo"]
  76. })
  77. )
  78. )
  79. }
  80. }