Working with Databases in C++: PostgreSQL and MongoDB
Modern C++ applications rarely function without interacting with databases. Whether you are developing a high-load server, an analytics system, or embedded software, the ability to work with relational (PostgreSQL) and document-oriented (MongoDB) DBMS is an essential skill. In this article, we will cover connection, query execution, and error handling for both systems using practical examples.
1. Environment Setup and Library Selection
For working with PostgreSQL in C++, the de facto standard library is libpqxx. For MongoDB, the official driver is mongocxx (based on libmongoc).
Installing libpqxx (Linux / macOS)
# Ubuntu / Debiansudo apt-get install libpqxx-dev
# macOS (Homebrew)brew install libpqxxInstalling mongocxx (Linux / macOS)
# Requires prior installation of libmongoc and boostsudo apt-get install libmongoc-1.0-0 libbson-1.0 libmongocxx-dev
# macOSbrew install mongo-cxx-driverFor Windows, use vcpkg or download precompiled builds from the official repositories.
2. Working with PostgreSQL via libpqxx
The libpqxx library provides a convenient C++ interface on top of the C driver libpq. The main classes are: connection, work (transaction), result.
Connecting to the Database
#include <iostream>#include <pqxx/pqxx>
int main() { try { // Connection string: "dbname=test user=postgres password=secret hostaddr=127.0.0.1 port=5432" pqxx::connection conn("dbname=testdb user=myuser password=mypass hostaddr=localhost"); if (conn.is_open()) { std::cout << "Connected to PostgreSQL: " << conn.dbname() << std::endl; } } catch (const std::exception &e) { std::cerr << "Connection error: " << e.what() << std::endl; return 1; } return 0;}Executing Queries (CRUD)
void createTable(pqxx::connection &conn) { pqxx::work txn(conn); txn.exec("CREATE TABLE IF NOT EXISTS users (" "id SERIAL PRIMARY KEY," "name VARCHAR(100) NOT NULL," "email VARCHAR(255) UNIQUE," "age INT" ")"); txn.commit();}
void insertUser(pqxx::connection &conn, const std::string &name, const std::string &email, int age) { pqxx::work txn(conn); // Using a parameterized query to protect against SQL injection txn.exec_params("INSERT INTO users (name, email, age) VALUES ($1, $2, $3)", name, email, age); txn.commit(); std::cout << "User inserted." << std::endl;}
void selectUsers(pqxx::connection &conn) { pqxx::nontransaction txn(conn); pqxx::result result = txn.exec("SELECT id, name, email, age FROM users"); for (auto row : result) { std::cout << "ID: " << row["id"].as<int>() << ", Name: " << row["name"].as<std::string>() << ", Email: " << row["email"].as<std::string>() << ", Age: " << row["age"].as<int>() << std::endl; }}Error Handling
Wrap all operations in try-catch blocks. libpqxx throws exceptions of classes pqxx::sql_error, pqxx::broken_connection, and others.
3. Working with MongoDB via mongocxx
The mongocxx driver uses modern C++17. The main entities are: client, database, collection, document (via bsoncxx).
Connecting and Obtaining a Collection
#include <ios