Char* and Strings


#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


#2

Are you calling sqlite3_free() anywhere?

http://www.sqlite.org/c3ref/mprintf.html


#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

 


#4

http://www.juce.com/api/classString.html#a026f5d21f882d2ffe0406ef1e4907897

Also search this forum for a previous thread where I asked about SQLITE

Rail


#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


#6
    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