C++ SQLite throws SQLITE_BUSY error.
by apoorv569 from LinuxQuestions.org on (#5GYWQ)
I have a application that I'm making in C++ using wxWidgets for managing audio samples, and using SQLite for the database. When I insert a couple of files it handles them fine, but if I try to insert a lot of files at once, the database eventually throws SQLITE_BUSY error, and stops inserting anything to database. How do I handle this error and fix it, so the database can handle such load.
This is how my application looks like,
https://i.imgur.com/X7kS93e.png
I add files to by either double clicking items in the left browser panel, or dragging and dropping directories/files on to it from external file browser for example.
This is the insert function that inserts those files to the SQLite database,
Code:void Database::InsertSample(int favorite, std::string filename,
std::string fileExtension, std::string samplePack,
std::string type, int channels, int length,
int sampleRate, int bitrate, std::string path,
int trashed)
{
try
{
rc = sqlite3_open("sample.hive", &m_Database);
std::string insert = "INSERT INTO SAMPLES (FAVORITE, FILENAME, \
EXTENSION, SAMPLEPACK, TYPE, CHANNELS, LENGTH, \
SAMPLERATE, BITRATE, PATH, TRASHED) \
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
rc = sqlite3_prepare_v2(m_Database, insert.c_str(), insert.size(), &m_Stmt, NULL);
rc = sqlite3_bind_int(m_Stmt, 1, favorite);
rc = sqlite3_bind_text(m_Stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC);
rc = sqlite3_bind_text(m_Stmt, 3, fileExtension.c_str(), fileExtension.size(), SQLITE_STATIC);
rc = sqlite3_bind_text(m_Stmt, 4, samplePack.c_str(), samplePack.size(), SQLITE_STATIC);
rc = sqlite3_bind_text(m_Stmt, 5, type.c_str(), type.size(), SQLITE_STATIC);
rc = sqlite3_bind_int(m_Stmt, 6, channels);
rc = sqlite3_bind_int(m_Stmt, 7, length);
rc = sqlite3_bind_int(m_Stmt, 8, sampleRate);
rc = sqlite3_bind_int(m_Stmt, 9, bitrate);
rc = sqlite3_bind_text(m_Stmt, 10, path.c_str(), path.size(), SQLITE_STATIC);
rc = sqlite3_bind_int(m_Stmt, 11, trashed);
if (sqlite3_step(m_Stmt) != SQLITE_DONE)
{
wxLogWarning("No data inserted.");
}
rc = sqlite3_finalize(m_Stmt);
if (rc != SQLITE_OK)
{
wxMessageDialog msgDialog(NULL,
"Error! Cannot insert data into table.",
"Error", wxOK | wxICON_ERROR);
msgDialog.ShowModal();
sqlite3_free(m_ErrMsg);
}
else
{
wxLogInfo("Data inserted successfully. %s", m_ErrMsg);
}
if (rc == SQLITE_BUSY)
wxLogDebug("SQLITE_BUSY");
if (rc == SQLITE_ABORT)
wxLogDebug("SQLITE_ABORT");
if (rc == SQLITE_NOMEM)
wxLogDebug("SQLITE_NOMEM");
if (rc == SQLITE_LOCKED)
wxLogDebug("SQLITE_LOCKED");
if (rc == SQLITE_IOERR)
wxLogDebug("SQLITE_IOERR");
if (rc == SQLITE_CORRUPT)
wxLogDebug("SQLITE_CORRUPT");
if (rc == SQLITE_READONLY)
wxLogDebug("SQLITE_READONLY");
if (rc == SQLITE_ERROR)
wxLogDebug("SQLITE_ERROR");
if (rc == SQLITE_PERM)
wxLogDebug("SQLITE_PERM");
if (rc == SQLITE_INTERNAL)
wxLogDebug("SQLITE_INTERNAL");
sqlite3_close(m_Database);
}
catch (const std::exception &exception)
{
wxLogDebug(exception.what());
}
}Those if (rc == SQLITE_BUSY) and all checks below it I added after I encountered the problem with items not getting inserted in the database, to see what is happening, that's when I discovered it throws SQLITE_BUSY.


This is how my application looks like,
https://i.imgur.com/X7kS93e.png
I add files to by either double clicking items in the left browser panel, or dragging and dropping directories/files on to it from external file browser for example.
This is the insert function that inserts those files to the SQLite database,
Code:void Database::InsertSample(int favorite, std::string filename,
std::string fileExtension, std::string samplePack,
std::string type, int channels, int length,
int sampleRate, int bitrate, std::string path,
int trashed)
{
try
{
rc = sqlite3_open("sample.hive", &m_Database);
std::string insert = "INSERT INTO SAMPLES (FAVORITE, FILENAME, \
EXTENSION, SAMPLEPACK, TYPE, CHANNELS, LENGTH, \
SAMPLERATE, BITRATE, PATH, TRASHED) \
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
rc = sqlite3_prepare_v2(m_Database, insert.c_str(), insert.size(), &m_Stmt, NULL);
rc = sqlite3_bind_int(m_Stmt, 1, favorite);
rc = sqlite3_bind_text(m_Stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC);
rc = sqlite3_bind_text(m_Stmt, 3, fileExtension.c_str(), fileExtension.size(), SQLITE_STATIC);
rc = sqlite3_bind_text(m_Stmt, 4, samplePack.c_str(), samplePack.size(), SQLITE_STATIC);
rc = sqlite3_bind_text(m_Stmt, 5, type.c_str(), type.size(), SQLITE_STATIC);
rc = sqlite3_bind_int(m_Stmt, 6, channels);
rc = sqlite3_bind_int(m_Stmt, 7, length);
rc = sqlite3_bind_int(m_Stmt, 8, sampleRate);
rc = sqlite3_bind_int(m_Stmt, 9, bitrate);
rc = sqlite3_bind_text(m_Stmt, 10, path.c_str(), path.size(), SQLITE_STATIC);
rc = sqlite3_bind_int(m_Stmt, 11, trashed);
if (sqlite3_step(m_Stmt) != SQLITE_DONE)
{
wxLogWarning("No data inserted.");
}
rc = sqlite3_finalize(m_Stmt);
if (rc != SQLITE_OK)
{
wxMessageDialog msgDialog(NULL,
"Error! Cannot insert data into table.",
"Error", wxOK | wxICON_ERROR);
msgDialog.ShowModal();
sqlite3_free(m_ErrMsg);
}
else
{
wxLogInfo("Data inserted successfully. %s", m_ErrMsg);
}
if (rc == SQLITE_BUSY)
wxLogDebug("SQLITE_BUSY");
if (rc == SQLITE_ABORT)
wxLogDebug("SQLITE_ABORT");
if (rc == SQLITE_NOMEM)
wxLogDebug("SQLITE_NOMEM");
if (rc == SQLITE_LOCKED)
wxLogDebug("SQLITE_LOCKED");
if (rc == SQLITE_IOERR)
wxLogDebug("SQLITE_IOERR");
if (rc == SQLITE_CORRUPT)
wxLogDebug("SQLITE_CORRUPT");
if (rc == SQLITE_READONLY)
wxLogDebug("SQLITE_READONLY");
if (rc == SQLITE_ERROR)
wxLogDebug("SQLITE_ERROR");
if (rc == SQLITE_PERM)
wxLogDebug("SQLITE_PERM");
if (rc == SQLITE_INTERNAL)
wxLogDebug("SQLITE_INTERNAL");
sqlite3_close(m_Database);
}
catch (const std::exception &exception)
{
wxLogDebug(exception.what());
}
}Those if (rc == SQLITE_BUSY) and all checks below it I added after I encountered the problem with items not getting inserted in the database, to see what is happening, that's when I discovered it throws SQLITE_BUSY.