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

  1. $ 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.

  1. export PATH=$PATH:<yugabyte-install-dir>/postgres/bin

Build and Install

  1. $ cd libpqxx
  2. $ ./configure
  3. $ make
  4. $ make install

Working example

Sample C++ code

Create a file ybsql_hello_world.cpp and copy the contents below:

  1. #include <iostream>
  2. #include <pqxx/pqxx>
  3. int main(int, char *argv[])
  4. {
  5. pqxx::connection c("host=127.0.0.1 port=5433 dbname=yugabyte user=yugabyte password=yugabyte");
  6. pqxx::work txn(c);
  7. pqxx::result r;
  8. /* Create table */
  9. try
  10. {
  11. r = txn.exec("CREATE TABLE employee (id int PRIMARY KEY, \
  12. name varchar, age int, \
  13. language varchar)");
  14. }
  15. catch (const std::exception &e)
  16. {
  17. std::cerr << e.what() << std::endl;
  18. return 1;
  19. }
  20. std::cout << "Created table employee\n";
  21. /* Insert a row */
  22. try
  23. {
  24. r = txn.exec("INSERT INTO employee (id, name, age, language) \
  25. VALUES (1, 'John', 35, 'C++')");
  26. }
  27. catch (const std::exception &e)
  28. {
  29. std::cerr << e.what() << std::endl;
  30. return 1;
  31. }
  32. std::cout << "Inserted data (1, 'John', 35, 'C++')\n";
  33. /* Query the row */
  34. try
  35. {
  36. r = txn.exec("SELECT name, age, language FROM employee WHERE id = 1");
  37. for (auto row: r)
  38. std::cout << "Query returned: "
  39. << row["name"].c_str() << ", "
  40. << row["age"].as<int>() << ", "
  41. << row["language"].c_str() << std::endl;
  42. }
  43. catch (const std::exception &e)
  44. {
  45. std::cerr << e.what() << std::endl;
  46. return 1;
  47. }
  48. txn.commit();
  49. return 0;
  50. }

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:

  1. $ g++ -std=c++11 ybsql_hello_world.cpp -lpqxx -lpq -I<yugabyte-install-dir>/postgres/include -o ybsql_hello_world

Run with:

  1. $ ./ybsql_hello_world

You should see the following output:

  1. Created table employee
  2. Inserted data (1, 'John', 35, 'C++')
  3. 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:

  1. $ 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:

  1. $ mkdir build
  2. $ cd build
  3. $ cmake ..
  4. $ make
  5. $ make install

Working example

Write an application

