mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-28 11:31:53 +01:00
feat(Data::Session): add 'sqlParse' feature #4230
This commit is contained in:
@@ -55,7 +55,8 @@ public:
|
|||||||
_storage(std::string("deque")),
|
_storage(std::string("deque")),
|
||||||
_bulk(false),
|
_bulk(false),
|
||||||
_emptyStringIsNull(false),
|
_emptyStringIsNull(false),
|
||||||
_forceEmptyString(false)
|
_forceEmptyString(false),
|
||||||
|
_sqlParse(true)
|
||||||
/// Creates the AbstractSessionImpl.
|
/// Creates the AbstractSessionImpl.
|
||||||
///
|
///
|
||||||
/// Adds "storage" property and sets the default internal storage container
|
/// Adds "storage" property and sets the default internal storage container
|
||||||
@@ -108,6 +109,10 @@ public:
|
|||||||
addFeature("forceEmptyString",
|
addFeature("forceEmptyString",
|
||||||
&AbstractSessionImpl<C>::setForceEmptyString,
|
&AbstractSessionImpl<C>::setForceEmptyString,
|
||||||
&AbstractSessionImpl<C>::getForceEmptyString);
|
&AbstractSessionImpl<C>::getForceEmptyString);
|
||||||
|
|
||||||
|
addFeature("sqlParse",
|
||||||
|
&AbstractSessionImpl<C>::setSQLParse,
|
||||||
|
&AbstractSessionImpl<C>::getSQLParse);
|
||||||
}
|
}
|
||||||
|
|
||||||
~AbstractSessionImpl()
|
~AbstractSessionImpl()
|
||||||
@@ -257,7 +262,7 @@ public:
|
|||||||
return _emptyStringIsNull;
|
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.
|
/// Sets the behavior regarding empty variable length strings.
|
||||||
/// Those are treated as NULL by Oracle and as empty string by
|
/// Those are treated as NULL by Oracle and as empty string by
|
||||||
/// most other databases.
|
/// most other databases.
|
||||||
@@ -278,6 +283,25 @@ public:
|
|||||||
return _forceEmptyString;
|
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:
|
protected:
|
||||||
void addFeature(const std::string& name, FeatureSetter setter, FeatureGetter getter)
|
void addFeature(const std::string& name, FeatureSetter setter, FeatureGetter getter)
|
||||||
/// Adds a feature to the map of supported features.
|
/// Adds a feature to the map of supported features.
|
||||||
@@ -325,6 +349,7 @@ private:
|
|||||||
bool _bulk;
|
bool _bulk;
|
||||||
bool _emptyStringIsNull;
|
bool _emptyStringIsNull;
|
||||||
bool _forceEmptyString;
|
bool _forceEmptyString;
|
||||||
|
bool _sqlParse;
|
||||||
Poco::Any _handle;
|
Poco::Any _handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ public:
|
|||||||
/// Returns true if session has transaction capabilities.
|
/// Returns true if session has transaction capabilities.
|
||||||
|
|
||||||
virtual bool isTransaction() const = 0;
|
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;
|
virtual void setTransactionIsolation(Poco::UInt32) = 0;
|
||||||
/// Sets the transaction isolation level.
|
/// Sets the transaction isolation level.
|
||||||
@@ -149,6 +149,9 @@ public:
|
|||||||
bool isAutocommit() const;
|
bool isAutocommit() const;
|
||||||
/// Returns true if autocommit is on, false otherwise.
|
/// 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;
|
virtual bool hasFeature(const std::string& name) const = 0;
|
||||||
/// Returns true if session has the named feature.
|
/// 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
|
} } // namespace Poco::Data
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -578,7 +578,9 @@ inline const std::string& Statement::parseError()
|
|||||||
inline Optional<bool> Statement::isSelect() const
|
inline Optional<bool> Statement::isSelect() const
|
||||||
{
|
{
|
||||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
#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
|
#else
|
||||||
return Optional<bool>();
|
return Optional<bool>();
|
||||||
#endif
|
#endif
|
||||||
@@ -588,7 +590,9 @@ inline Optional<bool> Statement::isSelect() const
|
|||||||
inline Optional<bool> Statement::isInsert() const
|
inline Optional<bool> Statement::isInsert() const
|
||||||
{
|
{
|
||||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
#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
|
#else
|
||||||
return Optional<bool>();
|
return Optional<bool>();
|
||||||
#endif
|
#endif
|
||||||
@@ -598,7 +602,9 @@ inline Optional<bool> Statement::isInsert() const
|
|||||||
inline Optional<bool> Statement::isUpdate() const
|
inline Optional<bool> Statement::isUpdate() const
|
||||||
{
|
{
|
||||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
#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
|
#else
|
||||||
return Optional<bool>();
|
return Optional<bool>();
|
||||||
#endif
|
#endif
|
||||||
@@ -608,7 +614,9 @@ inline Optional<bool> Statement::isUpdate() const
|
|||||||
inline Optional<bool> Statement::isDelete() const
|
inline Optional<bool> Statement::isDelete() const
|
||||||
{
|
{
|
||||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
#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
|
#else
|
||||||
return Optional<bool>();
|
return Optional<bool>();
|
||||||
#endif
|
#endif
|
||||||
@@ -618,7 +626,9 @@ inline Optional<bool> Statement::isDelete() const
|
|||||||
inline Optional<bool> Statement::hasSelect() const
|
inline Optional<bool> Statement::hasSelect() const
|
||||||
{
|
{
|
||||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
#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
|
#else
|
||||||
return Optional<bool>();
|
return Optional<bool>();
|
||||||
#endif
|
#endif
|
||||||
@@ -628,7 +638,9 @@ inline Optional<bool> Statement::hasSelect() const
|
|||||||
inline Optional<bool> Statement::hasInsert() const
|
inline Optional<bool> Statement::hasInsert() const
|
||||||
{
|
{
|
||||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
#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
|
#else
|
||||||
return Optional<bool>();
|
return Optional<bool>();
|
||||||
#endif
|
#endif
|
||||||
@@ -638,7 +650,9 @@ inline Optional<bool> Statement::hasInsert() const
|
|||||||
inline Optional<bool> Statement::hasUpdate() const
|
inline Optional<bool> Statement::hasUpdate() const
|
||||||
{
|
{
|
||||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
#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
|
#else
|
||||||
return Optional<bool>();
|
return Optional<bool>();
|
||||||
#endif
|
#endif
|
||||||
@@ -648,7 +662,9 @@ inline Optional<bool> Statement::hasUpdate() const
|
|||||||
inline Optional<bool> Statement::hasDelete() const
|
inline Optional<bool> Statement::hasDelete() const
|
||||||
{
|
{
|
||||||
#ifndef POCO_DATA_NO_SQL_PARSER
|
#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
|
#else
|
||||||
return Optional<bool>();
|
return Optional<bool>();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -259,6 +259,9 @@ protected:
|
|||||||
SessionImpl& session();
|
SessionImpl& session();
|
||||||
/// Rteurns session associated with this statement.
|
/// Rteurns session associated with this statement.
|
||||||
|
|
||||||
|
const SessionImpl& session() const;
|
||||||
|
/// Rteurns session associated with this statement.
|
||||||
|
|
||||||
virtual AbstractBinding::BinderPtr binder() = 0;
|
virtual AbstractBinding::BinderPtr binder() = 0;
|
||||||
/// Returns the concrete binder used by the statement.
|
/// 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)
|
inline void StatementImpl::setStorage(Storage storage)
|
||||||
{
|
{
|
||||||
_storage = storage;
|
_storage = storage;
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ void Statement::formatQuery()
|
|||||||
void Statement::checkBeginTransaction()
|
void Statement::checkBeginTransaction()
|
||||||
{
|
{
|
||||||
SessionImpl& session = _pImpl->session();
|
SessionImpl& session = _pImpl->session();
|
||||||
if (!session.isAutocommit() && !session.isTransaction())
|
if (!session.isAutocommit() && !session.isTransaction() && session.shouldParse())
|
||||||
{
|
{
|
||||||
auto result = parse();
|
auto result = parse();
|
||||||
if (result.isSpecified() && result.value() && !isSelect().value())
|
if (result.isSpecified() && result.value() && !isSelect().value())
|
||||||
|
|||||||
@@ -1460,8 +1460,7 @@ void DataTest::testSQLParse()
|
|||||||
assertTrue (!stmt.isDelete().value());
|
assertTrue (!stmt.isDelete().value());
|
||||||
assertTrue (!stmt.hasDelete().value());
|
assertTrue (!stmt.hasDelete().value());
|
||||||
|
|
||||||
Session sess2(SessionFactory::instance().create("test", "cs"));
|
stmt.reset();
|
||||||
stmt.reset(sess2);
|
|
||||||
stmt = (sess << "INSERT INTO Test VALUES ('1', 2, 3.5);"
|
stmt = (sess << "INSERT INTO Test VALUES ('1', 2, 3.5);"
|
||||||
"SELECT * FROM Test WHERE First = ?;"
|
"SELECT * FROM Test WHERE First = ?;"
|
||||||
"UPDATE Test SET value=1 WHERE First = '1';"
|
"UPDATE Test SET value=1 WHERE First = '1';"
|
||||||
@@ -1480,6 +1479,29 @@ void DataTest::testSQLParse()
|
|||||||
assertTrue (!stmt.isDelete().value());
|
assertTrue (!stmt.isDelete().value());
|
||||||
assertTrue (stmt.hasDelete().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
|
#endif // POCO_DATA_NO_SQL_PARSER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,5 +52,5 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
cd "$basedir"/"$library"/testsuite/bin/"$OSNAME"/"$OSARCH"/ || exit
|
cd "$basedir"/"$library"/testsuite/bin/"$OSNAME"/"$OSARCH"/ || exit
|
||||||
testrunner -all
|
./testrunner -all
|
||||||
testrunnerd -all
|
./testrunnerd -all
|
||||||
|
|||||||
Reference in New Issue
Block a user