gpt4 book ai didi

C++ MySQL++ 删除查询语句的脑残题

转载 作者:行者123 更新时间:2023-11-30 04:35:52 27 4
gpt4 key购买 nike

我对 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 操作系统(Ubuntu 服务器)上

非常感谢,肖恩

最佳答案

MySQL++ doesn't have a free_result method... or does it?

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

this->_con = Connection(false);

这里的三个问题:

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

    您在这里所做的是 a) 创建一个默认的 Connection 对象,然后 b) 创建一个不同的 Connection 对象并关闭异常,然后 c) 覆盖第一个与第二个。如果可行,那将是非常低效的。 MySQL++ Connection 对象在过去的复制构造器方面存在问题,因此如果您使用的是旧版本的库,它可以解释您的问题。

  2. 您告诉 Connection 对象(以及它创建的每个对象,甚至是间接创建的对象,这几乎意味着 MySQL++ 中的所有内容)您不希望它抛出异常,但是随后你将它包装在一个大的 try block 中。选择一个。

    鉴于您的代码当前的结构方式,我建议使用异常——MySQL++ 中的默认设置。如果在 DeleteQueuedRepository() 中存在查询错误,则无法查看发生了什么,因为您只是将 false 传递给调用者,而调用者会忽略它,因为调用中没有 else 子句。如果这样做,请在 catch block 中记录 e.what() 消息。您现在只是在丢弃这些信息。

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

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

     _con = Connection(false);

    尽管如此,应该完全替换该行,而是使用 RepositoryChecker 构造函数初始化列表。

继续……

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

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

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++ 维护者

关于C++ MySQL++ 删除查询语句的脑残题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4951802/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com