as_ldt_init failed to initialize -- C++ client - c++

just day before i started to work with aerospike. I have some problem while writing one sample using LDT (Large data types -- Large List). I want to create a key with currdate with appended as key (20160419_2000_List) and later i will add raw data (byte array) as list values.
For that i am able to connect the database correctly, but i am not able to create key for list. Can you please guide me on this.
You can refer the following code to get idea of what i am doing exactly.
m_sTFPKeyStr.assign(datevalue); //datavalue consists datatime string
m_sTFPListStr.assign("List_");
m_sTFPListStr.append(datevalue);
as_key_init_str(&m_sTFPKey, m_sInputNameSpace.c_str(), m_sInputSetName.c_str(), m_sTFPKeyStr.c_str());
if (!as_ldt_init(m_sTFPListKey, m_sTFPListStr.c_str(), AS_LDT_LLIST, NULL))
{
memset(logmessage, 0x0, sizeof(logmessage));
sprintf(logmessage, "CDataBaseManager::SaveTFP Fails to initialize tfplist key %s", m_sTFPListStr.c_str());
m_pCaptureManager->m_pLogMgr->LogMsg(logmessage);
return;
}

Check the length of m_sTFPListStr in your code.
The codes of function as_ldt_init which will check the parameters :
as_ldt * as_ldt_init(as_ldt * ldt, const as_bin_name name, const as_ldt_type type, const as_udf_module_name module)
{
if (!name || name[0] == '\0' || strlen(name) > AS_BIN_NAME_MAX_LEN
|| (module && strlen(module) > AS_UDF_MODULE_MAX_LEN) )
{
return NULL;
}
...
}
As the value of AS_BIN_NAME_MAX_LEN:
#define AS_BIN_NAME_MAX_LEN (AS_BIN_NAME_MAX_SIZE - 1)
#define AS_BIN_NAME_MAX_SIZE 15

Related

How to set a NULL column value through an ADO query connected to a MySQL ODBC source in C++?

Given a given MySQL table
DESC tabl_foo;
--------------------------------
Field Type Null Key Default Extra
-----------------------------------------------------------------
fooId varchar(15) NO PRI NULL
FooDate date YES MUL NULL
I need to update FooDate for a given row. So I tried this code :
query->SQL->Add("UPDATE tbl_foo SET FooDate = :FooDate WHERE fooId = :id"):
// both arguments are AnsiString
query->Parameters->FindParam("id")->Value = FoodId;
query->Parameters->FindParam("FooDate")->Value = FooDate;
query->ExecSQL();
However, this fails
Incorrect date value: "" for folumn FooDate at row 1
It turns out that FooDate may be an empty string (or { data:NULL }), and MySQL does not like that. So, I tried setting Null() :
if (FooDate.IsEmpty())
query->Parameters->FindParam("FooDate")->Value = Null();
else
query->Parameters->FindParam("FooDate")->Value = FooDate;
But then I get this error :
Parameter object is improperly defined. Inconsistent or incomplete information was provided.
What should be the value to set for MySQL NULL?
To make the update the system needs to know the types of the parameters. It can deduce the type from the variant you apply, and MySQL can do certain conversions for you, but it's always best to specify the data type.
So what you would need is something like:
if((pParam=query->Parameters->FindParam("FooDate"))!=NULL)
{
pParam->DataType=ftDate;
if(FooDate.IsEmpty())
{
pParam->Value=Null();
}
else
{
pParam->Value=FooDate;
}
}
You may want to look at keeping FooDate as a TDateTime, but you will need to detect NULL dates properly.

Mapping of Blob type in C++Driver

According to "datastax.github.io/cpp-driver/topics/basics/", the blob data type of Cassandra is matched to 'const cass_byte_t*'. Suppose the database, contains a structure saved in the form of blob; how can I fetch it.
Somebody had suggested me using cass_value_get_bytes(). Can anybody give example of how to use this function to fetch the structure?
What is the problem with cass_value_get_bytes()? You simply need to perform casting of data read to your structure, something like:
const cass_byte_t* outPtr = null;
size_t outSize = 0;
if (cass_value_get_bytes(casValue, &outPtr, &outSize) == CASS_OK) {
if (outSize == sizeof(YourStruct)) {
const YourStruct* yourStruct = reinterpret_cast<const YourStruct*>(outPtr);
}
}

Indentifier not found in non-program loop script

