use num_enum::TryFromPrimitive;
use std::str::FromStr;
use crate::*;
pub trait FirebirdClient
where
Self: FirebirdClientDbOps,
Self: FirebirdClientSqlOps<DbHandle = <Self as FirebirdClientDbOps>::DbHandle>,
{
}
impl<Hdl, A: FirebirdClientDbOps<DbHandle = Hdl> + FirebirdClientSqlOps<DbHandle = Hdl>>
FirebirdClient for A
where
Hdl: Send,
{
}
pub trait FirebirdClientDbOps: Send {
type DbHandle: Send;
type AttachmentConfig: Send + Clone;
fn attach_database(
&mut self,
config: &Self::AttachmentConfig,
) -> Result<Self::DbHandle, FbError>;
fn detach_database(&mut self, db_handle: &mut Self::DbHandle) -> Result<(), FbError>;
fn drop_database(&mut self, db_handle: &mut Self::DbHandle) -> Result<(), FbError>;
}
pub trait FirebirdClientSqlOps {
type DbHandle: Send;
type TrHandle: Send;
type StmtHandle: Send;
fn begin_transaction(
&mut self,
db_handle: &mut Self::DbHandle,
isolation_level: TrIsolationLevel,
) -> Result<Self::TrHandle, FbError>;
fn transaction_operation(
&mut self,
tr_handle: &mut Self::TrHandle,
op: TrOp,
) -> Result<(), FbError>;
fn exec_immediate(
&mut self,
db_handle: &mut Self::DbHandle,
tr_handle: &mut Self::TrHandle,
dialect: Dialect,
sql: &str,
) -> Result<(), FbError>;
fn prepare_statement(
&mut self,
db_handle: &mut Self::DbHandle,
tr_handle: &mut Self::TrHandle,
dialect: Dialect,
sql: &str,
) -> Result<(StmtType, Self::StmtHandle), FbError>;
fn free_statement(
&mut self,
stmt_handle: &mut Self::StmtHandle,
op: FreeStmtOp,
) -> Result<(), FbError>;
fn execute(
&mut self,
db_handle: &mut Self::DbHandle,
tr_handle: &mut Self::TrHandle,
stmt_handle: &mut Self::StmtHandle,
params: Vec<SqlType>,
) -> Result<(), FbError>;
fn execute2(
&mut self,
db_handle: &mut Self::DbHandle,
tr_handle: &mut Self::TrHandle,
stmt_handle: &mut Self::StmtHandle,
params: Vec<SqlType>,
) -> Result<Vec<Column>, FbError>;
fn fetch(
&mut self,
db_handle: &mut Self::DbHandle,
tr_handle: &mut Self::TrHandle,
stmt_handle: &mut Self::StmtHandle,
) -> Result<Option<Vec<Column>>, FbError>;
}
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
#[repr(u8)]
pub enum Dialect {
D1 = 1,
D2 = 2,
D3 = 3,
}
impl FromStr for Dialect {
type Err = FbError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"1" => Ok(Dialect::D1),
"2" => Ok(Dialect::D2),
"3" => Ok(Dialect::D3),
_ => Err(FbError::from(format!(
"'{}' doesn't represent any dialect",
s
))),
}
}
}
#[repr(u8)]
pub enum TrIsolationLevel {
Concurrency = ibase::isc_tpb_concurrency as u8,
Concistency = ibase::isc_tpb_consistency as u8,
ReadCommited = ibase::isc_tpb_read_committed as u8,
}
impl Default for TrIsolationLevel {
fn default() -> Self {
Self::ReadCommited
}
}
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum TrOp {
Commit,
CommitRetaining,
Rollback,
RollbackRetaining,
}
#[repr(u8)]
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum FreeStmtOp {
Close = ibase::DSQL_close as u8,
Drop = ibase::DSQL_drop as u8,
}
#[repr(u8)]
#[derive(Debug, Eq, PartialEq, Copy, Clone, TryFromPrimitive)]
pub enum StmtType {
Select = ibase::isc_info_sql_stmt_select as u8,
Insert = ibase::isc_info_sql_stmt_insert as u8,
Update = ibase::isc_info_sql_stmt_update as u8,
Delete = ibase::isc_info_sql_stmt_delete as u8,
DDL = ibase::isc_info_sql_stmt_ddl as u8,
GetSegment = ibase::isc_info_sql_stmt_get_segment as u8,
PutSegment = ibase::isc_info_sql_stmt_put_segment as u8,
ExecProcedure = ibase::isc_info_sql_stmt_exec_procedure as u8,
StartTrans = ibase::isc_info_sql_stmt_start_trans as u8,
Commit = ibase::isc_info_sql_stmt_commit as u8,
Rollback = ibase::isc_info_sql_stmt_rollback as u8,
SelectForUpd = ibase::isc_info_sql_stmt_select_for_upd as u8,
SetGenerator = ibase::isc_info_sql_stmt_set_generator as u8,
Savepoint = ibase::isc_info_sql_stmt_savepoint as u8,
}