pvaz
1
Hi there,
I have one situation in hands that I've tried many ways to solve but still not.
I am using SQLite databases and on a function to get data from database i had many leaks to solve, but one until know i could not solve it.
The code i'm using is:
char* sql;
sql = sqlite3_mprintf("SELECT * from Users where id = '%s';", userid);
userid is a String that is passed to the function.
The function from SQLite called sqlite3_mprintf give me leaks and i could not compile my project in MacOS, since it give me errors.
Or, how can I convert a String to a char* ?
Is there any other way for me to create the SQL sentence of type char* that will not cause any leak ?
Thank you,
Paulo
matty
2
Are you calling sqlite3_free() anywhere?
http://www.sqlite.org/c3ref/mprintf.html
pvaz
3
Yes, Matty.
I'm calling:
sqlite3_free(sql) and sqlite3_finalize(query);
I solved my problem right now, problem was that i was using the expression wrongly, i needed to put:
sql = sqlite3_mprintf("SELECT * from Users where id = '%s';", userid.toRawUTF8());
Now i finally made the complete function without any leaks.
My final function is:
UsersTBL LoginComponent::DBGetUserByID(String userid)
{
UsersTBL UserData;
int ret = 0;
String DBPath = getStoragePath();
char* sql = NULL;
sqlite3* pDb = NULL;
sqlite3_stmt* query = NULL;
UserData.ID = 0;
File fptr_db(DBPath);
if (fptr_db.existsAsFile())
{
sqlite3_initialize();
ret = sqlite3_open_v2(DBPath.toRawUTF8(), &pDb, SQLITE_OPEN_READONLY, NULL);
if (ret != SQLITE_OK)
{
sqlite3_close(pDb);
sqlite3_shutdown();
return UserData;
}
sql = sqlite3_mprintf("SELECT * from Users where id = '%s';", userid.toRawUTF8());
ret = sqlite3_prepare_v2(pDb, sql, -1, &query, NULL);
if (ret != SQLITE_OK)
{
sqlite3_free(sql);
sqlite3_finalize(query);
sqlite3_close(pDb);
sqlite3_shutdown();
return UserData;
}
if (SQLITE_ROW != (ret = sqlite3_step(query)))
{
UserData.ID = 0;
sqlite3_free(sql);
sqlite3_finalize(query);
sqlite3_close(pDb);
sqlite3_shutdown();
return UserData;
} else {
UserData.ID = (int)sqlite3_column_text(query, 0);
UserData.Name = (char*)sqlite3_column_text(query, 2);
UserData.Password = (char*)sqlite3_column_text(query, 3);
}
sqlite3_free(sql);
sqlite3_finalize(query);
sqlite3_close(pDb);
sqlite3_shutdown();
}
sql = nullptr;
pDb = nullptr;
query = nullptr;
return UserData;
}
Still have one issue with:
UserData.ID = (int)sqlite3_column_text(query, 0);
That in MacOSX says when compiling: "Cast from pointer to smaller type 'int' loses information".
If you have any advice it's great.
I share my function that perhaps can be improved but can also serve as reference to others.
Paulo
http://www.juce.com/api/classString.html#a026f5d21f882d2ffe0406ef1e4907897
Also search this forum for a previous thread where I asked about SQLITE
Rail
pvaz
5
Solved ! uff.
in:
UserData.ID = (int)sqlite3_column_text(query, 0);
should be:
UserData.ID = (intptr_t)sqlite3_column_text(query, 0);
and this is finally well.
Paulo
sqlite3_stmt* stmt;
int rc;
const char* tail;
String szSQL;
szSQL = "SELECT * from Users where id = '" + String (iIDValue) + "';";
rc = sqlite3_prepare_v2 (m_db, szSQL.getCharPointer(), -1, &stmt, &tail);
and to read a String…
String sqlite3TextToString (const uint8* pSqlite3TextValue, int iLength)
{
if (pSqlite3TextValue == nullptr)
return String::empty;
const CharPointer_UTF8::CharType* c = reinterpret_cast<const CharPointer_UTF8::CharType*>(pSqlite3TextValue);
return String (CharPointer_UTF8 (c), CharPointer_UTF8 (c + iLength));
}
and usage:
String szValue = sqlite3TextToString (sqlite3_column_text (stmt, 0), sqlite3_column_bytes (stmt, 0));
Rail