pub mod extension {
pub fn create_extension(
extension_name: &str,
if_not_exists: bool,
schema: Option<&str>,
) -> String {
let if_not_exists_clause = if if_not_exists { " IF NOT EXISTS" } else { "" };
let schema_clause = if let Some(s) = schema {
format!(" SCHEMA \"{}\"", s)
} else {
String::new()
};
format!(
"CREATE EXTENSION{} \"{}\"{}",
if_not_exists_clause, extension_name, schema_clause
)
}
pub fn drop_extension(extension_name: &str, if_exists: bool, cascade: bool) -> String {
let if_exists_clause = if if_exists { " IF EXISTS" } else { "" };
let cascade_clause = if cascade { " CASCADE" } else { "" };
format!(
"DROP EXTENSION{} \"{}\"{}",
if_exists_clause, extension_name, cascade_clause
)
}
}
pub mod index {
pub fn create_gin_index(
index_name: &str,
table: &str,
expression: &str,
where_clause: Option<&str>,
) -> String {
let where_part = if let Some(w) = where_clause {
format!(" WHERE {}", w)
} else {
String::new()
};
format!(
"CREATE INDEX \"{}\" ON \"{}\" USING GIN ({}){}",
index_name, table, expression, where_part
)
}
pub fn create_gist_index(
index_name: &str,
table: &str,
expression: &str,
where_clause: Option<&str>,
) -> String {
let where_part = if let Some(w) = where_clause {
format!(" WHERE {}", w)
} else {
String::new()
};
format!(
"CREATE INDEX \"{}\" ON \"{}\" USING GIST ({}){}",
index_name, table, expression, where_part
)
}
pub fn create_brin_index(
index_name: &str,
table: &str,
expression: &str,
where_clause: Option<&str>,
) -> String {
let where_part = if let Some(w) = where_clause {
format!(" WHERE {}", w)
} else {
String::new()
};
format!(
"CREATE INDEX \"{}\" ON \"{}\" USING BRIN ({}){}",
index_name, table, expression, where_part
)
}
}
pub mod enum_type {
pub fn create_enum(type_name: &str, values: &[&str]) -> String {
let values_str = values
.iter()
.map(|v| format!("'{}'", v.replace('\'', "''")))
.collect::<Vec<_>>()
.join(", ");
format!(
"CREATE TYPE \"{}\" AS ENUM ({})",
type_name.replace('"', "\"\""),
values_str
)
}
pub fn drop_enum(type_name: &str, if_exists: bool, cascade: bool) -> String {
let if_exists_clause = if if_exists { " IF EXISTS" } else { "" };
let cascade_clause = if cascade { " CASCADE" } else { "" };
format!(
"DROP TYPE{} \"{}\"{}",
if_exists_clause,
type_name.replace('"', "\"\""),
cascade_clause
)
}
pub fn add_enum_value(type_name: &str, new_value: &str, after: Option<&str>) -> String {
let after_clause = if let Some(a) = after {
format!(" AFTER '{}'", a.replace('\'', "''"))
} else {
String::new()
};
format!(
"ALTER TYPE \"{}\" ADD VALUE '{}'{}",
type_name.replace('"', "\"\""),
new_value.replace('\'', "''"),
after_clause
)
}
}
pub mod sequence {
pub fn set_sequence_value(sequence_name: &str, value_expression: &str) -> String {
format!(
"SELECT setval('{}', ({}))",
sequence_name.replace('\'', "''"),
value_expression
)
}
pub fn next_sequence_value(sequence_name: &str) -> String {
format!("SELECT nextval('{}')", sequence_name.replace('\'', "''"))
}
pub fn current_sequence_value(sequence_name: &str) -> String {
format!("SELECT currval('{}')", sequence_name.replace('\'', "''"))
}
}
pub mod locking {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LockMode {
ForUpdate,
ForNoKeyUpdate,
ForShare,
ForKeyShare,
}
impl LockMode {
pub fn as_sql(&self) -> &'static str {
match self {
LockMode::ForUpdate => "FOR UPDATE",
LockMode::ForNoKeyUpdate => "FOR NO KEY UPDATE",
LockMode::ForShare => "FOR SHARE",
LockMode::ForKeyShare => "FOR KEY SHARE",
}
}
}
pub fn append_row_lock(sql: &str, lock_mode: LockMode, nowait: bool) -> String {
let nowait_clause = if nowait { " NOWAIT" } else { "" };
format!("{} {}{}", sql, lock_mode.as_sql(), nowait_clause)
}
}