A tool to compile SQL to Elasticsearch queries
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

compiler.rs 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. use serde_json::{json, Value};
  2. use std::fmt::{Display, Formatter};
  3. use crate::error::CompilerError;
  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, CompilerError> {
  26. let mut source = false;
  27. let field_names: Vec<Value> = expr
  28. .fields
  29. .iter()
  30. .map(|f| match f {
  31. Field::Star => {
  32. source = true;
  33. Value::String("*".to_string())
  34. }
  35. Field::Named(name) => Value::String(name.clone()),
  36. })
  37. .collect();
  38. let body = json!({
  39. "query": { "match_all":{} },
  40. "_source": source,
  41. "fields": Value::Array(field_names)
  42. });
  43. Ok(Query::new(expr.source, body))
  44. }
  45. #[cfg(test)]
  46. mod tests {
  47. use super::*;
  48. use crate::lexer::scan;
  49. use crate::parser::parse;
  50. fn _compile(input: &str) -> Result<Query, CompilerError> {
  51. let tokens = scan(input).unwrap();
  52. let select = parse(tokens).unwrap();
  53. compile(select)
  54. }
  55. #[test]
  56. fn it_compiles_a_simple_select() {
  57. assert_eq!(
  58. _compile("SELECT * FROM bar").unwrap(),
  59. Query::new(
  60. Identifier::new("bar"),
  61. json!({
  62. "query": {
  63. "match_all": {}
  64. },
  65. "fields": ["*"],
  66. "_source": true
  67. })
  68. )
  69. )
  70. }
  71. #[test]
  72. fn it_compiles_a_select_with_specific_fields() {
  73. assert_eq!(
  74. _compile("SELECT foo FROM bar").unwrap(),
  75. Query::new(
  76. Identifier::new("bar"),
  77. json!({
  78. "query": {
  79. "match_all": {}
  80. },
  81. "fields": ["foo"],
  82. "_source": false
  83. })
  84. )
  85. )
  86. }
  87. }