Libpqxx连接池

时间:2012-09-21 09:51:31

标签: c++ libpqxx

我正在尝试使用libpqxx库开发一个非常简单直接的连接池。我对c ++很新,但仍然对指针和引用很困惑。该类的行为非常简单:具有一些初始化连接的向量,并在需要时弹出并推送到向量上。由于指针和引用的错误实现,代码有很多错误。你能给我一些提示吗?

编辑:我设法解决了所有编译错误。当我运行main函数时,它给了我一个分段错误。

class DbPool {

公共:

pqxx::result runQuery(const string& query) {

    connection *conn = getCon();
    work trans(*conn);
    result res = trans.exec(query);
    trans.commit();
    releaseCon(conn);

    return res;
}

DbPool(uint32_t max_cons) {

    for (uint32_t i = 0; i < max_cons; i++) {

        connection* con = createCon();
        m_freeCons.push_back(shared_ptr < connection > (con));
    }
}

私人:

connection * createCon() {

    connection * conn =
            new connection(
                    "user='ak' password='rootpassword' dbname='bips_office' hostaddr='127.0.0.1' port='5432'");
    return conn;
}

void releaseCon(connection *con) {

    m_freeCons.push_back(shared_ptr < connection > (con));
}

connection* getCon() {

    shared_ptr < connection > conn = *(m_freeCons.end() - 1);
    m_freeCons.pop_back();
    return conn.get();
}

vector<shared_ptr<connection> > m_freeCons;

};

int main(int argc, char *argv[]) {
     DbPool *pool = new DbPool(5);
     result res = pool->runQuery("SELECT COUNT (*) from captures");
     return 0;
}

2 个答案:

答案 0 :(得分:2)

如果你担心设计问题,这是我的五分钱:

  • 您的代码是否实际编译?我想不是,因为你有一个指向连接的指针,但你正在推回连接对象(m_freeCons.push_back(*con); - *取消引用指向连接的指针)...
  • 向成员提供可修改的句柄通常是个坏主意(正如您在getCon方法中所做的那样 - 至少如果可能,请返回connection const *
  • 如果必须使用指针集合,请考虑使用shared_ptr而不是原始指针 - 这样您就不必担心释放内存了;或使用Boost.PointerContainer;另见here
  • 只是一个奇怪的风格:为什么你使用return &(*conn)?取消引用指针conn然后再次获取它的地址。相反,您只需编写return conn
  • 即可

使用shared_ptr来回答您重写的问题: 您仍然需要使用new创建连接,并在其周围包装shared_ptr;例如for createCon:

connection * createCon(){

    connection * conn = new connection("user='ak' password='rootpassword' dbname='bips_office' hostaddr='127.0.0.1' port='5432'");
    return conn;
}

    connection* con = createCon();
    m_freeCons.push_back(shared_ptr<connection>(con));

和其他地方类似。

答案 1 :(得分:1)

受到帖子的启发,我在自己的项目中使用了这个简单的连接池。我用过std :: stack。推动和弹出。添加连接时,除了try-catch之外没有错误检查。对于postgresql-db。

Database.hpp:

#include <stack>
#include <pqxx/pqxx>

class Database {
private:
    const std::string connectionString = "dbname=db user=usr hostaddr=127.0.0.1 port=5432";
    std::stack<pqxx::connection *> dbpool;

public:
    Database(const unsigned int);

Database.cpp:

#include "Database.hpp"

Database::Database(const unsigned int connections) {
    for (int i = 0; i < connections; ++i) {
        try {
            auto* dbconn = new pqxx::connection(connectionString);
            dbpool.emplace(dbconn);
        } catch (const std::exception& e) {
            std::cerr << e.what() << std::endl;
        }
    }
}

main.cpp中:

#include "Database.hpp"

int main(int argc, char* argv[]) {
    Database database {10};

    auto *D = dbpool.top();
    dbpool.pop();

    const std::string query = "select * from mytable";
    pqxx::nontransaction N(*D);
    pqxx::result R(N.exec(query));

    for (pqxx::result::const_iterator c = R.begin(); c != R.end(); ++c) {
        std::cout << c[1].as<std::string>() << std::endl;
    };

    dbpool.push(D);
}