diff --git a/src/Database.cpp b/src/Database.cpp index e954693..d074e51 100644 --- a/src/Database.cpp +++ b/src/Database.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -39,6 +40,24 @@ void throw_on_sqlite3_error(int rc) } } +void debug_log_on_error(int rc) +{ + if (rc != SQLITE_OK) + { + sqlite3_errstr(rc); + } +} + +void show_modal_dialog_and_log(const std::string &message, const std::string &title, const std::string &error_msg) +{ + std::stringstream ss; + ss << message << error_msg; + const auto msg = ss.str(); + wxLogDebug(msg.c_str()); + wxMessageDialog msgDialog(NULL, msg, title, wxOK | wxICON_ERROR); + msgDialog.ShowModal(); +} + class Sqlite3Statement { public: @@ -67,66 +86,44 @@ Database::~Database() void Database::CreateTableSamples() { /* Create SQL statement */ - std::string samples = "CREATE TABLE IF NOT EXISTS SAMPLES(" - "FAVORITE INT NOT NULL," - "FILENAME TEXT NOT NULL," - "EXTENSION TEXT NOT NULL," - "SAMPLEPACK TEXT NOT NULL," - "TYPE TEXT NOT NULL," - "CHANNELS INT NOT NULL," - "LENGTH INT NOT NULL," - "SAMPLERATE INT NOT NULL," - "BITRATE INT NOT NULL," - "PATH TEXT NOT NULL," - "TRASHED INT NOT NULL," - "HIVE TEXT NOT NULL);"; + const auto samples = "CREATE TABLE IF NOT EXISTS SAMPLES(" + "FAVORITE INT NOT NULL," + "FILENAME TEXT NOT NULL," + "EXTENSION TEXT NOT NULL," + "SAMPLEPACK TEXT NOT NULL," + "TYPE TEXT NOT NULL," + "CHANNELS INT NOT NULL," + "LENGTH INT NOT NULL," + "SAMPLERATE INT NOT NULL," + "BITRATE INT NOT NULL," + "PATH TEXT NOT NULL," + "TRASHED INT NOT NULL," + "HIVE TEXT NOT NULL);"; try { - rc = sqlite3_exec(m_Database, samples.c_str(), NULL, 0, &m_ErrMsg); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, "Error! Cannot create table samples.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - else - { - wxLogDebug("Samples table created successfully."); - } + throw_on_sqlite3_error(sqlite3_exec(m_Database, samples, NULL, 0, &m_ErrMsg)); + wxLogDebug("Samples table created successfully."); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot create table samples: ", "Error", e.what()); } } void Database::CreateTableHives() { /* Create SQL statement */ - std::string hives = "CREATE TABLE IF NOT EXISTS HIVES(HIVE TEXT NOT NULL);"; + const auto hives = "CREATE TABLE IF NOT EXISTS HIVES(HIVE TEXT NOT NULL);"; try { - rc = sqlite3_exec(m_Database, hives.c_str(), NULL, 0, &m_ErrMsg); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, "Error! Cannot create table hives.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - else - { - wxLogDebug("Hives table created successfully."); - } + throw_on_sqlite3_error(sqlite3_exec(m_Database, hives, NULL, 0, &m_ErrMsg)); + wxLogDebug("Hives table created successfully."); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot create table hives: ", "Error", e.what()); } } @@ -135,18 +132,14 @@ void Database::InsertIntoSamples(const std::vector &samples) { try { - std::string insert = "INSERT INTO SAMPLES (FAVORITE, FILENAME, \ - EXTENSION, SAMPLEPACK, TYPE, CHANNELS, LENGTH, \ - SAMPLERATE, BITRATE, PATH, TRASHED, HIVE) \ - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"; + const auto sql = "INSERT INTO SAMPLES (FAVORITE, FILENAME, \ + EXTENSION, SAMPLEPACK, TYPE, CHANNELS, LENGTH, \ + SAMPLERATE, BITRATE, PATH, TRASHED, HIVE) \ + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"; - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, insert.c_str(), insert.size(), &stmt, NULL); + Sqlite3Statement statement(m_Database, sql); - rc = sqlite3_exec(m_Database, "BEGIN TRANSACTION", NULL, NULL, &m_ErrMsg); - - if (rc != SQLITE_OK) - wxLogDebug("Cannot prepare sql statement.."); + throw_on_sqlite3_error(sqlite3_exec(m_Database, "BEGIN TRANSACTION", NULL, NULL, &m_ErrMsg)); Sample sample; @@ -168,57 +161,27 @@ void Database::InsertIntoSamples(const std::vector &samples) std::string hive = "Favorites"; - rc = sqlite3_bind_int(stmt, 1, sample.GetFavorite()); - rc = sqlite3_bind_text(stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC); - rc = sqlite3_bind_text(stmt, 3, file_extension.c_str(), file_extension.size(), SQLITE_STATIC); - rc = sqlite3_bind_text(stmt, 4, sample_pack.c_str(), sample_pack.size(), SQLITE_STATIC); - rc = sqlite3_bind_text(stmt, 5, type.c_str(), type.size(), SQLITE_STATIC); - rc = sqlite3_bind_int(stmt, 6, sample.GetChannels()); - rc = sqlite3_bind_int(stmt, 7, sample.GetLength()); - rc = sqlite3_bind_int(stmt, 8, sample.GetSampleRate()); - rc = sqlite3_bind_int(stmt, 9, sample.GetBitrate()); - rc = sqlite3_bind_text(stmt, 10, path.c_str(), path.size(), SQLITE_STATIC); - rc = sqlite3_bind_int(stmt, 11, sample.GetTrashed()); - rc = sqlite3_bind_text(stmt, 12, hive.c_str(), hive.size(), SQLITE_STATIC); + throw_on_sqlite3_error(sqlite3_bind_int(statement.stmt, 1, sample.GetFavorite())); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC)); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 3, file_extension.c_str(), file_extension.size(), SQLITE_STATIC)); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 4, sample_pack.c_str(), sample_pack.size(), SQLITE_STATIC)); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 5, type.c_str(), type.size(), SQLITE_STATIC)); + throw_on_sqlite3_error(sqlite3_bind_int(statement.stmt, 6, sample.GetChannels())); + throw_on_sqlite3_error(sqlite3_bind_int(statement.stmt, 7, sample.GetLength())); + throw_on_sqlite3_error(sqlite3_bind_int(statement.stmt, 8, sample.GetSampleRate())); + throw_on_sqlite3_error(sqlite3_bind_int(statement.stmt, 9, sample.GetBitrate())); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 10, path.c_str(), path.size(), SQLITE_STATIC)); + throw_on_sqlite3_error(sqlite3_bind_int(statement.stmt, 11, sample.GetTrashed())); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 12, hive.c_str(), hive.size(), SQLITE_STATIC)); - rc = sqlite3_step(stmt); - rc = sqlite3_clear_bindings(stmt); - rc = sqlite3_reset(stmt); + sqlite3_step(statement.stmt); + throw_on_sqlite3_error(sqlite3_clear_bindings(statement.stmt)); + throw_on_sqlite3_error(sqlite3_reset(statement.stmt)); } - rc = sqlite3_exec(m_Database, "END TRANSACTION", NULL, NULL, &m_ErrMsg); + throw_on_sqlite3_error(sqlite3_exec(m_Database, "END TRANSACTION", NULL, NULL, &m_ErrMsg)); - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxLogDebug("Error! Cannot insert data into table. Error code: %d: Msg: %s", rc, sqlite3_errmsg(m_Database)); - } - else - { - wxLogDebug("Data inserted successfully."); - } - - 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"); + wxLogDebug("Data inserted successfully."); } catch (const std::exception &exception) { @@ -230,16 +193,11 @@ void Database::InsertIntoHives(const std::string &hiveName) { try { - std::string insert = "INSERT INTO HIVES(HIVE) VALUES(?);"; - - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, insert.c_str(), insert.size(), &stmt, NULL); + const auto sql = "INSERT INTO HIVES(HIVE) VALUES(?);"; + Sqlite3Statement statement(m_Database, sql); // rc = sqlite3_exec(m_Database, "BEGIN TRANSACTION", NULL, NULL, &m_ErrMsg); - if (rc != SQLITE_OK) - wxLogDebug("Cannot prepare sql statement.."); - // Sample sample; // std::string filename; @@ -260,47 +218,17 @@ void Database::InsertIntoHives(const std::string &hiveName) // std::string hive = "Favourites"; - // rc = sqlite3_bind_int(stmt, 1, sample.GetFavorite()); - rc = sqlite3_bind_text(stmt, 1, hiveName.c_str(), hiveName.size(), SQLITE_STATIC); + // rc = sqlite3_bind_int(statement.stmt, 1, sample.GetFavorite()); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, hiveName.c_str(), hiveName.size(), SQLITE_STATIC)); - rc = sqlite3_step(stmt); - // rc = sqlite3_clear_bindings(stmt); - // rc = sqlite3_reset(stmt); + throw_on_sqlite3_error(sqlite3_step(statement.stmt)); + // rc = sqlite3_clear_bindings(statement.stmt); + // rc = sqlite3_reset(statement.stmt); // } // rc = sqlite3_exec(m_Database, "END TRANSACTION", NULL, NULL, &m_ErrMsg); - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxLogDebug("Error! Cannot insert data into table. Error code: %d: Msg: %s", rc, sqlite3_errmsg(m_Database)); - } - else - { - wxLogDebug("Data inserted successfully."); - } - - 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"); + wxLogDebug("Data inserted successfully."); } catch (const std::exception &exception) { @@ -312,29 +240,16 @@ void Database::UpdateHive(const std::string &hiveOldName, const std::string &hiv { try { - std::string update = "UPDATE HIVES SET HIVE = ? WHERE HIVE = ?;"; + const auto sql = "UPDATE HIVES SET HIVE = ? WHERE HIVE = ?;"; + Sqlite3Statement statement(m_Database, sql); - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, update.c_str(), update.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, hiveNewName.c_str(), hiveNewName.size(), SQLITE_STATIC)); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 2, hiveOldName.c_str(), hiveOldName.size(), SQLITE_STATIC)); - rc = sqlite3_bind_text(stmt, 1, hiveNewName.c_str(), hiveNewName.size(), SQLITE_STATIC); - rc = sqlite3_bind_text(stmt, 2, hiveOldName.c_str(), hiveOldName.size(), SQLITE_STATIC); - - if (sqlite3_step(stmt) != SQLITE_DONE) + if (sqlite3_step(statement.stmt) != SQLITE_DONE) { wxLogWarning("No data inserted."); } - - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, - "Error! Cannot update hive name.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } else { wxLogDebug("Hive updated successfully. %s", m_ErrMsg); @@ -350,35 +265,22 @@ void Database::UpdateHiveName(const std::string &filename, const std::string &hi { try { - std::string update = "UPDATE SAMPLES SET HIVE = ? WHERE FILENAME = ?;"; + const auto sql = "UPDATE SAMPLES SET HIVE = ? WHERE FILENAME = ?;"; + Sqlite3Statement statement(m_Database, sql); - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, update.c_str(), update.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, hiveName.c_str(), hiveName.size(), SQLITE_STATIC)); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC)); - rc = sqlite3_bind_text(stmt, 1, hiveName.c_str(), hiveName.size(), SQLITE_STATIC); - rc = sqlite3_bind_text(stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC); - - if (sqlite3_step(stmt) == SQLITE_ROW) + if (sqlite3_step(statement.stmt) == SQLITE_ROW) { wxLogDebug("Record found, updating.."); } - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, "Error! Cannot update record.", "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - else - { - wxLogDebug("Updated record successfully."); - } + wxLogDebug("Updated record successfully."); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot update record: ", "Error", e.what()); } } @@ -386,35 +288,22 @@ void Database::UpdateFavoriteColumn(const std::string &filename, int value) { try { - std::string update = "UPDATE SAMPLES SET FAVORITE = ? WHERE FILENAME = ?;"; + const auto sql = "UPDATE SAMPLES SET FAVORITE = ? WHERE FILENAME = ?;"; + Sqlite3Statement statement(m_Database, sql); - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, update.c_str(), update.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_int(statement.stmt, 1, value)); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC)); - rc = sqlite3_bind_int(stmt, 1, value); - rc = sqlite3_bind_text(stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC); - - if (sqlite3_step(stmt) == SQLITE_ROW) + if (sqlite3_step(statement.stmt) == SQLITE_ROW) { wxLogDebug("Record found, updating.."); } - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, "Error! Cannot update record.", "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - else - { - wxLogDebug("Updated record successfully."); - } + wxLogDebug("Updated record successfully."); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot update record: ", "Error", e.what()); } } @@ -422,35 +311,22 @@ void Database::UpdateSamplePack(const std::string &filename, const std::string & { try { - std::string update = "UPDATE SAMPLES SET SAMPLEPACK = ? WHERE FILENAME = ?;"; + const auto sql = "UPDATE SAMPLES SET SAMPLEPACK = ? WHERE FILENAME = ?;"; + Sqlite3Statement statement(m_Database, sql); - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, update.c_str(), update.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, samplePack.c_str(), samplePack.size(), SQLITE_STATIC)); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC)); - rc = sqlite3_bind_text(stmt, 1, samplePack.c_str(), samplePack.size(), SQLITE_STATIC); - rc = sqlite3_bind_text(stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC); - - if (sqlite3_step(stmt) == SQLITE_ROW) + if (sqlite3_step(statement.stmt) == SQLITE_ROW) { wxLogDebug("Record found, updating.."); } - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, "Error! Cannot update record.", "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - else - { - wxLogDebug("Updated record successfully."); - } + wxLogDebug("Updated record successfully."); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot update record: ", "Error", e.what()); } } @@ -458,35 +334,21 @@ void Database::UpdateSampleType(const std::string &filename, const std::string & { try { - std::string update = "UPDATE SAMPLES SET TYPE = ? WHERE FILENAME = ?;"; + const auto sql = "UPDATE SAMPLES SET TYPE = ? WHERE FILENAME = ?;"; + Sqlite3Statement statement(m_Database, sql); - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, update.c_str(), update.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, type.c_str(), type.size(), SQLITE_STATIC)); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC)); - rc = sqlite3_bind_text(stmt, 1, type.c_str(), type.size(), SQLITE_STATIC); - rc = sqlite3_bind_text(stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC); - - if (sqlite3_step(stmt) == SQLITE_ROW) + if (sqlite3_step(statement.stmt) == SQLITE_ROW) { wxLogDebug("Record found, updating.."); } - - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, "Error! Cannot update record.", "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - else - { - wxLogDebug("Updated record successfully."); - } + wxLogDebug("Updated record successfully."); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot update record: ", "Error", e.what()); } } @@ -496,37 +358,22 @@ std::string Database::GetSampleType(const std::string &filename) try { - std::string select = "SELECT TYPE FROM SAMPLES WHERE FILENAME = ?;"; + const auto sql = "SELECT TYPE FROM SAMPLES WHERE FILENAME = ?;"; + Sqlite3Statement statement(m_Database, sql); - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, select.c_str(), select.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC)); - rc = sqlite3_bind_text(stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC); - - if (sqlite3_step(stmt) == SQLITE_ROW) + if (sqlite3_step(statement.stmt) == SQLITE_ROW) { wxLogDebug("Record found, fetching.."); - type = std::string(reinterpret_cast(sqlite3_column_text(stmt, 0))); - } - - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, "Error! Cannot get sample type column value from table.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - else - { - wxLogDebug("Selected data from table successfully."); + type = std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 0))); } + wxLogDebug("Selected data from table successfully."); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot get sample type column value from table: ", "Error", e.what()); } return type; @@ -538,36 +385,22 @@ int Database::GetFavoriteColumnValueByFilename(const std::string &filename) try { - std::string select = "SELECT FAVORITE FROM SAMPLES WHERE FILENAME = ?;"; + const auto sql = "SELECT FAVORITE FROM SAMPLES WHERE FILENAME = ?;"; + Sqlite3Statement statement(m_Database, sql); - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, select.c_str(), select.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC)); - rc = sqlite3_bind_text(stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC); - - if (sqlite3_step(stmt) == SQLITE_ROW) + if (sqlite3_step(statement.stmt) == SQLITE_ROW) { wxLogDebug("Record found, fetching.."); - value = sqlite3_column_int(stmt, 0); + value = sqlite3_column_int(statement.stmt, 0); } - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, "Error! Cannot get favorite column value from table.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - else - { - wxLogDebug("Selected data from table successfully."); - } + wxLogDebug("Selected data from table successfully."); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot get favorite column value from table: ", "Error", e.what()); } return value; @@ -579,37 +412,22 @@ std::string Database::GetHiveByFilename(const std::string &filename) try { - std::string select = "SELECT HIVE FROM SAMPLES WHERE FILENAME = ?;"; + const auto sql = "SELECT HIVE FROM SAMPLES WHERE FILENAME = ?;"; + Sqlite3Statement statement(m_Database, sql); - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, select.c_str(), select.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC)); - rc = sqlite3_bind_text(stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC); - - if (sqlite3_step(stmt) == SQLITE_ROW) + if (sqlite3_step(statement.stmt) == SQLITE_ROW) { wxLogDebug("Record found, fetching.."); - - hive = std::string(reinterpret_cast(sqlite3_column_text(stmt, 0))); + hive = std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 0))); } - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, "Error! Cannot get hive value from table.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - else - { - wxLogDebug("Selected data from table successfully."); - } + wxLogDebug("Selected data from table successfully."); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot get hive value from table: ", "Error", e.what()); } return hive; @@ -619,35 +437,21 @@ void Database::RemoveSampleFromDatabase(const std::string &filename) { try { - std::string remove = "DELETE FROM SAMPLES WHERE FILENAME = ?;"; + const auto sql = "DELETE FROM SAMPLES WHERE FILENAME = ?;"; + Sqlite3Statement statement(m_Database, sql); - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, remove.c_str(), remove.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC)); - rc = sqlite3_bind_text(stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC); - - if (sqlite3_step(stmt) == SQLITE_DONE) + if (sqlite3_step(statement.stmt) == SQLITE_DONE) { wxLogDebug("Record found, Deleting.."); } - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, "Error! Cannot delete data from table.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - else - { - wxLogDebug("Deleted data from table successfully."); - } + wxLogDebug("Deleted data from table successfully."); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot get hive value from table: ", "Error", e.what()); } } @@ -655,35 +459,21 @@ void Database::RemoveHiveFromDatabase(const std::string &hiveName) { try { - std::string remove = "DELETE FROM HIVES WHERE HIVE = ?;"; + const auto sql = "DELETE FROM HIVES WHERE HIVE = ?;"; + Sqlite3Statement statement(m_Database, sql); - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, remove.c_str(), remove.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, hiveName.c_str(), hiveName.size(), SQLITE_STATIC)); - rc = sqlite3_bind_text(stmt, 1, hiveName.c_str(), hiveName.size(), SQLITE_STATIC); - - if (sqlite3_step(stmt) == SQLITE_DONE) + if (sqlite3_step(statement.stmt) == SQLITE_DONE) { wxLogDebug("Record found, Deleting.."); } - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, "Error! Cannot delete data from table.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - else - { - wxLogDebug("Deleted data from table successfully."); - } + wxLogDebug("Deleted data from table successfully."); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot get hive value from table: ", "Error", e.what()); } } @@ -693,36 +483,22 @@ std::string Database::GetSamplePathByFilename(const std::string &filename) try { - std::string select = "SELECT PATH FROM SAMPLES WHERE FILENAME = ?;"; + const auto sql = "SELECT PATH FROM SAMPLES WHERE FILENAME = ?;"; + Sqlite3Statement statement(m_Database, sql); - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, select.c_str(), select.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC)); - rc = sqlite3_bind_text(stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC); - - if (sqlite3_step(stmt) == SQLITE_ROW) + if (sqlite3_step(statement.stmt) == SQLITE_ROW) { wxLogDebug("Record found, fetching.."); - path = std::string(reinterpret_cast(sqlite3_column_text(stmt, 0))); + path = std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 0))); } - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, "Error! Cannot select sample path from table.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - else - { - wxLogDebug("Selected data from table successfully."); - } + wxLogDebug("Selected data from table successfully."); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot select sample path from table: ", "Error", e.what()); } return path; @@ -734,46 +510,32 @@ std::string Database::GetSampleFileExtension(const std::string &filename) try { - std::string select = "SELECT EXTENSION FROM SAMPLES WHERE FILENAME = ?;"; + const auto sql = "SELECT EXTENSION FROM SAMPLES WHERE FILENAME = ?;"; + Sqlite3Statement statement(m_Database, sql); - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, select.c_str(), select.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC)); - rc = sqlite3_bind_text(stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC); - - if (sqlite3_step(stmt) == SQLITE_ROW) + if (sqlite3_step(statement.stmt) == SQLITE_ROW) { - wxLogDebug("Record found, fetching.."); - extension = std::string(reinterpret_cast(sqlite3_column_text(stmt, 0))); + wxLogInfo("Record found, fetching.."); + extension = std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 0))); } - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, "Error! Cannot select sample path from table.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - else - { - wxLogDebug("Selected data from table successfully."); - } + wxLogDebug("Selected data from table successfully."); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot select sample extension from table: ", "Error", e.what()); } return extension; } wxVector> Database::LoadSamplesDatabase( - // wxTreeCtrl& favorite_tree, wxTreeItemId& favorite_item, - wxDataViewTreeCtrl &favorite_tree, wxDataViewItem &favorite_item, - wxTreeCtrl &trash_tree, wxTreeItemId &trash_item, bool show_extension, - const std::string &icon_star_filled, const std::string &icon_star_empty) + // wxTreeCtrl& favorite_tree, wxTreeItemId& favorite_item, + wxDataViewTreeCtrl &favorite_tree, wxDataViewItem &favorite_item, + wxTreeCtrl &trash_tree, wxTreeItemId &trash_item, bool show_extension, + const std::string &icon_star_filled, const std::string &icon_star_empty) { wxVector> vecSet; wxVariant icon_filled, icon_empty; @@ -908,13 +670,9 @@ wxVector> Database::LoadSamplesDatabase( row++; } } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxMessageDialog msgDialog(NULL, "Error! Cannot load data from table.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot load data from table: ", "Error", e.what()); } return vecSet; @@ -930,85 +688,69 @@ Database::FilterDatabaseBySampleName(const std::string &sampleName, bool show_ex icon_empty = wxVariant(wxBitmap(icon_star_empty)); try { - - std::string filter = "SELECT FAVORITE, FILENAME, SAMPLEPACK, TYPE, \ + Sqlite3Statement statement(m_Database, "SELECT FAVORITE, FILENAME, SAMPLEPACK, TYPE, \ CHANNELS, LENGTH, SAMPLERATE, BITRATE, PATH \ - FROM SAMPLES WHERE FILENAME LIKE '%' || ? || '%' ;"; - sqlite3_stmt *stmt = nullptr; + FROM SAMPLES WHERE FILENAME LIKE '%' || ? || '%' ;"); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, sampleName.c_str(), sampleName.size(), SQLITE_STATIC)); - rc = sqlite3_prepare_v2(m_Database, filter.c_str(), filter.size(), &stmt, NULL); - rc = sqlite3_bind_text(stmt, 1, sampleName.c_str(), sampleName.size(), SQLITE_STATIC); + int row = 0; - if (rc == SQLITE_OK) + while (SQLITE_ROW == sqlite3_step(statement.stmt)) { - int row = 0; + wxLogDebug("Record found, fetching.."); + int favorite = sqlite3_column_int(statement.stmt, 0); + wxString filename = wxString(std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 1)))); + wxString sample_pack = wxString(std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 2)))); + wxString sample_type = std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 3))); + int channels = sqlite3_column_int(statement.stmt, 4); + int length = sqlite3_column_int(statement.stmt, 5); + int sample_rate = sqlite3_column_int(statement.stmt, 6); + int bitrate = sqlite3_column_int(statement.stmt, 7); + wxString path = wxString(std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 8)))); - while (SQLITE_ROW == sqlite3_step(stmt)) + wxLongLong llLength = length; + int total_min = static_cast((llLength / 60000).GetValue()); + int total_sec = static_cast(((llLength % 60000) / 1000).GetValue()); + + wxVector vec; + + if (favorite == 1) + vec.push_back(icon_filled); + else + vec.push_back(icon_empty); + + // if (favorite == 1) + // vec.push_back(true); + // else + // vec.push_back(false); + + // vec.push_back(filename); + + if (show_extension) { - wxLogDebug("Record found, fetching.."); - int favorite = sqlite3_column_int(stmt, 0); - wxString filename = wxString(std::string(reinterpret_cast(sqlite3_column_text(stmt, 1)))); - wxString sample_pack = wxString(std::string(reinterpret_cast(sqlite3_column_text(stmt, 2)))); - wxString sample_type = std::string(reinterpret_cast(sqlite3_column_text(stmt, 3))); - int channels = sqlite3_column_int(stmt, 4); - int length = sqlite3_column_int(stmt, 5); - int sample_rate = sqlite3_column_int(stmt, 6); - int bitrate = sqlite3_column_int(stmt, 7); - wxString path = wxString(std::string(reinterpret_cast(sqlite3_column_text(stmt, 8)))); - - wxLongLong llLength = length; - int total_min = static_cast((llLength / 60000).GetValue()); - int total_sec = static_cast(((llLength % 60000) / 1000).GetValue()); - - wxVector vec; - - if (favorite == 1) - vec.push_back(icon_filled); - else - vec.push_back(icon_empty); - - // if (favorite == 1) - // vec.push_back(true); - // else - // vec.push_back(false); - - // vec.push_back(filename); - - if (show_extension) - { - vec.push_back(path.AfterLast('/')); - } - else - { - vec.push_back(path.AfterLast('/').BeforeLast('.')); - } - - vec.push_back(sample_pack); - vec.push_back(sample_type); - vec.push_back(wxString::Format("%d", channels)); - vec.push_back(wxString::Format("%2i:%02i", total_min, total_sec)); - vec.push_back(wxString::Format("%d", sample_rate)); - vec.push_back(wxString::Format("%d", bitrate)); - vec.push_back(path); - - sampleVec.push_back(vec); - - row++; + vec.push_back(path.AfterLast('/')); + } + else + { + vec.push_back(path.AfterLast('/').BeforeLast('.')); } - } - else - { - wxMessageDialog msgDialog(NULL, "Error! Cannot filter data from table.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - rc = sqlite3_finalize(stmt); + vec.push_back(sample_pack); + vec.push_back(sample_type); + vec.push_back(wxString::Format("%d", channels)); + vec.push_back(wxString::Format("%2i:%02i", total_min, total_sec)); + vec.push_back(wxString::Format("%d", sample_rate)); + vec.push_back(wxString::Format("%d", bitrate)); + vec.push_back(path); + + sampleVec.push_back(vec); + + row++; + } } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot filter data from table: ", "Error", e.what()); } return sampleVec; @@ -1024,85 +766,70 @@ Database::FilterDatabaseByHiveName(const std::string &hiveName, bool show_extens icon_empty = wxVariant(wxBitmap(icon_star_empty)); try { - std::string filter = "SELECT FAVORITE, FILENAME, SAMPLEPACK, TYPE, \ + Sqlite3Statement statement(m_Database, "SELECT FAVORITE, FILENAME, SAMPLEPACK, TYPE, \ CHANNELS, LENGTH, SAMPLERATE, BITRATE, PATH \ - FROM SAMPLES WHERE HIVE = ? AND FAVORITE = 1;"; + FROM SAMPLES WHERE HIVE = ? AND FAVORITE = 1;"); - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, filter.c_str(), filter.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, hiveName.c_str(), hiveName.size(), SQLITE_STATIC)); - rc = sqlite3_bind_text(stmt, 1, hiveName.c_str(), hiveName.size(), SQLITE_STATIC); + int row = 0; - if (rc == SQLITE_OK) + while (SQLITE_ROW == sqlite3_step(statement.stmt)) { - int row = 0; + wxLogDebug("Record found, fetching.."); + int favorite = sqlite3_column_int(statement.stmt, 0); + wxString filename = wxString(std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 1)))); + wxString sample_pack = wxString(std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 2)))); + wxString sample_type = std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 3))); + int channels = sqlite3_column_int(statement.stmt, 4); + int length = sqlite3_column_int(statement.stmt, 5); + int sample_rate = sqlite3_column_int(statement.stmt, 6); + int bitrate = sqlite3_column_int(statement.stmt, 7); + wxString path = wxString(std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 8)))); - while (SQLITE_ROW == sqlite3_step(stmt)) + wxLongLong llLength = length; + int total_min = static_cast((llLength / 60000).GetValue()); + int total_sec = static_cast(((llLength % 60000) / 1000).GetValue()); + + wxVector vec; + + if (favorite == 1) + vec.push_back(icon_filled); + else + vec.push_back(icon_empty); + + // if (favorite == 1) + // vec.push_back(true); + // else + // vec.push_back(false); + + // vec.push_back(filename); + + if (show_extension) { - wxLogDebug("Record found, fetching.."); - int favorite = sqlite3_column_int(stmt, 0); - wxString filename = wxString(std::string(reinterpret_cast(sqlite3_column_text(stmt, 1)))); - wxString sample_pack = wxString(std::string(reinterpret_cast(sqlite3_column_text(stmt, 2)))); - wxString sample_type = std::string(reinterpret_cast(sqlite3_column_text(stmt, 3))); - int channels = sqlite3_column_int(stmt, 4); - int length = sqlite3_column_int(stmt, 5); - int sample_rate = sqlite3_column_int(stmt, 6); - int bitrate = sqlite3_column_int(stmt, 7); - wxString path = wxString(std::string(reinterpret_cast(sqlite3_column_text(stmt, 8)))); - - wxLongLong llLength = length; - int total_min = static_cast((llLength / 60000).GetValue()); - int total_sec = static_cast(((llLength % 60000) / 1000).GetValue()); - - wxVector vec; - - if (favorite == 1) - vec.push_back(icon_filled); - else - vec.push_back(icon_empty); - - // if (favorite == 1) - // vec.push_back(true); - // else - // vec.push_back(false); - - // vec.push_back(filename); - - if (show_extension) - { - vec.push_back(path.AfterLast('/')); - } - else - { - vec.push_back(path.AfterLast('/').BeforeLast('.')); - } - - vec.push_back(sample_pack); - vec.push_back(sample_type); - vec.push_back(wxString::Format("%d", channels)); - vec.push_back(wxString::Format("%2i:%02i", total_min, total_sec)); - vec.push_back(wxString::Format("%d", sample_rate)); - vec.push_back(wxString::Format("%d", bitrate)); - vec.push_back(path); - - sampleVec.push_back(vec); - - row++; + vec.push_back(path.AfterLast('/')); + } + else + { + vec.push_back(path.AfterLast('/').BeforeLast('.')); } - } - else - { - wxMessageDialog msgDialog(NULL, "Error! Cannot filter data from table.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - rc = sqlite3_finalize(stmt); + vec.push_back(sample_pack); + vec.push_back(sample_type); + vec.push_back(wxString::Format("%d", channels)); + vec.push_back(wxString::Format("%2i:%02i", total_min, total_sec)); + vec.push_back(wxString::Format("%d", sample_rate)); + vec.push_back(wxString::Format("%d", bitrate)); + vec.push_back(path); + + sampleVec.push_back(vec); + + row++; + } } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot filter data from table: ", "Error", e.what()); } return sampleVec; @@ -1112,34 +839,20 @@ void Database::LoadHivesDatabase(wxDataViewTreeCtrl &treeCtrl) { try { - std::string select = "SELECT HIVE FROM HIVES;"; + const auto sql = "SELECT HIVE FROM HIVES;"; + Sqlite3Statement statement(m_Database, sql); - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, select.c_str(), select.size(), &stmt, NULL); - - if (rc == SQLITE_OK) + while (SQLITE_ROW == sqlite3_step(statement.stmt)) { - while (SQLITE_ROW == sqlite3_step(stmt)) - { - wxLogDebug("Record found, fetching.."); - wxString hive = wxString(std::string(reinterpret_cast(sqlite3_column_text(stmt, 0)))); + wxLogDebug("Record found, fetching.."); + const auto hive = wxString(std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 0)))); - treeCtrl.AppendContainer(wxDataViewItem(wxNullPtr), hive); - } + treeCtrl.AppendContainer(wxDataViewItem(wxNullPtr), hive); } - else - { - wxMessageDialog msgDialog(NULL, "Error! Cannot load hive from hives table.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - - rc = sqlite3_finalize(stmt); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot load hive from hives table: ", "Error", e.what()); } } @@ -1153,27 +866,23 @@ wxArrayString Database::CheckDuplicates(const wxArrayString &files) try { - std::string select = "SELECT * FROM SAMPLES WHERE FILENAME = ?;"; - - sqlite3_stmt *stmt = nullptr; - throw_on_sqlite3_error(sqlite3_prepare_v2(m_Database, select.c_str(), select.size(), &stmt, NULL)); + const auto sql = "SELECT * FROM SAMPLES WHERE FILENAME = ?;"; + Sqlite3Statement statement(m_Database, sql); for (unsigned int i = 0; i < files.size(); i++) { filename = files[i].AfterLast('/').BeforeLast('.').ToStdString(); - rc = sqlite3_bind_text(stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC)); - if (sqlite3_step(stmt) != SQLITE_ROW) + if (sqlite3_step(statement.stmt) != SQLITE_ROW) sorted_files.push_back(files[i]); else wxLogDebug("Already added: %s. Skipping..", files[i]); - rc = sqlite3_clear_bindings(stmt); - rc = sqlite3_reset(stmt); + rc = sqlite3_clear_bindings(statement.stmt); + rc = sqlite3_reset(statement.stmt); } - - sqlite3_finalize(stmt); } catch (const std::exception &exception) { @@ -1187,38 +896,24 @@ bool Database::IsTrashed(const std::string &filename) { try { - std::string select = "SELECT TRASHED FROM SAMPLES WHERE FILENAME = ?;"; + const auto sql = "SELECT TRASHED FROM SAMPLES WHERE FILENAME = ?;"; + Sqlite3Statement statement(m_Database, sql); - sqlite3_stmt *stmt = nullptr; - rc = sqlite3_prepare_v2(m_Database, select.c_str(), select.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC)); - rc = sqlite3_bind_text(stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC); - - if (sqlite3_step(stmt) == SQLITE_ROW) + if (sqlite3_step(statement.stmt) == SQLITE_ROW) { wxLogDebug("Record found, fetching.."); - if (sqlite3_column_int(stmt, 0) == 1) + if (sqlite3_column_int(statement.stmt, 0) == 1) return true; } - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, "Error! Cannot select sample path from table.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - else - { - wxLogDebug("Selected data from table successfully."); - } + wxLogDebug("Selected data from table successfully."); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot select sample path from table: ", "Error", e.what()); } return false; @@ -1228,36 +923,22 @@ void Database::UpdateTrashColumn(const std::string &filename, int value) { try { - std::string update = "UPDATE SAMPLES SET TRASHED = ? WHERE FILENAME = ?;"; - sqlite3_stmt *stmt = nullptr; + const auto sql = "UPDATE SAMPLES SET TRASHED = ? WHERE FILENAME = ?;"; + Sqlite3Statement statement(m_Database, sql); - rc = sqlite3_prepare_v2(m_Database, update.c_str(), update.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_int(statement.stmt, 1, value)); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC)); - rc = sqlite3_bind_int(stmt, 1, value); - rc = sqlite3_bind_text(stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC); - - if (sqlite3_step(stmt) == SQLITE_ROW) + if (sqlite3_step(statement.stmt) == SQLITE_ROW) { wxLogDebug("Record found, updating.."); } - rc = sqlite3_finalize(stmt); - - if (rc != SQLITE_OK) - { - wxMessageDialog msgDialog(NULL, "Error! Cannot update record.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - else - { - wxLogDebug("Updated record successfully."); - } + wxLogDebug("Updated record successfully."); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot update record: ", "Error", e.what()); } } @@ -1271,75 +952,61 @@ Database::RestoreFromTrashByFilename(const std::string &filename, icon_empty = wxVariant(wxBitmap(icon_star_empty)); try { - std::string restore = "SELECT FAVORITE, FILENAME, EXTENSION, SAMPLEPACK, \ + const auto sql = "SELECT FAVORITE, FILENAME, EXTENSION, SAMPLEPACK, \ TYPE, CHANNELS, LENGTH, SAMPLERATE, BITRATE, PATH, \ TRASHED, HIVE FROM SAMPLES WHERE FILENAME = ?;"; - sqlite3_stmt *stmt = nullptr; + Sqlite3Statement statement(m_Database, sql); - rc = sqlite3_prepare_v2(m_Database, restore.c_str(), restore.size(), &stmt, NULL); + throw_on_sqlite3_error(sqlite3_bind_text(statement.stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC)); - rc = sqlite3_bind_text(stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC); - - if (rc == SQLITE_OK) + while (SQLITE_ROW == sqlite3_step(statement.stmt)) { - while (SQLITE_ROW == sqlite3_step(stmt)) + int favorite = sqlite3_column_int(statement.stmt, 0); + wxString filename = std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 1))); + wxString file_extension = std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 2))); + wxString sample_pack = std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 3))); + wxString sample_type = std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 4))); + int channels = sqlite3_column_int(statement.stmt, 5); + int length = sqlite3_column_int(statement.stmt, 6); + int sample_rate = sqlite3_column_int(statement.stmt, 7); + int bitrate = sqlite3_column_int(statement.stmt, 8); + wxString path = std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 9))); + int trashed = sqlite3_column_int(statement.stmt, 10); + wxString hive_name = std::string(reinterpret_cast(sqlite3_column_text(statement.stmt, 11))); + + wxLongLong llLength = length; + int total_min = static_cast((llLength / 60000).GetValue()); + int total_sec = static_cast(((llLength % 60000) / 1000).GetValue()); + + wxVector vec; + + if (trashed == 0) { - int favorite = sqlite3_column_int(stmt, 0); - wxString filename = std::string(reinterpret_cast(sqlite3_column_text(stmt, 1))); - wxString file_extension = std::string(reinterpret_cast(sqlite3_column_text(stmt, 2))); - wxString sample_pack = std::string(reinterpret_cast(sqlite3_column_text(stmt, 3))); - wxString sample_type = std::string(reinterpret_cast(sqlite3_column_text(stmt, 4))); - int channels = sqlite3_column_int(stmt, 5); - int length = sqlite3_column_int(stmt, 6); - int sample_rate = sqlite3_column_int(stmt, 7); - int bitrate = sqlite3_column_int(stmt, 8); - wxString path = std::string(reinterpret_cast(sqlite3_column_text(stmt, 9))); - int trashed = sqlite3_column_int(stmt, 10); - wxString hive_name = std::string(reinterpret_cast(sqlite3_column_text(stmt, 11))); + if (favorite == 1) + vec.push_back(icon_filled); + else + vec.push_back(icon_empty); - wxLongLong llLength = length; - int total_min = static_cast((llLength / 60000).GetValue()); - int total_sec = static_cast(((llLength % 60000) / 1000).GetValue()); + if (show_extension) + vec.push_back(path.AfterLast('/')); + else + vec.push_back(path.AfterLast('/').BeforeLast('.')); - wxVector vec; + vec.push_back(sample_pack); + vec.push_back(sample_type); + vec.push_back(wxString::Format("%d", channels)); + vec.push_back(wxString::Format("%2i:%02i", total_min, total_sec)); + vec.push_back(wxString::Format("%d", sample_rate)); + vec.push_back(wxString::Format("%d", bitrate)); + vec.push_back(path); - if (trashed == 0) - { - if (favorite == 1) - vec.push_back(icon_filled); - else - vec.push_back(icon_empty); - - if (show_extension) - vec.push_back(path.AfterLast('/')); - else - vec.push_back(path.AfterLast('/').BeforeLast('.')); - - vec.push_back(sample_pack); - vec.push_back(sample_type); - vec.push_back(wxString::Format("%d", channels)); - vec.push_back(wxString::Format("%2i:%02i", total_min, total_sec)); - vec.push_back(wxString::Format("%d", sample_rate)); - vec.push_back(wxString::Format("%d", bitrate)); - vec.push_back(path); - - vecSet.push_back(vec); - } + vecSet.push_back(vec); } } - else - { - wxMessageDialog msgDialog(NULL, "Error! Cannot load data from table.", - "Error", wxOK | wxICON_ERROR); - msgDialog.ShowModal(); - sqlite3_free(m_ErrMsg); - } - - rc = sqlite3_finalize(stmt); } - catch (const std::exception &exception) + catch (const std::exception &e) { - wxLogDebug(exception.what()); + show_modal_dialog_and_log("Error! Cannot load data from table: ", "Error", e.what()); } return vecSet; @@ -1347,28 +1014,10 @@ Database::RestoreFromTrashByFilename(const std::string &filename, void Database::open(const std::string &dbPath) { - try - { - throw_on_sqlite3_error(sqlite3_open(dbPath.c_str(), &m_Database)); - - const auto qry = std::string("pragma journal_mode = WAL; pragma synchronous = normal; pragma temp_store = memory; pragma mmap_size = 30000000000;"); - - sqlite3_stmt *stmt = nullptr; - throw_on_sqlite3_error(sqlite3_prepare_v2(m_Database, qry.c_str(), qry.size(), &stmt, NULL)); - if (SQLITE_ROW != sqlite3_step(stmt)) - { - wxLogDebug("Error executing query"); - } - throw_on_sqlite3_error(sqlite3_finalize(stmt)); - } - catch (const std::exception &exception) - { - wxLogDebug(exception.what()); - } + throw_on_sqlite3_error(sqlite3_open(dbPath.c_str(), &m_Database)); } void Database::close() { throw_on_sqlite3_error(sqlite3_close(m_Database)); } - diff --git a/src/MainFrame.cpp b/src/MainFrame.cpp index 99e2f7e..26630d5 100644 --- a/src/MainFrame.cpp +++ b/src/MainFrame.cpp @@ -398,7 +398,12 @@ MainFrame::MainFrame() // Intializing wxTimer m_Timer = new wxTimer(this); - m_TopWaveformPanel = new WaveformViewer(this, m_TopPanel, *m_Library, *m_MediaCtrl, *m_InfoBar, + // Initialize the database + m_database = std::make_unique(*m_InfoBar, m_DatabaseFilepath); + m_database->CreateTableSamples(); + m_database->CreateTableHives(); + + m_TopWaveformPanel = new WaveformViewer(this, m_TopPanel, *m_Library, *m_MediaCtrl, *m_database, m_ConfigFilepath, m_DatabaseFilepath); // Binding events. @@ -543,11 +548,6 @@ MainFrame::MainFrame() m_BottomRightPanelMainSizer->SetSizeHints(m_BottomRightPanel); m_BottomRightPanelMainSizer->Layout(); - // Initialize the database - m_database = std::make_unique(*m_InfoBar, m_DatabaseFilepath); - m_database->CreateTableSamples(); - m_database->CreateTableHives(); - // Restore the data previously added to Library LoadDatabase(); diff --git a/src/WaveformViewer.cpp b/src/WaveformViewer.cpp index d69ed10..64a6739 100644 --- a/src/WaveformViewer.cpp +++ b/src/WaveformViewer.cpp @@ -39,10 +39,10 @@ #include WaveformViewer::WaveformViewer(wxWindow* parentFrame, wxWindow* window, wxDataViewListCtrl& library, - wxMediaCtrl& mediaCtrl, wxInfoBar& infoBar, + wxMediaCtrl& mediaCtrl, Database& database, const std::string& configFilepath, const std::string& databaseFilepath) : wxPanel(window, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxNO_BORDER | wxFULL_REPAINT_ON_RESIZE), - m_ParentFrame(parentFrame), m_Window(window), m_Library(library), m_InfoBar(infoBar), m_MediaCtrl(mediaCtrl), + m_ParentFrame(parentFrame), m_Window(window), m_Library(library), m_database(database), m_MediaCtrl(mediaCtrl), m_ConfigFilepath(configFilepath), m_DatabaseFilepath(databaseFilepath) { this->SetDoubleBuffered(true); @@ -110,15 +110,13 @@ void WaveformViewer::OnPaint(wxPaintEvent& event) void WaveformViewer::RenderPlayhead(wxDC& dc) { - Database db(m_InfoBar); - int selected_row = m_Library.GetSelectedRow(); if (selected_row < 0) return; wxString selected = m_Library.GetTextValue(selected_row, 1); - std::string path = db.GetSamplePathByFilename(m_DatabaseFilepath, selected.BeforeLast('.').ToStdString()); + std::string path = m_database.GetSamplePathByFilename(selected.BeforeLast('.').ToStdString()); Tags tags(path); @@ -150,7 +148,6 @@ void WaveformViewer::RenderPlayhead(wxDC& dc) void WaveformViewer::UpdateWaveformBitmap() { - Database db(m_InfoBar); Settings settings(m_ParentFrame, m_ConfigFilepath, m_DatabaseFilepath); Serializer serializer(m_ConfigFilepath); @@ -161,12 +158,12 @@ void WaveformViewer::UpdateWaveformBitmap() wxString selection = m_Library.GetTextValue(selected_row, 1); - wxString filepath_with_extension = db.GetSamplePathByFilename(m_DatabaseFilepath, selection.BeforeLast('.').ToStdString()); - wxString filepath_without_extension = db.GetSamplePathByFilename(m_DatabaseFilepath, selection.ToStdString()); + wxString filepath_with_extension = m_database.GetSamplePathByFilename(selection.BeforeLast('.').ToStdString()); + wxString filepath_without_extension = m_database.GetSamplePathByFilename(selection.ToStdString()); std::string extension = settings.ShouldShowFileExtension() ? - db.GetSampleFileExtension(m_DatabaseFilepath, selection.ToStdString()) : - db.GetSampleFileExtension(m_DatabaseFilepath, selection.BeforeLast('.').ToStdString()); + m_database.GetSampleFileExtension(selection.ToStdString()) : + m_database.GetSampleFileExtension(selection.BeforeLast('.').ToStdString()); wxString path = selection.Contains(wxString::Format(".%s", extension)) ? filepath_with_extension : filepath_without_extension; @@ -293,15 +290,13 @@ void WaveformViewer::OnControlKeyUp(wxKeyEvent &event) void WaveformViewer::OnMouseMotion(wxMouseEvent& event) { - Database db(m_InfoBar); - int selected_row = m_Library.GetSelectedRow(); if (selected_row < 0) return; wxString selected = m_Library.GetTextValue(selected_row, 1); - std::string path = db.GetSamplePathByFilename(m_DatabaseFilepath, selected.BeforeLast('.').ToStdString()); + std::string path = m_database.GetSamplePathByFilename(selected.BeforeLast('.').ToStdString()); Tags tags(path); @@ -335,14 +330,13 @@ void WaveformViewer::OnMouseMotion(wxMouseEvent& event) void WaveformViewer::OnMouseLeftButtonDown(wxMouseEvent& event) { - Database db(m_InfoBar); int selected_row = m_Library.GetSelectedRow(); if (selected_row < 0) return; wxString selected = m_Library.GetTextValue(selected_row, 1); - std::string path = db.GetSamplePathByFilename(m_DatabaseFilepath, selected.BeforeLast('.').ToStdString()); + std::string path = m_database.GetSamplePathByFilename(selected.BeforeLast('.').ToStdString()); Tags tags(path); @@ -385,15 +379,13 @@ void WaveformViewer::OnMouseLeftButtonDown(wxMouseEvent& event) void WaveformViewer::OnMouseLeftButtonUp(wxMouseEvent& event) { - Database db(m_InfoBar); - int selected_row = m_Library.GetSelectedRow(); if (selected_row < 0) return; wxString selected = m_Library.GetTextValue(selected_row, 1); - std::string path = db.GetSamplePathByFilename(m_DatabaseFilepath, selected.BeforeLast('.').ToStdString()); + std::string path = m_database.GetSamplePathByFilename(selected.BeforeLast('.').ToStdString()); Tags tags(path); @@ -457,15 +449,13 @@ void WaveformViewer::SendLoopPoints() SampleHive::SH_LoopPointsEvent event(SampleHive::SH_EVT_LOOP_POINTS_UPDATED, this->GetId()); event.SetEventObject(this); - Database db(m_InfoBar); - int selected_row = m_Library.GetSelectedRow(); if (selected_row < 0) return; wxString selected = m_Library.GetTextValue(selected_row, 1); - std::string path = db.GetSamplePathByFilename(m_DatabaseFilepath, selected.BeforeLast('.').ToStdString()); + std::string path = m_database.GetSamplePathByFilename(selected.BeforeLast('.').ToStdString()); Tags tags(path); diff --git a/src/WaveformViewer.hpp b/src/WaveformViewer.hpp index a1f6a67..f16b5a0 100644 --- a/src/WaveformViewer.hpp +++ b/src/WaveformViewer.hpp @@ -20,6 +20,8 @@ #pragma once +#include "Database.hpp" + #include #include #include @@ -37,7 +39,7 @@ class WaveformViewer : public wxPanel { public: WaveformViewer(wxWindow* parentFrame, wxWindow* window, wxDataViewListCtrl& library, - wxMediaCtrl& mediaCtrl, wxInfoBar& infoBar, + wxMediaCtrl& mediaCtrl, Database& database, const std::string& configFilepath, const std::string& databaseFilepath); ~WaveformViewer(); @@ -47,7 +49,7 @@ class WaveformViewer : public wxPanel wxWindow* m_Window; wxDataViewListCtrl& m_Library; - wxInfoBar& m_InfoBar; + Database& m_database; wxMediaCtrl& m_MediaCtrl; const std::string& m_ConfigFilepath;