C++ cassandra client select int value - c++

I'm trying to select an integer value but I can't
This is my code:
cassandra_socket = boost::shared_ptr<TSocket>(new TSocket(host, port));
cassandra_transport = boost::shared_ptr<TFramedTransport>(new TFramedTransport(cassandra_socket));
protocol = boost::shared_ptr<TBinaryProtocol>(new TBinaryProtocol(cassandra_transport));
cassandra_client = new CassandraClient(protocol);
try {
cassandra_transport->open();
cassandra_client->set_keyspace("MPS");
ColumnOrSuperColumn csc;
ColumnPath cpath;
cpath.column_family.assign("SubmitResposes_count");
/* This is required - thrift 'feature' */
cpath.__isset.column = true;
cpath.column = "Counter";
cassandra_client->get(csc, "1", cpath,org::apache::cassandra::ConsistencyLevel::ONE);
cout << "Value read is '" << csc.column.value << "'..." << endl;
}
catch (NotFoundException &nf) {
FORCE_TRACE(0, "NOT FOUND EXCEPTION ERROR: %s", nf.what());
} catch (InvalidRequestException &re) {
FORCE_TRACE(0, "INVALID REQUEST ERROR: %s", re.why);
} catch (TException &tx) {
FORCE_TRACE(0, "TEEXCEPTION ERROR: %s", tx.what());
}
it gives me this exception:
InvalidRequest ERROR: Expected 4 or 0 byte int (1)
& this is the table I've created:
create table SubmitResposes_count(
ID int primary key,
Counter bigint);

Your key is an int:
ID int primary key,
but you are querying using a string key:
cassandra_client->get(csc, "1", cpath,org::apache::cassandra::ConsistencyLevel::ONE);
^^^
Cassandra is trying to validate your string as an int, which is causing this exception.

Related

Handle PostgreSQL transaction errors in GDALVectorTranslate

In c++ I'm using the GDAL library for importing geo-spatial files into Postgres/PostGIS.
The GDAL library will create a table in the Postgres database and insert the data. But I can't figure out how to handle errors during the inserting of data.
I'm using GDALVectorTranslate https://gdal.org/api/gdal_utils.html#gdal__utils_8h_1aa176ae667bc857ab9c6016dbe62166eb
If an Postgres error occurs the error text will be outputted and the program continues to run. I would like to handle these Postgres errors.
An error could be:
ERROR 1: INSERT command for new feature failed.
ERROR: invalid byte sequence for encoding "UTF8": 0xe5 0x20 0x46
For now I let my program count the rows in the destination table and if zero then assume error. But that doesn't work if appending to an existing table.
auto *dst = (GDALDataset *) GDALVectorTranslate(nullptr, pgDs, 1, &sourceDs, opt, &bUsageError);
if (dst == nullptr) {
std::cout << "ERROR! Couldn't create table" << std::endl;
return FALSE;
} else {
OGRLayer *layer = dst->GetLayerByName(altName);
// Here the rows are counted
if (layer->GetFeatureCount() == 0) {
std::cout << "ERROR! Insert failed" << std::endl;
return FALSE;
}
std::cout << " Imported";
return TRUE;
}
You can register your own error handler to log and count the underlying errors:
struct {/*members for handling errors*/} ctx;
static void myErrorHandler(CPLErr e, CPLErrorNum n, const char* msg) {
ctx *myctx = (ctx*)CPLGetErrorHandlerUserData();
/* do something with ctx to log and increment error count */
}
int myTranslateFunc() {
ctx myctx; //+initialization
CPLPushErrorHandlerEx(&myErrorHandler,&myctx);
auto *dst = (GDALDataset *) GDALVectorTranslate(nullptr, pgDs, 1, &sourceDs, opt, &bUsageError);
CPLPopErrorHandler();
//inspect myctx for potential errors
}

Create Elliptical Curve Signing Key using TSS/C++

