Develop C/C++ Apps

AttentionThis page documents an earlier version. Go to the latest (v2.1)version.

Pre-requisites

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/datastax/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

Writing the C/C++ Code.

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>

6. #include "cassandra.h"

8. void print_error(CassFuture* future) {
9. const char* message;
10. size_t message_length;
11. cass_future_error_message(future, &message, &message_length);
12. fprintf(stderr, "Error: %.*s\n", (int)message_length, message);
13. }

15. // Create a new cluster.
16. CassCluster* create_cluster(const char* hosts) {
17. CassCluster* cluster = cass_cluster_new();
18. cass_cluster_set_contact_points(cluster, hosts);
19. return cluster;
20. }

22. // Connect to the cluster given a session.
23. CassError connect_session(CassSession* session, const CassCluster* cluster) {
24. CassError rc = CASS_OK;
25. CassFuture* future = cass_session_connect(session, cluster);

27. cass_future_wait(future);
28. rc = cass_future_error_code(future);
29. if (rc != CASS_OK) {
30. print_error(future);
31. }
32. cass_future_free(future);

34. return rc;
35. }

37. CassError execute_query(CassSession* session, const char* query) {
38. CassError rc = CASS_OK;
39. CassFuture* future = NULL;
40. CassStatement* statement = cass_statement_new(query, 0);

42. future = cass_session_execute(session, statement);
43. cass_future_wait(future);

45. rc = cass_future_error_code(future);
46. if (rc != CASS_OK) {
47. print_error(future);
48. }

50. cass_future_free(future);
51. cass_statement_free(statement);

53. return rc;
54. }

56. CassError execute_and_log_select(CassSession* session, const char* stmt) {
57. CassError rc = CASS_OK;
58. CassFuture* future = NULL;
59. CassStatement* statement = cass_statement_new(stmt, 0);

61. future = cass_session_execute(session, statement);
62. rc = cass_future_error_code(future);
63. if (rc != CASS_OK) {
64. print_error(future);
65. } else {
66. const CassResult* result = cass_future_get_result(future);
67. CassIterator* iterator = cass_iterator_from_result(result);
68. if (cass_iterator_next(iterator)) {
69. const CassRow* row = cass_iterator_get_row(iterator);
70. int age;
71. const char* name; size_t name_length;
72. const char* language; size_t language_length;
73. cass_value_get_string(cass_row_get_column(row, 0), &name, &name_length);
74. cass_value_get_int32(cass_row_get_column(row, 1), &age);
75. cass_value_get_string(cass_row_get_column(row, 2), &language, &language_length);
76. printf ("Select statement returned: Row[%.*s, %d, %.*s]\n", (int)name_length, name,
77. age, (int)language_length, language);
78. } else {
79. printf("Unable to fetch row!\n");
80. }

82. cass_result_free(result);
83. cass_iterator_free(iterator);
84. }

86. cass_future_free(future);
87. cass_statement_free(statement);

89. return rc;
90. }

92. int main() {
93. // Ensure we log errors.
94. cass_log_set_level(CASS_LOG_ERROR);

96. CassCluster* cluster = NULL;
97. CassSession* session = cass_session_new();
98. CassFuture* close_future = NULL;
99. char* hosts = "127.0.0.1";

101. cluster = create_cluster(hosts);

103. if (connect_session(session, cluster) != CASS_OK) {
104. cass_cluster_free(cluster);
105. cass_session_free(session);
106. return -1;
107. }

109. CassError rc = CASS_OK;
110. rc = execute_query(session, "CREATE KEYSPACE IF NOT EXISTS ybdemo");
111. if (rc != CASS_OK) return -1;
112. printf("Created keyspace ybdemo\n");

114. rc = execute_query(session, "DROP TABLE IF EXISTS ybdemo.employee");
115. if (rc != CASS_OK) return -1;

117. rc = execute_query(session,
118. "CREATE TABLE ybdemo.employee (id int PRIMARY KEY, \
119. name varchar, \
120. age int, \
121. language varchar)");
122. if (rc != CASS_OK) return -1;
123. printf("Created table ybdemo.employee\n");

125. const char* insert_stmt = "INSERT INTO ybdemo.employee (id, name, age, language) VALUES (1, 'John', 35, 'C/C++')";
126. rc = execute_query(session, insert_stmt);
127. if (rc != CASS_OK) return -1;
128. printf("Inserted data: %s\n", insert_stmt);

130. const char* select_stmt = "SELECT name, age, language from ybdemo.employee WHERE id = 1";
131. rc = execute_and_log_select(session, select_stmt);
132. if (rc != CASS_OK) return -1;

134. close_future = cass_session_close(session);
135. cass_future_wait(close_future);
136. cass_future_free(close_future);

138. cass_cluster_free(cluster);
139. cass_session_free(session);

141. return 0;
142. }

Running 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++]

Pre-requisites

The tutorial assumes that you have:

  • installed YugabyteDB, created a universe and are able to interact with it using the Redis shell. Ifnot please follow these steps in the quick start guide.
  • have C++11.

Installing the Redis C++ Driver

We use the cpp_redis driver. To install the library do the following:

  • Clone the cpp_redis repository

1. $ git clone https://github.com/Cylix/cpp_redis.git

  • Get the networking module (tacopie)

1. $ cd cpp_redis
2. $ git submodule init && git submodule update

  • Create a build directory and move into it

1. $ mkdir build && cd build

  • Generate the Makefile using CMake

1. $ cmake .. -DCMAKE_BUILD_TYPE=Release

  • Build and install the library

1. $ make
2. $ make install

Writing a hello world redis app

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


1. #include <cpp_redis/cpp_redis>

3. #include<iostream>
4. #include<vector>
5. #include<string>
6. #include<utility>
7. using namespace std;

9. int main() {
10. cpp_redis::client client;

12. client.connect("127.0.0.1", 6379, [](const std::string& host, std::size_t port, cpp_redis::client::connect_state status) {
13. if (status == cpp_redis::client::connect_state::dropped) {
14. std::cout << "client disconnected from " << host << ":" << port << std::endl;
15. }
16. });

18. string userid = "1";
19. vector<pair<string, string>> userProfile;
20. userProfile.push_back(make_pair("name", "John"));
21. userProfile.push_back(make_pair("age", "35"));
22. userProfile.push_back(make_pair("language", "Redis"));

24. // Insert the data
25. client.hmset(userid, userProfile, [](cpp_redis::reply& reply) {
26. cout<< "HMSET returned " << reply << ": id=1, name=John, age=35, language=Redis" << endl;
27. });

29. // Query the data
30. client.hgetall(userid, [](cpp_redis::reply& reply) {
31. std::vector<cpp_redis::reply> retVal;
32. if (reply.is_array()) {
33. retVal = reply.as_array();
34. }
35. cout << "Query result:" <<endl;
36. for (int i = 0; i < retVal.size(); i=i+2) {
37. cout << retVal[i] << "=" <<retVal[i+1] << endl;
38. }
39. });

41. // synchronous commit, no timeout
42. client.sync_commit();

44. return 0;
45. }

Running the app

To compile the file, run the following command


1. $ g++ -ltacopie -lcpp_redis -std=c++11 -o ybredis_hello_world ybredis_hello_world.cpp

To run the app do


1. $ ./ybredis_hello_world

You should see the following output


1. HMSET returned OK: id=1, name=John, age=35, language=Redis
2. Query result:
3. age=35
4. language=Redis
5. name=John