mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-08 19:04:06 +01:00
81d7307fa7
adjust make and CMake for SQLParser and DataTest lib separate samples from tests in CMake remove unused StatementImpl from Data testsuite
1071 lines
30 KiB
C++
1071 lines
30 KiB
C++
//
|
|
// Statement.h
|
|
//
|
|
// Library: Data
|
|
// Package: DataCore
|
|
// Module: Statement
|
|
//
|
|
// Definition of the Statement class.
|
|
//
|
|
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
|
// and Contributors.
|
|
//
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
//
|
|
|
|
|
|
#ifndef Data_Statement_INCLUDED
|
|
#define Data_Statement_INCLUDED
|
|
|
|
|
|
#include "Poco/Data/Data.h"
|
|
#include "Poco/Data/StatementImpl.h"
|
|
#include "Poco/Data/Binding.h"
|
|
#include "Poco/Data/Range.h"
|
|
#include "Poco/Data/Bulk.h"
|
|
#include "Poco/Data/Row.h"
|
|
#include "Poco/Data/SQLParser.h"
|
|
#include "Poco/Data/SimpleRowFormatter.h"
|
|
#include "Poco/SharedPtr.h"
|
|
#include "Poco/Mutex.h"
|
|
#include "Poco/ActiveMethod.h"
|
|
#include "Poco/ActiveResult.h"
|
|
#include "Poco/Format.h"
|
|
#include "Poco/Optional.h"
|
|
#include <algorithm>
|
|
|
|
|
|
namespace Poco {
|
|
namespace Data {
|
|
|
|
|
|
class AbstractBinding;
|
|
class AbstractExtraction;
|
|
class Session;
|
|
class Limit;
|
|
|
|
|
|
class Data_API Statement
|
|
/// A Statement is used to execute SQL statements.
|
|
/// It does not contain code of its own.
|
|
/// Its main purpose is to forward calls to the concrete StatementImpl stored inside.
|
|
/// Statement execution can be synchronous or asynchronous.
|
|
/// Synchronous ececution is achieved through execute() call, while asynchronous is
|
|
/// achieved through executeAsync() method call.
|
|
/// An asynchronously executing statement should not be copied during the execution.
|
|
///
|
|
/// Note:
|
|
///
|
|
/// Once set as asynchronous through 'async' manipulator, statement remains
|
|
/// asynchronous for all subsequent execution calls, both execute() and executeAsync().
|
|
/// However, calling executAsync() on a synchronous statement shall execute
|
|
/// asynchronously but without altering the underlying statement's synchronous nature.
|
|
///
|
|
/// Once asynchronous, a statement can be reverted back to synchronous state in two ways:
|
|
///
|
|
/// 1) By calling setAsync(false)
|
|
/// 2) By means of 'sync' or 'reset' manipulators
|
|
///
|
|
/// See individual functions documentation for more details.
|
|
///
|
|
/// Statement owns the RowFormatter, which can be provided externaly through setFormatter()
|
|
/// member function.
|
|
/// If no formatter is externally supplied to the statement, the SimpleRowFormatter is lazy
|
|
/// created and used.
|
|
///
|
|
/// If compiled with SQLParser support, Statement knows the number and type of the SQL statement(s)
|
|
/// it contains, to the extent that the SQL string is a standard SQL and the staement type is supported.
|
|
/// No proprietary SQL extensions are supported.
|
|
///
|
|
/// Supported statement types are:
|
|
///
|
|
/// - SELECT
|
|
/// - INSERT
|
|
/// - UPDATE
|
|
/// - DELETE
|
|
///
|
|
{
|
|
public:
|
|
typedef void (*Manipulator)(Statement&);
|
|
|
|
using Result = ActiveResult<std::size_t>;
|
|
using ResultPtr = SharedPtr<Result>;
|
|
using AsyncExecMethod = ActiveMethod<std::size_t, bool, StatementImpl>;
|
|
using AsyncExecMethodPtr = SharedPtr<AsyncExecMethod>;
|
|
using State = StatementImpl::State;
|
|
|
|
static const int WAIT_FOREVER = -1;
|
|
|
|
enum Storage
|
|
{
|
|
STORAGE_DEQUE = StatementImpl::STORAGE_DEQUE_IMPL,
|
|
STORAGE_VECTOR = StatementImpl::STORAGE_VECTOR_IMPL,
|
|
STORAGE_LIST = StatementImpl::STORAGE_LIST_IMPL,
|
|
STORAGE_UNKNOWN = StatementImpl::STORAGE_UNKNOWN_IMPL
|
|
};
|
|
|
|
Statement(StatementImpl::Ptr pImpl);
|
|
/// Creates the Statement.
|
|
|
|
explicit Statement(Session& session);
|
|
/// Creates the Statement for the given Session.
|
|
///
|
|
/// The following:
|
|
///
|
|
/// Statement stmt(sess);
|
|
/// stmt << "SELECT * FROM Table", ...
|
|
///
|
|
/// is equivalent to:
|
|
///
|
|
/// Statement stmt(sess << "SELECT * FROM Table", ...);
|
|
///
|
|
/// but in some cases better readable.
|
|
|
|
~Statement();
|
|
/// Destroys the Statement.
|
|
|
|
Statement(const Statement& stmt);
|
|
/// Copy constructor.
|
|
/// If the statement has been executed asynchronously and has not been
|
|
/// synchronized prior to copy operation (i.e. is copied while executing),
|
|
/// this constructor shall synchronize it.
|
|
|
|
Statement(Statement&& other) noexcept;
|
|
/// Move constructor.
|
|
|
|
Statement& operator = (const Statement& stmt);
|
|
/// Assignment operator.
|
|
|
|
Statement& operator = (Statement&& stmt) noexcept;
|
|
/// Move assignment.
|
|
|
|
void swap(Statement& other) noexcept;
|
|
/// Swaps the statement with another one.
|
|
|
|
template <typename T>
|
|
Statement& operator << (const T& t)
|
|
/// Concatenates data with the SQL statement string.
|
|
{
|
|
_pImpl->add(t);
|
|
return *this;
|
|
}
|
|
|
|
Statement& operator , (Manipulator manip);
|
|
/// Handles manipulators, such as now, async, etc.
|
|
|
|
Statement& operator , (AbstractBinding::Ptr pBind);
|
|
/// Registers the Binding with the Statement by calling addBind().
|
|
|
|
Statement& addBind(AbstractBinding::Ptr pBind);
|
|
/// Registers a single binding with the statement.
|
|
|
|
void removeBind(const std::string& name);
|
|
/// Removes the all the bindings with specified name from the statement.
|
|
|
|
Statement& operator , (AbstractBindingVec& bindVec);
|
|
/// Registers the Binding vector with the Statement.
|
|
|
|
template <typename C>
|
|
Statement& addBinding(C& bindingCont, bool reset)
|
|
/// Registers binding container with the Statement.
|
|
{
|
|
if (reset) _pImpl->resetBinding();
|
|
typename C::iterator itAB = bindingCont.begin();
|
|
typename C::iterator itABEnd = bindingCont.end();
|
|
for (; itAB != itABEnd; ++itAB) addBind(*itAB);
|
|
return *this;
|
|
}
|
|
|
|
template <typename C>
|
|
Statement& bind(const C& value)
|
|
/// Adds a binding to the Statement. This can be used to implement
|
|
/// generic binding mechanisms and is a nicer syntax for:
|
|
///
|
|
/// statement , bind(value);
|
|
{
|
|
(*this) , Keywords::bind(value);
|
|
return *this;
|
|
}
|
|
|
|
Statement& operator , (AbstractExtraction::Ptr extract);
|
|
/// Registers objects used for extracting data with the Statement by
|
|
/// calling addExtract().
|
|
|
|
Statement& operator , (AbstractExtractionVec& extVec);
|
|
/// Registers the extraction vector with the Statement.
|
|
/// The vector is registered at position 0 (i.e. for the first returned data set).
|
|
|
|
Statement& operator , (AbstractExtractionVecVec& extVecVec);
|
|
/// Registers the vector of extraction vectors with the Statement.
|
|
|
|
template <typename C>
|
|
Statement& addExtraction(C& val, bool reset)
|
|
/// Registers extraction container with the Statement.
|
|
{
|
|
if (reset) _pImpl->resetExtraction();
|
|
typename C::iterator it = val.begin();
|
|
typename C::iterator end = val.end();
|
|
for (; it != end; ++it) addExtract(*it);
|
|
return *this;
|
|
}
|
|
|
|
template <typename C>
|
|
Statement& addExtractions(C& val)
|
|
/// Registers container of extraction containers with the Statement.
|
|
{
|
|
_pImpl->resetExtraction();
|
|
typename C::iterator it = val.begin();
|
|
typename C::iterator end = val.end();
|
|
for (; it != end; ++it) addExtraction(*it, false);
|
|
return *this;
|
|
}
|
|
|
|
Statement& addExtract(AbstractExtraction::Ptr pExtract);
|
|
/// Registers a single extraction with the statement.
|
|
|
|
Statement& operator , (const Bulk& bulk);
|
|
/// Sets the bulk execution mode (both binding and extraction) for this
|
|
/// statement.Statement must not have any extractors or binders set at the
|
|
/// time when this operator is applied.
|
|
/// Failure to adhere to the above constraint shall result in
|
|
/// InvalidAccessException.
|
|
|
|
Statement& operator , (BulkFnType);
|
|
/// Sets the bulk execution mode (both binding and extraction) for this
|
|
/// statement.Statement must not have any extractors or binders set at the
|
|
/// time when this operator is applied.
|
|
/// Additionally, this function requires limit to be set in order to
|
|
/// determine the bulk size.
|
|
/// Failure to adhere to the above constraints shall result in
|
|
/// InvalidAccessException.
|
|
|
|
Statement& operator , (const Limit& extrLimit);
|
|
/// Sets a limit on the maximum number of rows a select is allowed to return.
|
|
///
|
|
/// Set per default to zero to Limit::LIMIT_UNLIMITED, which disables the limit.
|
|
|
|
Statement& operator , (RowFormatter::Ptr pRowFformatter);
|
|
/// Sets the row formatter for the statement.
|
|
|
|
Statement& operator , (const Range& extrRange);
|
|
/// Sets a an extraction range for the maximum number of rows a select is allowed to return.
|
|
///
|
|
/// Set per default to Limit::LIMIT_UNLIMITED which disables the range.
|
|
|
|
Statement& operator , (char value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
|
|
Statement& operator , (Poco::UInt8 value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
|
|
Statement& operator , (Poco::Int8 value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
|
|
Statement& operator , (Poco::UInt16 value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
|
|
Statement& operator , (Poco::Int16 value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
|
|
Statement& operator , (Poco::UInt32 value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
|
|
Statement& operator , (Poco::Int32 value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
|
|
#ifndef POCO_INT64_IS_LONG
|
|
Statement& operator , (long value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
|
|
Statement& operator , (unsigned long value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
#endif
|
|
|
|
Statement& operator , (Poco::UInt64 value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
|
|
Statement& operator , (Poco::Int64 value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
|
|
Statement& operator , (double value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
|
|
Statement& operator , (float value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
|
|
Statement& operator , (bool value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
|
|
Statement& operator , (const std::string& value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
|
|
Statement& operator , (const char* value);
|
|
/// Adds the value to the list of values to be supplied to the SQL string formatting function.
|
|
|
|
const std::string& toString() const;
|
|
/// Creates a string from the accumulated SQL statement.
|
|
|
|
Optional<std::size_t> statementsCount() const;
|
|
/// Returns the total number of SQL statements held in the accummulated SQL statement.
|
|
|
|
Optional<bool> parse();
|
|
/// Parses the SQL statement and returns true if successful.
|
|
///
|
|
/// Note that parsing is not guaranteed to succeed, as some backends have proprietary
|
|
/// keywords not supported by the parser. Parsing failures are silent in terms of
|
|
/// throwing exceptions or logging, but it is possible to get error information by
|
|
/// calling parseError().
|
|
|
|
const std::string& parseError();
|
|
/// Returns the SQL statement parse error message, if any.
|
|
/// For Poco::Data builds without SQLParser, it always returns empty string.
|
|
|
|
Optional<bool> isSelect() const;
|
|
/// Returns true if the statement consists only of SELECT statement(s).
|
|
/// For Poco::Data builds without SQLParser, it always returns unspecified.
|
|
|
|
Optional<bool> isInsert() const;
|
|
/// Returns true if the statement consists only of INSERT statement(s).
|
|
/// For Poco::Data builds without SQLParser, it always returns unspecified.
|
|
|
|
Optional<bool> isUpdate() const;
|
|
/// Returns true if the statement consists only of UPDATE statement(s).
|
|
/// For Poco::Data builds without SQLParser, it always returns unspecified.
|
|
|
|
Optional<bool> isDelete() const;
|
|
/// Returns true if the statement consists only of DELETE statement(s).
|
|
/// For Poco::Data builds without SQLParser, it always returns unspecified.
|
|
|
|
Optional<bool> hasSelect() const;
|
|
/// Returns true if the statement contains a SELECT statement.
|
|
/// For Poco::Data builds without SQLParser, it always returns unspecified.
|
|
|
|
Optional<bool> hasInsert() const;
|
|
/// Returns true if the statement contains an INSERT statement.
|
|
/// For Poco::Data builds without SQLParser, it always returns unspecified.
|
|
|
|
Optional<bool> hasUpdate() const;
|
|
/// Returns true if the statement contains an UPDATE statement.
|
|
/// For Poco::Data builds without SQLParser, it always returns unspecified.
|
|
|
|
Optional<bool> hasDelete() const;
|
|
/// Returns true if the statement contains a DELETE statement.
|
|
/// For Poco::Data builds without SQLParser, it always returns unspecified.
|
|
|
|
std::size_t execute(bool reset = true);
|
|
/// Executes the statement synchronously or asynchronously.
|
|
/// Stops when either a limit is hit or the whole statement was executed.
|
|
/// Returns the number of rows extracted from the database (for statements
|
|
/// returning data) or number of rows affected (for all other statements).
|
|
/// If reset is true (default), associated storage is reset and reused.
|
|
/// Otherwise, the results from this execution step are appended.
|
|
/// The reset argument has no meaning for unlimited statements that return all rows.
|
|
/// If isAsync() returns true, the statement is executed asynchronously
|
|
/// and the return value from this function is zero.
|
|
/// The result of execution (i.e. number of returned or affected rows) can be
|
|
/// obtained by calling wait() on the statement at a later point in time.
|
|
///
|
|
/// When Poco::Data is compiled with SQL parsing support, if session is not already in
|
|
/// a transaction and not in autocommit mode, an attempt to parse the SQL is made before
|
|
/// statement execution, and if (1) successful, and (2) the statement does not consist
|
|
/// only of SELECT statements, a transaction is started.
|
|
///
|
|
/// Note that parsing is not guaranteed to succeed, as some backends have proprietary
|
|
/// keywords not supported by the parser. Parsing failures are silent in terms of
|
|
/// throwing exceptions or logging, but it is possible to get error information by calling
|
|
/// Statement::parseError().
|
|
/// When parsing does not succeed, transaction is not started, and Poco::Data::Session will
|
|
/// not reflect its state accurately. The underlying database session, however, will be in
|
|
/// transaction state. In such state, in order to complete the transaction and unlock the
|
|
/// resources, commit() or rollback() must be called on the Poco::Data::Session; this is
|
|
/// true even for a single SELECT statement in non-autocommit mode when parsing does not
|
|
/// succeed.
|
|
///
|
|
/// For Poco::Data builds without SQLParser support, the behavior is the same as
|
|
/// for unsuccesful parsing.
|
|
|
|
void executeDirect(const std::string& query);
|
|
/// Executes the query synchronously and directly.
|
|
/// Even when isAsync() returns true, the statement is still executed synchronously.
|
|
/// For transactional behavior, see execute() documentation.
|
|
|
|
const Result& executeAsync(bool reset = true);
|
|
/// Executes the statement asynchronously.
|
|
/// Stops when either a limit is hit or the whole statement was executed.
|
|
/// Returns immediately. Calling wait() (on either the result returned from this
|
|
/// call or the statement itself) returns the number of rows extracted or number
|
|
/// of rows affected by the statement execution.
|
|
/// When executed on a synchronous statement, this method does not alter the
|
|
/// statement's synchronous nature.
|
|
/// For transactional behavior, see execute() documentation.
|
|
|
|
void setAsync(bool async = true);
|
|
/// Sets the asynchronous flag. If this flag is true, executeAsync() is called
|
|
/// from the now() manipulator. This setting does not affect the statement's
|
|
/// capability to be executed synchronously by directly calling execute().
|
|
|
|
bool isAsync() const;
|
|
/// Returns true if statement was marked for asynchronous execution.
|
|
|
|
std::size_t wait(long milliseconds = WAIT_FOREVER);
|
|
/// Waits for the execution completion for asynchronous statements or
|
|
/// returns immediately for synchronous ones. The return value for
|
|
/// asynchronous statement is the execution result (i.e. number of
|
|
/// rows retrieved). For synchronous statements, the return value is zero.
|
|
|
|
bool initialized();
|
|
/// Returns true if the statement was initialized (i.e. not executed yet).
|
|
|
|
bool paused();
|
|
/// Returns true if the statement was paused (a range limit stopped it
|
|
/// and there is more work to do).
|
|
|
|
bool done();
|
|
/// Returns true if the statement was completely executed or false if a range limit stopped it
|
|
/// and there is more work to do. When no limit is set, it will always return true after calling execute().
|
|
|
|
Statement& reset(Session& session);
|
|
/// Resets the Statement and assigns it a new session, so that it can be filled with a new SQL query.
|
|
|
|
Statement& reset();
|
|
/// Resets the Statement so that it can be filled with a new SQL query.
|
|
|
|
bool canModifyStorage();
|
|
/// Returns true if statement is in a state that allows the internal storage to be modified.
|
|
|
|
Storage storage() const;
|
|
/// Returns the internal storage type for the statement.
|
|
|
|
void setStorage(const std::string& storage);
|
|
/// Sets the internal storage type for the statement.
|
|
|
|
const std::string& getStorage() const;
|
|
/// Returns the internal storage type for the statement.
|
|
|
|
std::size_t columnsExtracted(int dataSet = StatementImpl::USE_CURRENT_DATA_SET) const;
|
|
/// Returns the number of columns returned for current data set.
|
|
/// Default value indicates current data set (if any).
|
|
|
|
std::size_t rowsExtracted(int dataSet = StatementImpl::USE_CURRENT_DATA_SET) const;
|
|
/// Returns the number of rows returned for current data set during last statement
|
|
/// execution. Default value indicates current data set (if any).
|
|
|
|
std::size_t subTotalRowCount(int dataSet = StatementImpl::USE_CURRENT_DATA_SET) const;
|
|
/// Returns the number of rows extracted so far for the data set.
|
|
/// Default value indicates current data set (if any).
|
|
|
|
std::size_t affectedRowCount() const;
|
|
/// Returns the number of affected rows.
|
|
/// Used to find out the number of rows affected by insert, delete or update.
|
|
|
|
std::size_t extractionCount() const;
|
|
/// Returns the number of extraction storage buffers associated
|
|
/// with the current data set.
|
|
|
|
std::size_t dataSetCount() const;
|
|
/// Returns the number of data sets associated with the statement.
|
|
|
|
std::size_t nextDataSet();
|
|
/// Returns the index of the next data set.
|
|
|
|
std::size_t previousDataSet();
|
|
/// Returns the index of the previous data set.
|
|
|
|
bool hasMoreDataSets() const;
|
|
/// Returns false if the current data set index points to the last
|
|
/// data set. Otherwise, it returns true.
|
|
|
|
void setRowFormatter(RowFormatter::Ptr pRowFormatter);
|
|
/// Sets the row formatter for this statement.
|
|
/// Statement takes the ownership of the formatter.
|
|
|
|
State state() const;
|
|
/// Returns the statement state.
|
|
|
|
protected:
|
|
using ImplPtr = StatementImpl::Ptr;
|
|
|
|
const AbstractExtractionVec& extractions() const;
|
|
/// Returns the extractions vector.
|
|
|
|
const MetaColumn& metaColumn(std::size_t pos) const;
|
|
/// Returns the type for the column at specified position.
|
|
|
|
const MetaColumn& metaColumn(const std::string& name) const;
|
|
/// Returns the type for the column with specified name.
|
|
|
|
bool isNull(std::size_t col, std::size_t row) const;
|
|
/// Returns true if the current row value at column pos is null.
|
|
|
|
bool isBulkExtraction() const;
|
|
/// Returns true if this statement extracts data in bulk.
|
|
|
|
ImplPtr impl() const;
|
|
/// Returns pointer to statement implementation.
|
|
|
|
const RowFormatter::Ptr& getRowFormatter();
|
|
/// Returns the row formatter for this statement.
|
|
|
|
Session session();
|
|
/// Returns the underlying session.
|
|
|
|
private:
|
|
const Result& doAsyncExec(bool reset = true);
|
|
/// Asynchronously executes the statement.
|
|
|
|
template <typename T>
|
|
Statement& commaPODImpl(const T& val)
|
|
{
|
|
_arguments.push_back(val);
|
|
return *this;
|
|
}
|
|
|
|
void formatQuery();
|
|
/// Formats the query string.
|
|
|
|
void checkBeginTransaction();
|
|
/// Checks if the transaction needs to be started
|
|
/// and starts it if not.
|
|
/// Transaction is automatically started for the first
|
|
/// statement on a non-autocommit session.
|
|
/// The best effort is made to detect if the query
|
|
/// consists of SELECT statements only, in which case
|
|
/// transaction does not need to started.
|
|
/// However, due to many SQL dialects, this logic is
|
|
/// not 100% accurate and transaction MAY be started
|
|
/// for SELECT-only queries.
|
|
|
|
#ifndef POCO_DATA_NO_SQL_PARSER
|
|
|
|
bool isType(Parser::StatementType type) const;
|
|
/// Returns true if the statement is of the argument type.
|
|
|
|
bool hasType(Parser::StatementType type) const;
|
|
/// Returns true if the statement is of the argument type.
|
|
|
|
Poco::SharedPtr<Parser::SQLParserResult> _pParseResult;
|
|
std::string _parseError;
|
|
#endif // POCO_DATA_NO_SQL_PARSER
|
|
|
|
StatementImpl::Ptr _pImpl;
|
|
|
|
// asynchronous execution related members
|
|
bool _async;
|
|
mutable ResultPtr _pResult;
|
|
Mutex _mutex;
|
|
AsyncExecMethodPtr _pAsyncExec;
|
|
std::vector<Any> _arguments;
|
|
RowFormatter::Ptr _pRowFormatter;
|
|
mutable std::string _stmtString;
|
|
};
|
|
|
|
//
|
|
// inlines
|
|
|
|
inline std::size_t Statement::subTotalRowCount(int dataSet) const
|
|
{
|
|
return _pImpl->subTotalRowCount(dataSet);
|
|
}
|
|
|
|
|
|
inline const std::string& Statement::parseError()
|
|
{
|
|
#ifdef POCO_DATA_NO_SQL_PARSER
|
|
static std::string empty;
|
|
return empty;
|
|
#else
|
|
return _parseError;
|
|
#endif
|
|
}
|
|
|
|
|
|
inline Optional<bool> Statement::isSelect() const
|
|
{
|
|
#ifndef POCO_DATA_NO_SQL_PARSER
|
|
if (_pImpl->session().shouldParse())
|
|
return isType(Parser::StatementType::kStmtSelect);
|
|
else return Optional<bool>();
|
|
#else
|
|
return Optional<bool>();
|
|
#endif
|
|
}
|
|
|
|
|
|
inline Optional<bool> Statement::isInsert() const
|
|
{
|
|
#ifndef POCO_DATA_NO_SQL_PARSER
|
|
if (_pImpl->session().shouldParse())
|
|
return isType(Parser::StatementType::kStmtInsert);
|
|
else return Optional<bool>();
|
|
#else
|
|
return Optional<bool>();
|
|
#endif
|
|
}
|
|
|
|
|
|
inline Optional<bool> Statement::isUpdate() const
|
|
{
|
|
#ifndef POCO_DATA_NO_SQL_PARSER
|
|
if (_pImpl->session().shouldParse())
|
|
return isType(Parser::StatementType::kStmtUpdate);
|
|
else return Optional<bool>();
|
|
#else
|
|
return Optional<bool>();
|
|
#endif
|
|
}
|
|
|
|
|
|
inline Optional<bool> Statement::isDelete() const
|
|
{
|
|
#ifndef POCO_DATA_NO_SQL_PARSER
|
|
if (_pImpl->session().shouldParse())
|
|
return isType(Parser::StatementType::kStmtDelete);
|
|
else return Optional<bool>();
|
|
#else
|
|
return Optional<bool>();
|
|
#endif
|
|
}
|
|
|
|
|
|
inline Optional<bool> Statement::hasSelect() const
|
|
{
|
|
#ifndef POCO_DATA_NO_SQL_PARSER
|
|
if (_pImpl->session().shouldParse())
|
|
return hasType(Parser::StatementType::kStmtSelect);
|
|
else return Optional<bool>();
|
|
#else
|
|
return Optional<bool>();
|
|
#endif
|
|
}
|
|
|
|
|
|
inline Optional<bool> Statement::hasInsert() const
|
|
{
|
|
#ifndef POCO_DATA_NO_SQL_PARSER
|
|
if (_pImpl->session().shouldParse())
|
|
return hasType(Parser::StatementType::kStmtInsert);
|
|
else return Optional<bool>();
|
|
#else
|
|
return Optional<bool>();
|
|
#endif
|
|
}
|
|
|
|
|
|
inline Optional<bool> Statement::hasUpdate() const
|
|
{
|
|
#ifndef POCO_DATA_NO_SQL_PARSER
|
|
if (_pImpl->session().shouldParse())
|
|
return hasType(Parser::StatementType::kStmtUpdate);
|
|
else return Optional<bool>();
|
|
#else
|
|
return Optional<bool>();
|
|
#endif
|
|
}
|
|
|
|
|
|
inline Optional<bool> Statement::hasDelete() const
|
|
{
|
|
#ifndef POCO_DATA_NO_SQL_PARSER
|
|
if (_pImpl->session().shouldParse())
|
|
return hasType(Parser::StatementType::kStmtDelete);
|
|
else return Optional<bool>();
|
|
#else
|
|
return Optional<bool>();
|
|
#endif
|
|
}
|
|
|
|
|
|
namespace Keywords {
|
|
|
|
|
|
//
|
|
// Manipulators
|
|
//
|
|
|
|
inline void Data_API now(Statement& statement)
|
|
/// Enforces immediate execution of the statement.
|
|
/// If _isAsync flag has been set, execution is invoked asynchronously.
|
|
{
|
|
statement.execute();
|
|
}
|
|
|
|
|
|
inline void Data_API sync(Statement& statement)
|
|
/// Sets the _isAsync flag to false, signalling synchronous execution.
|
|
/// Synchronous execution is default, so specifying this manipulator
|
|
/// only makes sense if async() was called for the statement before.
|
|
{
|
|
statement.setAsync(false);
|
|
}
|
|
|
|
|
|
inline void Data_API async(Statement& statement)
|
|
/// Sets the _async flag to true, signalling asynchronous execution.
|
|
{
|
|
statement.setAsync(true);
|
|
}
|
|
|
|
|
|
inline void Data_API deque(Statement& statement)
|
|
/// Sets the internal storage to std::deque.
|
|
/// std::deque is default storage, so specifying this manipulator
|
|
/// only makes sense if list() or deque() were called for the statement before.
|
|
{
|
|
if (!statement.canModifyStorage())
|
|
throw InvalidAccessException("Storage not modifiable.");
|
|
|
|
statement.setStorage("deque");
|
|
}
|
|
|
|
|
|
inline void Data_API vector(Statement& statement)
|
|
/// Sets the internal storage to std::vector.
|
|
{
|
|
if (!statement.canModifyStorage())
|
|
throw InvalidAccessException("Storage not modifiable.");
|
|
|
|
statement.setStorage("vector");
|
|
}
|
|
|
|
|
|
inline void Data_API list(Statement& statement)
|
|
/// Sets the internal storage to std::list.
|
|
{
|
|
if (!statement.canModifyStorage())
|
|
throw InvalidAccessException("Storage not modifiable.");
|
|
|
|
statement.setStorage("list");
|
|
}
|
|
|
|
|
|
inline void Data_API reset(Statement& statement)
|
|
/// Sets all internal settings to their respective default values.
|
|
{
|
|
if (!statement.canModifyStorage())
|
|
throw InvalidAccessException("Storage not modifiable.");
|
|
|
|
statement.setStorage("deque");
|
|
statement.setAsync(false);
|
|
}
|
|
|
|
|
|
} // namespace Keywords
|
|
|
|
|
|
//
|
|
// inlines
|
|
//
|
|
|
|
inline Statement& Statement::operator , (RowFormatter::Ptr pRowFformatter)
|
|
{
|
|
_pRowFormatter = pRowFformatter;
|
|
return *this;
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (char value)
|
|
{
|
|
return commaPODImpl(value);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (Poco::UInt8 value)
|
|
{
|
|
return commaPODImpl(value);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (Poco::Int8 value)
|
|
{
|
|
return commaPODImpl(value);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (Poco::UInt16 value)
|
|
{
|
|
return commaPODImpl(value);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (Poco::Int16 value)
|
|
{
|
|
return commaPODImpl(value);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (Poco::UInt32 value)
|
|
{
|
|
return commaPODImpl(value);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (Poco::Int32 value)
|
|
{
|
|
return commaPODImpl(value);
|
|
}
|
|
|
|
|
|
#ifndef POCO_INT64_IS_LONG
|
|
inline Statement& Statement::operator , (long value)
|
|
{
|
|
return commaPODImpl(value);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (unsigned long value)
|
|
{
|
|
return commaPODImpl(value);
|
|
}
|
|
#endif
|
|
|
|
|
|
inline Statement& Statement::operator , (Poco::UInt64 value)
|
|
{
|
|
return commaPODImpl(value);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (Poco::Int64 value)
|
|
{
|
|
return commaPODImpl(value);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (double value)
|
|
{
|
|
return commaPODImpl(value);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (float value)
|
|
{
|
|
return commaPODImpl(value);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (bool value)
|
|
{
|
|
return commaPODImpl(value);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (const std::string& value)
|
|
{
|
|
return commaPODImpl(value);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (const char* value)
|
|
{
|
|
return commaPODImpl(std::string(value));
|
|
}
|
|
|
|
|
|
inline void Statement::removeBind(const std::string& name)
|
|
{
|
|
_pImpl->removeBind(name);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (AbstractBinding::Ptr pBind)
|
|
{
|
|
return addBind(pBind);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (AbstractBindingVec& bindVec)
|
|
{
|
|
return addBinding(bindVec, false);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (AbstractExtraction::Ptr pExtract)
|
|
{
|
|
return addExtract(pExtract);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (AbstractExtractionVec& extVec)
|
|
{
|
|
return addExtraction(extVec, false);
|
|
}
|
|
|
|
|
|
inline Statement& Statement::operator , (AbstractExtractionVecVec& extVecVec)
|
|
{
|
|
return addExtractions(extVecVec);
|
|
}
|
|
|
|
|
|
inline Statement::ImplPtr Statement::impl() const
|
|
{
|
|
return _pImpl;
|
|
}
|
|
|
|
|
|
inline const std::string& Statement::toString() const
|
|
{
|
|
return _stmtString = _pImpl->toString();
|
|
}
|
|
|
|
inline const AbstractExtractionVec& Statement::extractions() const
|
|
{
|
|
return _pImpl->extractions();
|
|
}
|
|
|
|
|
|
inline const MetaColumn& Statement::metaColumn(std::size_t pos) const
|
|
{
|
|
return _pImpl->metaColumn(pos);
|
|
}
|
|
|
|
|
|
inline const MetaColumn& Statement::metaColumn(const std::string& name) const
|
|
{
|
|
return _pImpl->metaColumn(name);
|
|
}
|
|
|
|
|
|
inline void Statement::setStorage(const std::string& storage)
|
|
{
|
|
_pImpl->setStorage(storage);
|
|
}
|
|
|
|
|
|
inline std::size_t Statement::affectedRowCount() const
|
|
{
|
|
return static_cast<std::size_t>(_pImpl->affectedRowCount());
|
|
}
|
|
|
|
|
|
inline std::size_t Statement::extractionCount() const
|
|
{
|
|
return _pImpl->extractionCount();
|
|
}
|
|
|
|
|
|
inline std::size_t Statement::columnsExtracted(int dataSet) const
|
|
{
|
|
return _pImpl->columnsExtracted(dataSet);
|
|
}
|
|
|
|
|
|
inline std::size_t Statement::rowsExtracted(int dataSet) const
|
|
{
|
|
return _pImpl->rowsExtracted(dataSet);
|
|
}
|
|
|
|
|
|
inline std::size_t Statement::dataSetCount() const
|
|
{
|
|
return _pImpl->dataSetCount();
|
|
}
|
|
|
|
|
|
inline std::size_t Statement::nextDataSet()
|
|
{
|
|
return _pImpl->activateNextDataSet();
|
|
}
|
|
|
|
|
|
inline std::size_t Statement::previousDataSet()
|
|
{
|
|
return _pImpl->activatePreviousDataSet();
|
|
}
|
|
|
|
|
|
inline bool Statement::hasMoreDataSets() const
|
|
{
|
|
return _pImpl->hasMoreDataSets();
|
|
}
|
|
|
|
|
|
inline Statement::Storage Statement::storage() const
|
|
{
|
|
return static_cast<Storage>(_pImpl->getStorage());
|
|
}
|
|
|
|
|
|
inline bool Statement::canModifyStorage()
|
|
{
|
|
return (0 == extractionCount()) && (initialized() || done());
|
|
}
|
|
|
|
|
|
inline bool Statement::initialized()
|
|
{
|
|
return _pImpl->getState() == StatementImpl::ST_INITIALIZED;
|
|
}
|
|
|
|
|
|
inline bool Statement::paused()
|
|
{
|
|
return _pImpl->getState() == StatementImpl::ST_PAUSED;
|
|
}
|
|
|
|
|
|
inline bool Statement::done()
|
|
{
|
|
return _pImpl->getState() == StatementImpl::ST_DONE;
|
|
}
|
|
|
|
|
|
inline bool Statement::isNull(std::size_t col, std::size_t row) const
|
|
{
|
|
return _pImpl->isNull(col, row);
|
|
}
|
|
|
|
|
|
inline bool Statement::isBulkExtraction() const
|
|
{
|
|
return _pImpl->isBulkExtraction();
|
|
}
|
|
|
|
|
|
inline bool Statement::isAsync() const
|
|
{
|
|
return _async;
|
|
}
|
|
|
|
|
|
inline Statement::State Statement::state() const
|
|
{
|
|
return _pImpl->getState();
|
|
}
|
|
|
|
|
|
inline void Statement::setRowFormatter(RowFormatter::Ptr pRowFormatter)
|
|
{
|
|
_pRowFormatter = pRowFormatter;
|
|
}
|
|
|
|
|
|
inline const RowFormatter::Ptr& Statement::getRowFormatter()
|
|
{
|
|
if (!_pRowFormatter) _pRowFormatter = new SimpleRowFormatter;
|
|
return _pRowFormatter;
|
|
}
|
|
|
|
|
|
inline void swap(Statement& s1, Statement& s2) noexcept
|
|
{
|
|
s1.swap(s2);
|
|
}
|
|
|
|
|
|
} } // namespace Poco::Data
|
|
|
|
|
|
namespace std
|
|
{
|
|
template<>
|
|
inline void swap<Poco::Data::Statement>(Poco::Data::Statement& s1, Poco::Data::Statement& s2) noexcept
|
|
/// Full template specalization of std:::swap for Statement
|
|
{
|
|
s1.swap(s2);
|
|
}
|
|
}
|
|
|
|
|
|
#endif // Data_Statement_INCLUDED
|