这是一个通用SQL执行函数的安全实现吗?

时间:2016-04-20 15:56:08

标签: c++ mysql pointers c++11

假设使用MySQL查询数据库的以下通用函数实现:

 bool execute(const sql::SQLString query, std::vector<sql::ResultSet*> &results)
 {
    // ConnectionPool holds premade connections to the database
    sql::Connection* conn = ConnectionPool::getInstance()::getConnection();
    std::unique_ptr<sql::Statement> stmt;
    bool success = false;

    try
    {
       stmt.reset( conn->createStatement() );
       stmt->execute( query );

       do
       {
          results.push_back( stmt->getResultSet() );
       } while ( stmt->getMoreResults() )

       success = true;
    }
    catch ( ... )
    {
       // Other catch() statements are not a part of this question
       std::cerr << "Exception caught!" << std::endl;
       success = false;
    }

    conn->commit();
    ConnectionPool::getInstance()::returnConnection( conn );

    return success;
 }

根据this example检索查询结果,需要显式删除ResultSet。关于上面的实现,这是否意味着ResultSet指针的向量是安全的(即,它们指向的对象不会被删除创建语句删除)?

此外,我是否正在通过此实施做一些无法形容的邪恶?

1 个答案:

答案 0 :(得分:0)

以下实施更安全。这是因为ResultSet绑定到Connection而不是Statement。如果在读取结果之前关闭,销毁或用于其他目的的连接,ResultSet对象可能会失效并导致中止条件。让调用函数自己处理Connection是更安全的。

请注意,更好的实施方式是sql::Connection*参数为std::unique_ptr< sql::Connection >&,但我的个人需求决定了目前无法完成此操作。

 bool execute(sql::Connection *conn, const sql::SQLString query, std::vector< std::unique_ptr<sql::ResultSet> > &results)
 {
    std::unique_ptr<sql::Statement> stmt;
    bool success = false;

    try
    {
       stmt.reset( conn->createStatement() );
       stmt->execute( query );

       do
       {
          results.emplace_back( stmt->getResultSet() );
       } while ( stmt->getMoreResults() )

       success = true;
    }
    catch ( ... )
    {
       // Other catch() statements are not a part of this question
       std::cerr << "Exception caught!" << std::endl;
       success = false;
    }

    conn->commit();
    return success;
 }