mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-13 10:32:57 +01:00
feat(Data::Session): add 'sqlParse' feature #4230
This commit is contained in:
parent
79e54d88ba
commit
afd9c8c408
@ -55,7 +55,8 @@ public:
|
||||
_storage(std::string("deque")),
|
||||
_bulk(false),
|
||||
_emptyStringIsNull(false),
|
||||
_forceEmptyString(false)
|
||||
_forceEmptyString(false),
|
||||
_sqlParse(true)
|
||||
/// Creates the AbstractSessionImpl.
|
||||
///
|
||||
/// Adds "storage" property and sets the default internal storage container
|
||||
@ -108,6 +109,10 @@ public:
|
||||
addFeature("forceEmptyString",
|
||||
&AbstractSessionImpl<C>::setForceEmptyString,
|
||||
&AbstractSessionImpl<C>::getForceEmptyString);
|
||||
|
||||
addFeature("sqlParse",
|
||||
&AbstractSessionImpl<C>::setSQLParse,
|
||||
&AbstractSessionImpl<C>::getSQLParse);
|
||||
}
|
||||
|
||||
~AbstractSessionImpl()
|
||||
@ -257,7 +262,7 @@ public:
|
||||
return _emptyStringIsNull;
|
||||
}
|
||||
|
||||
void setForceEmptyString(const std::string& name, bool forceEmptyString)
|
||||
void setForceEmptyString(const std::string&, bool forceEmptyString)
|
||||
/// Sets the behavior regarding empty variable length strings.
|
||||
/// Those are treated as NULL by Oracle and as empty string by
|
||||
/// most other databases.
|
||||
@ -278,6 +283,25 @@ public:
|
||||
return _forceEmptyString;
|
||||
}
|
||||
|
||||
void setSQLParse(const std::string&, bool doParse)
|
||||
/// Enables the SQL parsing. Value must be of type bool.
|
||||
/// When SQL parsing is enabled (default), the Statement attempts
|
||||
/// to parse the SQL prior to executing it. The parsing is done
|
||||
/// in non-autocommit mode only, with purpose to determine the
|
||||
/// type of query and whether to start the transaction automatically.
|
||||
///
|
||||
/// See Statement documentation for more information.
|
||||
{
|
||||
_sqlParse = doParse;
|
||||
}
|
||||
|
||||
|
||||
bool getSQLParse(const std::string& name = "") const
|
||||
/// Returns the value of the SQL parsing flag.
|
||||
{
|
||||
return _sqlParse;
|
||||
}
|
||||
|
||||
protected:
|
||||
void addFeature(const std::string& name, FeatureSetter setter, FeatureGetter getter)
|
||||
/// Adds a feature to the map of supported features.
|
||||
@ -325,6 +349,7 @@ private:
|
||||
bool _bulk;
|
||||
bool _emptyStringIsNull;
|
||||
bool _forceEmptyString;
|
||||
bool _sqlParse;
|
||||
Poco::Any _handle;
|
||||
};
|
||||
|
||||
|
@ -118,7 +118,7 @@ public:
|
||||
/// Returns true if session has transaction capabilities.
|
||||
|
||||
virtual bool isTransaction() const = 0;
|
||||
/// Returns true iff a transaction is a transaction is in progress, false otherwise.
|
||||
/// Returns true iff a transaction is in progress, false otherwise.
|
||||
|
||||
virtual void setTransactionIsolation(Poco::UInt32) = 0;
|
||||
/// Sets the transaction isolation level.
|
||||
@ -149,6 +149,9 @@ public:
|
||||
bool isAutocommit() const;
|
||||
/// Returns true if autocommit is on, false otherwise.
|
||||
|
||||
bool shouldParse() const;
|
||||
/// Returns true if SQL parser is enabled, false otherwise.
|
||||
|
||||
virtual bool hasFeature(const std::string& name) const = 0;
|
||||
/// Returns true if session has the named feature.
|
||||
|
||||
@ -247,6 +250,12 @@ inline bool SessionImpl::isAutocommit() const
|
||||
}
|
||||
|
||||
|
||||
inline bool SessionImpl::shouldParse() const
|
||||
{
|
||||
return hasFeature("sqlParse") && getFeature("sqlParse");
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::Data
|
||||
|
||||
|
||||
|
@ -578,7 +578,9 @@ inline const std::string& Statement::parseError()
|
||||
inline Optional<bool> Statement::isSelect() const
|
||||
{
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
return isType(Parser::StatementType::kStmtSelect);
|
||||
if (_pImpl->session().shouldParse())
|
||||
return isType(Parser::StatementType::kStmtSelect);
|
||||
else return Optional<bool>();
|
||||
#else
|
||||
return Optional<bool>();
|
||||
#endif
|
||||
@ -588,7 +590,9 @@ inline Optional<bool> Statement::isSelect() const
|
||||
inline Optional<bool> Statement::isInsert() const
|
||||
{
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
return isType(Parser::StatementType::kStmtInsert);
|
||||
if (_pImpl->session().shouldParse())
|
||||
return isType(Parser::StatementType::kStmtInsert);
|
||||
else return Optional<bool>();
|
||||
#else
|
||||
return Optional<bool>();
|
||||
#endif
|
||||
@ -598,7 +602,9 @@ inline Optional<bool> Statement::isInsert() const
|
||||
inline Optional<bool> Statement::isUpdate() const
|
||||
{
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
return isType(Parser::StatementType::kStmtUpdate);
|
||||
if (_pImpl->session().shouldParse())
|
||||
return isType(Parser::StatementType::kStmtUpdate);
|
||||
else return Optional<bool>();
|
||||
#else
|
||||
return Optional<bool>();
|
||||
#endif
|
||||
@ -608,7 +614,9 @@ inline Optional<bool> Statement::isUpdate() const
|
||||
inline Optional<bool> Statement::isDelete() const
|
||||
{
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
return isType(Parser::StatementType::kStmtDelete);
|
||||
if (_pImpl->session().shouldParse())
|
||||
return isType(Parser::StatementType::kStmtDelete);
|
||||
else return Optional<bool>();
|
||||
#else
|
||||
return Optional<bool>();
|
||||
#endif
|
||||
@ -618,7 +626,9 @@ inline Optional<bool> Statement::isDelete() const
|
||||
inline Optional<bool> Statement::hasSelect() const
|
||||
{
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
return hasType(Parser::StatementType::kStmtSelect);
|
||||
if (_pImpl->session().shouldParse())
|
||||
return hasType(Parser::StatementType::kStmtSelect);
|
||||
else return Optional<bool>();
|
||||
#else
|
||||
return Optional<bool>();
|
||||
#endif
|
||||
@ -628,7 +638,9 @@ inline Optional<bool> Statement::hasSelect() const
|
||||
inline Optional<bool> Statement::hasInsert() const
|
||||
{
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
return hasType(Parser::StatementType::kStmtInsert);
|
||||
if (_pImpl->session().shouldParse())
|
||||
return hasType(Parser::StatementType::kStmtInsert);
|
||||
else return Optional<bool>();
|
||||
#else
|
||||
return Optional<bool>();
|
||||
#endif
|
||||
@ -638,7 +650,9 @@ inline Optional<bool> Statement::hasInsert() const
|
||||
inline Optional<bool> Statement::hasUpdate() const
|
||||
{
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
return hasType(Parser::StatementType::kStmtUpdate);
|
||||
if (_pImpl->session().shouldParse())
|
||||
return hasType(Parser::StatementType::kStmtUpdate);
|
||||
else return Optional<bool>();
|
||||
#else
|
||||
return Optional<bool>();
|
||||
#endif
|
||||
@ -648,7 +662,9 @@ inline Optional<bool> Statement::hasUpdate() const
|
||||
inline Optional<bool> Statement::hasDelete() const
|
||||
{
|
||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
||||
return hasType(Parser::StatementType::kStmtDelete);
|
||||
if (_pImpl->session().shouldParse())
|
||||
return hasType(Parser::StatementType::kStmtDelete);
|
||||
else return Optional<bool>();
|
||||
#else
|
||||
return Optional<bool>();
|
||||
#endif
|
||||
|
@ -259,6 +259,9 @@ protected:
|
||||
SessionImpl& session();
|
||||
/// Rteurns session associated with this statement.
|
||||
|
||||
const SessionImpl& session() const;
|
||||
/// Rteurns session associated with this statement.
|
||||
|
||||
virtual AbstractBinding::BinderPtr binder() = 0;
|
||||
/// Returns the concrete binder used by the statement.
|
||||
|
||||
@ -512,6 +515,12 @@ inline SessionImpl& StatementImpl::session()
|
||||
}
|
||||
|
||||
|
||||
inline const SessionImpl& StatementImpl::session() const
|
||||
{
|
||||
return _rSession;
|
||||
}
|
||||
|
||||
|
||||
inline void StatementImpl::setStorage(Storage storage)
|
||||
{
|
||||
_storage = storage;
|
||||
|
@ -232,7 +232,7 @@ void Statement::formatQuery()
|
||||
void Statement::checkBeginTransaction()
|
||||
{
|
||||
SessionImpl& session = _pImpl->session();
|
||||
if (!session.isAutocommit() && !session.isTransaction())
|
||||
if (!session.isAutocommit() && !session.isTransaction() && session.shouldParse())
|
||||
{
|
||||
auto result = parse();
|
||||
if (result.isSpecified() && result.value() && !isSelect().value())
|
||||
|
@ -1460,8 +1460,7 @@ void DataTest::testSQLParse()
|
||||
assertTrue (!stmt.isDelete().value());
|
||||
assertTrue (!stmt.hasDelete().value());
|
||||
|
||||
Session sess2(SessionFactory::instance().create("test", "cs"));
|
||||
stmt.reset(sess2);
|
||||
stmt.reset();
|
||||
stmt = (sess << "INSERT INTO Test VALUES ('1', 2, 3.5);"
|
||||
"SELECT * FROM Test WHERE First = ?;"
|
||||
"UPDATE Test SET value=1 WHERE First = '1';"
|
||||
@ -1480,6 +1479,29 @@ void DataTest::testSQLParse()
|
||||
assertTrue (!stmt.isDelete().value());
|
||||
assertTrue (stmt.hasDelete().value());
|
||||
|
||||
sess.setFeature("sqlParse", false);
|
||||
assertTrue (!sess.getFeature("sqlParse"));
|
||||
|
||||
stmt.reset();
|
||||
stmt = (sess << "INSERT INTO Test VALUES ('1', 2, 3.5);"
|
||||
"SELECT * FROM Test WHERE First = ?;"
|
||||
"UPDATE Test SET value=1 WHERE First = '1';"
|
||||
"DELETE FROM Test WHERE First = ?;"
|
||||
"DROP TABLE table_name;"
|
||||
"ALTER TABLE mytable DROP COLUMN IF EXISTS mycolumn;"
|
||||
"PREPARE prep_inst FROM 'INSERT INTO test VALUES (?, ?, ?)';"
|
||||
"EXECUTE prep_inst(1, 2, 3);");
|
||||
|
||||
stmt.execute();
|
||||
assertTrue (!stmt.isSelect().isSpecified());
|
||||
assertTrue (!stmt.hasSelect().isSpecified());
|
||||
assertTrue (!stmt.isUpdate().isSpecified());
|
||||
assertTrue (!stmt.hasUpdate().isSpecified());
|
||||
assertTrue (!stmt.isInsert().isSpecified());
|
||||
assertTrue (!stmt.hasInsert().isSpecified());
|
||||
assertTrue (!stmt.isDelete().isSpecified());
|
||||
assertTrue (!stmt.hasDelete().isSpecified());
|
||||
|
||||
#endif // POCO_DATA_NO_SQL_PARSER
|
||||
}
|
||||
|
||||
|
@ -52,5 +52,5 @@ else
|
||||
fi
|
||||
|
||||
cd "$basedir"/"$library"/testsuite/bin/"$OSNAME"/"$OSARCH"/ || exit
|
||||
testrunner -all
|
||||
testrunnerd -all
|
||||
./testrunner -all
|
||||
./testrunnerd -all
|
||||
|
Loading…
Reference in New Issue
Block a user