C ++ MySQL ++删除查询语句脑部杀手问题

时间:2011-02-09 23:27:47

标签: c++ mysql++

我对C ++中的MySQL ++连接器比较陌生,并且已经有了一个非常讨厌的问题!

我设法让存储过程正常工作,但是我遇到了删除语句的问题。我看上去很高,没有找到带有例子的文档。

首先我想可能代码需要在调用存储过程后释放查询/连接结果,但当然MySQL ++没有free_result方法......或者是吗?

无论如何,这就是我所拥有的:

#include <iostream>
#include <stdio.h>
#include <queue>
#include <deque>
#include <sys/stat.h>
#include <mysql++/mysql++.h>
#include <boost/thread/thread.hpp>
#include "RepositoryQueue.h"

using namespace boost;
using namespace mysqlpp;

class RepositoryChecker
{
private:
    bool _isRunning;
Connection _con;
public:
RepositoryChecker()
{
    try
    {
        this->_con = Connection(false);
        this->_con.set_option(new MultiStatementsOption(true));
        this->_con.set_option(new ReconnectOption(true));
        this->_con.connect("**", "***", "***", "***");

        this->ChangeRunningState(true);
    }
    catch(const Exception& e)
    {
        this->ChangeRunningState(false);
    }
}
/**
* Thread method which runs and creates the repositories
*/
void CheckRepositoryQueues()
{
    //while(this->IsRunning())
    //{
        std::queue<RepositoryQueue> queues = this->GetQueue();

        if(queues.size() > 0)
        {
            while(!queues.empty())
            {
                RepositoryQueue &q = queues.front();
                char cmd[256];
                sprintf(cmd, "svnadmin create /home/svn/%s/%s/%s", q.GetPublicStatus().c_str(),
                    q.GetUsername().c_str(), q.GetRepositoryName().c_str());
                    if(this->DeleteQueuedRepository(q.GetQueueId()))
                    {
                        printf("query deleted?\n");
                    }
                    printf("Repository created!\n");
                queues.pop();
            }
        }
        boost::this_thread::sleep(boost::posix_time::milliseconds(500));
    //}
}
protected:
/**
* Gets the latest queue of repositories from the database
* and returns them inside a cool queue defined with the 
* RepositoryQueue class.
*/
std::queue<RepositoryQueue> GetQueue()
{
    std::queue<RepositoryQueue> queues;

    Query query = this->_con.query("CALL sp_GetRepositoryQueue();");
    StoreQueryResult result = query.store();
    RepositoryQueue rQ;

    if(result.num_rows() > 0)
    {
        for(unsigned int i = 0;i < result.num_rows(); ++i)
        {
            rQ = RepositoryQueue((unsigned int)result[i][0],
                                (unsigned int)result[i][1],
                                (String)result[i][2],
                                (String)result[i][3],
                                (String)result[i][4],
                                (bool)result[i][5]);
            queues.push(rQ);
        }
    }

    return queues;
}
/**
* Allows the thread to be shut off.
*/
void ChangeRunningState(bool isRunning)
{
    this->_isRunning = isRunning;
}
/**
* Returns the running value of the active thread.
*/
bool IsRunning()
{
    return this->_isRunning;
}
/**
* Deletes the repository from the mysql queue table. This is
* only called once it has been created.
*/
bool DeleteQueuedRepository(unsigned int id)
{
    char cmd[256];
    sprintf(cmd, "DELETE FROM RepositoryQueue WHERE Id = %d LIMIT 1;", id);
    Query query = this->_con.query(cmd);
    return (query.exec());
}
};

我已经删除了所有其他方法,因为它们不需要......

基本上它是DeleteQueuedRepository方法无效,GetQueue工作正常。

PS:这是在Linux OS(Ubuntu服务器)

非常感谢, 肖恩

2 个答案:

答案 0 :(得分:2)

  

MySQL ++没有free_result方法......或者是吗?

它不需要一个。当结果对象超出GetQueue()末尾的范围时,将自动释放与其关联的所有内存。

this->_con = Connection(false);

这里有三个问题:

  1. 创建RepositoryChecker对象时,您已经创建了一个Connection对象。如果需要将不同的参数传递给它的构造函数,那么你可以在RepositoryChecker构造函数的初始化列表中执行该操作,而不是在其正文中。阅读你的C ++书。

    你在这里所做的是a)创建一个默认的Connection对象,然后b)创建一个不同的Connection对象,关闭异常,然后c)用第二个覆盖第一个。如果有效,那就非常低效。 MySQL ++ Connection对象过去曾经遇到过复制问题,所以如果您使用旧版本的库,它可以解释您的问题。

  2. 你告诉Connection对象(以及它创建的每个对象,甚至间接地,这意味着MySQL ++中的几乎所有东西)你不希望它抛出异常,但是你把它包起来在一个大的try块中。选一个。

    我建议使用异常 - MySQL ++中的默认值 - 给出代码当前结构的方式。如果在DeleteQueuedRepository()中出现查询错误,则无法查看发生了什么,因为您只是将false传递给调用者,由于没有else,因此会被忽略电话中的条款。如果您这样做,请在e.what()数据块中记录catch消息。你现在就把这些信息丢掉了。

  3. 有几个地方你使用的结构看起来更像是Python(或者说是JavaScript)而不是C ++。这让我想知道你的问题是不是因为其他一些误用C ++而造成的损坏。

    特别是在这一行,您明确地使用了this指针,而C ++中没有这个指针。这段代码完全相同:

     _con = Connection(false);
    

    尽管如此,应该使用RepositoryChecker ctor初始值设定项列表完全替换该行。

  4. 继续......

    sprintf(cmd, "DELETE FROM RepositoryQueue WHERE Id = %d LIMIT 1;", id);
    

    正如其他人所评论的那样,您最好使用Query流界面:

    Query q = _con.query();
    q << "DELETE FROM RepositoryQueue WHERE Id = " << id << " LIMIT 1";
    

    这有几个好处:

    • 修复了建议将%d更改为%u的人隐含的类型安全问题。 C ++ IOStreams会为您解决这个问题。

    • 如果需要,自动引用插入流中的数据。 (在这种情况下,它不是。)

    • 防止任何跑掉缓冲区结束的可能性。你可以在这里使用不可移植的snprintf(),但为什么?

    如果您对printf()感到满意,那就是template query interface

    boost::this_thread::sleep(boost::posix_time::milliseconds(500));
    

    您是否阅读了用户手册中的threads chapter?你没有在MySQL ++中免费获得线程安全。您的问题可能是由于内存损坏。

    Warren Young,MySQL ++ Maintainer

答案 1 :(得分:0)

尝试在sprintf中将“%d”更改为“%u”。