Create a file ybcql_hello_world.c and copy the contents below:

  1. #include <assert.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include "cassandra.h"
  6. void print_error(CassFuture* future) {
  7. const char* message;
  8. size_t message_length;
  9. cass_future_error_message(future, &message, &message_length);
  10. fprintf(stderr, "Error: %.*s\n", (int)message_length, message);
  11. }
  12. // Create a new cluster.
  13. CassCluster* create_cluster(const char* hosts) {
  14. CassCluster* cluster = cass_cluster_new();
  15. cass_cluster_set_contact_points(cluster, hosts);
  16. return cluster;
  17. }
  18. // Connect to the cluster given a session.
  19. CassError connect_session(CassSession* session, const CassCluster* cluster) {
  20. CassError rc = CASS_OK;
  21. CassFuture* future = cass_session_connect(session, cluster);
  22. cass_future_wait(future);
  23. rc = cass_future_error_code(future);
  24. if (rc != CASS_OK) {
  25. print_error(future);
  26. }
  27. cass_future_free(future);
  28. return rc;
  29. }
  30. CassError execute_query(CassSession* session, const char* query) {
  31. CassError rc = CASS_OK;
  32. CassFuture* future = NULL;
  33. CassStatement* statement = cass_statement_new(query, 0);
  34. future = cass_session_execute(session, statement);
  35. cass_future_wait(future);
  36. rc = cass_future_error_code(future);
  37. if (rc != CASS_OK) {
  38. print_error(future);
  39. }
  40. cass_future_free(future);
  41. cass_statement_free(statement);
  42. return rc;
  43. }
  44. CassError execute_and_log_select(CassSession* session, const char* stmt) {
  45. CassError rc = CASS_OK;
  46. CassFuture* future = NULL;
  47. CassStatement* statement = cass_statement_new(stmt, 0);
  48. future = cass_session_execute(session, statement);
  49. rc = cass_future_error_code(future);
  50. if (rc != CASS_OK) {
  51. print_error(future);
  52. } else {
  53. const CassResult* result = cass_future_get_result(future);
  54. CassIterator* iterator = cass_iterator_from_result(result);
  55. if (cass_iterator_next(iterator)) {
  56. const CassRow* row = cass_iterator_get_row(iterator);
  57. int age;
  58. const char* name; size_t name_length;
  59. const char* language; size_t language_length;
  60. cass_value_get_string(cass_row_get_column(row, 0), &name, &name_length);
  61. cass_value_get_int32(cass_row_get_column(row, 1), &age);
  62. cass_value_get_string(cass_row_get_column(row, 2), &language, &language_length);
  63. printf ("Select statement returned: Row[%.*s, %d, %.*s]\n", (int)name_length, name,
  64. age, (int)language_length, language);
  65. } else {
  66. printf("Unable to fetch row!\n");
  67. }
  68. cass_result_free(result);
  69. cass_iterator_free(iterator);
  70. }
  71. cass_future_free(future);
  72. cass_statement_free(statement);
  73. return rc;
  74. }
  75. int main() {
  76. // Ensure we log errors.
  77. cass_log_set_level(CASS_LOG_ERROR);
  78. CassCluster* cluster = NULL;
  79. CassSession* session = cass_session_new();
  80. CassFuture* close_future = NULL;
  81. char* hosts = "127.0.0.1";
  82. cluster = create_cluster(hosts);
  83. if (connect_session(session, cluster) != CASS_OK) {
  84. cass_cluster_free(cluster);
  85. cass_session_free(session);
  86. return -1;
  87. }
  88. CassError rc = CASS_OK;
  89. rc = execute_query(session, "CREATE KEYSPACE IF NOT EXISTS ybdemo");
  90. if (rc != CASS_OK) return -1;
  91. printf("Created keyspace ybdemo\n");
  92. rc = execute_query(session, "DROP TABLE IF EXISTS ybdemo.employee");
  93. if (rc != CASS_OK) return -1;
  94. rc = execute_query(session,
  95. "CREATE TABLE ybdemo.employee (id int PRIMARY KEY, \
  96. name varchar, \
  97. age int, \
  98. language varchar)");
  99. if (rc != CASS_OK) return -1;
  100. printf("Created table ybdemo.employee\n");
  101. const char* insert_stmt = "INSERT INTO ybdemo.employee (id, name, age, language) VALUES (1, 'John', 35, 'C/C++')";
  102. rc = execute_query(session, insert_stmt);
  103. if (rc != CASS_OK) return -1;
  104. printf("Inserted data: %s\n", insert_stmt);
  105. const char* select_stmt = "SELECT name, age, language from ybdemo.employee WHERE id = 1";
  106. rc = execute_and_log_select(session, select_stmt);
  107. if (rc != CASS_OK) return -1;
  108. close_future = cass_session_close(session);
  109. cass_future_wait(close_future);
  110. cass_future_free(close_future);
  111. cass_cluster_free(cluster);
  112. cass_session_free(session);
  113. return 0;
  114. }

Run the application

You can compile the file using gcc or clang.For clang, you can use:

  1. $ clang ybcql_hello_world.c -lcassandra -Iinclude -o yb_cql_hello_world

Run with:

  1. $ ./yb_cql_hello_world

You should see the following output:

  1. Created keyspace ybdemo
  2. Created table ybdemo.employee
  3. Inserted data: INSERT INTO ybdemo.employee (id, name, age, language) VALUES (1, 'John', 35, 'C/C++')
  4. Select statement returned: Row[John, 35, C/C++]