1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//! OCI descriptors

use crate::{Result, Error, oci};
use super::*;
use std::ops::{Deref, DerefMut};

pub(crate) struct Descriptor<T> (Ptr<T::OCIType>)
where T: DescriptorType
    , T::OCIType: OCIStruct
;

impl<T> Deref for Descriptor<T>
where T: DescriptorType
    , T::OCIType: OCIStruct
{
    type Target = T::OCIType;

    fn deref(&self) -> &Self::Target {
        self.0.as_ref()
    }
}

impl<T> DerefMut for Descriptor<T>
where T: DescriptorType
    , T::OCIType: OCIStruct
{
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.0.as_mut()
    }
}

impl<T> AsRef<T::OCIType> for Descriptor<T> 
where T: DescriptorType
    , T::OCIType: OCIStruct
{
    fn as_ref(&self) -> &T::OCIType {
        self.0.as_ref()
    }
}

impl<T> AsMut<T::OCIType> for Descriptor<T> 
where T: DescriptorType
    , T::OCIType: OCIStruct
{
    fn as_mut(&mut self) -> &mut T::OCIType {
        self.0.as_mut()
    }
}

impl<T> Drop for Descriptor<T>
where T: DescriptorType
    , T::OCIType: OCIStruct
{
    fn drop(&mut self) {
        if !self.0.is_null() {
            unsafe {
                OCIDescriptorFree(self.0.get() as _, T::get_type());
            }
        }
    }
}

impl<T> Descriptor<T>
    where T: DescriptorType
        , T::OCIType : OCIStruct
{
    fn alloc(env: &impl AsRef<OCIEnv>) -> Result<Ptr<T::OCIType>> {
        let mut desc_ptr = Ptr::<T::OCIType>::null();
        oci::descriptor_alloc(env.as_ref(), desc_ptr.as_mut_ptr(), T::get_type())?;
        if desc_ptr.is_null() {
            Err( Error::new("OCIDescriptorAlloc returned NULL") )
        } else {
            Ok( desc_ptr )
        }
    }

    pub(crate) fn new(env: &impl AsRef<OCIEnv>) -> Result<Self> {
        let desc_ptr = Self::alloc(env)?;
        Ok( Self(desc_ptr) )
    }

    pub(crate) fn from(desc_ptr: Ptr<T::OCIType>) -> Self {
        Self(desc_ptr)
    }

    pub(crate) fn take(other: &mut Self) -> Self {
        let mut desc_ptr = Ptr::<T::OCIType>::null();
        desc_ptr.swap(&mut other.0);
        Self(desc_ptr)
    }

    pub(crate) fn replace(&mut self, mut ptr: Ptr<T::OCIType>) {
        self.0.swap(&mut ptr);
    }

    pub(crate) fn get_ptr(&self) -> Ptr<T::OCIType> {
        self.0
    }

    pub(crate) fn as_ptr(&self) -> *const *mut T::OCIType {
        self.0.as_ptr() as _
    }

    pub(crate) fn as_mut_ptr(&mut self) -> *mut *mut T::OCIType {
        self.0.as_mut_ptr() as _
    }

    pub(crate) fn swap(&mut self, other: &mut Self) {
        self.0.swap(&mut other.0);
    }

    pub(crate) fn get_attr<V: attr::AttrGet>(&self, attr_type: u32, err: &OCIError) -> Result<V> {
        attr::get::<T::OCIType, V>(attr_type, T::get_type(), &self.0, err)
    }

    pub(crate) fn get_attr_into<V: attr::AttrGetInto>(&self, attr_type: u32, into: &mut V, err: &OCIError) -> Result<()> {
        attr::get_into::<T::OCIType, V>(attr_type, into, T::get_type(), &self.0, err)
    }

    pub(crate) fn set_attr<V: attr::AttrSet>(&self, attr_type: u32, attr_val: V, err: &OCIError) -> Result<()> {
        attr::set::<T::OCIType, V>(attr_type, attr_val, T::get_type(), &self.0, err)
    }
}