From 5fc9e02cb7ee0d35acaf4ab6caab9644fb0f0263 Mon Sep 17 00:00:00 2001 From: Maximilian Bandle Date: Fri, 12 Jun 2026 06:47:37 +0200 Subject: [PATCH] Update C++ libpqxx docs for libpqxx 8 and Ubuntu 26.04 - Warn that Ubuntu 26.04's libpqxx-dev (7.10) has a double-free, with instructions to build libpqxx 8.0.1 from source - Update compile command to c++23 - Update insert API from exec_prepared to exec(pqxx::prepped{}, pqxx::params{}) - Replace `using namespace std` with explicit std:: prefixes --- content/clients/cpp/_index.md | 37 +++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/content/clients/cpp/_index.md b/content/clients/cpp/_index.md index dec1f385..acc53a42 100644 --- a/content/clients/cpp/_index.md +++ b/content/clients/cpp/_index.md @@ -8,7 +8,7 @@ CedarDB is compatible with the [PostgreSQL libpqxx](https://pqxx.org/development ## Installing -Before demonstrating the connection to CedarDB, we need to get the correct dependencies . +Before demonstrating the connection to CedarDB, we need to get the correct dependencies. libpqxx uses the libpq library internally. On Debian or Ubuntu you can simply get the dev files from an apt repository. @@ -16,10 +16,23 @@ On Debian or Ubuntu you can simply get the dev files from an apt repository. sudo apt install libpqxx-dev ``` +{{% callout type="warning" %}} +The `libpqxx-dev` package in Ubuntu 26.04 ships libpqxx 7.10, which [crashes on exit](https://github.com/jtv/libpqxx/issues/1195) due to a double-free in `pqxx::internal::demangle_type_name`. We recommend building libpqxx 8 from source instead: + +```bash +sudo apt install cmake g++ libpq-dev +git clone --depth 1 --branch 8.0.1 https://github.com/jtv/libpqxx.git /tmp/libpqxx +cmake -S /tmp/libpqxx -B /tmp/libpqxx/build -DSKIP_BUILD_TEST=ON -DCMAKE_BUILD_TYPE=Release +cmake --build /tmp/libpqxx/build -j$(nproc) +sudo cmake --install /tmp/libpqxx/build +``` + +{{% /callout %}} + After finishing the client (see at the full program at the bottom of the program), we need to first compile our program with `g++` and then execute it. ```bash -g++ -std=c++17 main.cpp -lpqxx -lpq -o CedarDBClient +g++ -std=c++23 main.cpp -lpqxx -lpq -o CedarDBClient ./CedarDBClient ``` @@ -69,12 +82,12 @@ pqxx::work transaction(connection); // Insert data connection.prepare("insert", "INSERT INTO chatlog VALUES ($1 , $2, $3)"); -string_view message = "(☞゚∀゚)☞"sv; +std::string_view message = "(☞゚∀゚)☞"sv; auto id = 0; -auto time = chrono::system_clock::to_time_t(chrono::system_clock::now()); +auto time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); std::stringstream ss; ss << std::put_time(std::localtime(&time), "%Y-%m-%d %X%z"); -transaction.exec_prepared("insert", id, message, ss); +transaction.exec(pqxx::prepped{"insert"}, pqxx::params{id, message, ss.str()}); transaction.commit(); ``` @@ -129,7 +142,7 @@ LOG: 100000 rows (0.000012 s parsing, 0.000374 s compilation, 0.025395 s transmi #include #include -using namespace std; +using namespace std::string_view_literals; int main(int argc, char* argv[]) { auto connectionString = "dbname= user= password= host=localhost port=5432"; @@ -137,7 +150,7 @@ int main(int argc, char* argv[]) { // Establishing a connection pqxx::connection connection(connectionString); if (!connection.is_open()) { - cerr << "Can't connect!" << endl; + std::cerr << "Can't connect!" << std::endl; return 1; } @@ -156,12 +169,12 @@ int main(int argc, char* argv[]) { // Insert data connection.prepare("insert", "INSERT INTO chatlog VALUES ($1 , $2, $3)"); - string_view message = "(☞゚∀゚)☞"sv; + std::string_view message = "(☞゚∀゚)☞"sv; auto id = 0; - auto time = chrono::system_clock::to_time_t(chrono::system_clock::now()); + auto time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); std::stringstream ss; ss << std::put_time(std::localtime(&time), "%Y-%m-%d %X%z"); - transaction.exec_prepared("insert", id, message, ss); + transaction.exec(pqxx::prepped{"insert"}, pqxx::params{id, message, ss.str()}); transaction.commit(); } { @@ -182,13 +195,13 @@ int main(int argc, char* argv[]) { // Read data auto readTable = "SELECT * FROM chatlog ORDER BY userid LIMIT 10"sv; - for (auto [id, message, time] : transaction.stream(readTable)) { + for (auto [id, message, time] : transaction.stream(readTable)) { std::cout << id << "," << message << "," << time << "\n"; } transaction.commit(); } } catch (const std::exception& e) { - cerr << e.what() << std::endl; + std::cerr << e.what() << std::endl; return 1; } return 0;