pub struct PreparedStatement { /* private fields */ }Expand description
Allows injection-safe SQL execution and repeated calls of the same statement with different parameters with as few roundtrips as possible.
§Providing Input Parameters
§Type systems
Type systems, really? Yes, there are in fact four type systems involved!
-
Your application is written in rust, and uses the rust type system.
-
hdbconnect_async’s driver API represents values with theenumHdbValue; this type system aims to be as close to the rust type system as possible and hides the complexity of the following two internal type systems. -
The wire has its own type system - it’s focus is on efficient data transfer.
hdbconnect_asyncdeals with these types internally. -
The database type system consists of the standard SQL types and proprietary types to represent values, like TINYINT, FLOAT, NVARCHAR, and many others. This type system is NOT directly visible to
hdbconnect_async.TypeIdenumerates a somewhat reduced superset of the server-side and the wire type system.
§From Rust types to HdbValue
Prepared statements typically take one or more input parameter(s).
As part of the statement preparation, the database server provides the client
with detailed metadata for these parameters, which are kept by the PreparedStatement.
The parameter values can be handed over to the PreparedStatement either as
Serializable rust types, or explicitly as HdbValue instances.
If they are handed over as Serializable rust types, then the built-in
serde_db-based
conversion will convert them directly into those HdbValue variants
that correspond to the TypeId that the server has requested.
The application can also provide the values explicitly as HdbValue
instances and by that
enforce the usage of a different wire type and of server-side type conversions.
§Sending HdbValues to the database
The protocol for sending values can be version-specific. Sending e.g. an
HdbValue::DECIMAL to the database occurs in different formats:
- with older HANA versions, a proprietary DECIMAL format is used that is independent of the number range of the concrete field.
- In newer HANA versions, three different formats are used
(
TypeId::FIXED8,TypeId::FIXED12andTypeId::FIXED16) that together allow for a wider value range and a lower bandwidth.
hdbconnect_async cares about these details.
Similarly, an HdbValue::STRING is used to transfer values to all string-like wire types.
The wire protocol sometimes also allows sending data in another wire type than requested.
If the database e.g. requests an INT, you can also send a String representation of the
number, by using HdbValue::STRING("1088"), instead of the binary INT representation
HdbValue::INT(1088).
Implementations§
Source§impl<'a> PreparedStatement
impl<'a> PreparedStatement
Sourcepub async fn execute<T>(&mut self, input: &T) -> Result<HdbResponse, HdbError>where
T: Serialize,
pub async fn execute<T>(&mut self, input: &T) -> Result<HdbResponse, HdbError>where
T: Serialize,
Converts the input into a row of parameters, and executes the statement with these parameters immediately.
The row of parameters must be consistent with the input parameter metadata.
The input conversion is done with the help of serde, so the input must implement
serde::ser::Serialize.
let mut statement = connection.prepare("select * from phrases where ID = ? and text = ?").await.unwrap();
let hdbresponse = statement.execute(&(42, "Foo is bar")).await.unwrap();If the statement has no parameter, you can execute it like this
let hdbresponse = stmt.execute(&()).await.unwrap();or like this
let hdbresponse = stmt.execute_batch().await.unwrap();§Errors
Several variants of HdbError can occur.
Sourcepub async fn execute_row(
&'a mut self,
hdb_values: Vec<HdbValue<'a>>,
) -> Result<HdbResponse, HdbError>
pub async fn execute_row( &'a mut self, hdb_values: Vec<HdbValue<'a>>, ) -> Result<HdbResponse, HdbError>
Consumes the given HdbValues as a row of parameters for immediate execution.
In most cases
PreparedStatement::execute()
will be more convenient. Streaming LOBs to the database however is an important exception -
it only works with this method!
Note that with older versions of HANA, streaming LOBs to the database only works if auto-commit is switched off. Consequently, you need to commit the update then explicitly.
§Example for streaming LOBs to the database
The first parameter in this example inserts a string into a normal NVARCHAR column.
We’re using a HdbValue::STR here which allows passing the String as reference
(compared to HdbValue::STRING, which needs to own the String).
The second parameter of type HdbValue::ASYNC_LOBSTREAM
wraps a shared mutable reference to a reader object
which is supposed to produce the content you want to store.
use hdbconnect_async::{Connection, HdbValue, HdbResult, IntoConnectParams};
use std::io::Cursor;
use std::sync::Arc;
use tokio::sync::Mutex;
let mut stmt = connection.prepare(&insert_stmt_string).await.unwrap();
stmt.execute_row(vec![
HdbValue::STR("nice descriptive text, could be quite long"),
HdbValue::ASYNC_LOBSTREAM(Some(Arc::new(Mutex::new(Cursor::new("foo bar"))))),
]).await.unwrap();PreparedStatement::execute_row() first sends the specified statement to the database,
with the given parameter values, where ASYNC_LOBSTREAM instances are replaced with placeholders.
Subsequently the data from the readers are transferred to the database in additional
roundtrips. Upon completion of the last LOB chunk transfer, the database really executes
the procedure and returns its results.
§Errors
Several variants of HdbError can occur.
Sourcepub fn add_batch<T>(&mut self, input: &T) -> Result<(), HdbError>where
T: Serialize,
pub fn add_batch<T>(&mut self, input: &T) -> Result<(), HdbError>where
T: Serialize,
Converts the input into a row of parameters and adds it to the batch of this
PreparedStatement, if it is consistent with the metadata.
§Errors
Several variants of HdbError can occur.
Sourcepub fn add_row_to_batch(
&mut self,
hdb_values: Vec<HdbValue<'static>>,
) -> Result<(), HdbError>
pub fn add_row_to_batch( &mut self, hdb_values: Vec<HdbValue<'static>>, ) -> Result<(), HdbError>
Consumes the input as a row of parameters for the batch.
Useful mainly for generic code.
In most cases add_batch()
is more convenient.
Note that LOB streaming can not be combined with using the batch.
§Errors
Several variants of HdbError can occur.
Sourcepub fn current_batch_size(&self) -> usize
pub fn current_batch_size(&self) -> usize
Returns the number of parameter rows that were already added to the batch.
Sourcepub async fn execute_batch(&mut self) -> Result<HdbResponse, HdbError>
pub async fn execute_batch(&mut self) -> Result<HdbResponse, HdbError>
Executes the statement with the collected batch, and clears the batch.
Does nothing and returns with an error, if the statement needs input and no batch exists. If the statement does not need input and the batch is empty, a single execution is triggered.
§Errors
Several variants of HdbError can occur.
Sourcepub fn parameter_descriptors(&self) -> Arc<ParameterDescriptors>
pub fn parameter_descriptors(&self) -> Arc<ParameterDescriptors>
Descriptors of all parameters of the prepared statement (in, out, inout).
Sourcepub fn set_cursor_holdability(
&mut self,
holdability: CursorHoldability,
) -> Result<(), HdbError>
pub fn set_cursor_holdability( &mut self, holdability: CursorHoldability, ) -> Result<(), HdbError>
Sourcepub fn cursor_holdability(&self) -> Result<CursorHoldability, HdbError>
pub fn cursor_holdability(&self) -> Result<CursorHoldability, HdbError>
Sourcepub fn server_usage(&self) -> ServerUsage
pub fn server_usage(&self) -> ServerUsage
Provides information about the the server-side resource consumption that
is related to this PreparedStatement object.
Trait Implementations§
Source§impl Clone for PreparedStatement
impl Clone for PreparedStatement
Source§fn clone(&self) -> PreparedStatement
fn clone(&self) -> PreparedStatement
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for PreparedStatement
impl !RefUnwindSafe for PreparedStatement
impl Send for PreparedStatement
impl Sync for PreparedStatement
impl Unpin for PreparedStatement
impl !UnwindSafe for PreparedStatement
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoCollection<T> for T
impl<T> IntoCollection<T> for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);