Build a C++ application
Prerequisites
The tutorial assumes that you have:
- installed YugabyteDB, and created a universe with YSQL enabled. If not, please follow these steps in the Quick Start guide.
- have a 32-bit (x86) or 64-bit (x64) architecture machine.
- have gcc 4.1.2+, clang 3.4+ installed.
Installing the C++ driver (libpqxx)
Download the source from here and build the binaries as follows. Detailed instructions are provided here.
Get the source
$ git clone https://github.com/jtv/libpqxx.git
Dependencies
Note that this package depends on PostgreSQL binaries. Make sure that the PostgreSQL bin
directory is on the command path.
export PATH=$PATH:<yugabyte-install-dir>/postgres/bin
Build and Install
$ cd libpqxx
$ ./configure
$ make
$ make install
Working example
Sample C++ code
Create a file ybsql_hello_world.cpp
and copy the contents below:
#include <iostream>
#include <pqxx/pqxx>
int main(int, char *argv[])
{
pqxx::connection c("host=127.0.0.1 port=5433 dbname=yugabyte user=yugabyte password=yugabyte");
pqxx::work txn(c);
pqxx::result r;
/* Create table */
try
{
r = txn.exec("CREATE TABLE employee (id int PRIMARY KEY, \
name varchar, age int, \
language varchar)");
}
catch (const std::exception &e)
{
std::cerr << e.what() << std::endl;
return 1;
}
std::cout << "Created table employee\n";
/* Insert a row */
try
{
r = txn.exec("INSERT INTO employee (id, name, age, language) \
VALUES (1, 'John', 35, 'C++')");
}
catch (const std::exception &e)
{
std::cerr << e.what() << std::endl;
return 1;
}
std::cout << "Inserted data (1, 'John', 35, 'C++')\n";
/* Query the row */
try
{
r = txn.exec("SELECT name, age, language FROM employee WHERE id = 1");
for (auto row: r)
std::cout << "Query returned: "
<< row["name"].c_str() << ", "
<< row["age"].as<int>() << ", "
<< row["language"].c_str() << std::endl;
}
catch (const std::exception &e)
{
std::cerr << e.what() << std::endl;
return 1;
}
txn.commit();
return 0;
}
Run the application
You can compile the file using gcc
or clang
. Note that C++ 11 is the minimum supported C++ version. Make sure your compiler supports this, and if necessary, that you have support for C++11 configured. For gcc, you can use:
$ g++ -std=c++11 ybsql_hello_world.cpp -lpqxx -lpq -I<yugabyte-install-dir>/postgres/include -o ybsql_hello_world
Run with:
$ ./ybsql_hello_world
You should see the following output:
Created table employee
Inserted data (1, 'John', 35, 'C++')
Query returned: John, 35, C++
Prerequisites
The tutorial assumes that you have:
- installed YugabyteDB, created a universe and are able to interact with it using the CQL shell. Ifnot, please follow these steps in the Quick Start guide.
- have a 32-bit (x86) or 64-bit (x64) architecture machine.
- have gcc 4.1.2+, Clang 3.4+ installed.
Installing the C/C++ driver
To get the C/C++ driver, run:
$ git clone https://github.com/yugabyte/cassandra-cpp-driver.git
Dependencies
The C/C++ driver depends on the following:
- CMake v2.6.4+
- libuv 1.x
- OpenSSL v1.0.x or v1.1.x
More detailed instructions for installing the dependencies aregiven here.
Build and install
To build and install the driver:
$ mkdir build
$ cd build
$ cmake ..
$ make
$ make install
Working example
Write an application
Create a file ybcql_hello_world.c
and copy the contents below:
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "cassandra.h"
void print_error(CassFuture* future) {
const char* message;
size_t message_length;
cass_future_error_message(future, &message, &message_length);
fprintf(stderr, "Error: %.*s\n", (int)message_length, message);
}
// Create a new cluster.
CassCluster* create_cluster(const char* hosts) {
CassCluster* cluster = cass_cluster_new();
cass_cluster_set_contact_points(cluster, hosts);
return cluster;
}
// Connect to the cluster given a session.
CassError connect_session(CassSession* session, const CassCluster* cluster) {
CassError rc = CASS_OK;
CassFuture* future = cass_session_connect(session, cluster);
cass_future_wait(future);
rc = cass_future_error_code(future);
if (rc != CASS_OK) {
print_error(future);
}
cass_future_free(future);
return rc;
}
CassError execute_query(CassSession* session, const char* query) {
CassError rc = CASS_OK;
CassFuture* future = NULL;
CassStatement* statement = cass_statement_new(query, 0);
future = cass_session_execute(session, statement);
cass_future_wait(future);
rc = cass_future_error_code(future);
if (rc != CASS_OK) {
print_error(future);
}
cass_future_free(future);
cass_statement_free(statement);
return rc;
}
CassError execute_and_log_select(CassSession* session, const char* stmt) {
CassError rc = CASS_OK;
CassFuture* future = NULL;
CassStatement* statement = cass_statement_new(stmt, 0);
future = cass_session_execute(session, statement);
rc = cass_future_error_code(future);
if (rc != CASS_OK) {
print_error(future);
} else {
const CassResult* result = cass_future_get_result(future);
CassIterator* iterator = cass_iterator_from_result(result);
if (cass_iterator_next(iterator)) {
const CassRow* row = cass_iterator_get_row(iterator);
int age;
const char* name; size_t name_length;
const char* language; size_t language_length;
cass_value_get_string(cass_row_get_column(row, 0), &name, &name_length);
cass_value_get_int32(cass_row_get_column(row, 1), &age);
cass_value_get_string(cass_row_get_column(row, 2), &language, &language_length);
printf ("Select statement returned: Row[%.*s, %d, %.*s]\n", (int)name_length, name,
age, (int)language_length, language);
} else {
printf("Unable to fetch row!\n");
}
cass_result_free(result);
cass_iterator_free(iterator);
}
cass_future_free(future);
cass_statement_free(statement);
return rc;
}
int main() {
// Ensure we log errors.
cass_log_set_level(CASS_LOG_ERROR);
CassCluster* cluster = NULL;
CassSession* session = cass_session_new();
CassFuture* close_future = NULL;
char* hosts = "127.0.0.1";
cluster = create_cluster(hosts);
if (connect_session(session, cluster) != CASS_OK) {
cass_cluster_free(cluster);
cass_session_free(session);
return -1;
}
CassError rc = CASS_OK;
rc = execute_query(session, "CREATE KEYSPACE IF NOT EXISTS ybdemo");
if (rc != CASS_OK) return -1;
printf("Created keyspace ybdemo\n");
rc = execute_query(session, "DROP TABLE IF EXISTS ybdemo.employee");
if (rc != CASS_OK) return -1;
rc = execute_query(session,
"CREATE TABLE ybdemo.employee (id int PRIMARY KEY, \
name varchar, \
age int, \
language varchar)");
if (rc != CASS_OK) return -1;
printf("Created table ybdemo.employee\n");
const char* insert_stmt = "INSERT INTO ybdemo.employee (id, name, age, language) VALUES (1, 'John', 35, 'C/C++')";
rc = execute_query(session, insert_stmt);
if (rc != CASS_OK) return -1;
printf("Inserted data: %s\n", insert_stmt);
const char* select_stmt = "SELECT name, age, language from ybdemo.employee WHERE id = 1";
rc = execute_and_log_select(session, select_stmt);
if (rc != CASS_OK) return -1;
close_future = cass_session_close(session);
cass_future_wait(close_future);
cass_future_free(close_future);
cass_cluster_free(cluster);
cass_session_free(session);
return 0;
}
Run the application
You can compile the file using gcc or clang.For clang, you can use:
$ clang ybcql_hello_world.c -lcassandra -Iinclude -o yb_cql_hello_world
Run with:
$ ./yb_cql_hello_world
You should see the following output:
Created keyspace ybdemo
Created table ybdemo.employee
Inserted data: INSERT INTO ybdemo.employee (id, name, age, language) VALUES (1, 'John', 35, 'C/C++')
Select statement returned: Row[John, 35, C/C++]