|
Lightweight 0.20261105.1
|
High level API for (prepared) raw SQL statements. More...
#include <SqlStatement.hpp>
Public Member Functions | |
| LIGHTWEIGHT_API | SqlStatement () |
| Construct a new SqlStatement object, using a new connection, and connect to the default database. | |
| LIGHTWEIGHT_API | SqlStatement (SqlStatement &&other) noexcept |
| Move constructor. | |
| LIGHTWEIGHT_API SqlStatement & | operator= (SqlStatement &&other) noexcept |
| Move assignment operator. | |
| SqlStatement (SqlStatement const &) noexcept=delete | |
| SqlStatement & | operator= (SqlStatement const &) noexcept=delete |
| LIGHTWEIGHT_API | SqlStatement (SqlConnection &relatedConnection) |
| Construct a new SqlStatement object, using the given connection. | |
| LIGHTWEIGHT_API | SqlStatement (std::nullopt_t) |
| Construct a new empty SqlStatement object. No SqlConnection is associated with this statement. | |
| LIGHTWEIGHT_API bool | IsAlive () const noexcept |
| Checks whether the statement's connection is alive and the statement handle is valid. | |
| LIGHTWEIGHT_API bool | IsPrepared () const noexcept |
| Checks whether the statement has been prepared. | |
| LIGHTWEIGHT_API SqlConnection & | Connection () noexcept |
| Retrieves the connection associated with this statement. | |
| LIGHTWEIGHT_API SqlConnection const & | Connection () const noexcept |
| Retrieves the connection associated with this statement. | |
| LIGHTWEIGHT_API SqlErrorInfo | LastError () const |
| Retrieves the last error information with respect to this SQL statement handle. | |
| LIGHTWEIGHT_API SqlQueryBuilder | Query (std::string_view const &table={}) const |
| Creates a new query builder for the given table, compatible with the SQL server being connected. | |
| LIGHTWEIGHT_API SqlQueryBuilder | QueryAs (std::string_view const &table, std::string_view const &tableAlias) const |
| Creates a new query builder for the given table with an alias, compatible with the SQL server being connected. | |
| LIGHTWEIGHT_API SQLHSTMT | NativeHandle () const noexcept |
| Retrieves the native handle of the statement. | |
| LIGHTWEIGHT_API void | Prepare (std::string_view query) & |
| LIGHTWEIGHT_API SqlStatement | Prepare (std::string_view query) && |
| Prepares the statement for execution on an rvalue reference and returns the statement. | |
| void | Prepare (SqlQueryObject auto const &queryObject) & |
| SqlStatement | Prepare (SqlQueryObject auto const &queryObject) && |
| Prepares the statement from a query object on an rvalue reference and returns the statement. | |
| std::string const & | PreparedQuery () const noexcept |
| Retrieves the last prepared query string. | |
| SqlPreparedStatementCaching | PreparedStatementCaching () const noexcept |
| Whether this statement takes part in its connection's prepared-statement cache. | |
| LIGHTWEIGHT_API void | SetPreparedStatementCaching (SqlPreparedStatementCaching caching) noexcept |
| Opts this statement in or out of its connection's prepared-statement cache. | |
| LIGHTWEIGHT_API void | SetQueryTimeout (std::chrono::seconds timeout) |
| Bounds how long each later execution of this statement may run, where the driver supports it. | |
| LIGHTWEIGHT_API std::chrono::seconds | QueryTimeout () const |
| Reads the query timeout from the driver. | |
| template<SqlInputParameterBinder Arg> | |
| void | BindInputParameter (SQLSMALLINT columnIndex, Arg const &arg) |
| template<SqlInputParameterBinder Arg, typename ColumnName > | |
| void | BindInputParameter (SQLSMALLINT columnIndex, Arg const &arg, ColumnName &&columnNameHint) |
| template<SqlInputParameterBinder Arg> | |
| void | BindInputParameter (SQLSMALLINT columnIndex, Arg const &&arg)=delete |
Deleted: a temporary would be destroyed before the driver reads it at Execute() time. | |
| template<SqlInputParameterBinder Arg, typename ColumnName > | |
| void | BindInputParameter (SQLSMALLINT columnIndex, Arg const &&arg, ColumnName &&columnNameHint)=delete |
Deleted: a temporary would be destroyed before the driver reads it at Execute() time. | |
| template<SqlInputParameterBinder... Args> | |
| SqlResultCursor | Execute (Args const &... args) |
| Binds the given arguments to the prepared statement and executes it. | |
| LIGHTWEIGHT_API SqlResultCursor | ExecuteWithVariants (std::vector< SqlVariant > const &args) |
| Binds the given arguments to the prepared statement and executes it. | |
| template<SqlInputParameterBatchBinder FirstColumnBatch, std::ranges::contiguous_range... MoreColumnBatches> | |
| SqlResultCursor | ExecuteBatchNative (FirstColumnBatch const &firstColumnBatch, MoreColumnBatches const &... moreColumnBatches) |
| template<SqlInputParameterBatchBinder FirstColumnBatch, std::ranges::range... MoreColumnBatches> | |
| SqlResultCursor | ExecuteBatchSoft (FirstColumnBatch const &firstColumnBatch, MoreColumnBatches const &... moreColumnBatches) |
| template<SqlInputParameterBatchBinder FirstColumnBatch, std::ranges::range... MoreColumnBatches> | |
| SqlResultCursor | ExecuteBatch (FirstColumnBatch const &firstColumnBatch, MoreColumnBatches const &... moreColumnBatches) |
| LIGHTWEIGHT_API SqlResultCursor | ExecuteBatch (std::span< SqlRawColumn const > columns, size_t rowCount) |
| LIGHTWEIGHT_API SqlResultCursor | ExecuteBatch (std::span< SqlRawColumn const > columns, std::size_t rowCount, std::span< SQLUSMALLINT > paramStatus, SQLULEN ¶msProcessed) |
| template<std::ranges::contiguous_range Rows, typename... ColumnAccessors> requires (sizeof...(ColumnAccessors) >= 1 && (std::invocable<ColumnAccessors const&, std::ranges::range_value_t<Rows> const&> && ...)) | |
| SqlResultCursor | ExecuteBatch (Rows const &rows, ColumnAccessors const &... accessors) |
| LIGHTWEIGHT_API SqlResultCursor | ExecuteDirect (std::string_view const &query, std::source_location location=std::source_location::current()) |
| Executes the given query directly. | |
| SqlResultCursor | ExecuteDirect (SqlQueryObject auto const &query, std::source_location location=std::source_location::current()) |
| Executes the given query directly. | |
| LIGHTWEIGHT_API RowArrayCursor | ExecuteBatchFetch (std::string_view query, std::size_t arrayDepth) |
| template<typename Callable > requires std::invocable<Callable, SqlMigrationQueryBuilder&> | |
| void | MigrateDirect (Callable const &callable, std::source_location location=std::source_location::current()) |
| Executes an SQL migration query, as created b the callback. | |
| template<typename T > requires (!std::same_as<T, SqlVariant>) | |
| std::optional< T > | ExecuteDirectScalar (std::string_view const &query, std::source_location location=std::source_location::current()) |
| template<typename T > requires (std::same_as<T, SqlVariant>) | |
| T | ExecuteDirectScalar (std::string_view const &query, std::source_location location=std::source_location::current()) |
| Executes the given query and returns the single result as an SqlVariant. | |
| template<typename T > requires (!std::same_as<T, SqlVariant>) | |
| std::optional< T > | ExecuteDirectScalar (SqlQueryObject auto const &query, std::source_location location=std::source_location::current()) |
| template<typename T > requires (std::same_as<T, SqlVariant>) | |
| T | ExecuteDirectScalar (SqlQueryObject auto const &query, std::source_location location=std::source_location::current()) |
| Executes the given query object and returns the single result as an SqlVariant. | |
| LIGHTWEIGHT_API size_t | LastInsertId (std::string_view tableName) |
| Retrieves the last insert ID of the given table. | |
| LIGHTWEIGHT_API void | ConsumePendingResults (std::source_location location=std::source_location::current()) |
| Steps through every result the last execution still has pending and throws for the first one that failed. | |
| template<SqlOutputColumnBinder... Args> | |
| LIGHTWEIGHT_FORCE_INLINE void | BindOutputColumns (Args *... args) |
Out-of-line definition of SqlStatement::BindOutputColumns. | |
| template<SqlOutputColumnBinder T> | |
| LIGHTWEIGHT_FORCE_INLINE void | BindOutputColumn (SQLUSMALLINT columnIndex, T *arg) |
Out-of-line definition of SqlStatement::BindOutputColumn. | |
| template<SqlInputParameterBinder Arg> | |
| LIGHTWEIGHT_FORCE_INLINE void | BindInputParameter (SQLSMALLINT columnIndex, Arg const &arg) |
| template<SqlInputParameterBinder Arg, typename ColumnName > | |
| LIGHTWEIGHT_FORCE_INLINE void | BindInputParameter (SQLSMALLINT columnIndex, Arg const &arg, ColumnName &&columnNameHint) |
| template<SqlInputParameterBatchBinder FirstColumnBatch, std::ranges::range... MoreColumnBatches> | |
| LIGHTWEIGHT_FORCE_INLINE SqlResultCursor | ExecuteBatch (FirstColumnBatch const &firstColumnBatch, MoreColumnBatches const &... moreColumnBatches) |
Public Member Functions inherited from Lightweight::SqlDataBinderCallback | |
| SqlDataBinderCallback ()=default | |
| Default constructor. | |
| SqlDataBinderCallback (SqlDataBinderCallback &&)=default | |
| Default move constructor. | |
| SqlDataBinderCallback (SqlDataBinderCallback const &)=default | |
| Default copy constructor. | |
| SqlDataBinderCallback & | operator= (SqlDataBinderCallback &&)=default |
| Default move assignment operator. | |
| SqlDataBinderCallback & | operator= (SqlDataBinderCallback const &)=default |
| Default copy assignment operator. | |
High level API for (prepared) raw SQL statements.
SQL prepared statement lifecycle:
Definition at line 82 of file SqlStatement.hpp.
|
inlinenoexcept |
Checks whether the statement's connection is alive and the statement handle is valid.
Definition at line 1356 of file SqlStatement.hpp.
References Lightweight::SqlConnection::IsAlive().
|
inlinenoexcept |
Checks whether the statement has been prepared.
Definition at line 1361 of file SqlStatement.hpp.
|
inlinenoexcept |
Retrieves the connection associated with this statement.
Definition at line 1366 of file SqlStatement.hpp.
Referenced by MigrateDirect(), Lightweight::DataMapper::Query(), Lightweight::DataMapper::Query(), Lightweight::DataMapper::Query(), and Lightweight::DataMapper::QuerySingle().
|
inlinenoexcept |
Retrieves the connection associated with this statement.
Definition at line 1371 of file SqlStatement.hpp.
|
inline |
Retrieves the last error information with respect to this SQL statement handle.
Definition at line 1376 of file SqlStatement.hpp.
|
inlinenoexcept |
Retrieves the native handle of the statement.
Definition at line 1381 of file SqlStatement.hpp.
| LIGHTWEIGHT_API void Lightweight::SqlStatement::Prepare | ( | std::string_view | query | ) | & |
Prepares the statement for execution.
Referenced by Lightweight::DataMapper::ConfigureRelationAutoLoading(), Lightweight::DataMapper::Delete(), Prepare(), Lightweight::DataMapper::Query(), Lightweight::DataMapper::Query(), Lightweight::DataMapper::Query(), Lightweight::DataMapper::QuerySingle(), and Lightweight::DataMapper::Update().
|
inline |
Prepares the statement for execution.
Definition at line 1404 of file SqlStatement.hpp.
References Prepare.
|
inline |
Prepares the statement from a query object on an rvalue reference and returns the statement.
Definition at line 1411 of file SqlStatement.hpp.
References Prepare().
|
inlinenoexcept |
Retrieves the last prepared query string.
Definition at line 1418 of file SqlStatement.hpp.
|
inlinenoexcept |
Whether this statement takes part in its connection's prepared-statement cache.
SqlPreparedStatementCaching::Enabled by default). Definition at line 712 of file SqlStatement.hpp.
|
noexcept |
Opts this statement in or out of its connection's prepared-statement cache.
Only has an effect while the connection has a non-zero cache capacity (see SqlConnection::SetPreparedStatementCacheCapacity). Opt out for a statement whose query plan must be re-derived — for instance because it runs across a schema change.
The handle this statement currently holds is unaffected; from the next Prepare() on it is simply neither taken from nor given back to the pool.
| caching | Whether pooled handles may be reused by, and published from, this statement. |
| LIGHTWEIGHT_API void Lightweight::SqlStatement::SetQueryTimeout | ( | std::chrono::seconds | timeout | ) |
Bounds how long each later execution of this statement may run, where the driver supports it.
The timeout belongs to this statement: it stays in effect across Prepare() and ExecuteDirect(), also when the prepared-statement cache gives the statement another ODBC handle, and it never reaches another statement of the connection, not even one that takes over this statement's pooled handle. It bounds a single execution rather than a sequence of them, and neither a DataMapper nor a lazily loaded relation uses it.
What the driver does with it (see docs/usage.md):
HYT00.57014.0.IsQueryTimeoutError recognises both failures. SqlRetryPolicy treats SQL Server's HYT00 as transient, so running such a statement under a retry policy spends the timeout once per attempt.
| timeout | The bound in whole seconds; 0 lifts it. |
| std::invalid_argument | If timeout is negative. |
| SqlException | If the driver rejects the value. |
| LIGHTWEIGHT_API std::chrono::seconds Lightweight::SqlStatement::QueryTimeout | ( | ) | const |
Reads the query timeout from the driver.
A driver that ignores the timeout reports 0 here whatever was set, so this tells whether SetQueryTimeout() can have any effect.
0 means none. | SqlException | If the driver cannot report it. |
| void Lightweight::SqlStatement::BindInputParameter | ( | SQLSMALLINT | columnIndex, |
| Arg const & | arg | ||
| ) |
Binds an input parameter to the prepared statement at the given column index.
The value is bound by address: the driver reads it only at the next Execute(), so arg must stay alive until then. Temporaries are therefore rejected at compile time.
| columnIndex | The 1-based parameter index. |
| arg | The value to bind; it must outlive the next Execute(). |
Referenced by Lightweight::DataMapper::Delete(), and Lightweight::DataMapper::Update().
| void Lightweight::SqlStatement::BindInputParameter | ( | SQLSMALLINT | columnIndex, |
| Arg const & | arg, | ||
| ColumnName && | columnNameHint | ||
| ) |
Binds an input parameter to the prepared statement at the given column index with a column name hint.
| columnIndex | The 1-based parameter index. |
| arg | The value to bind; it must outlive the next Execute(). |
| columnNameHint | The column name, reported to the SQL logger. |
| SqlResultCursor Lightweight::SqlStatement::Execute | ( | Args const &... | args | ) |
Binds the given arguments to the prepared statement and executes it.
Definition at line 1518 of file SqlStatement.hpp.
References Execute.
Referenced by Lightweight::DataMapper::ConfigureRelationAutoLoading(), Lightweight::DataMapper::Delete(), Lightweight::DataMapper::Query(), Lightweight::DataMapper::Query(), Lightweight::DataMapper::Query(), Lightweight::DataMapper::QuerySingle(), and Lightweight::DataMapper::Update().
| SqlResultCursor Lightweight::SqlStatement::ExecuteBatchNative | ( | FirstColumnBatch const & | firstColumnBatch, |
| MoreColumnBatches const &... | moreColumnBatches | ||
| ) |
Executes the prepared statement on a batch of data.
Each parameter represents a column, to be bound as input parameter. The element types of each column container must be explicitly supported.
In order to support column value types, their underlying storage must be contiguous. Also the input range itself must be contiguous. If any of these conditions are not met, the function will not compile - use ExecuteBatch() instead.
Definition at line 1626 of file SqlStatement.hpp.
References ExecuteBatch.
| SqlResultCursor Lightweight::SqlStatement::ExecuteBatchSoft | ( | FirstColumnBatch const & | firstColumnBatch, |
| MoreColumnBatches const &... | moreColumnBatches | ||
| ) |
Executes the prepared statement on a batch of data.
Each parameter represents a column, to be bound as input parameter, and the number of elements in these bound column containers will mandate how many executions will happen.
This function will bind and execute each row separately, which is less efficient than ExecuteBatchNative(), but works non-contiguous input ranges.
Definition at line 1681 of file SqlStatement.hpp.
| SqlResultCursor Lightweight::SqlStatement::ExecuteBatch | ( | FirstColumnBatch const & | firstColumnBatch, |
| MoreColumnBatches const &... | moreColumnBatches | ||
| ) |
Executes the prepared statement on a batch of data.
Each parameter represents a column, to be bound as input parameter, and the number of elements in these bound column containers will mandate how many executions will happen.
| LIGHTWEIGHT_API SqlResultCursor Lightweight::SqlStatement::ExecuteBatch | ( | std::span< SqlRawColumn const > | columns, |
| size_t | rowCount | ||
| ) |
Executes the prepared statement on a batch of SqlRawColumn-prepared data.
| columns | The columns to bind as input parameters. |
| rowCount | The number of rows to execute. |
| LIGHTWEIGHT_API SqlResultCursor Lightweight::SqlStatement::ExecuteBatch | ( | std::span< SqlRawColumn const > | columns, |
| std::size_t | rowCount, | ||
| std::span< SQLUSMALLINT > | paramStatus, | ||
| SQLULEN & | paramsProcessed | ||
| ) |
Executes the prepared statement on a batch of SqlRawColumn-prepared data, reporting the outcome of each row (parameter set).
Unlike the overload without a status array, this one does not accept a partial success: a driver that continues past a failing parameter set (SQL Server does) returns SQL_SUCCESS_WITH_INFO, which only the status array tells apart from a full success. The status and processed pointers are bound for this execution only, and reset on every exit.
| columns | The columns to bind as input parameters. |
| rowCount | The number of rows to execute. |
| paramStatus | Receives one status per row (SQL_PARAM_SUCCESS, SQL_PARAM_ERROR, ...); at least rowCount entries. Entries the driver does not fill read SQL_PARAM_UNUSED; a driver that stops at the first failing row leaves the rows after it that way. |
| paramsProcessed | Receives the number of rows the driver processed; rowCount if the driver does not report it. |
| SqlException | if the execution fails, if any row reports SQL_PARAM_ERROR (carrying the first diagnostic record), or if the driver processed fewer than rowCount rows. paramStatus and paramsProcessed hold what the driver reported either way. |
| std::invalid_argument | if the column count does not match the prepared statement or paramStatus holds fewer than rowCount entries. |
| SqlResultCursor Lightweight::SqlStatement::ExecuteBatch | ( | Rows const & | rows, |
| ColumnAccessors const &... | accessors | ||
| ) |
Executes the prepared statement once per row of a row-major batch, preferring native ODBC row-wise array binding (a single zero-copy SQLExecute) and transparently falling back to a prepare-once + per-row execute when native binding is not possible.
Unlike the column-major ExecuteBatch overloads, the data here is laid out as an array of row structs (e.g. records). Each accessors invocable maps a row to one bound column's value, returning a reference into the row (so the native path binds the value in place):
The native row-wise path is taken when every column value type is row-bindable (SqlNativeRowBindableValue, or std::optional of such a non-numeric type), every accessor returns an lvalue reference, the row stride satisfies the indicator-alignment requirement, and the driver advertises parameter-array support (SqlConnection::SupportsNativeRowBatch). A per-row runtime stride check guards against accessors that are not constant-offset subobjects. Otherwise the soft path is used, which correctly binds every supported type (strings, binary, variant, std::optional of any type, …) one row at a time.
| rows | Contiguous range of row structs (e.g. std::span<Record const>). |
| accessors | One invocable per bound column; accessor(row) yields that column's value. |
rows is empty). Definition at line 1720 of file SqlStatement.hpp.
|
inline |
Executes the given query directly.
Definition at line 2387 of file SqlStatement.hpp.
References ExecuteDirect.
| LIGHTWEIGHT_API RowArrayCursor Lightweight::SqlStatement::ExecuteBatchFetch | ( | std::string_view | query, |
| std::size_t | arrayDepth | ||
| ) |
Executes query and prepares bulk row-array fetching with up to arrayDepth rows per SQLFetchScroll round-trip.
This is a fast-path alternative to the per-cell SQLGetData loop used by the regular result cursor: it binds one contiguous buffer per result column and materializes whole row blocks per ODBC round-trip. Only fixed-stride column types are supported (integers, floating point, and bounded character columns). LOB / unbounded columns (varchar(max)/text/varbinary(max)) are rejected by the returned cursor's construction.
| query | The SQL query to execute. |
| arrayDepth | Maximum number of rows materialized per SQLFetchScroll call (must be > 0). |
| void Lightweight::SqlStatement::MigrateDirect | ( | Callable const & | callable, |
| std::source_location | location = std::source_location::current() |
||
| ) |
Executes an SQL migration query, as created b the callback.
Definition at line 2398 of file SqlStatement.hpp.
References Lightweight::SqlConnection::ClearPreparedStatementCache(), Connection(), ExecuteDirect, and Lightweight::SqlConnection::QueryFormatter().
|
inline |
Executes the given query, assuming that only one result row and column is affected, that one will be returned.
Definition at line 2439 of file SqlStatement.hpp.
References ExecuteDirect.
Referenced by Lightweight::DataMapper::Execute().
|
inline |
Executes the given query and returns the single result as an SqlVariant.
Definition at line 2448 of file SqlStatement.hpp.
References ExecuteDirect, and Lightweight::SqlNullValue.
|
inline |
Executes the given query, assuming that only one result row and column is affected, that one will be returned.
Definition at line 2459 of file SqlStatement.hpp.
|
inline |
Executes the given query object and returns the single result as an SqlVariant.
Definition at line 2466 of file SqlStatement.hpp.
| LIGHTWEIGHT_API void Lightweight::SqlStatement::ConsumePendingResults | ( | std::source_location | location = std::source_location::current() | ) |
Steps through every result the last execution still has pending and throws for the first one that failed.
A batch of several statements can report an error of a later statement only when its result is reached (on SQL Server, every statement that produces a row count is a result of its own). Closing the cursor discards those results without looking, because it must not throw. Call this after executing a batch whose failure must not go unnoticed.
| location | The caller's source location, reported with the error. |
| SqlException | A pending result reports an error. |
|
inline |
Out-of-line definition of SqlStatement::BindOutputColumns.
Definition at line 1425 of file SqlStatement.hpp.
|
inline |
Out-of-line definition of SqlStatement::BindOutputColumn.
Definition at line 1483 of file SqlStatement.hpp.
|
inline |
Binds an input parameter to the prepared statement at the given column index.
The value is bound by address: the driver reads it only at the next Execute(), so arg must stay alive until then. Temporaries are therefore rejected at compile time.
| columnIndex | The 1-based parameter index. |
| arg | The value to bind; it must outlive the next Execute(). |
Definition at line 1500 of file SqlStatement.hpp.
|
inline |
Binds an input parameter to the prepared statement at the given column index with a column name hint.
| columnIndex | The 1-based parameter index. |
| arg | The value to bind; it must outlive the next Execute(). |
| columnNameHint | The column name, reported to the SQL logger. |
Definition at line 1509 of file SqlStatement.hpp.
|
inline |
Executes the prepared statement on a batch of data.
Each parameter represents a column, to be bound as input parameter, and the number of elements in these bound column containers will mandate how many executions will happen.
Definition at line 1669 of file SqlStatement.hpp.