diff --git a/Changelog.md b/Changelog.md index 9c90b2eb..7c67c1d2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,10 @@ # Changelog +## 0.52.0 + +* `sys::Timestamp` is now directly supported with `get_data`. +* `InputParameter` is now implying the new `CElement` trait. + ## 0.51.0 * Removed `ColumnProjection` trait. diff --git a/odbc-api/src/cursor.rs b/odbc-api/src/cursor.rs index 4d7f522b..3b126efe 100644 --- a/odbc-api/src/cursor.rs +++ b/odbc-api/src/cursor.rs @@ -3,10 +3,10 @@ use odbc_sys::HStmt; use crate::{ buffers::Indicator, error::ExtendResult, - handles::{AsStatementRef, SqlResult, State, Statement, StatementRef}, - parameter::{VarBinarySliceMut, VarCharSliceMut}, + handles::{AsStatementRef, SqlResult, State, Statement, StatementRef, CDataMut}, + parameter::{VarBinarySliceMut, VarCharSliceMut, CElement}, sleep::{wait_for, Sleep}, - Error, OutputParameter, ResultSetMetadata, + Error, ResultSetMetadata, }; use std::{cmp::max, thread::panicking}; @@ -96,7 +96,7 @@ impl<'s> CursorRow<'s> { pub fn get_data( &mut self, col_or_param_num: u16, - target: &mut impl OutputParameter, + target: &mut (impl CElement + CDataMut), ) -> Result<(), Error> { self.statement .get_data(col_or_param_num, target) diff --git a/odbc-api/src/parameter.rs b/odbc-api/src/parameter.rs index 9f50ba01..50980f81 100644 --- a/odbc-api/src/parameter.rs +++ b/odbc-api/src/parameter.rs @@ -337,25 +337,21 @@ use crate::{ /// A CData representing a single value rater than an entire buffer of a range of values. /// /// # Safety -/// -/// Callers must be able to rely on all pointers being valid, i.e. the "range" is not empty. -pub unsafe trait CElement: CData {} - -/// Use implementations of this type as arguments to SQL Statements. -/// -/// # Safety -/// +/// /// Considerations for implementers /// -/// Extend the [`crate::handles::HasDataType`] trait with the guarantee, that the bound parameter -/// buffer contains at least one element. +/// Callers must be able to rely on all pointers being valid, i.e. the "range" is not empty. /// /// Since the indicator provided by implementation is used to indicate the length of the value in /// the buffer, care must be taken to prevent out of bounds access in case the implementation also /// is used as an output parameter, and contains truncated values (i.e. the indicator is longer than /// the buffer and the value within). -pub unsafe trait InputParameter: HasDataType + CElement {} -unsafe impl InputParameter for T where T: CElement + HasDataType {} +pub unsafe trait CElement: CData {} + +/// Can be used to fill in a fielf value indicated by a placeholder (`?`) then executing an SQL +/// statement. +pub trait InputParameter: HasDataType + CElement {} +impl InputParameter for T where T: CElement + HasDataType {} /// # Safety /// @@ -433,14 +429,18 @@ pub struct Out<'a, T>(pub &'a mut T); /// Can also be used to wrap [`crate::sys::Timestamp`] so they implement [`OutputParameter`]. /// /// ```no_run -/// # use odbc_api::{Cursor, DataType, parameter::WithDataType, sys::Timestamp}; -/// # fn given(cursor: &mut impl Cursor) { -/// let mut actual = WithDataType { +/// # use odbc_api::{ +/// # Connection, Cursor, DataType, parameter::WithDataType, IntoParameter, sys::Timestamp +/// # }; +/// # fn given(cursor: &mut impl Cursor, connection: Connection<'_>) { +/// let mut ts = WithDataType { /// value: Timestamp::default(), /// data_type: DataType::Timestamp { precision: 0 }, /// }; -/// let mut row = cursor.next_row().unwrap().unwrap(); -/// row.get_data(1, &mut actual).unwrap(); +/// connection.execute( +/// "INSERT INTO Posts (text, timestamps) VALUES (?,?)", +/// (&"Hello".into_parameter(), &ts.into_parameter()) +/// ); /// # } /// ``` #[derive(Debug)] diff --git a/odbc-api/src/parameter/c_string.rs b/odbc-api/src/parameter/c_string.rs index 14450a39..697ec6a5 100644 --- a/odbc-api/src/parameter/c_string.rs +++ b/odbc-api/src/parameter/c_string.rs @@ -38,7 +38,7 @@ impl HasDataType for CStr { } } unsafe impl CElement for CStr {} -unsafe impl InputParameter for CStr {} +impl InputParameter for CStr {} unsafe impl CData for CString { fn cdata_type(&self) -> CDataType { diff --git a/odbc-api/tests/integration.rs b/odbc-api/tests/integration.rs index 621cb014..704828e6 100644 --- a/odbc-api/tests/integration.rs +++ b/odbc-api/tests/integration.rs @@ -2112,10 +2112,7 @@ fn get_data_timestamp(profile: &Profile, timestamp_type: &str) { let mut cursor = conn.execute(&sql, ()).unwrap().unwrap(); - let mut actual = WithDataType { - value: Timestamp::default(), - data_type: DataType::Timestamp { precision: 0 }, - }; + let mut actual = Timestamp::default(); let mut row = cursor.next_row().unwrap().unwrap(); row.get_data(1, &mut actual).unwrap(); @@ -2129,7 +2126,7 @@ fn get_data_timestamp(profile: &Profile, timestamp_type: &str) { second: 0, fraction: 0 }, - actual.value + actual ); }