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:
Alex Fabijanic
2023-11-01 00:25:21 +01:00
parent e174be8660
commit 6dad8502d3
45 changed files with 949 additions and 196 deletions

View File

@@ -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())
{