I have started working with C++ libcql
library for Cassandra.. I am trying to retrieve data from Cassandra using C++ with libcql library..
Whenever I go on the command line using cqlsh
and do select like this -
select records from profile_user where user_id = '1';
I always get the below output on the cql command line and in which records
column is actually a map
in which key is e1
and value is HELLO
. In the same way key is e2
and value is HELLO
again.. When I created the table in CQL, I created records as the map as I was using collection feature of CQL..
records
--------------------------------
{'e1': 'HELLO', 'e2': 'HELLO'}
Now Coming to C++ world-
Now I am trying to retrieve the same thing from the C++ libcql library
... I will be running the same above select query in C++ and I want to return a map which will have e1, e2 as the key
and HELLO as there value inside that map
... It is possible to do it in C++?
/**
* This method will retrieve the data from Cassandra..
* And then call print_rows method to print it out on the console
*/
void get_attributes(string id){
try{
// some code
//Connection open
connection_open();
execute_query("USE testks;");
//this will give me the result back of the select query
cql_result_t& result = execute_query("select * from profile_user where key ='"+id+"';");
// and this is printing it out on the console
print_rows(result);
// some code
} catch (int e){
// some code here
}
}
Below is the method which will print out the results on the console after running my C++ program -
/**
* This method prints out the result on the console.. *
*
*/
void print_rows(cql::cql_result_t& result) {
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);
std::cout.write(reinterpret_cast<char*>(data), size);
std::cout << " | ";
}
std::cout << std::endl;
}
}
The result that I see on the console after running my above C++ program is something like this -
e1HELLOe2HELLO |
But what I am looking for is - Store the result in a Map in C++, in such a way such that key should be e1 and e2
in the Map.. And the value for them should be HELLO
in the same Map... And then iterate the Map and print out the result in C++? Is this possible to do with the current code I have?
If yes, can anyone provide a simple example on this? Thanks...
It is basically a C++ question I guess.. Just retrieve the data and put it into the Map... But the problem I am facing is my background is totally in Java so having little bit hard time to figure out how to do that...
I don't know libcql
and I failed to locate any documentation. Looking at the header for cql_result_t
indicates that there are functions to determine how many columns there are and how to access them. From the looks of it, you merely copied the demo example which doesn't seem to be a particular good demo. I would start off with refining the print_result()
function to look something like the below and see what I'd get. My guess is that you get a "map" type from your query and you'll need to see how to extract and use the corresponding representation by digging through their headers (unless there is somewhere some documentation). The code below mere extracts a few types and mostly prints that it needs to deal with processing the respective type (assuming it actually compiles):
void print_result(cql::cql_result_t& result)
{
std::size_t const columns(result.column_count());
while (result.next()) {
for (std::size_t column(0); column != columns; ++column) {
cql::cql_column_type_enum type;
if (result.column_type(column, type)) {
switch (type) {
case cql::CQL_COLUMN_TYPE_CUSTOM:
std::cout << "todo: process custom type\n";
break;
case cql::CQL_COLUMN_TYPE_ASCII:
std::cout << "todo: process ascii type\n";
break;
case cql::CQL_COLUMN_TYPE_BIGINT:
std::cout << "todo: process bigint type\n";
break;
case cql::CQL_COLUMN_TYPE_BLOB:
std::cout << "todo: process blob type\n";
break;
case cql::CQL_COLUMN_TYPE_BOOLEAN:
std::cout << "todo: process boolean type\n";
break;
case cql::CQL_COLUMN_TYPE_COUNTER:
std::cout << "todo: process counter type\n";
break;
case cql::CQL_COLUMN_TYPE_DECIMAL:
std::cout << "todo: process decimal type\n";
break;
case cql::CQL_COLUMN_TYPE_DOUBLE: {
double value;
if (result.get_double(column, value)) {
std::cout << "column=" << column << " "
<< "double=" << value << "\n";
}
else {
std::cout << "failed to extract double for column "
<< column << "\n";
}
break;
case cql::CQL_COLUMN_TYPE_FLOAT: {
float value;
if (result.get_float(column, value)) {
std::cout << "column=" << column << " "
<< "float=" << value << "\n";
}
else {
std::cout << "failed to extract float for column "
<< column << "\n";
}
break;
case cql::CQL_COLUMN_TYPE_INT: {
int value;
if (result.get_int(column, value)) {
std::cout << "column=" << column << " "
<< "int=" << value << "\n";
}
else {
std::cout << "failed to extract int for column "
<< column << "\n";
}
break;
case cql::CQL_COLUMN_TYPE_TEXT: {
std::string value;
if (result.get_string(column, value)) {
std::cout << "column=" << column << " "
<< "text='" << value << "'\n";
}
else {
std::cout << "failed to extract text for column "
<< column << "\n";
}
break;
case cql::CQL_COLUMN_TYPE_TIMESTAMP:
std::cout << "todo: process timestamp type\n";
break;
case cql::CQL_COLUMN_TYPE_UUID:
std::cout << "todo: process uiid type\n";
break;
case cql::CQL_COLUMN_TYPE_VARCHAR:
std::cout << "todo: process varchar type\n";
break;
case cql::CQL_COLUMN_TYPE_VARINT:
std::cout << "todo: process varint type\n";
break;
case cql::CQL_COLUMN_TYPE_TIMEUUID:
std::cout << "todo: process timeuuid type\n";
break;
case cql::CQL_COLUMN_TYPE_INET:
std::cout << "todo: process inet type\n";
break;
case cql::CQL_COLUMN_TYPE_LIST:
std::cout << "todo: process list type\n";
break;
case cql::CQL_COLUMN_TYPE_MAP:
std::cout << "todo: process map type\n";
break;
case cql::CQL_COLUMN_TYPE_SET:
std::cout << "todo: process set type\n";
break;
}
}
}
}
}
cql_result_t has a method get_map. Use get_map instead of get_data:
cql::cql_result_t *r;
cql::cql_map_t *props = 0;
if (!r->get_map("records", &props)) {
delete props;
// throw an error
}
std::auto_ptr<cql::cql_map_t> p(props);
std::map<std::string, std::string> m;
for (std::size_t i = 0; i < p->size(); ++i) {
std::string key;
if (!p->get_key_string(i, key))
// throw an error
std::string value;
if (!p->get_value_string(i, value))
// throw an error
m.insert(std::make_pair(key, value));
}