I have my code below. My values _emailVaue
_passwordValue
and _nameValue
are taken from UITextFields
in my app. I was under t
I'll try to explain what happened with your code and how it could be improved so that the crash would not occur. I totally agree with the usage of bound arguments, this answer is posted only as it represents an answer to how your crash can be fixed, and might help people that don't have the time to switch to bound statements.
Here's what happened:
sqlite3_prepare_v2()
failed as your query string was invalid due to the fact that your strings contained the "
charactedstatement
was either NULL
or contained a garbage valuesqlite3_step()
crashed as an invalid pointer was passed as argument.Here's the fix:
"
by \"
, this will generate a valid query; if you were using '
in your query, then you would have to replace '
's by \'
Example for email:
NSString *escapedEmail = [_emailValue stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];
sqlite3_prepare_v2()
before using the statement in any other sqlite
calls.As a general note, you need to code very defensively when dealing with C API's as C doesn't forgive you if you forget to check for NULL
pointers. Objective-C is more soft, as it allows you to send messages to nil
objects.
I hope it's OK to answer my own question if it seems to work. Hopefully someone will find it useful. Would appreciate any feedback on where I might be going wrong.
sqlite3_stmt *statement;
const char *dbpath = [_databasePath UTF8String];
const char *insertSQL;
if (sqlite3_open(dbpath, &_contactDB) == SQLITE_OK)
{
insertSQL = "INSERT INTO CONTACTS (email, password, name) VALUES (?, ?, ?)";
if(sqlite3_prepare_v2(_contactDB, insertSQL, -1, &statement, NULL) == SQLITE_OK)
{
sqlite3_bind_text(statement, 1, [_emailValue UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 2, [_passwordValue UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(statement, 3, [_nameValue UTF8String], -1, SQLITE_TRANSIENT);
}
if (sqlite3_step(statement) == SQLITE_DONE)
{
//worked
} else {
//didn't work
}
sqlite3_finalize(statement);
sqlite3_close(_contactDB);
}