mod anchor;
mod context;
mod dialect;
mod gen_expr;
mod gen_projection;
mod gen_query;
mod preprocess;
mod std;
pub use dialect::Dialect;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use crate::{ast::rq::Query, PRQL_VERSION};
use self::{context::AnchorContext, dialect::DialectHandler};
pub fn compile(query: Query, options: Option<Options>) -> Result<String> {
let options = options.unwrap_or_default();
let sql_ast = gen_query::translate_query(query, options.dialect)?;
let sql = sql_ast.to_string();
let sql = if options.format {
let formatted = sqlformat::format(
&sql,
&sqlformat::QueryParams::default(),
sqlformat::FormatOptions::default(),
);
formatted.replace("{ {", "{{").replace("} }", "}}")
} else {
sql
};
let sql = if options.signature_comment {
let pre = if options.format { "\n\n" } else { " " };
let post = if options.format { "\n" } else { "" };
let signature = format!(
"{pre}-- Generated by PRQL compiler version {} (https://prql-lang.org){post}",
*PRQL_VERSION
);
sql + &signature
} else {
sql
};
Ok(sql)
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Options {
pub format: bool,
pub dialect: Option<Dialect>,
pub signature_comment: bool,
}
impl Default for Options {
fn default() -> Self {
Self {
format: true,
dialect: None,
signature_comment: true,
}
}
}
impl Options {
pub fn no_format(mut self) -> Self {
self.format = false;
self
}
pub fn no_signature(mut self) -> Self {
self.signature_comment = false;
self
}
pub fn with_dialect(mut self, dialect: Dialect) -> Self {
self.dialect = Some(dialect);
self
}
pub fn some(self) -> Option<Self> {
Some(self)
}
}
struct Context {
pub dialect: Box<dyn DialectHandler>,
pub anchor: AnchorContext,
pub omit_ident_prefix: bool,
pub pre_projection: bool,
}