I have tried to look up the "identifier not found" error only to find posts where the function must be moved outside the main loop or should use a forward declaration. However, my script is used as a module for a game engine thus has no real main loop and the function in question is called by a different function above the failing line with no issues:
// Create a Steam ID
CSteamID Steam::createSteamID(uint32 steamID, int accountType){
CSteamID cSteamID;
if(accountType < 0 || accountType >= k_EAccountTypeMax){
accountType = 1;
}
cSteamID.Set(steamID, EUniverse(k_EUniversePublic), EAccountType(accountType));
return cSteamID;
}
// Set a Steam user as someone recently played with
void Steam::setPlayedWith(int steamID){
if(SteamFriends() == NULL){
return;
}
CSteamID friendID = createSteamID(steamID);
SteamFriends()->SetPlayedWith(friendID);
}
// Get friend's Steam username
String getFriendPersonaName(int steamID){
if(SteamFriends() == NULL || steamID == 0){
return "";
}
CSteamID friendID = createSteamID(steamID);
bool isDataLoading = SteamFriends()->RequestUserInformation(friendID, true);
if(!isDataLoading){
return SteamFriends()->GetFriendPersonaName(friendID);
}
}
The ID creation function sits at the very top and these two functions come much later. The first one (setPlayedWith) succeeds no problem but the second one (getFriendPersonaName) fails with: 'createSteamID': identifier not found when compiling the script.
I'm kind of at a loss and hopefully someone can point me in the right direction.
if getFriendPersonaName() is a member function then you have forgotten to define it the correct way so it will look like:
string Steam::getFriendPersonaName(int steamID)...
if it is not a member then you can't access it. however you can Only access it if getFriendPersonaName() is a friend function where you should edit the signature to:
String getFriendPersonaName(int steamID, const steam& rhs);

Saving text in Sqlite3, c++

here is my second post in the community, excuse me if I'm forget to add something, just let me know:
I am trying to do a program in c++ able to save text (i want to save code) in a database using sqlite3. Currently I've made a wxWidget program that call some functions from a DLL and this ones interactuate with the database.
The database that I want to make is really simple, it has 3 columns in one table (id,name, ref). My problem comes when I want to save big amount of text that also contains simblos that can conflict with the sql queries (I would like to save files inside the database, for example in the "ref" column ).
I'm using mostly the sqlite3_exec function, because the functions sqlite3_prepare_v2, sqlite_bind, sqlite3_step crash me the DLL where I'm working.
My doubt: Can I directly save any text as big as I want, without taking care about if it has simbols or not? and how can I do it?.
More info: I am working in c++ with code:block(13.12) making a DLL of sqlite3 functions and using MinGW toolchain. (windows 7).
This is an example of an insert function that I'm using:
int DLL_EXPORT add_item(sqlite3* db, string tbname,string col,string item)
{
char* db_err = 0;
if (tbname==std::string()||col==std::string()||item==std::string())
throw std::invalid_argument( "stoi: invalid argument table name");
char buf[200];
sprintf(buf,"insert into %s (%s) values ('%s');", tbname.c_str(), col.c_str(),item.c_str());
int n = sqlite3_exec(db, buf, NULL, 0, &db_err);
dsperr(&db_err);
if( n != SQLITE_OK )
{
//throw something
}
return 0;
}
Thank you in advance.
Thank to CL. for the up commentary
// Add one text to a table
// The column must be specify
//
int DLL_EXPORT add_text(sqlite3* db, string tbname,string col,string id,string item)
{
char* db_err = 0;
if (tbname==std::string()||col==std::string()||item==std::string())
throw std::invalid_argument( "stoi: invalid argument table name");
char *zSQL = sqlite3_mprintf("UPDATE %q SET %q=(%Q) WHERE id=%q", tbname.c_str(),col.c_str() ,item.c_str(),id.c_str());
int n = sqlite3_exec(db, zSQL, NULL, 0, &db_err);
dsperr(&db_err);
sqlite3_free(zSQL);
if( n != SQLITE_OK )
{
// throw something
}
return 0;
}

Implementing bulk record fetching

