Connect an application
Yugabyte C++ Driver for YCQL is based on DataStax C++ Driver with additional smart driver features.
YugabyteDB Aeon
To use the driver's partition-aware load balancing feature in a YugabyteDB Aeon cluster, applications must be deployed in a VPC that has been peered with the cluster VPC so that they have access to all nodes in the cluster. For more information, refer to Using YCQL drivers with YugabyteDB Aeon.Prerequisites
The tutorial assumes that you have:
- installed YugabyteDB, created a universe, and are able to interact with it using the YCQL shell (
ycqlsh
). If not, follow the steps in Quick start. - have a 32-bit (x86) or 64-bit (x64) architecture machine.
- have gcc 4.1.2 or later, Clang 3.4 or later installed.
Install the YugabyteDB C++ Driver for YCQL
To get the YugabyteDB C++ Driver for YCQL, clone the repository:
$ git clone https://github.com/yugabyte/cassandra-cpp-driver.git
Dependencies
The YugabyteDB C++ Driver for YCQL 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 are given here.
Build and install
To build and install the driver, run the following commands:
$ 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 you 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
, run the following command:
$ 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++]