mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-28 03:20:11 +01:00
fix(Data):
* make bool Session::isTransaction() return Poco::Optional * move parsing to Statement * SQLParser make build * other fixes and improvemets #4230
This commit is contained in:
@@ -28,6 +28,9 @@ namespace Data {
|
||||
|
||||
|
||||
Statement::Statement(StatementImpl::Ptr pImpl):
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
_pParseResult(new Parser::SQLParserResult()),
|
||||
#endif
|
||||
_pImpl(pImpl),
|
||||
_async(false)
|
||||
{
|
||||
@@ -43,24 +46,42 @@ Statement::Statement(Session& session):
|
||||
|
||||
|
||||
Statement::Statement(const Statement& stmt):
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
_pParseResult(stmt._pParseResult),
|
||||
#endif
|
||||
_pImpl(stmt._pImpl),
|
||||
_async(stmt._async),
|
||||
_pResult(stmt._pResult),
|
||||
_pAsyncExec(stmt._pAsyncExec),
|
||||
_arguments(stmt._arguments),
|
||||
_pRowFormatter(stmt._pRowFormatter)
|
||||
_pRowFormatter(stmt._pRowFormatter),
|
||||
_stmtString(stmt._stmtString),
|
||||
_parseError(stmt._parseError)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Statement::Statement(Statement&& stmt) noexcept:
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
_pParseResult(std::move(stmt._pParseResult)),
|
||||
#endif
|
||||
_pImpl(std::move(stmt._pImpl)),
|
||||
_async(std::move(stmt._async)),
|
||||
_pResult(std::move(stmt._pResult)),
|
||||
_pAsyncExec(std::move(stmt._pAsyncExec)),
|
||||
_arguments(std::move(stmt._arguments)),
|
||||
_pRowFormatter(std::move(stmt._pRowFormatter))
|
||||
_pRowFormatter(std::move(stmt._pRowFormatter)),
|
||||
_stmtString(std::move(stmt._stmtString)),
|
||||
_parseError(std::move(stmt._parseError))
|
||||
{
|
||||
stmt._pImpl = nullptr;
|
||||
stmt._async = false;
|
||||
stmt._pResult = nullptr;
|
||||
stmt._pAsyncExec = nullptr;
|
||||
stmt._arguments.clear();
|
||||
stmt._pRowFormatter = nullptr;
|
||||
_stmtString.clear();
|
||||
_parseError.clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -79,12 +100,25 @@ Statement& Statement::operator = (const Statement& stmt)
|
||||
|
||||
Statement& Statement::operator = (Statement&& stmt) noexcept
|
||||
{
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
_pParseResult = std::move(stmt._pParseResult);
|
||||
#endif
|
||||
_pImpl = std::move(stmt._pImpl);
|
||||
stmt._pImpl = nullptr;
|
||||
_async = std::move(stmt._async);
|
||||
stmt._async = false;
|
||||
_pResult = std::move(stmt._pResult);
|
||||
stmt._pResult = nullptr;
|
||||
_pAsyncExec = std::move(stmt._pAsyncExec);
|
||||
stmt._pAsyncExec = nullptr;
|
||||
_arguments = std::move(stmt._arguments);
|
||||
stmt._arguments.clear();
|
||||
_pRowFormatter = std::move(stmt._pRowFormatter);
|
||||
stmt._pRowFormatter = nullptr;
|
||||
_stmtString = std::move(stmt._stmtString);
|
||||
_stmtString.clear();
|
||||
_parseError = std::move(stmt._parseError);
|
||||
_parseError.clear();
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -92,13 +126,17 @@ Statement& Statement::operator = (Statement&& stmt) noexcept
|
||||
void Statement::swap(Statement& other) noexcept
|
||||
{
|
||||
using std::swap;
|
||||
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
swap(_pParseResult, other._pParseResult);
|
||||
#endif
|
||||
swap(_pImpl, other._pImpl);
|
||||
swap(_async, other._async);
|
||||
swap(_pAsyncExec, other._pAsyncExec);
|
||||
swap(_pResult, other._pResult);
|
||||
swap(_pAsyncExec, other._pAsyncExec);
|
||||
_arguments.swap(other._arguments);
|
||||
swap(_pRowFormatter, other._pRowFormatter);
|
||||
swap(_stmtString, other._stmtString);
|
||||
swap(_parseError, other._parseError);
|
||||
}
|
||||
|
||||
|
||||
@@ -110,17 +148,107 @@ Statement& Statement::reset(Session& session)
|
||||
}
|
||||
|
||||
|
||||
Statement& Statement::reset()
|
||||
{
|
||||
Statement stmt(_pImpl->session().createStatementImpl());
|
||||
swap(stmt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::size_t Statement::statementsCount() const
|
||||
{
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
return _pParseResult->size();
|
||||
#else
|
||||
return 0u;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Optional<bool> Statement::parse()
|
||||
{
|
||||
Optional<bool> result;
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
if (_stmtString.empty()) toString();
|
||||
if (!_stmtString.empty())
|
||||
{
|
||||
_pParseResult->reset();
|
||||
Parser::SQLParser::parse(_stmtString, _pParseResult.get());
|
||||
result = _pParseResult->isValid();
|
||||
if (!result.value())
|
||||
{
|
||||
Poco::format(_parseError, "%s (line %d, pos %d)",
|
||||
std::string(_pParseResult->errorMsg()),
|
||||
_pParseResult->errorLine(),
|
||||
_pParseResult->errorColumn());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
|
||||
bool Statement::isType(Parser::StatementType type) const
|
||||
{
|
||||
std::size_t sz = _pParseResult->size();
|
||||
if (sz)
|
||||
{
|
||||
for (int i = 0; i < sz; ++i)
|
||||
{
|
||||
if (_pParseResult->getStatement(i)->type() != type)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Statement::hasType(Parser::StatementType type) const
|
||||
{
|
||||
for (int i = 0; i < _pParseResult->size(); ++i)
|
||||
{
|
||||
if (_pParseResult->getStatement(i)->type() == type)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // POCO_DATA_NO_SQL_PARSER
|
||||
|
||||
|
||||
void Statement::formatQuery()
|
||||
{
|
||||
if (_arguments.size())
|
||||
{
|
||||
_pImpl->formatSQL(_arguments);
|
||||
_arguments.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Statement::checkBeginTransaction()
|
||||
{
|
||||
SessionImpl& session = _pImpl->session();
|
||||
if (!session.isAutocommit() && !session.isTransaction())
|
||||
{
|
||||
auto result = parse();
|
||||
if (result.isSpecified() && result.value() && !isSelect().value())
|
||||
session.begin();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::size_t Statement::execute(bool reset)
|
||||
{
|
||||
Mutex::ScopedLock lock(_mutex);
|
||||
bool isDone = done();
|
||||
if (initialized() || paused() || isDone)
|
||||
{
|
||||
if (_arguments.size())
|
||||
{
|
||||
_pImpl->formatSQL(_arguments);
|
||||
_arguments.clear();
|
||||
}
|
||||
formatQuery();
|
||||
checkBeginTransaction();
|
||||
|
||||
if (!isAsync())
|
||||
{
|
||||
@@ -136,12 +264,15 @@ std::size_t Statement::execute(bool reset)
|
||||
else throw InvalidAccessException("Statement still executing.");
|
||||
}
|
||||
|
||||
|
||||
void Statement::executeDirect(const std::string& query)
|
||||
{
|
||||
Mutex::ScopedLock lock(_mutex);
|
||||
bool isDone = done();
|
||||
if (initialized() || paused() || isDone)
|
||||
{
|
||||
formatQuery();
|
||||
checkBeginTransaction();
|
||||
|
||||
if (!isAsync())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user