diff --git a/src/backend/dbi/CMakeLists.txt b/src/backend/dbi/CMakeLists.txt index 711a65d810..be5fc155d5 100644 --- a/src/backend/dbi/CMakeLists.txt +++ b/src/backend/dbi/CMakeLists.txt @@ -5,7 +5,7 @@ ADD_SUBDIRECTORY(test) # Source file gncmod-backend-dbi.c does not appear to be use in Makefile.in, so not included here. SET (backend_dbi_SOURCES - gnc-backend-dbi.cpp + gnc-backend-dbi.cpp gnc-dbisqlconnection.cpp ) SET (backend_dbi_noinst_HEADERS gnc-backend-dbi.h gnc-backend-dbi.hpp diff --git a/src/backend/dbi/Makefile.am b/src/backend/dbi/Makefile.am index ac07b8d2e5..a2a2baaed2 100644 --- a/src/backend/dbi/Makefile.am +++ b/src/backend/dbi/Makefile.am @@ -21,7 +21,8 @@ AM_CPPFLAGS = \ ${WARN_CFLAGS} libgncmod_backend_dbi_la_SOURCES = \ - gnc-backend-dbi.cpp + gnc-backend-dbi.cpp \ + gnc-dbisqlconnection.cpp noinst_HEADERS = \ gnc-backend-dbi.h \ diff --git a/src/backend/dbi/gnc-backend-dbi.cpp b/src/backend/dbi/gnc-backend-dbi.cpp index 8f559d99e9..087266f431 100644 --- a/src/backend/dbi/gnc-backend-dbi.cpp +++ b/src/backend/dbi/gnc-backend-dbi.cpp @@ -125,13 +125,8 @@ static gboolean gnc_dbi_lock_database (QofBackend *qbe, gboolean ignore_lock); static void gnc_dbi_unlock (QofBackend *qbe); static gboolean save_may_clobber_data (QofBackend* qbe); -static std::string create_index_ddl (const GncSqlConnection* conn, - const std::string& index_name, - const std::string& table_name, - const EntryVec& col_table); static GncDbiTestResult conn_test_dbi_library (dbi_conn conn); -#define DBI_MAX_CONN_ATTEMPTS 5 enum class DbType { DBI_SQLITE, @@ -170,57 +165,6 @@ public: }; /* ================================================================= */ - -/* Check if the dbi connection is valid. If not attempt to re-establish it - * Returns TRUE is there is a valid connection in the end or FALSE otherwise - */ -bool -GncDbiSqlConnection::verify () noexcept -{ - if (m_conn_ok) - return true; - - /* We attempt to connect only once here. The error function will - * automatically re-attempt up until DBI_MAX_CONN_ATTEMPTS time to connect - * if this call fails. After all these attempts, conn_ok will indicate if - * there is a valid connection or not. - */ - init_error (); - m_conn_ok = true; - (void)dbi_conn_connect (m_conn); - - return m_conn_ok; -} - -bool -GncDbiSqlConnection::retry_connection(const char* msg) - noexcept -{ - while (m_retry && m_error_repeat <= DBI_MAX_CONN_ATTEMPTS) - { - m_conn_ok = false; - if (dbi_conn_connect(m_conn) == 0) - { - init_error(); - m_conn_ok = true; - return true; - } -#ifdef G_OS_WIN32 - const guint backoff_msecs = 1; - Sleep (backoff_msecs * 2 << ++m_error_repeat); -#else - const guint backoff_usecs = 1000; - usleep (backoff_usecs * 2 << ++m_error_repeat); -#endif - PINFO ("DBI error: %s - Reconnecting...\n", msg); - - } - PERR ("DBI error: %s - Giving up after %d consecutive attempts.\n", msg, - DBI_MAX_CONN_ATTEMPTS); - m_conn_ok = false; - return false; -} - /* ================================================================= */ static void @@ -1103,10 +1047,8 @@ GncDbiProviderImpl::get_index_list (dbi_conn conn) template<> void GncDbiProviderImpl::drop_index (dbi_conn conn, const std::string& index) { - unsigned int sep{0}, count{0}; - while ((sep = index.find(' ', sep)) != std::string::npos) - ++count; - if (count != 1) + auto sep = index.find(' ', 0); + if (index.find(' ', sep + 1) != std::string::npos) { PWARN("Drop index error: invalid MySQL index format ( ): %s", index.c_str()); @@ -1536,33 +1478,6 @@ save_may_clobber_data (QofBackend* qbe) return retval; } -dbi_result -GncDbiSqlConnection::table_manage_backup (const std::string& table_name, - TableOpType op) -{ - auto new_name = table_name + "_back"; - dbi_result result = nullptr; - switch (op) - { - case backup: - result = dbi_conn_queryf (m_conn, "ALTER TABLE %s RENAME TO %s", - table_name.c_str(), new_name.c_str()); - break; - case rollback: - result = dbi_conn_queryf (m_conn, - "ALTER TABLE %s RENAME TO %s", - new_name.c_str(), table_name.c_str()); - break; - case drop_backup: - result = dbi_conn_queryf (m_conn, "DROP TABLE %s", - new_name.c_str()); - break; - default: - break; - } - return result; -} - /** * Perform a specified SQL operation on every table in a * database. Possible operations are: @@ -2142,215 +2057,6 @@ GncDbiSqlResult::size() const noexcept } /* --------------------------------------------------------- */ -class GncDbiSqlStatement : public GncSqlStatement -{ -public: - GncDbiSqlStatement(const GncSqlConnection* conn, const std::string& sql) : - m_conn{conn}, m_sql {sql} {} - ~GncDbiSqlStatement() {} - const char* to_sql() const override; - void add_where_cond(QofIdTypeConst, const PairVec&) override; - -private: - const GncSqlConnection* m_conn; - std::string m_sql; -}; - - -const char* -GncDbiSqlStatement::to_sql() const -{ - return m_sql.c_str(); -} - -void -GncDbiSqlStatement::add_where_cond(QofIdTypeConst type_name, - const PairVec& col_values) -{ - m_sql += " WHERE "; - for (auto colpair : col_values) - { - if (colpair != *col_values.begin()) - m_sql += " AND "; - m_sql += colpair.first + " = " + - m_conn->quote_string (colpair.second.c_str()); - } -} - -/* --------------------------------------------------------- */ -GncSqlResultPtr -GncDbiSqlConnection::execute_select_statement (const GncSqlStatementPtr& stmt) - noexcept -{ - dbi_result result; - - DEBUG ("SQL: %s\n", stmt->to_sql()); - gnc_push_locale (LC_NUMERIC, "C"); - do - { - init_error (); - result = dbi_conn_query (m_conn, stmt->to_sql()); - } - while (m_retry); - if (result == nullptr) - PERR ("Error executing SQL %s\n", stmt->to_sql()); - gnc_pop_locale (LC_NUMERIC); - return GncSqlResultPtr(new GncDbiSqlResult (this, result)); -} - -int -GncDbiSqlConnection::execute_nonselect_statement (const GncSqlStatementPtr& stmt) - noexcept -{ - dbi_result result; - - DEBUG ("SQL: %s\n", stmt->to_sql()); - do - { - init_error (); - result = dbi_conn_query (m_conn, stmt->to_sql()); - } - while (m_retry); - if (result == nullptr && m_last_error) - { - PERR ("Error executing SQL %s\n", stmt->to_sql()); - return -1; - } - if (!result) - return 0; - auto num_rows = (gint)dbi_result_get_numrows_affected (result); - auto status = dbi_result_free (result); - if (status < 0) - { - PERR ("Error in dbi_result_free() result\n"); - qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); - } - return num_rows; -} - -GncSqlStatementPtr -GncDbiSqlConnection::create_statement_from_sql (const std::string& sql) - const noexcept -{ - return std::unique_ptr{new GncDbiSqlStatement (this, sql)}; -} - -bool -GncDbiSqlConnection::does_table_exist (const std::string& table_name) - const noexcept -{ - auto dbname = dbi_conn_get_option (m_conn, "dbname"); - auto tables = dbi_conn_get_table_list (m_conn, dbname, table_name.c_str()); - auto nTables = dbi_result_get_numrows (tables); - auto status = dbi_result_free (tables); - if (status < 0) - { - PERR ("Error in dbi_result_free() result\n"); - qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); - } - - return nTables == 1; -} - -bool -GncDbiSqlConnection::begin_transaction () noexcept -{ - dbi_result result; - - DEBUG ("BEGIN\n"); - - if (!verify ()) - { - PERR ("gnc_dbi_verify_conn() failed\n"); - qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); - return FALSE; - } - - do - { - init_error (); - result = dbi_conn_queryf (m_conn, "BEGIN"); - } - while (m_retry); - - auto success = (result != nullptr); - auto status = dbi_result_free (result); - if (status < 0) - { - PERR ("Error in dbi_result_free() result\n"); - qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); - } - if (!success) - { - PERR ("BEGIN transaction failed()\n"); - qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); - } - - return success; -} - -bool -GncDbiSqlConnection::rollback_transaction () const noexcept -{ - DEBUG ("ROLLBACK\n"); - const char* command = "ROLLBACK"; - auto result = dbi_conn_query (m_conn, command); - auto success = (result != nullptr); - - auto status = dbi_result_free (result); - if (status < 0) - { - PERR ("Error in dbi_result_free() result\n"); - qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); - } - if (!success) - { - PERR ("Error in conn_rollback_transaction()\n"); - qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); - } - - return success; -} - -bool -GncDbiSqlConnection::commit_transaction () const noexcept -{ - DEBUG ("COMMIT\n"); - auto result = dbi_conn_queryf (m_conn, "COMMIT"); - auto success = (result != nullptr); - - auto status = dbi_result_free (result); - if (status < 0) - { - PERR ("Error in dbi_result_free() result\n"); - qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); - } - if (!success) - { - PERR ("Error in conn_commit_transaction()\n"); - qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); - } - - return success; -} - -static std::string -create_index_ddl (const GncSqlConnection* conn, const std::string& index_name, - const std::string& table_name, const EntryVec& col_table) -{ - std::string ddl; - ddl += "CREATE INDEX " + index_name + " ON " + table_name + "("; - for (auto const table_row : col_table) - { - if (table_row != *col_table.begin()) - { - ddl =+ ", "; - } - ddl += table_row->name(); - } - ddl += ")"; - return ddl; -} std::string add_columns_ddl(const GncSqlConnection* conn, @@ -2482,7 +2188,7 @@ GncDbiProviderImpl::append_col_def (std::string& ddl, ddl += info.m_name + " " + type_name; if (info.m_size != 0 && info.m_type == BCT_STRING) { - ddl += std::to_string(info.m_size); + ddl += "(" + std::to_string(info.m_size) + ")"; } if (info.m_unicode) { @@ -2561,86 +2267,6 @@ GncDbiProviderImpl::append_col_def (std::string& ddl, } } -bool -GncDbiSqlConnection::create_table (const std::string& table_name, - const ColVec& info_vec) const noexcept -{ - auto ddl = m_provider->create_table_ddl(this, table_name, info_vec); - if (ddl.empty()) - return false; - - DEBUG ("SQL: %s\n", ddl.c_str()); - auto result = dbi_conn_query (m_conn, ddl.c_str()); - auto status = dbi_result_free (result); - if (status < 0) - { - PERR ("Error in dbi_result_free() result\n"); - qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); - } - - return true; -} - -bool -GncDbiSqlConnection::create_index(const std::string& index_name, - const std::string& table_name, - const EntryVec& col_table) const noexcept -{ - auto ddl = create_index_ddl (this, index_name, table_name, col_table); - if (ddl.empty()) - return false; - DEBUG ("SQL: %s\n", ddl.c_str()); - auto result = dbi_conn_query (m_conn, ddl.c_str()); - auto status = dbi_result_free (result); - if (status < 0) - { - PERR ("Error in dbi_result_free() result\n"); - qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); - } - - return true; -} - -bool -GncDbiSqlConnection::add_columns_to_table(const std::string& table_name, - const ColVec& info_vec) - const noexcept -{ - auto ddl = add_columns_ddl(this, table_name, info_vec); - if (ddl.empty()) - return false; - - DEBUG ("SQL: %s\n", ddl.c_str()); - auto result = dbi_conn_query (m_conn, ddl.c_str()); - auto status = dbi_result_free (result); - if (status < 0) - { - PERR( "Error in dbi_result_free() result\n" ); - qof_backend_set_error(m_qbe, ERR_BACKEND_SERVER_ERR ); - } - - return true; -} - -std::string -GncDbiSqlConnection::quote_string (const std::string& unquoted_str) - const noexcept -{ - gchar* quoted_str; - size_t size; - - size = dbi_conn_quote_string_copy (m_conn, unquoted_str.c_str(), - "ed_str); - if (size != 0) - { - return std::string{quoted_str}; - } - else - { - return std::string{""}; - } -} - static std::vector conn_get_table_list (dbi_conn conn, const std::string& dbname) { diff --git a/src/backend/dbi/gnc-dbisqlconnection.cpp b/src/backend/dbi/gnc-dbisqlconnection.cpp new file mode 100644 index 0000000000..e95e26feb4 --- /dev/null +++ b/src/backend/dbi/gnc-dbisqlconnection.cpp @@ -0,0 +1,405 @@ +/******************************************************************** + * gnc-dbisqlconnection.cpp: Encapsulate libdbi dbi_conn * + * * + * Copyright 2016 John Ralls * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * + * Boston, MA 02110-1301, USA gnu@gnu.org * +\********************************************************************/ + +#include +extern "C" +{ +#include +#include +#include +} +#include "gnc-backend-dbi.hpp" + +static QofLogModule log_module = G_LOG_DOMAIN; + +static const unsigned int DBI_MAX_CONN_ATTEMPTS = 5; + + +/* --------------------------------------------------------- */ +class GncDbiSqlStatement : public GncSqlStatement +{ +public: + GncDbiSqlStatement(const GncSqlConnection* conn, const std::string& sql) : + m_conn{conn}, m_sql {sql} {} + ~GncDbiSqlStatement() {} + const char* to_sql() const override; + void add_where_cond(QofIdTypeConst, const PairVec&) override; + +private: + const GncSqlConnection* m_conn; + std::string m_sql; +}; + + +const char* +GncDbiSqlStatement::to_sql() const +{ + return m_sql.c_str(); +} + +void +GncDbiSqlStatement::add_where_cond(QofIdTypeConst type_name, + const PairVec& col_values) +{ + m_sql += " WHERE "; + for (auto colpair : col_values) + { + if (colpair != *col_values.begin()) + m_sql += " AND "; + m_sql += colpair.first + " = " + + m_conn->quote_string (colpair.second.c_str()); + } +} + +GncSqlResultPtr +GncDbiSqlConnection::execute_select_statement (const GncSqlStatementPtr& stmt) + noexcept +{ + dbi_result result; + + DEBUG ("SQL: %s\n", stmt->to_sql()); + gnc_push_locale (LC_NUMERIC, "C"); + do + { + init_error (); + result = dbi_conn_query (m_conn, stmt->to_sql()); + } + while (m_retry); + if (result == nullptr) + PERR ("Error executing SQL %s\n", stmt->to_sql()); + gnc_pop_locale (LC_NUMERIC); + return GncSqlResultPtr(new GncDbiSqlResult (this, result)); +} + +int +GncDbiSqlConnection::execute_nonselect_statement (const GncSqlStatementPtr& stmt) + noexcept +{ + dbi_result result; + + DEBUG ("SQL: %s\n", stmt->to_sql()); + do + { + init_error (); + result = dbi_conn_query (m_conn, stmt->to_sql()); + } + while (m_retry); + if (result == nullptr && m_last_error) + { + PERR ("Error executing SQL %s\n", stmt->to_sql()); + return -1; + } + if (!result) + return 0; + auto num_rows = (gint)dbi_result_get_numrows_affected (result); + auto status = dbi_result_free (result); + if (status < 0) + { + PERR ("Error in dbi_result_free() result\n"); + qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); + } + return num_rows; +} + +GncSqlStatementPtr +GncDbiSqlConnection::create_statement_from_sql (const std::string& sql) + const noexcept +{ + return std::unique_ptr{new GncDbiSqlStatement (this, sql)}; +} + +bool +GncDbiSqlConnection::does_table_exist (const std::string& table_name) + const noexcept +{ + auto dbname = dbi_conn_get_option (m_conn, "dbname"); + auto tables = dbi_conn_get_table_list (m_conn, dbname, table_name.c_str()); + auto nTables = dbi_result_get_numrows (tables); + auto status = dbi_result_free (tables); + if (status < 0) + { + PERR ("Error in dbi_result_free() result\n"); + qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); + } + + return nTables == 1; +} + +bool +GncDbiSqlConnection::begin_transaction () noexcept +{ + dbi_result result; + + DEBUG ("BEGIN\n"); + + if (!verify ()) + { + PERR ("gnc_dbi_verify_conn() failed\n"); + qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); + return FALSE; + } + + do + { + init_error (); + result = dbi_conn_queryf (m_conn, "BEGIN"); + } + while (m_retry); + + auto success = (result != nullptr); + auto status = dbi_result_free (result); + if (status < 0) + { + PERR ("Error in dbi_result_free() result\n"); + qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); + } + if (!success) + { + PERR ("BEGIN transaction failed()\n"); + qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); + } + + return success; +} + +bool +GncDbiSqlConnection::rollback_transaction () const noexcept +{ + DEBUG ("ROLLBACK\n"); + const char* command = "ROLLBACK"; + auto result = dbi_conn_query (m_conn, command); + auto success = (result != nullptr); + + auto status = dbi_result_free (result); + if (status < 0) + { + PERR ("Error in dbi_result_free() result\n"); + qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); + } + if (!success) + { + PERR ("Error in conn_rollback_transaction()\n"); + qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); + } + + return success; +} + +bool +GncDbiSqlConnection::commit_transaction () const noexcept +{ + DEBUG ("COMMIT\n"); + auto result = dbi_conn_queryf (m_conn, "COMMIT"); + auto success = (result != nullptr); + + auto status = dbi_result_free (result); + if (status < 0) + { + PERR ("Error in dbi_result_free() result\n"); + qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); + } + if (!success) + { + PERR ("Error in conn_commit_transaction()\n"); + qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); + } + + return success; +} + + +bool +GncDbiSqlConnection::create_table (const std::string& table_name, + const ColVec& info_vec) const noexcept +{ + auto ddl = m_provider->create_table_ddl(this, table_name, info_vec); + if (ddl.empty()) + return false; + + DEBUG ("SQL: %s\n", ddl.c_str()); + auto result = dbi_conn_query (m_conn, ddl.c_str()); + auto status = dbi_result_free (result); + if (status < 0) + { + PERR ("Error in dbi_result_free() result\n"); + qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); + } + + return true; +} + +static std::string +create_index_ddl (const GncSqlConnection* conn, const std::string& index_name, + const std::string& table_name, const EntryVec& col_table) +{ + std::string ddl; + ddl += "CREATE INDEX " + index_name + " ON " + table_name + "("; + for (auto const table_row : col_table) + { + if (table_row != *col_table.begin()) + { + ddl =+ ", "; + } + ddl += table_row->name(); + } + ddl += ")"; + return ddl; +} + +bool +GncDbiSqlConnection::create_index(const std::string& index_name, + const std::string& table_name, + const EntryVec& col_table) const noexcept +{ + auto ddl = create_index_ddl (this, index_name, table_name, col_table); + if (ddl.empty()) + return false; + DEBUG ("SQL: %s\n", ddl.c_str()); + auto result = dbi_conn_query (m_conn, ddl.c_str()); + auto status = dbi_result_free (result); + if (status < 0) + { + PERR ("Error in dbi_result_free() result\n"); + qof_backend_set_error (m_qbe, ERR_BACKEND_SERVER_ERR); + } + + return true; +} + +bool +GncDbiSqlConnection::add_columns_to_table(const std::string& table_name, + const ColVec& info_vec) + const noexcept +{ + auto ddl = add_columns_ddl(this, table_name, info_vec); + if (ddl.empty()) + return false; + + DEBUG ("SQL: %s\n", ddl.c_str()); + auto result = dbi_conn_query (m_conn, ddl.c_str()); + auto status = dbi_result_free (result); + if (status < 0) + { + PERR( "Error in dbi_result_free() result\n" ); + qof_backend_set_error(m_qbe, ERR_BACKEND_SERVER_ERR ); + } + + return true; +} + +std::string +GncDbiSqlConnection::quote_string (const std::string& unquoted_str) + const noexcept +{ + gchar* quoted_str; + size_t size; + + size = dbi_conn_quote_string_copy (m_conn, unquoted_str.c_str(), + "ed_str); + if (size != 0) + { + return std::string{quoted_str}; + } + else + { + return std::string{""}; + } +} + +/* Check if the dbi connection is valid. If not attempt to re-establish it + * Returns TRUE is there is a valid connection in the end or FALSE otherwise + */ +bool +GncDbiSqlConnection::verify () noexcept +{ + if (m_conn_ok) + return true; + + /* We attempt to connect only once here. The error function will + * automatically re-attempt up until DBI_MAX_CONN_ATTEMPTS time to connect + * if this call fails. After all these attempts, conn_ok will indicate if + * there is a valid connection or not. + */ + init_error (); + m_conn_ok = true; + (void)dbi_conn_connect (m_conn); + + return m_conn_ok; +} + +bool +GncDbiSqlConnection::retry_connection(const char* msg) + noexcept +{ + while (m_retry && m_error_repeat <= DBI_MAX_CONN_ATTEMPTS) + { + m_conn_ok = false; + if (dbi_conn_connect(m_conn) == 0) + { + init_error(); + m_conn_ok = true; + return true; + } +#ifdef G_OS_WIN32 + const guint backoff_msecs = 1; + Sleep (backoff_msecs * 2 << ++m_error_repeat); +#else + const guint backoff_usecs = 1000; + usleep (backoff_usecs * 2 << ++m_error_repeat); +#endif + PINFO ("DBI error: %s - Reconnecting...\n", msg); + + } + PERR ("DBI error: %s - Giving up after %d consecutive attempts.\n", msg, + DBI_MAX_CONN_ATTEMPTS); + m_conn_ok = false; + return false; +} + + +dbi_result +GncDbiSqlConnection::table_manage_backup (const std::string& table_name, + TableOpType op) +{ + auto new_name = table_name + "_back"; + dbi_result result = nullptr; + switch (op) + { + case backup: + result = dbi_conn_queryf (m_conn, "ALTER TABLE %s RENAME TO %s", + table_name.c_str(), new_name.c_str()); + break; + case rollback: + result = dbi_conn_queryf (m_conn, + "ALTER TABLE %s RENAME TO %s", + new_name.c_str(), table_name.c_str()); + break; + case drop_backup: + result = dbi_conn_queryf (m_conn, "DROP TABLE %s", + new_name.c_str()); + break; + default: + break; + } + return result; +} diff --git a/src/backend/dbi/test/CMakeLists.txt b/src/backend/dbi/test/CMakeLists.txt index 11a6bfe2d6..cc09d9dfe0 100644 --- a/src/backend/dbi/test/CMakeLists.txt +++ b/src/backend/dbi/test/CMakeLists.txt @@ -19,6 +19,7 @@ SET(test_dbi_backend_SOURCES test-dbi-business-stuff.cpp test-dbi-stuff.cpp ../gnc-backend-dbi.cpp + ../gnc-dbisqlconnection.cpp ) # This test does not work on Win32 diff --git a/src/backend/dbi/test/Makefile.am b/src/backend/dbi/test/Makefile.am index ae2f057db8..cd6a5f44a4 100644 --- a/src/backend/dbi/test/Makefile.am +++ b/src/backend/dbi/test/Makefile.am @@ -61,6 +61,7 @@ test_backend_dbi_SOURCES = \ test-backend-dbi-basic.cpp \ test-dbi-stuff.cpp \ test-dbi-business-stuff.cpp \ + ../gnc-dbisqlconnection.cpp \ ../gnc-backend-dbi.cpp test_backend_dbi_CPPFLAGS = \