sibyl/
env.rs

1//! OCI environment
2
3#[cfg(feature="blocking")]
4#[cfg_attr(docsrs, doc(cfg(feature="blocking")))]
5mod blocking;
6
7#[cfg(feature="nonblocking")]
8#[cfg_attr(docsrs, doc(cfg(feature="nonblocking")))]
9mod nonblocking;
10
11use std::{ptr, sync::Arc};
12use crate::{Error, Result, oci::*, types::Ctx};
13
14/// Represents an OCI environment.
15pub struct Environment {
16    err: Handle<OCIError>,
17    // `OCIEnv` handle must be behind Arc as it needs to survive the Environment drop,
18    // so that `OCIEnv` is still available to async-drop used, for example, in `Session`.
19    env: Arc<Handle<OCIEnv>>,
20}
21
22impl AsRef<OCIEnv> for Environment {
23    fn as_ref(&self) -> &OCIEnv {
24        &*self.env
25    }
26}
27
28impl AsRef<OCIError> for Environment {
29    fn as_ref(&self) -> &OCIError {
30        &*self.err
31    }
32}
33
34impl Ctx for Environment {
35    fn try_as_session(&self) -> Option<&OCISession> {
36        None
37    }
38}
39
40impl Environment {
41    /**
42    Returns a new environment handle, which is then used by the OCI functions.
43
44    # Example
45
46    ```
47    use sibyl::Environment;
48
49    let oracle = Environment::new()?;
50
51    # Ok::<(),sibyl::Error>(())
52    ```
53    */
54    pub fn new() -> Result<Self> {
55        let mut env = Ptr::<OCIEnv>::null();
56        let res = unsafe {
57            OCIEnvNlsCreate(
58                env.as_mut_ptr(), OCI_OBJECT | OCI_THREADED,
59                ptr::null(), ptr::null(), ptr::null(), ptr::null(), 0, ptr::null(),
60                AL32UTF8, UTF8
61            )
62        };
63        if res != OCI_SUCCESS {
64            return Err( Error::new("Cannot create OCI environment") );
65        }
66        let env = Handle::from(env);
67        let err = Handle::<OCIError>::new(&env)?;
68        let env = Arc::new(env);
69        Ok(Self { env, err })
70    }
71
72    pub(crate) fn get_env(&self) -> Arc<Handle<OCIEnv>> {
73        self.env.clone()
74    }
75
76    fn get_attr<V: attr::AttrGet>(&self, attr_type: u32) -> Result<V> {
77        self.env.get_attr(attr_type, self.as_ref())
78    }
79
80    fn get_attr_into<V: attr::AttrGetInto>(&self, attr_type: u32, into: &mut V) -> Result<()> {
81        self.env.get_attr_into(attr_type, into, self.as_ref())
82    }
83
84    fn set_attr<V: attr::AttrSet>(&self, attr_type: u32, attr_val: V) -> Result<()> {
85        self.env.set_attr(attr_type, attr_val, self.as_ref())
86    }
87
88    /**
89    Returns the maximum size (high watermark) for the client-side object cache
90    as a percentage of the optimal size.
91
92    # Example
93
94    ```
95    let oracle = sibyl::env()?;
96
97    let max_size_percentage = oracle.max_cache_size()?;
98
99    assert_eq!(max_size_percentage, 10);
100    # Ok::<(),Box<dyn std::error::Error>>(())
101    ```
102    */
103    pub fn max_cache_size(&self) -> Result<u32> {
104        self.get_attr(OCI_ATTR_CACHE_MAX_SIZE)
105    }
106
107    /**
108    Sets the maximum size (high watermark) for the client-side object cache as a percentage
109    of the optimal size. Usually, you can set this value at 10%, the default, of the optimal size.
110    Setting this attribute to 0 results in a value of 10 being used. The object cache uses the
111    maximum and optimal values for freeing unused memory in the object cache.
112
113    If the memory occupied by the objects currently in the cache reaches or exceeds the maximum
114    cache size, the cache automatically begins to free (or ages out) unmarked objects that have
115    a pin count of zero. The cache continues freeing such objects until memory usage in the cache
116    reaches the optimal size, or until it runs out of objects eligible for freeing. Note that the
117    cache can grow beyond the specified maximum cache size.
118
119    The maximum object cache size (in bytes) is computed by incrementing `optimal_size` by the
120    `max_size_percentage`, using the following algorithm:
121
122    ```
123    # fn example(optimal_size: u32, max_size_percentage: u32) -> u32 {
124    let maximum_cache_size = optimal_size + optimal_size * max_size_percentage / 100;
125    # maximum_cache_size }
126    ```
127
128    # Parameters
129
130    * `size` - The maximum size for the client-side object cache as a oercentage of the cache optimal size.
131
132    # Example
133
134    ```
135    let oracle = sibyl::env()?;
136
137    oracle.set_cache_max_size(30)?;
138
139    let max_size_percentage = oracle.max_cache_size()?;
140    assert_eq!(max_size_percentage, 30);
141    # Ok::<(),Box<dyn std::error::Error>>(())
142    ```
143    */
144    pub fn set_cache_max_size(&self, size: u32) -> Result<()> {
145        self.set_attr(OCI_ATTR_CACHE_MAX_SIZE, size)
146    }
147
148    /**
149    Returns the optimal size for the client-side object cache in bytes.
150
151    # Example
152
153    ```
154    let oracle = sibyl::env()?;
155
156    let optimal_size = oracle.optimal_cache_size()?;
157
158    assert_eq!(optimal_size, 8*1024*1024);
159    # Ok::<(),Box<dyn std::error::Error>>(())
160    ```
161    */
162    pub fn optimal_cache_size(&self) -> Result<u32> {
163        self.get_attr(OCI_ATTR_CACHE_OPT_SIZE)
164    }
165
166    /**
167        Sets the optimal size for the client-side object cache in bytes. The default value is 8 megabytes (MB).
168        Setting this attribute to 0 results in a value of 8 MB being used.
169
170        # Parameters
171
172        * `size` - The optimal size of the client-side object cache in bytes
173
174        # Example
175
176        ```
177        let oracle = sibyl::env()?;
178
179        oracle.set_cache_opt_size(64*1024*1024)?;
180
181        let optimal_size = oracle.optimal_cache_size()?;
182        assert_eq!(optimal_size, 64*1024*1024);
183        # Ok::<(),Box<dyn std::error::Error>>(())
184        ```
185    */
186    pub fn set_cache_opt_size(&self, size: u32) -> Result<()> {
187        self.set_attr(OCI_ATTR_CACHE_OPT_SIZE, size)
188    }
189
190    /**
191    Returns the name of the language used for the database sessions created in the current environment.
192
193    See [Database Globalization Support Guide / Locale Data / Languages][1]
194
195    [1]: https://docs.oracle.com/en/database/oracle/oracle-database/19/nlspg/appendix-A-locale-data.html#GUID-D2FCFD55-EDC3-473F-9832-AAB564457830
196
197    # Example
198
199    ```
200    let oracle = sibyl::env()?;
201
202    let lang = oracle.nls_language()?;
203
204    assert_eq!(lang, "AMERICAN");
205    # Ok::<(),Box<dyn std::error::Error>>(())
206    ```
207    */
208    pub fn nls_language(&self) -> Result<String> {
209        let mut lang = String::with_capacity(32);
210        self.get_attr_into(OCI_ATTR_ENV_NLS_LANGUAGE, &mut lang)?;
211        Ok(lang)
212    }
213
214    /**
215    Sets the language used for the database sessions created in the current environment.
216
217    # Parameters
218
219    * `lang` - The name of the language used for the database sessions
220
221    # Example
222
223    ```
224    let oracle = sibyl::env()?;
225
226    oracle.set_nls_language("ENGLISH")?;
227
228    let lang = oracle.nls_language()?;
229    assert_eq!(lang, "ENGLISH");
230    # Ok::<(),Box<dyn std::error::Error>>(())
231    */
232    pub fn set_nls_language(&self, lang: &str) -> Result<()> {
233        self.set_attr(OCI_ATTR_ENV_NLS_LANGUAGE, lang)
234    }
235
236    /**
237    Returns the name of the territory used for the database sessions created in the current environment.
238
239    See [Database Globalization Support Guide / Locale Data / Territories][1]
240
241    [1]: https://docs.oracle.com/en/database/oracle/oracle-database/19/nlspg/appendix-A-locale-data.html#GUID-550D6A25-DB53-4911-9419-8065A73FFB06
242
243    # Example
244
245    ```
246    let oracle = sibyl::env()?;
247
248    let territory = oracle.nls_territory()?;
249
250    assert_eq!(territory, "AMERICA");
251    # Ok::<(),Box<dyn std::error::Error>>(())
252    ```
253    */
254    pub fn nls_territory(&self) -> Result<String> {
255        let mut territory = String::with_capacity(24);
256        self.get_attr_into(OCI_ATTR_ENV_NLS_TERRITORY, &mut territory)?;
257        Ok(territory)
258    }
259
260    /**
261    Sets the name of the territory used for the database sessions created in the current environment.
262
263    # Parameters
264
265    * `territory` - The name of the territory used for the database sessions
266
267    # Example
268
269    ```
270    let oracle = sibyl::env()?;
271    oracle.set_nls_territory("CANADA")?;
272    let territory = oracle.nls_territory()?;
273
274    assert_eq!(territory, "CANADA");
275    # Ok::<(),Box<dyn std::error::Error>>(())
276    ```
277    */
278    pub fn set_nls_territory(&self, territory: &str) -> Result<()> {
279        self.set_attr(OCI_ATTR_ENV_NLS_TERRITORY, territory)
280    }
281}