首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++ MySQL++删除查询语句脑筋急转弯问题

C++ MySQL++删除查询语句脑筋急转弯问题
EN

Stack Overflow用户
提问于 2011-02-10 07:27:47
回答 2查看 1.8K关注 0票数 1

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

我已经设法让存储过程工作了,但是我在使用delete语句时遇到了问题。我已经到处找过了,也没有找到任何示例文档。

首先,我认为在调用存储过程之后,代码可能需要释放查询/连接结果,但当然MySQL++没有free_result方法……或者真的是这样?

不管怎样,这是我得到的:

代码语言:javascript
复制
#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操作系统(Ubuntu服务器)上

非常感谢,肖恩

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-02-10 15:23:25

MySQL++没有free_result方法...或者真的是这样?

它不需要。当结果对象在GetQueue()结束时超出作用域时,与其关联的所有内存都会自动释放。

代码语言:javascript
复制
this->_con = Connection(false);

这里有三个问题:

  1. 当您创建RepositoryChecker对象时,您已经创建了一个Connection对象。如果需要向其构造函数传递不同的参数,可以在RepositoryChecker构造函数的初始化列表中完成,而不是在其主体中完成。阅读你的C++书籍。

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

  • You're告诉Connection对象(以及它创建的每个对象,即使是间接的,这意味着MySQL++中的几乎所有内容)您不希望它抛出异常,但然后将其包装在一个大的try块中。选一个。

考虑到代码当前的结构,我建议使用exceptions - MySQL++中的默认设置。如果在DeleteQueuedRepository()中出现查询错误,就无法看到发生了什么,因为您只是将false向上传递给调用者,而调用者忽略了这一点,因为调用中没有else子句。如果执行此操作,请在catch块中记录e.what()消息。

  • 有几个地方你使用的构造看起来更像Python (或者JavaScript)而不是C++。这让我想知道您的问题是否不是由于误用C++造成的损坏。

特别是在这一行中,您显式地使用了this指针,这在C++中是不需要的。这段代码做的是完全相同的事情:

_con =连接(False);

不过,这一行应该完全替换,改为使用RepositoryChecker ctor初始化器列表。

继续..。

代码语言:javascript
复制
sprintf(cmd, "DELETE FROM RepositoryQueue WHERE Id = %d LIMIT 1;", id);

正如其他人评论的那样,您最好使用Query流接口:

代码语言:javascript
复制
Query q = _con.query();
q << "DELETE FROM RepositoryQueue WHERE Id = " << id << " LIMIT 1";

这有几个优点:

  • 修复了建议将%d更改为%u的人所暗示的类型安全问题。如果需要,对于插入到流中的数据进行you.
  • Automatic引用时,C++ IOStreams会处理此问题。(在这个case.)
  • Prevents中,它不是运行在缓冲区末尾的任何可能性。你可以在这里使用不可移植的snprintf(),但是为什么呢?

如果你真的对printf()感到满意,那就用template query interface吧。

代码语言:javascript
复制
boost::this_thread::sleep(boost::posix_time::milliseconds(500));

你读过用户手册中的threads chapter吗?在MySQL++中,您不会免费获得线程安全。您的问题可能是由于内存损坏造成的。

沃伦·杨,MySQL++维护者

票数 3
EN

Stack Overflow用户

发布于 2011-02-10 07:34:07

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4951802

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档