///////////////////////////////////////////////////////////////////////////////////////////
实在是没看出来这样有什么优势,为了记录是否走过某个path?
Query::execute(const SQLString& str)这里看到了递归操作,难道是为了辅助递归?
总感觉这里越搞越复杂,,,
///////////////////////////////////////////////////////////////////////////////////////////
/// \brief A template for setting a flag on a variable as long as the
/// object that set it is in scope. Flag resets when object goes
/// out of scope. Works on anything that looks like bool.
template <class T = bool>
class AutoFlag
{
public:
/// \brief Constructor: sets ref to true.
AutoFlag(T& ref) :
referent_(ref)
{
referent_ = true;
}
/// \brief Destructor: sets referent passed to ctor to false.
~AutoFlag()
{
referent_ = false;
}
private:
T& referent_;
};
///////////////////////////////////////////////////////////////////////////////////////////
ResNSel
Query::execute(const SQLString& str)
{
if ((def.size() == 1) && !def.processing_) {
// . The
// auto-reset flag is required because we'll end up back in this
// function once the query string is built, but we need to take
// the 'else' path to avoid an infinite loop.
AutoFlag<> af(def.processing_);
return execute(SQLQueryParms() << str);
}
else {
// Take str to be the entire query string
return execute(str.c_str(), str.length());
}
}
ResNSel
Query::execute(const char* str)
{
return execute(SQLString(str));
}
ResNSel
Query::execute(const char* str, size_t len)
{
if (lock()) {
success_ = false;
if (throw_exceptions()) {
throw LockFailed();
}
else {
return ResNSel();
}
}
success_ = !mysql_real_query(&conn_->mysql_, str, len);
unlock();
if (success_) {
return ResNSel(conn_);
}
else if (throw_exceptions()) {
throw BadQuery(error());
}
else {
return ResNSel();
}
}