Cassandra supports conditional updates with IF clause.
After update there should be response available with info about its success. This response includes [applied] info and also information about the condition/s that failed.
How to get this response information? If I run cass_iterator_get_row after conditional update, I receive an empty row.
Example:
CassError rc = CASS_OK;
CassStatement* statement = NULL;
CassFuture* future = NULL;
const char* query = "UPDATE examples.basic SET dbl=0.2 WHERE key = 'test' IF dbl=0.3";
statement = cass_statement_new(query, 0);
cass_statement_bind_string(statement, 0, key);
future = cass_session_execute(session, statement);
cass_future_wait(future);
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);
cass_value_get_bool(cass_row_get_column(row, 0), &basic->bln);
printf("Res: %u \n", basic->bln);
}
cass_result_free(result);
cass_iterator_free(iterator);
}
//it prints "Res: 0" also when successfully updated
The output you show is printing the integer value of the cass_boot_t enumeration cass_false. If the second column of the single row returned from the result is checked it will be dbl and have a value of 0.3. To show the failing conditional more clearly using the basic example provided with the driver look at the following updated example that updates the dbl column only if the i64 column is valid during the LWT; https://pastebin.com/CdF3HUxy.
In this updated example the output is modified slightly to display more information about the result and row using the driver API:
CassError rc = CASS_OK;
CassStatement* statement = NULL;
CassFuture* future = NULL;
const char* query = "UPDATE examples.basic SET dbl=? WHERE key = ? IF i64=?";
statement = cass_statement_new(query, 3);
cass_statement_bind_double(statement, 0, update_dbl);
cass_statement_bind_string(statement, 1, key);
cass_statement_bind_int64(statement, 2, only_if_i64);
future = cass_session_execute(session, statement);
cass_future_wait(future);
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);
const char* column_name = NULL;
size_t column_name_length = 0;
cass_bool_t bln = cass_false;
printf("Column count: %lu\n", cass_result_column_count(result));
cass_result_column_name(result, 0, &column_name, &column_name_length);
cass_value_get_bool(cass_row_get_column(row, 0), &bln);
printf("%.*s: %s\n", (int) column_name_length, column_name,
(bln == cass_true ? "true" : "false"));
if (bln == cass_false) {
cass_int64_t cause = 0;
cass_result_column_name(result, 1, &column_name, &column_name_length);
cass_value_get_int64(cass_row_get_column(row, 1), &cause);
printf("%.*s: %"PRId64"\n", (int) column_name_length, column_name,
cause);
}
printf("\n");
}
cass_result_free(result);
cass_iterator_free(iterator);
}
cass_future_free(future);
cass_statement_free(statement);
Using the update values:
key = "test" | dbl = 0.0003 | i64 = 2
key = "test" | dbl = 0.0004 | i64 = 2
key = "test" | dbl = 0.0005 | i64 = 37
the output will be:
Column count: 1
[applied]: true
Column count: 1
[applied]: true
Column count: 2
[applied]: false
i64: 2
NOTE: If you have a more complex conditional that uses multiple columns then more columns will be returned during the failed LWT.
~Fero