I need to create an elliptical signing key using the TSS/C++ library.
However when I create it I get a strange error from the TPM simulator:
TPM Error - TPM_RC::: The specified path is invalid.
Here is the method I use to create the signing key. Can someone show me what I am doing incorrectly
DWORD CreateKeyPair(Tpm2 tpm)
{
DWORD retCode = 0;
try
{
//Create a dummy PIN for now
ByteVec userAuth = ByteVec{ 1, 2, 3, 4 };
TPMS_SENSITIVE_CREATE sensCreate(userAuth, vector<BYTE>());
vector<TPMS_PCR_SELECTION> pcrSelectSigning{};
//signing key
TPMS_ECC_PARMS signingKeyParams(TPMT_SYM_DEF_OBJECT(),
TPMS_SCHEME_ECDSA(TPM_ALG_ID::SHA256),
TPM_ECC_CURVE::NIST_P256,
TPMS_NULL_KDF_SCHEME());
//Signing key public template
TPMT_PUBLIC signingKeyTemplate(TPM_ALG_ID::SHA256,
TPMA_OBJECT::sign | // Key attribues
// Not needed, TPMA_OBJECT::encrypt |
TPMA_OBJECT::fixedParent |
TPMA_OBJECT::fixedTPM |
TPMA_OBJECT::sensitiveDataOrigin |
TPMA_OBJECT::userWithAuth,
vector<BYTE>(),
signingKeyParams,
TPMS_ECC_POINT()
);
CreatePrimaryResponse singingPrimary = tpm.CreatePrimary(TPM_RH::OWNER,
sensCreate,
signingKeyTemplate,
vector<BYTE>(),
pcrSelectSigning);
}
catch (exception e)
{
cout << "Exception thrown: " << e.what() << endl;
}
return retCode;
}

How to declare an empty rowset properly with SOCI?

Imagine that I have the following function. In case of invalid parameters or exception, the function has to exit with an empty rowset.
rowset<row> SelectAllFromTable(string tableName)
{
session sql(odbc, "...");
// if parameters are not valid -> return empty rowset<row>
if (tableName == "")
{
// query that returns 0 result
rowset<row> res = (sql.prepare << "SELECT ID FROM T1 WHERE ID = -9999");
return res;
}
string query = "SELECT * FROM " + tableName;
try
{
rowset<row> rs = sql.prepare << query;
return rs;
}
catch (exception const &e)
{
cerr << "Error: " << e.what() << endl;
// query that returns 0 result
rowset<row> res = (sql.prepare << "SELECT ID FROM T1 WHERE ID = -9999");
return res;
}
// query that returns 0 result
rowset<row> res = (sql.prepare << "SELECT ID FROM T1 WHERE ID = -9999");
return res;
}
The solution I wrote above works but my question is : Is there a better way to return an empty rowset with SOCI ?
Since the documentation hasn't much to offer to this I looked into the rowset Header: There is no default constructor for it and no public method to set the iterators, ergo you can't get an empty rowset by yourself.
Despite why don't you use exceptions which are just perfect for that case. Just don't catch the soci_error exception, then the caller SelectAllFromTable could catch it. This would have many advantages:
The caller would know if there is really no data in the table or there is no table
The caller could know why he can't use the table (misspelled or security reasons)
The caller could know if there are other troubles and take action or if not, rethrow it, so his caller might can.

Get rows with a NULL column (non-existent) in Hbase using Thrift c++

I need to get rows with a NULL column (non-existent) in Hbase using Thrift c++. Some rows have this column, some don't.
I have the following code with the filter, which works perfectly, but how could I get rows with the non-existent column?
/* Connection to the thrift server */
boost::shared_ptr<TSocket> socket(new TSocket("localhost", 9090));
boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
/* Creating the Hbase client*/
HbaseClient client(protocol);
try
{
/* Open the client transport*/
transport->open();
/* The table name */
std::string t("sometable");
/* Open the scanner: need to scan with a filter*/
StrVec columnNames;
StrMap atr_test;
TScan tscan;
std::string filterStr;
filterStr = "SingleColumnValueFilter('ColumnFamily', 'ColumnQualifier', =, 'substring:value', true, false)";
tscan.__set_filterString(filterStr);
int scanner = client.scannerOpenWithScan(t, tscan, atr_test);
while (true) {
std::vector<TRowResult> value;
client.scannerGet(value, scanner);
// Print value
for (CellMap::const_iterator it = value[0].columns.begin(); it != value[0].columns.end(); ++it) {
std::cout << " " << it->first << " => " << it->second.value << ";\n";
}
}
}
I've read about setFilterIfMissing here - How to filter out rows with given column(not null)?, but how could I implement it in my code?
Or maybe there is some other solution?

Connector/C++ MySQL error code: 2014 , SQLState: HY000 and Commands out of sync error why?

