1 /*
2 This is free and unencumbered software released into the public domain.
3
4 Anyone is free to copy, modify, publish, use, compile, sell, or
5 distribute this software, either in source code form or as a compiled
6 binary, for any purpose, commercial or non-commercial, and by any
7 means.
8
9 In jurisdictions that recognize copyright laws, the author or authors
10 of this software dedicate any and all copyright interest in the
11 software to the public domain. We make this dedication for the benefit
12 of the public at large and to the detriment of our heirs and
13 successors. We intend this dedication to be an overt act of
14 relinquishment in perpetuity of all present and future rights to this
15 software under copyright law.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 OTHER DEALINGS IN THE SOFTWARE.
24
25 For more information, please refer to <http://unlicense.org/>
26 */
27
28 #include <assert.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "cassandra.h"
34
print_error_description(CassError rc)35 void print_error_description(CassError rc) {
36 fprintf(stderr, "Error Description: %s\n", cass_error_desc(rc));
37 }
38
print_error(CassFuture * future)39 void print_error(CassFuture* future) {
40 const char* message;
41 size_t message_length;
42 cass_future_error_message(future, &message, &message_length);
43 fprintf(stderr, "Error: %.*s\n", (int)message_length, message);
44 }
45
create_quorum_execution_profile()46 CassExecProfile* create_quorum_execution_profile() {
47 CassExecProfile* profile = cass_execution_profile_new();
48 cass_execution_profile_set_consistency(profile, CASS_CONSISTENCY_QUORUM);
49 cass_execution_profile_set_request_timeout(profile, 300000); /* Five minute request timeout */
50 return profile;
51 }
52
create_reduced_latency_write_execution_profile()53 CassExecProfile* create_reduced_latency_write_execution_profile() {
54 CassExecProfile* profile = cass_execution_profile_new();
55 cass_execution_profile_set_load_balance_round_robin(profile);
56 cass_execution_profile_set_token_aware_routing(profile, cass_true);
57 cass_execution_profile_set_consistency(profile, CASS_CONSISTENCY_ANY);
58 return profile;
59 }
60
create_cluster(const char * hosts)61 CassCluster* create_cluster(const char* hosts) {
62 CassCluster* cluster = cass_cluster_new();
63 cass_cluster_set_contact_points(cluster, hosts);
64 return cluster;
65 }
66
connect_session(CassSession * session,const CassCluster * cluster)67 CassError connect_session(CassSession* session, const CassCluster* cluster) {
68 /* Provide the cluster object as configuration to connect the session */
69 CassError rc = CASS_OK;
70 CassFuture* future = cass_session_connect(session, cluster);
71
72 rc = cass_future_error_code(future);
73 if (rc != CASS_OK) {
74 /* Handle error */
75 print_error(future);
76 }
77 cass_future_free(future);
78
79 return rc;
80 }
81
execute_query(CassSession * session,const char * query)82 CassError execute_query(CassSession* session, const char* query) {
83 /* Build statement and execute query */
84 CassError rc = CASS_OK;
85 CassFuture* future = NULL;
86 CassStatement* statement = cass_statement_new(query, 0);
87 future = cass_session_execute(session, statement);
88
89 rc = cass_future_error_code(future);
90 if (rc != CASS_OK) {
91 /* Handle error */
92 print_error(future);
93 }
94
95 cass_future_free(future);
96 cass_statement_free(statement);
97
98 return rc;
99 }
100
insert_into_examples(CassSession * session,const char * profile_name,const char * key,const cass_bool_t value)101 CassError insert_into_examples(CassSession* session, const char* profile_name, const char* key,
102 const cass_bool_t value) {
103 CassError rc = CASS_OK;
104 CassStatement* statement = NULL;
105 CassFuture* future = NULL;
106 const char* query = "INSERT INTO examples.execution_profiles \
107 (key, value) VALUES (?, ?)";
108
109 /* Build statement and execute query */
110 statement = cass_statement_new(query, 2);
111 if (profile_name != NULL) {
112 rc = cass_statement_set_execution_profile(statement, profile_name);
113 if (rc != CASS_OK) {
114 print_error_description(rc);
115 }
116 }
117 cass_statement_set_keyspace(statement, "execution_profiles");
118 cass_statement_add_key_index(statement, 0);
119 cass_statement_bind_string(statement, 0, key);
120 cass_statement_bind_bool(statement, 1, value);
121 future = cass_session_execute(session, statement);
122
123 rc = cass_future_error_code(future);
124 if (rc != CASS_OK) {
125 /* Handle error */
126 print_error(future);
127 }
128
129 cass_future_free(future);
130 cass_statement_free(statement);
131
132 return rc;
133 }
134
select_from_examples(CassSession * session,const char * profile_name,const char * key,cass_bool_t * return_value)135 CassError select_from_examples(CassSession* session, const char* profile_name, const char* key,
136 cass_bool_t* return_value) {
137 CassError rc = CASS_OK;
138 CassStatement* statement = NULL;
139 CassFuture* future = NULL;
140
141 /* Build statement and execute query */
142 const char* query = "SELECT * FROM examples.execution_profiles WHERE key = ?";
143 statement = cass_statement_new(query, 1);
144 if (profile_name != NULL) {
145 rc = cass_statement_set_execution_profile(statement, profile_name);
146 if (rc != CASS_OK) {
147 print_error_description(rc);
148 }
149 }
150 cass_statement_bind_string(statement, 0, key);
151 future = cass_session_execute(session, statement);
152
153 rc = cass_future_error_code(future);
154 if (rc != CASS_OK) {
155 /* Handle error */
156 print_error(future);
157 } else {
158 /* Retrieve result set and get the first row */
159 const CassResult* result = cass_future_get_result(future);
160 const CassRow* row = cass_result_first_row(result);
161 if (row) {
162 const CassValue* value = cass_row_get_column_by_name(row, "value");
163 cass_value_get_bool(value, return_value);
164 printf("SELECT: Key = %s | Value = %s\n", key,
165 (*return_value == cass_true ? "true" : "false"));
166 }
167
168 cass_result_free(result);
169 }
170
171 cass_future_free(future);
172 cass_statement_free(statement);
173
174 return rc;
175 }
176
main(int argc,char * argv[])177 int main(int argc, char* argv[]) {
178 /* Setup default objects */
179 CassCluster* cluster = NULL;
180 CassSession* session = cass_session_new();
181 CassExecProfile* profile = NULL;
182 cass_bool_t value = cass_false;
183 const char* hosts = "127.0.0.1,127.0.0.2,127.0.0.3";
184
185 /* Add contact points and create the cluster */
186 if (argc > 1) {
187 hosts = argv[1];
188 }
189 cluster = create_cluster(hosts);
190
191 /* Create and set execution profiles; freeing once added to configuration */
192 profile = create_reduced_latency_write_execution_profile();
193 cass_cluster_set_execution_profile(cluster, "reduced_latency", profile);
194 cass_execution_profile_free(profile);
195 profile = create_quorum_execution_profile();
196 cass_cluster_set_execution_profile(cluster, "quorum", profile);
197 cass_execution_profile_free(profile);
198
199 /* Provide the cluster object as configuration to connect the session */
200 if (connect_session(session, cluster) != CASS_OK) {
201 cass_cluster_free(cluster);
202 cass_session_free(session);
203 return -1;
204 }
205
206 /* Create a keyspace and table for the execution profile example */
207 execute_query(session, "CREATE KEYSPACE IF NOT EXISTS examples WITH replication = { \
208 'class': 'SimpleStrategy', 'replication_factor': '3' \
209 }");
210 execute_query(session, "CREATE TABLE IF NOT EXISTS examples.execution_profiles ( \
211 key text PRIMARY KEY, \
212 value boolean \
213 )");
214
215 /* Insert values using 'reduced_latency' profile */
216 insert_into_examples(session, "reduced_latency", "one", cass_true);
217 insert_into_examples(session, "reduced_latency", "two", cass_false);
218 insert_into_examples(session, "reduced_latency", "three", cass_true);
219 insert_into_examples(session, "reduced_latency", "four", cass_false);
220 insert_into_examples(session, "reduced_latency", "five", cass_true);
221
222 /* Select the values from the cluster using the 'quorum' profile */
223 select_from_examples(session, "quorum", "one", &value);
224 assert(value == cass_true);
225 select_from_examples(session, "quorum", "two", &value);
226 assert(value == cass_false);
227 select_from_examples(session, "quorum", "three", &value);
228 assert(value == cass_true);
229 select_from_examples(session, "quorum", "four", &value);
230 assert(value == cass_false);
231 select_from_examples(session, "quorum", "five", &value);
232 assert(value == cass_true);
233
234 cass_cluster_free(cluster);
235 cass_session_free(session);
236
237 return 0;
238 }
239