Skip to content

Commit

Permalink
indicator is now an option in error
Browse files Browse the repository at this point in the history
  • Loading branch information
pacman82 committed Nov 25, 2023
1 parent 342e0e5 commit ba372a7
Show file tree
Hide file tree
Showing 7 changed files with 16 additions and 36 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Expand Up @@ -11,6 +11,7 @@
* `DataType::utf16_len` now returns `Option<NonZeroUSize>` instead of `Option<usize>`
* `DataType::column_size` now returns `Option<NonZeroUSize>` instead of `usize`
* `BufferDesc::from_data_type` now returns `None` for variadic types without upper bound instead of a zero sized buffer.
* `Indicator::value_len` now is named `Indicator::length`.

## 3.0.1

Expand Down
2 changes: 1 addition & 1 deletion odbc-api/src/buffers/columnar.rs
Expand Up @@ -113,7 +113,7 @@ where
col_buffer
.has_truncated_values(*self.num_rows)
.map(|indicator| TruncationInfo {
indicator,
indicator: indicator.length(),
buffer_index,
})
})
Expand Down
14 changes: 1 addition & 13 deletions odbc-api/src/buffers/indicator.rs
@@ -1,5 +1,3 @@
use std::fmt::Display;

use odbc_sys::{NO_TOTAL, NULL_DATA};

/// Indicates existence and length of a value.
Expand All @@ -14,16 +12,6 @@ pub enum Indicator {
Length(usize),
}

impl Display for Indicator {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Indicator::Null => write!(f, "Null"),
Indicator::NoTotal => write!(f, "No Total"),
Indicator::Length(length) => write!(f, "{length}"),
}
}
}

impl Indicator {
/// Creates an indicator from an `isize` indicator value returned by ODBC. Users of this crate
/// have likely no need to call this method.
Expand Down Expand Up @@ -69,7 +57,7 @@ impl Indicator {
}

/// If the indicator is [`Indicator::Length`] this is [`Some`].
pub fn value_len(self) -> Option<usize> {
pub fn length(self) -> Option<usize> {
if let Indicator::Length(len) = self {
Some(len)
} else {
Expand Down
6 changes: 3 additions & 3 deletions odbc-api/src/cursor.rs
Expand Up @@ -238,7 +238,7 @@ impl<'s> CursorRow<'s> {
}
// We did get the complete value, including the terminating zero. Let's resize the buffer to
// match the retrieved value exactly (excluding terminating zero).
if let Some(len_in_bytes) = target.indicator().value_len() {
if let Some(len_in_bytes) = target.indicator().length() {
// Since the indicator refers to value length without terminating zero, and capacity is
// including the terminating zero this also implicitly drops the terminating zero at the
// end of the buffer.
Expand Down Expand Up @@ -395,8 +395,8 @@ pub unsafe trait RowSetBuffer {

/// Returned by [`RowSetBuffer::find_truncation`]. Contains information about the truncation found.
pub struct TruncationInfo {
/// Indicator of the complete untruncated value.
pub indicator: Indicator,
/// Length of the untruncated value if known
pub indicator: Option<usize>,
/// Zero based buffer index of the column in which the truncation occurred.
pub buffer_index: usize,
}
Expand Down
19 changes: 7 additions & 12 deletions odbc-api/src/error.rs
Expand Up @@ -2,10 +2,7 @@ use std::io;

use thiserror::Error as ThisError;

use crate::{
buffers::Indicator,
handles::{log_diagnostics, Diagnostics, Record as DiagnosticRecord, SqlResult},
};
use crate::handles::{log_diagnostics, Diagnostics, Record as DiagnosticRecord, SqlResult};

/// Error indicating a failed allocation for a column buffer
#[derive(Debug)]
Expand Down Expand Up @@ -50,7 +47,8 @@ pub enum Error {
#[error(
"No Diagnostics available. The ODBC function call to {} returned an error. Sadly neither \
the ODBC driver manager, nor the driver were polite enough to leave a diagnostic record \
specifying what exactly went wrong.", function
specifying what exactly went wrong.",
function
)]
NoDiagnostics {
/// ODBC API call which returned error without producing a diagnostic record.
Expand Down Expand Up @@ -127,17 +125,14 @@ pub enum Error {
},
#[error(
"A value (at least one) is too large to be written into the allocated buffer without \
truncation. Size in bytes indicated by ODBC driver: {indicator}"
truncation. Size in bytes indicated by ODBC driver: {indicator:?}"
)]
TooLargeValueForBuffer {
/// Length of the complete value in bytes as reported by the ODBC driver.
///
/// Only variants [`Indicator::NoTotal`], or [`Indicator::Length`] should be able to cause
/// this error.
indicator: Indicator,
/// Length of the complete value in bytes as reported by the ODBC driver. If the length is
/// not known, this is `None`.
indicator: Option<usize>,
/// Index of the buffer in which the truncation occurred.
buffer_index: usize,

},
}

Expand Down
2 changes: 1 addition & 1 deletion odbc-api/tests/integration.rs
Expand Up @@ -3528,7 +3528,7 @@ fn detect_truncated_output_in_bulk_fetch(profile: &Profile) {
assert!(matches!(
cursor.fetch_with_truncation_check(true),
Err(Error::TooLargeValueForBuffer {
indicator: Indicator::Length(10),
indicator: Some(10),
buffer_index: 0,
})
))
Expand Down
8 changes: 2 additions & 6 deletions odbcsv/src/main.rs
Expand Up @@ -583,7 +583,7 @@ fn cursor_to_csv(
fn provide_context_for_truncation_error(error: odbc_api::Error) -> Error {
match error {
odbc_api::Error::TooLargeValueForBuffer {
indicator: Indicator::Length(required),
indicator: Some(required),
buffer_index,
} => {
anyhow!(
Expand All @@ -595,7 +595,7 @@ fn provide_context_for_truncation_error(error: odbc_api::Error) -> Error {
)
}
odbc_api::Error::TooLargeValueForBuffer {
indicator: Indicator::NoTotal,
indicator: None,
buffer_index,
} => {
anyhow!(
Expand All @@ -607,10 +607,6 @@ fn provide_context_for_truncation_error(error: odbc_api::Error) -> Error {
large the value that caused the truncation is."
)
}
odbc_api::Error::TooLargeValueForBuffer {
indicator: Indicator::Null,
buffer_index,
} => unreachable!(),
other => other.into(),
}
}

0 comments on commit ba372a7

Please sign in to comment.