At the start of my program, I need to read data from a MS Access database (.mdb) into a drop down control. This is done so that whenever the user types in that control, the application can auto-complete.
Anyway, the reading from database took forever so I thought I'd implement bulk row fetching.
This is the code I have:
CString sDsn;
CString sField;
sDsn.Format("ODBC;DRIVER={%s};DSN='';DBQ=%s",sDriver,sFile);
TRY
{
// Open the database
database.Open(NULL,false,false,sDsn);
// Allocate the rowset
CMultiRowset recset( &database );
// Build the SQL statement
SqlString = "SELECT NAME "
"FROM INFOTABLE";
// Set the rowset size. These many rows will be fetched in one bulk operation
recset.SetRowsetSize(25);
// Open the rowset
recset.Open(CRecordset::forwardOnly, SqlString, CRecordset::readOnly | CRecordset::useMultiRowFetch);
// Loop through each rowset
while( !recset.IsEOF() )
{
int rowsFetched = (int)recset.GetRowsFetched(); // This value is always 1 somehow
for( int rowCount = 1; rowCount <= rowsFetched; rowCount++ )
{
recset.SetRowsetCursorPosition(rowCount);
recset.GetFieldValue("NAME",sField);
m_nameDropDown.AddString(sField);
}
// Go to next rowset
recset.MoveNext();
}
// Close the database
database.Close();
}
CATCH(CDBException, e)
{
// If a database exception occured, show error msg
AfxMessageBox("Database error: "+e->m_strError);
}
END_CATCH;
MultiRowset.cpp looks like:
#include "stdafx.h"
#include "afxdb.h"
#include "MultiRowset.h"
// Constructor
CMultiRowset::CMultiRowset(CDatabase *pDB)
: CRecordset(pDB)
{
m_NameData = NULL;
m_NameDataLengths = NULL;
m_nFields = 1;
CRecordset::CRecordset(pDB);
}
void CMultiRowset::DoBulkFieldExchange(CFieldExchange *pFX)
{
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text_Bulk(pFX, _T("[NAME]"), &m_NameData, &m_NameDataLengths, 30);
}
MultiRowset.h looks like:
#if !defined(__MULTIROWSET_H_AD12FD1F_0566_4cb2_AE11_057227A594B8__)
#define __MULTIROWSET_H_AD12FD1F_0566_4cb2_AE11_057227A594B8__
class CMultiRowset : public CRecordset
{
public:
// Field data members
LPSTR m_NameData;
// Pointers for the lengths of the field data
long* m_NameDataLengths;
// Constructor
CMultiRowset(CDatabase *);
// Methods
void DoBulkFieldExchange(CFieldExchange *);
};
#endif
And in my database, the INFOTABLE looks like:
NAME AGE
---- ---
Name1 Age1
Name2 Age2
.
.
.
.
All I need to do is only read the data from the database. Can someone please tell me what I'm doing wrong? My code right now behaves exactly like a normal fetch. There's no bulk fetching happening.
EDIT:
I just poked around in DBRFX.cpp and found out that RFX_Text_Bulk() initializes my passed m_NameData as new char[nRowsetSize * nMaxLength]!
This means m_NameData is only a character array! I need to fetch multiple names, so wouldn't I need a 2D character array? The strangest thing is, the same RFX_Text_Bulk() initializes my passed m_NDCDataLengths as new long[nRowsetSize]. Why in the world would a character array need an array of lengths?!
According to http://msdn.microsoft.com/en-us/library/77dcbckz.aspx#_core_how_crecordset_supports_bulk_row_fetching you have to open CRecordset with CRecordset::useMultiRowFetch flag before call SetRowsetSize:
To implement bulk row fetching, you must specify the
CRecordset::useMultiRowFetch option in the dwOptions parameter of the
Open member function. To change the setting for the rowset size, call
SetRowsetSize.
You almost got it right. To fetch the values,
I would change your
for( int rowCount = 1; rowCount <= rowsFetched; rowCount++ )
{
recset.SetRowsetCursorPosition(rowCount);
recset.GetFieldValue("NAME",sField);
m_nameDropDown.AddString(sField);
}
by something like this
for( int nPosInRowset = 0; nPosInRowset < rowsFetched; nPosInRowset++ )
{
//Check if value is null
if (*(recset.m_NameDataLengths + nPosInRowset) == SQL_NULL_DATA)
continue;
CString csComboString;
csComboString = (recset.m_NameData + (nPosInRowset * 30)); //Where 30 is the size specified in RFX_Text_Bulk
m_nameDropDown.AddString(csComboString);
}
EDIT: To fetch more than one row, remove the CRecordset::forwardOnly option
EDIT 2 : You can also keep CRecordset::forwardonly, but add the CRecordset::useExtendedFetch option
Just faced the same problem.
You should use in recset.Open() call for dwOptions parameter only CRecordset::useMultiRowFetch, and not CRecordset::readOnly | CRecordset::useMultiRowFetch.
Hope this helps someone...
EDIT:- After re-check here is the situation - when using bulk recordset and opening with CRecordset::forwardOnly and CRecordset::readOnly, you must also specify CRecordset::useExtendedFetch in dwOptions. For other types of scrolling, using CRecordset::readOnly | CRecordset::useMultiRowFetch is just fine.