Hi im using Connector/C++ and executing simple 2 sql commands like this :
the first select sql run ok but the second one cause this exception error :
ERR: Commands out of sync; you can't run this comman d now (MySQL
error code: 2014, SQLState: HY000 )
here is the code :
//member of the class
ResultSet *temp_res;
// in different method
m_driver = get_driver_instance();
m_con = m_driver->connect(m_DBhost,m_User,m_Password);
m_con->setSchema(m_Database);
//here i excute the querys :
vector<string> query;
query.push_back("SELECT * FROM info_tbl");
query.push_back("INSERT INTO info_tbl (id,name,age)VALUES (0,foo,36)");
query.push_back("SELECT * FROM info_tbl");
ResultSet *res;
Statement *stmt;
bool stmtVal = false;
try{
stmt = m_con->createStatement();
for(size_t i = 0;i < querys.size();i++)
{
string query = querys.at(i);
stmtVal = stmt->execute(query);
if(!stmtVal)
{
string error_log ="sql statment:";
error_log.append(query);
error_log.append(" failed!");
cout << error_log << endl;
break;
}
}
if(stmtVal)
{
if(returnSet)
{
res = stmt->getResultSet();
temp_res = res;
}
}
delete stmt;
//close connection to db
m_con->close();
} catch (sql::SQLException &e) {
......
}
UPDATE NEW CODE AS SUGGESTED ( NOT WORKING )
for(size_t i = 0;i < querys.size();i++)
{
string query = querys.at(i);
stmtVal = stmt->execute(query);
if(stmtVal)
{
if(returnSet)
{
if(stmt->getResultSet()->rowsCount() > 0)
{
res = stmt->getResultSet();
temp_res = res;
}
else
{
delete res;
}
}
else
{
delete res;
}
}
if(!stmtVal)
{
string error_log ="sql statment:";
error_log.append(query);
error_log.append(" failed!");
cout << error_log << endl;
break;
}
}
this is my simple table :
Column Type Null
id int(10) No
name varchar(255) No
age int(10) No
You can't have more than one active query on a connection at a time.
From the mysql_use_result docs:
You may not use mysql_data_seek(), mysql_row_seek(), mysql_row_tell(), mysql_num_rows(), or mysql_affected_rows() with a result returned from mysql_use_result(), nor may you issue other queries until mysql_use_result() has finished.
That's not exactly what you're using, but the problem is the same - you'll need to finish processing the first ResultSet and clean it up before you can issue any other query on that connection.
I was getting the same error until I changed my code to how MySQL says to do it.
Old code:
res.reset(stmt->getResultSet());
if (res->next())
{
vret.push_back(res->getDouble("VolumeEntered"));
vret.push_back(res->getDouble("VolumeDispensed"));
vret.push_back(res->getDouble("Balance"));
}
New code without error:
do
{
res.reset(stmt->getResultSet());
while(res->next())
{
vret.push_back(res->getDouble("VolumeEntered"));
vret.push_back(res->getDouble("VolumeDispensed"));
vret.push_back(res->getDouble("Balance"));
}
} while (stmt->getMoreResults());
I ran into this problem also and took me a little while to figure it out. I had even set the "CLIENT_MULTI_RESULTS" and "CLIENT_MULTI_STATEMENTS" with no avail.
What is happening is MySql thinks that there is another result set waiting to be read from the first call to the Query. Then if you try to run another Query, MySql thinks that it still has a ResultSet from last time and sends the "Out of Sync" Error.
This looks like it might be a C++ Connector issue but I have found a workaround and wanted to post it in case anyone else is having this same issue:
sql::PreparedStatement *sqlPrepStmt;
sql::ResultSet *sqlResult;
int id;
std::string name;
try {
//Build the Query String
sqlStr = "CALL my_routine(?,?)";
//Get the Result
sqlPrepStmt = this->sqlConn->prepareStatement(sqlStr);
sqlPrepStmt->setInt(1, itemID);
sqlPrepStmt->setInt(2, groupId);
sqlPrepStmt->executeUpdate();
sqlResult = sqlPrepStmt->getResultSet();
//Get the Results
while (sqlResult->next()) {
id = sqlResult->getInt("id");
name = sqlResult->getString("name");
}
//Workaround: Makes sure there are no more ResultSets
while (sqlPrepStmt->getMoreResults()) {
sqlResult = sqlPrepStmt->getResultSet();
}
sqlResult->close();
sqlPrepStmt->close();
delete sqlResult;
delete sqlPrepStmt;
}
catch (sql::SQLException &e) {
/*** Handle Exception ***/
}