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
// Copyright (c) 2017 mimir developers
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

//! Enqueue option handles are used to represent the options specified when enqueuing messages using
//! advanced queueing. They are created by calling the function `Connection::new_enq_options()` and
//! are destroyed by releasing the last reference by calling the function
//! `enqueue::Options::release()`.
use error::{ErrorKind, Result};
use odpi::opaque::ODPIEnqOptions;
use odpi::{enums, externs};
use std::convert::TryFrom;
use std::ptr;
use util::ODPIStr;

/// Enqueue option handles are used to represent the options specified when enqueuing messages.
#[derive(Clone)]
pub struct Options {
    /// The ODPI-C EnqOptions pointer.
    inner: *mut ODPIEnqOptions,
}

impl Options {
    #[doc(hidden)]
    pub fn inner(&self) -> *mut ODPIEnqOptions {
        self.inner
    }

    /// Returns the transformation of the message to be enqueued. See function
    /// `enqueue::Options::set_transformation()` for more information.
    pub fn get_transformation(&self) -> Result<String> {
        let mut txn_ptr = ptr::null();
        let mut txn_len = 0;

        try_dpi!(
            externs::dpiEnqOptions_getTransformation(self.inner, &mut txn_ptr, &mut txn_len),
            {
                let transformation = if txn_ptr.is_null() {
                    "".to_string()
                } else {
                    let res_s = ODPIStr::new(txn_ptr, txn_len);
                    res_s.into()
                };
                Ok(transformation)
            },
            ErrorKind::EnqOptions("dpiEnqOptions_getTransformation".to_string())
        )
    }

    /// Returns whether the message being enqueued is part of the current transaction or constitutes
    /// a transaction on its own.
    pub fn get_visibility(&self) -> Result<enums::ODPIVisibility> {
        let mut enq_vis_ptr = enums::ODPIVisibility::Immediate;

        try_dpi!(
            externs::dpiEnqOptions_getVisibility(self.inner, &mut enq_vis_ptr),
            Ok(enq_vis_ptr),
            ErrorKind::EnqOptions("dpiEnqOptions_getMode".to_string())
        )
    }

    /// Sets the message delivery mode that is to be used when enqueuing messages.
    pub fn set_delivery_mode(&self, mode: enums::ODPIMessageDeliveryMode) -> Result<()> {
        try_dpi!(
            externs::dpiEnqOptions_setDeliveryMode(self.inner, mode),
            Ok(()),
            ErrorKind::EnqOptions("dpiEnqOptions_setDeliveryMode".to_string())
        )
    }

    /// Sets the transformation of the message to be enqueued. The transformation is applied after
    /// the message is enqueued but before it is returned to the application. It must be created
    /// using DBMS_TRANSFORM.
    pub fn set_transformation(&self, transformation: Option<&str>) -> Result<()> {
        let txn_s: ODPIStr = TryFrom::try_from(transformation)?;

        try_dpi!(
            externs::dpiEnqOptions_setTransformation(self.inner, txn_s.ptr(), txn_s.len()),
            Ok(()),
            ErrorKind::EnqOptions("dpiEnqOptions_setTransformation".to_string())
        )
    }

    /// Sets whether the message being enqueued is part of the current transaction or constitutes a
    /// transaction on its own.
    pub fn set_visibility(&self, visibility: enums::ODPIVisibility) -> Result<()> {
        try_dpi!(
            externs::dpiEnqOptions_setVisibility(self.inner, visibility),
            Ok(()),
            ErrorKind::EnqOptions("dpiEnqOptions_setVisibility".to_string())
        )
    }
}

impl From<*mut ODPIEnqOptions> for Options {
    fn from(inner: *mut ODPIEnqOptions) -> Self {
        Self { inner }
    }
}

impl Drop for Options {
    fn drop(&mut self) {
        if !self.inner.is_null() {
            unsafe {
                externs::dpiEnqOptions_release(self.inner);
            }
        }
    }
}