Build a C++ application
The following tutorial shows a small C++ application that connects to a YugabyteDB cluster using the libpqxx driver and performs basic SQL operations. Use the application as a template to get started with Yugabyte Cloud in C++.
Prerequisites
- 32-bit (x86) or 64-bit (x64) architecture machine. (Use Rosetta to build and run on Apple silicon.)
- gcc 4.1.2 or later, or clang 3.4 or later installed.
- OpenSSL 1.1.1 or later (used by libpq and libpqxx to establish secure SSL connections).
- libpq. Homebrew users on macOS can install using
brew install libpq
. You can download the PostgreSQL binaries and source from PostgreSQL Downloads. - libpqxx. Homebrew users on macOS can install using
brew install libpqxx
. To build the driver yourself, refer to Building libpqxx.
Yugabyte Cloud
- You have a cluster deployed in Yugabyte Cloud. To get started, use the Quick start.
- You downloaded the cluster CA certificate. Refer to Download your cluster certificate.
- You have added your computer to the cluster IP allow list. Refer to Assign IP Allow Lists.
Clone the application from GitHub
Clone the sample application to your computer:
git clone https://github.com/yugabyte/yugabyte-simple-cpp-app && cd yugabyte-simple-cpp-app
Provide connection parameters
The application needs to establish a connection to the YugabyteDB cluster. To do this:
-
Open the
sample-app.cpp
file. -
Set the following configuration-related constants:
- HOST - the host name of your YugabyteDB cluster. To obtain a Yugabyte Cloud cluster host name, sign in to Yugabyte Cloud, select your cluster on the Clusters page, and click Settings. The host is displayed under Network Access.
- PORT - the port number that will be used by the driver (the default YugabyteDB YSQL port is 5433).
- DB_NAME - the name of the database you are connecting to (the default database is named
yugabyte
). - USER and PASSWORD - the username and password for the YugabyteDB database. If you are using the credentials you created when deploying a cluster in Yugabyte Cloud, these can be found in the credentials file you downloaded.
- SSL_MODE - the SSL mode to use. Yugabyte Cloud requires SSL connections; use
verify-full
. - SSL_ROOT_CERT - the full path to the Yugabyte Cloud cluster CA certificate.
-
Save the file.
Build and run the application
Build the application with gcc or clang.
g++ -std=c++17 sample-app.cpp -o sample-app -lpqxx -lpq \
-I<path-to-libpq>/libpq/include -I<path-to-libpqxx>/libpqxx/include \
-L<path-to-libpq>/libpq/lib -L<path-to-libpqxx>/libpqxx/lib
Replace <path-to-libpq>
with the path to the libpq installation, and <path-to-libpqxx>
with the path to the libpqxx installation; for example, /usr/local/opt
.
Start the application.
$ ./sample-app
You should see output similar to the following:
>>>> Successfully connected to YugabyteDB!
>>>> Successfully created table DemoAccount.
>>>> Selecting accounts:
name = Jessica, age = 28, country = USA, balance = 10000
name = John, age = 28, country = Canada, balance = 9000
>>>> Transferred 800 between accounts.
>>>> Selecting accounts:
name = Jessica, age = 28, country = USA, balance = 9200
name = John, age = 28, country = Canada, balance = 9800
You have successfully executed a basic C++ application that works with Yugabyte Cloud.
Explore the application logic
Open the sample-app.cpp
file in the yugabyte-simple-cpp-app
folder to review the methods.
connect
The connect
method establishes a connection with your cluster via the libpqxx driver.
std::string url = "host=" + HOST + " port=" + PORT + " dbname=" + DB_NAME +
" user=" + USER + " password=" + PASSWORD;
if (SSL_MODE != "") {
url += " sslmode=" + SSL_MODE;
if (SSL_ROOT_CERT != "") {
url += " sslrootcert=" + SSL_ROOT_CERT;
}
}
std::cout << ">>>> Connecting to YugabyteDB!" << std::endl;
pqxx::connection *conn = new pqxx::connection(url);
std::cout << ">>>> Successfully connected to YugabyteDB!" << std::endl;
createDatabase
The createDatabase
method uses PostgreSQL-compliant DDL commands to create a sample database.
pqxx::work txn(*conn);
txn.exec("DROP TABLE IF EXISTS DemoAccount");
txn.exec("CREATE TABLE DemoAccount ( \
id int PRIMARY KEY, \
name varchar, \
age int, \
country varchar, \
balance int)");
txn.exec("INSERT INTO DemoAccount VALUES \
(1, 'Jessica', 28, 'USA', 10000), \
(2, 'John', 28, 'Canada', 9000)");
txn.commit();
selectAccounts
The selectAccounts
method queries your distributed data using the SQL SELECT
statement.
res = txn.exec("SELECT name, age, country, balance FROM DemoAccount");
for (auto row: res) {
std::cout
<< "name=" << row["name"].c_str() << ", "
<< "age=" << row["age"].as<int>() << ", "
<< "country=" << row["country"].c_str() << ", "
<< "balance=" << row["balance"].as<int>() << std::endl;
}
transferMoneyBetweenAccounts
The transferMoneyBetweenAccounts
method updates your data consistently with distributed transactions.
try {
pqxx::work txn(*conn);
txn.exec("UPDATE DemoAccount SET balance = balance -" + std::to_string(amount)
+ " WHERE name = \'Jessica\'");
txn.exec("UPDATE DemoAccount SET balance = balance +" + std::to_string(amount)
+ " WHERE name = \'John\'");
txn.commit();
std::cout << ">>>> Transferred " << amount << " between accounts." << std::endl;
} catch (pqxx::sql_error const &e) {
if (e.sqlstate().compare("40001") == 0) {
std::cerr << "The operation is aborted due to a concurrent transaction that is modifying the same set of rows."
<< "Consider adding retry logic for production-grade applications." << std::endl;
}
throw e;
}