0

I am trying to retrieve data from Cassandra using libCQL library in C++.... The table that I have created in Cassandra is like this -

create table test_cql (user_id text, column_name text, column_value blob, primary key (id, column_name));

And below is the data that is there in the above table -

cqlsh:testks> select column_name, column_value from test_cql where user_id = '1';

 column_name              | column_value
--------------------------+--------------------------------------------------------------------------------------------
 @hello.1381780131229.dc1 | 0x7fff0000012c4ebb95550000001e42797465204172726179205465737420466f722042696720456e6469616e

Here column_value is the actual blob value which is what I am trying to retrieve...

Now below is the C++ code I have which will try to retrieve the data from Cassandra for user_id = 1 in which I am trying to print out column_name and column_value details.

    bool flag = false;
    std::map<std::string, std::string> m;
    std::string key, value;

    string query = "select column_name, column_value from test_cql where user_id ='1';";
    std::cout << query << endl;

// the below line will execute the query
    cql_result_t& result = execute_query(query);

// this will print out the result after executing the above query

    while (result.next()) {
        for (size_t i = 0; i < result.column_count(); ++i) {
            cql::cql_byte_t* data = NULL;
            cql::cql_int_t size = 0;
            result.get_data(i, &data, size);

            if (!flag) {
                key = reinterpret_cast<char*>(data);
                flag = true;
            } else if (flag) {
                value = reinterpret_cast<char*>(data);
                m[key] = value;
                flag = false;
            }
        }

        cout<<key << "-" << value <<endl;

    }

The above code only prints out key as @hello.1381780131229.dc1 but not the value somehow.. It should be printing out value as 0x7fff0000012c4ebb95550000001e42797465204172726179205465737420466f722042696720456e6469616e since the value is the byte array (binary blob) in Cassandra table which is column_value.

And I have declared key and value both as string which might be the problem I guess in my above code.. But I believe value is actual blob in Cassandra table (column_value).. So I am not sure how to retrieve the binary blob (byte array) using the above C++ code?

And also this binary byte array blob value can be of any variable length and it is always stored in BIG-ENDIAN byte order format.

Coming from Java background, I am having little bit problem... Any help will be appreciated on this... As I guess, its totally C++ question like which datatype I should use to represent binary byte array..

1
  • You cannot just "cast" the byte array into a String, because many byte values will not be pirntable. Code examples of how to convert a byte into its String representation are quite common. Which exactly is the issue? Commented Oct 15, 2013 at 9:20

1 Answer 1

1

Because the binary blob isn't a string, so you can't print it as a string. You have to manually print each byte in the "string".

If you wonder why, lets look at the three first bytes: 0x7f, 0xff and 0x00. Neither the first nor the second byte are printable, and the third byte is the string terminator so if you print it as a string the printing would stop there.

If you have C++11 you could do something like

std::cout << "Value = 0x";
for (const char& byte : value)
    std::cout << std::hex << static_cast<int>(byte);
std::cout << std::endl;

There is also a problem that you try to cast it as a string, which wont work (as described above). You can use std::string, but you have to use a constructor:

value = str::string(reinterpret_cast<char*>(data), size);

If the data is actually a structure, then you can use a structure for it:

struct employee
{
    uint16_t id;
    uint8_t lastModifiedDate[8];
    std::string value;
};

...

std::map<std::string, employee> m;

...

m[key].id = *reinterpret_cast<uint16_t*>(data);
std::copy(reinterpret_cast<uint8_t*>(data + 2),
          reinterpret_cast<uint8_t*>(data + 10),
          m[key].lastModifiedData);
m[key].value = std::string(reinterpret_cast<char*>(data + 10), size - 10);
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the suggestion.... You pointed our more finer details.. Let me explain you in more detail.. This byte array is composed of - first two bytes will contain my employeeId, next 8 bytes will be lastModifiedDate and remaining bytes is my actual value... Since you said, I need to manually print out each byte.. Is this possible to extract first two bytes, then next eight bytes and then the remaining bytes value from that byte array? NOTE: This byte array is in big endian byte order format..
And also what is ch here?
@TrekkieTechieT-T As for parsing the data, you could have a structure with the correct types, and cast it as such instead. Will update my answer.
Thanks a lot for the help.. here my employeeId is short datatype in java which is of two bytes.. and lastModifiedDate is long datatype in java which is of eight bytes and rest is again bytearray of variable length... So I need to extract these three things from that byte array..
uint8_t value[X]; here X we don't know, what it will be as it can be of variable length..
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.