use crate::{QueryBuilder, QuotedBuilder, SqlWriter};
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct Extension;
impl Extension {
pub fn create() -> ExtensionCreateStatement {
ExtensionCreateStatement::new()
}
pub fn drop() -> ExtensionDropStatement {
ExtensionDropStatement::new()
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct ExtensionCreateStatement {
pub(crate) name: String,
pub(crate) schema: Option<String>,
pub(crate) version: Option<String>,
pub(crate) if_not_exists: bool,
pub(crate) cascade: bool,
}
impl ExtensionCreateStatement {
pub fn new() -> Self {
Self::default()
}
pub fn name<T: Into<String>>(&mut self, name: T) -> &mut Self {
self.name = name.into();
self
}
pub fn schema<T: Into<String>>(&mut self, schema: T) -> &mut Self {
self.schema = Some(schema.into());
self
}
pub fn version<T: Into<String>>(&mut self, version: T) -> &mut Self {
self.version = Some(version.into());
self
}
pub fn cascade(&mut self) -> &mut Self {
self.cascade = true;
self
}
pub fn if_not_exists(&mut self) -> &mut Self {
self.if_not_exists = true;
self
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct ExtensionDropStatement {
pub(crate) name: String,
pub(crate) schema: Option<String>,
pub(crate) version: Option<String>,
pub(crate) if_exists: bool,
pub(crate) restrict: bool,
pub(crate) cascade: bool,
}
impl ExtensionDropStatement {
pub fn new() -> Self {
Self::default()
}
pub fn name<T: Into<String>>(&mut self, name: T) -> &mut Self {
self.name = name.into();
self
}
pub fn if_exists(&mut self) -> &mut Self {
self.if_exists = true;
self
}
pub fn cascade(&mut self) -> &mut Self {
self.cascade = true;
self
}
pub fn restrict(&mut self) -> &mut Self {
self.restrict = true;
self
}
}
pub trait ExtensionBuilder: QuotedBuilder {
fn prepare_extension_create_statement(
&self,
create: &ExtensionCreateStatement,
sql: &mut dyn SqlWriter,
);
fn prepare_extension_drop_statement(
&self,
drop: &ExtensionDropStatement,
sql: &mut dyn SqlWriter,
);
}
macro_rules! impl_extension_statement_builder {
( $struct_name: ident, $func_name: ident ) => {
impl $struct_name {
pub fn build_ref<T: ExtensionBuilder>(&self, extension_builder: &T) -> String {
let mut sql = String::with_capacity(256);
self.build_collect_ref(extension_builder, &mut sql)
}
pub fn build_collect<T: ExtensionBuilder>(
&self,
extension_builder: T,
sql: &mut dyn SqlWriter,
) -> String {
self.build_collect_ref(&extension_builder, sql)
}
pub fn build_collect_ref<T: ExtensionBuilder>(
&self,
extension_builder: &T,
sql: &mut dyn SqlWriter,
) -> String {
extension_builder.$func_name(self, sql);
sql.to_string()
}
pub fn to_string<T>(&self, extension_builder: T) -> String
where
T: ExtensionBuilder + QueryBuilder,
{
self.build_ref(&extension_builder)
}
}
};
}
impl_extension_statement_builder!(ExtensionCreateStatement, prepare_extension_create_statement);
impl_extension_statement_builder!(ExtensionDropStatement, prepare_extension_drop_statement);
#[cfg(test)]
mod test {
use super::super::PgLTree;
use super::*;
#[test]
fn creates_a_stmt_for_create_extension() {
let create_extension_stmt = Extension::create()
.name(PgLTree)
.schema("public")
.version("v0.1.0")
.cascade()
.if_not_exists()
.to_owned();
assert_eq!(create_extension_stmt.name, "ltree");
assert_eq!(create_extension_stmt.schema, Some("public".to_string()));
assert_eq!(create_extension_stmt.version, Some("v0.1.0".to_string()));
assert!(create_extension_stmt.cascade);
assert!(create_extension_stmt.if_not_exists);
}
#[test]
fn creates_a_stmt_for_drop_extension() {
let drop_extension_stmt = Extension::drop()
.name(PgLTree)
.cascade()
.if_exists()
.restrict()
.to_owned();
assert_eq!(drop_extension_stmt.name, "ltree");
assert!(drop_extension_stmt.cascade);
assert!(drop_extension_stmt.if_exists);
assert!(drop_extension_stmt.restrict);
}
}