use crate::{
ast::CreateDatabaseStmt,
binder::{bound::database::BoundCreateDatabaseStmt, error::BindError},
catalog::CatalogManager,
common::symbol::Symbol,
};
pub struct Binder<'c> {
catalog: &'c CatalogManager,
session_user: Symbol,
}
impl<'c> Binder<'c> {
pub fn new(catalog: &'c CatalogManager, session_user: Symbol) -> Self {
Self {
catalog,
session_user,
}
}
pub fn bind_create_database(
&self,
stmt: CreateDatabaseStmt,
) -> Result<BoundCreateDatabaseStmt, BindError> {
if !stmt.if_not_exists && self.catalog.database_exists(stmt.name) {
return Err(BindError::DatabaseAlreadyExists(stmt.name));
}
if let Some(owner) = stmt.owner {
if !self.catalog.role_exists(owner) {
return Err(BindError::RoleNotFound(owner));
}
}
let owner = stmt.owner.unwrap_or(self.session_user);
if let Some(ts) = stmt.tablespace {
if !self.catalog.tablespace_exists(ts) {
return Err(BindError::TablespaceNotFound(ts));
}
}
if let Some(limit) = stmt.connection_limit {
if limit < -1 {
return Err(BindError::InvalidConnectionLimit(limit));
}
}
Ok(BoundCreateDatabaseStmt {
name: stmt.name,
if_not_exists: stmt.if_not_exists,
owner,
encoding: stmt.encoding,
locale: stmt.locale,
tablespace: stmt.tablespace,
connection_limit: stmt.connection_limit,
})
}
}