我对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服务器)
上非常感谢, 肖恩
答案 0 :(得分:2)
MySQL ++没有free_result方法......或者是吗?
它不需要一个。当结果对象超出GetQueue()
末尾的范围时,将自动释放与其关联的所有内存。
this->_con = Connection(false);
这里有三个问题:
创建RepositoryChecker
对象时,您已经创建了一个Connection
对象。如果需要将不同的参数传递给它的构造函数,那么你可以在RepositoryChecker
构造函数的初始化列表中执行该操作,而不是在其正文中。阅读你的C ++书。
你在这里所做的是a)创建一个默认的Connection
对象,然后b)创建一个不同的Connection
对象,关闭异常,然后c)用第二个覆盖第一个。如果有效,那就非常低效。 MySQL ++ Connection
对象过去曾经遇到过复制问题,所以如果您使用旧版本的库,它可以解释您的问题。
你告诉Connection
对象(以及它创建的每个对象,甚至间接地,这意味着MySQL ++中的几乎所有东西)你不希望它抛出异常,但是你把它包起来在一个大的try
块中。选一个。
我建议使用异常 - MySQL ++中的默认值 - 给出代码当前结构的方式。如果在DeleteQueuedRepository()
中出现查询错误,则无法查看发生了什么,因为您只是将false
传递给调用者,由于没有else
,因此会被忽略电话中的条款。如果您这样做,请在e.what()
数据块中记录catch
消息。你现在就把这些信息丢掉了。
有几个地方你使用的结构看起来更像是Python(或者说是JavaScript)而不是C ++。这让我想知道你的问题是不是因为其他一些误用C ++而造成的损坏。
特别是在这一行,您明确地使用了this
指针,而C ++中没有这个指针。这段代码完全相同:
_con = Connection(false);
尽管如此,应该使用RepositoryChecker
ctor初始值设定项列表完全替换该行。
继续......
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”。