rsfbclient_core/
connection.rs

1//! Traits to abstract over firebird client implementations
2
3use num_enum::TryFromPrimitive;
4use std::str::FromStr;
5
6use crate::*;
7
8///A wrapper trait compatible with the niceties provided by the main rsfbclient crate
9pub trait FirebirdClient
10where
11    Self: FirebirdClientDbOps,
12    Self: FirebirdClientSqlOps<DbHandle = <Self as FirebirdClientDbOps>::DbHandle>,
13{
14}
15
16impl<Hdl, A: FirebirdClientDbOps<DbHandle = Hdl> + FirebirdClientSqlOps<DbHandle = Hdl>>
17    FirebirdClient for A
18where
19    Hdl: Send,
20{
21}
22
23/// Responsible for database administration and attachment/detachment
24pub trait FirebirdClientDbOps: Send {
25    /// A database handle
26    type DbHandle: Send;
27
28    /// Configuration details for attaching to the database.
29    /// A user of an implementation of this trait can configure attachment details
30    /// (database name, user name, etcetera) and then pass this configuration to the implementation
31    /// via this type when a new attachment is requested
32    type AttachmentConfig: Send + Clone;
33
34    /// Create a new attachment to a database with the provided configuration
35    /// Returns a database handle on success
36    fn attach_database(
37        &mut self,
38        config: &Self::AttachmentConfig,
39        dialect: Dialect,
40        no_db_triggers: bool,
41    ) -> Result<Self::DbHandle, FbError>;
42
43    /// Disconnect from the database
44    fn detach_database(&mut self, db_handle: &mut Self::DbHandle) -> Result<(), FbError>;
45
46    /// Drop the database
47    fn drop_database(&mut self, db_handle: &mut Self::DbHandle) -> Result<(), FbError>;
48
49    /// Create the database and attach
50    /// Returns a database handle on success
51    fn create_database(
52        &mut self,
53        config: &Self::AttachmentConfig,
54        page_size: Option<u32>,
55        dialect: Dialect,
56    ) -> Result<Self::DbHandle, FbError>;
57}
58
59///Responsible for actual transaction and statement execution
60pub trait FirebirdClientSqlOps {
61    /// A database handle
62    type DbHandle: Send;
63    /// A transaction handle
64    type TrHandle: Send;
65    /// A statement handle
66    type StmtHandle: Send;
67
68    /// Start a new transaction, with the specified transaction parameter buffer
69    fn begin_transaction(
70        &mut self,
71        db_handle: &mut Self::DbHandle,
72        confs: TransactionConfiguration,
73    ) -> Result<Self::TrHandle, FbError>;
74
75    /// Commit / Rollback a transaction
76    fn transaction_operation(
77        &mut self,
78        tr_handle: &mut Self::TrHandle,
79        op: TrOp,
80    ) -> Result<(), FbError>;
81
82    /// Execute a sql immediately, without returning rows
83    fn exec_immediate(
84        &mut self,
85        db_handle: &mut Self::DbHandle,
86        tr_handle: &mut Self::TrHandle,
87        dialect: Dialect,
88        sql: &str,
89    ) -> Result<(), FbError>;
90
91    /// Allocate and prepare a statement
92    /// Returns the statement type and handle
93    fn prepare_statement(
94        &mut self,
95        db_handle: &mut Self::DbHandle,
96        tr_handle: &mut Self::TrHandle,
97        dialect: Dialect,
98        sql: &str,
99    ) -> Result<(StmtType, Self::StmtHandle), FbError>;
100
101    /// Closes or drops a statement
102    fn free_statement(
103        &mut self,
104        stmt_handle: &mut Self::StmtHandle,
105        op: FreeStmtOp,
106    ) -> Result<(), FbError>;
107
108    /// Execute the prepared statement with parameters
109    /// and returns the affected rows count
110    fn execute(
111        &mut self,
112        db_handle: &mut Self::DbHandle,
113        tr_handle: &mut Self::TrHandle,
114        stmt_handle: &mut Self::StmtHandle,
115        params: Vec<SqlType>,
116    ) -> Result<usize, FbError>;
117
118    /// Execute the prepared statement
119    /// with input and output parameters.
120    ///
121    /// The output parameters will be returned
122    /// as in the Result
123    fn execute2(
124        &mut self,
125        db_handle: &mut Self::DbHandle,
126        tr_handle: &mut Self::TrHandle,
127        stmt_handle: &mut Self::StmtHandle,
128        params: Vec<SqlType>,
129    ) -> Result<Vec<Column>, FbError>;
130
131    /// Fetch rows from the executed statement, coercing the types
132    /// according to the provided blr
133    fn fetch(
134        &mut self,
135        db_handle: &mut Self::DbHandle,
136        tr_handle: &mut Self::TrHandle,
137        stmt_handle: &mut Self::StmtHandle,
138    ) -> Result<Option<Vec<Column>>, FbError>;
139}
140
141/// Firebird base event API
142pub trait FirebirdClientDbEvents: FirebirdClientDbOps {
143    /// Wait for an event to be posted on database
144    fn wait_for_event(
145        &mut self,
146        db_handle: &mut Self::DbHandle,
147        name: String,
148    ) -> Result<(), FbError>;
149}
150
151#[derive(Debug, Eq, PartialEq, Copy, Clone, Default)]
152#[repr(u8)]
153/// Firebird sql dialect
154pub enum Dialect {
155    D1 = 1,
156    D2 = 2,
157    #[default]
158    D3 = 3,
159}
160
161impl FromStr for Dialect {
162    type Err = FbError;
163
164    fn from_str(s: &str) -> Result<Self, Self::Err> {
165        match s {
166            "1" => Ok(Dialect::D1),
167            "2" => Ok(Dialect::D2),
168            "3" => Ok(Dialect::D3),
169            _ => Err(FbError::from(format!(
170                "'{}' doesn't represent any dialect",
171                s
172            ))),
173        }
174    }
175}
176
177#[repr(u8)]
178#[derive(Debug, Eq, PartialEq, Copy, Clone)]
179/// Drop / Close statement
180pub enum FreeStmtOp {
181    Close = ibase::DSQL_close as u8,
182    Drop = ibase::DSQL_drop as u8,
183}
184
185#[repr(u8)]
186#[derive(Debug, Eq, PartialEq, Copy, Clone, TryFromPrimitive)]
187/// Statement type
188pub enum StmtType {
189    Select = 1,        // isc_info_sql_stmt_select
190    Insert = 2,        // isc_info_sql_stmt_insert
191    Update = 3,        // isc_info_sql_stmt_update
192    Delete = 4,        // isc_info_sql_stmt_delete
193    Ddl = 5,           // isc_info_sql_stmt_ddl
194    GetSegment = 6,    // isc_info_sql_stmt_get_segment
195    PutSegment = 7,    // isc_info_sql_stmt_put_segment
196    ExecProcedure = 8, // isc_info_sql_stmt_exec_procedure
197    StartTrans = 9,    // isc_info_sql_stmt_start_trans
198    Commit = 10,       // isc_info_sql_stmt_commit
199    Rollback = 11,     // isc_info_sql_stmt_rollback
200    SelectForUpd = 12, // isc_info_sql_stmt_select_for_upd
201    SetGenerator = 13, // isc_info_sql_stmt_set_generator
202    Savepoint = 14,    // isc_info_sql_stmt_savepoint
203}