rbdc_oracle/connection/
mod.rs1use futures_core::future::BoxFuture;
2use futures_util::future;
3use rbdc::Error;
4use rbdc::StatementCache;
5use std::fmt::{self, Debug, Formatter};
6use std::sync::atomic::Ordering;
7
8pub(crate) use handle::ConnectionHandle;
9
10use crate::OracleConnectOptions;
11use crate::connection::establish::EstablishParams;
12use crate::connection::worker::ConnectionWorker;
13use crate::statement::VirtualStatement;
14
15mod establish;
16mod execute;
17mod executor;
18mod handle;
19mod worker;
20
21pub use worker::Command;
22
23pub struct OracleConnection {
24 pub(crate) worker: ConnectionWorker,
25 pub(crate) row_channel_size: usize,
26}
27
28unsafe impl Sync for OracleConnection {}
29
30pub struct ConnectionState {
31 pub(crate) handle: ConnectionHandle,
32 pub(crate) transaction_active: bool,
33 pub(crate) statements: Statements,
34}
35
36pub(crate) struct Statements {
37 cached: StatementCache<VirtualStatement>,
38 temp: Option<VirtualStatement>,
39}
40
41impl OracleConnection {
42 pub(crate) async fn establish(options: &OracleConnectOptions) -> Result<Self, Error> {
43 let params = EstablishParams::from_options(options)?;
44 let worker = ConnectionWorker::establish(params).await?;
45 Ok(Self {
46 worker,
47 row_channel_size: options.row_channel_size,
48 })
49 }
50}
51
52impl Debug for OracleConnection {
53 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
54 f.debug_struct("OracleConnection")
55 .field("row_channel_size", &self.row_channel_size)
56 .field("cached_statements_size", &self.cached_statements_size())
57 .finish()
58 }
59}
60
61impl OracleConnection {
62 pub async fn do_close(&mut self) -> Result<(), Error> {
63 self.worker.shutdown().await
64 }
65
66 pub fn ping(&mut self) -> BoxFuture<'_, Result<(), Error>> {
67 Box::pin(self.worker.ping())
68 }
69
70 pub fn cached_statements_size(&self) -> usize {
71 self.worker
72 .shared
73 .cached_statements_size
74 .load(Ordering::Acquire)
75 }
76
77 pub fn clear_cached_statements(&mut self) -> BoxFuture<'_, Result<(), Error>> {
78 Box::pin(async move {
79 self.worker.clear_cache().await?;
80 Ok(())
81 })
82 }
83
84 #[doc(hidden)]
85 pub fn flush(&mut self) -> BoxFuture<'_, Result<(), Error>> {
86 Box::pin(future::ok(()))
87 }
88
89 #[doc(hidden)]
90 pub fn should_flush(&self) -> bool {
91 false
92 }
93}
94
95impl Drop for ConnectionState {
96 fn drop(&mut self) {
97 self.statements.clear();
98 }
99}
100
101impl Statements {
102 fn new(capacity: usize) -> Self {
103 Statements {
104 cached: StatementCache::new(capacity),
105 temp: None,
106 }
107 }
108
109 fn get(&mut self, query: &str, persistent: bool) -> Result<&mut VirtualStatement, Error> {
110 if !persistent || !self.cached.is_enabled() {
111 return Ok(self.temp.insert(VirtualStatement::new(query, false)?));
112 }
113
114 let exists = self.cached.contains_key(query);
115
116 if !exists {
117 let statement = VirtualStatement::new(query, true)?;
118 self.cached.insert(query, statement);
119 }
120
121 let statement = self.cached.get_mut(query).unwrap();
122 if exists {
123 statement.reset()?;
124 }
125
126 Ok(statement)
127 }
128
129 fn len(&self) -> usize {
130 self.cached.len()
131 }
132
133 fn clear(&mut self) {
134 self.cached.clear();
135 self.temp = None;
136 }
137}