Пул соединений Libpqxx

Я пытаюсь разработать очень простой и понятный пул соединений с использованием библиотеки libpqxx. Я довольно новичок в c ++ и все еще очень запутался с указателями и ссылками. Поведение класса очень простое: иметь вектор с некоторым инициализированным соединением и вставлять и вставлять соединения в вектор, когда они необходимы. В коде много ошибок из-за плохой реализации указателей и ссылок. Можете ли вы дать мне несколько советов?

РЕДАКТИРОВАТЬ: мне удалось исправить все ошибки компиляции. Это вызывает ошибку сегментации, когда я запускаю основную функцию.

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;
}

4

Решение

Если вас беспокоит проблема дизайна, вот мои пять центов:

  • Ваш код на самом деле компилируется? Я думаю нет, потому что у вас есть вектор указатели на связь, но ты отталкиваешься соединение объекты (m_freeCons.push_back(*con);* разыменовывает указатель на соединение) …
  • Обычно плохая идея выдавать изменяемые дескрипторы членам (как вы делаете в getCon метод — по крайней мере, вернуть connection const * вместо этого, если возможно
  • Если вам нужно использовать коллекцию указателей, рассмотрите возможность использования shared_ptr вместо необработанных указателей — таким образом вам не придется беспокоиться об освобождении памяти; или использовать Boost.PointerContainer; также см Вот.
  • Просто вопрос странного стиля: почему вы используете return &(*conn)? Это разыменовывает указатель conn и затем снова принимает его адрес. Вместо этого вы можете просто написать return conn!

В ответ на ваш переписанный вопрос с shared_ptrs:
Вам все еще нужно создать соединение с новым и обернуть его в shared_ptr; например для 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));

и аналогично в других местах.

2

Другие решения

Вдохновленный вашим постом, я использовал этот простой пул соединений в своем собственном проекте. Я использовал 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);
}
1

По вопросам рекламы [email protected]