diff --git a/libgnucash/backend/dbi/gnc-backend-dbi.cpp b/libgnucash/backend/dbi/gnc-backend-dbi.cpp index e2aaddf2f2..97b15642d6 100644 --- a/libgnucash/backend/dbi/gnc-backend-dbi.cpp +++ b/libgnucash/backend/dbi/gnc-backend-dbi.cpp @@ -111,7 +111,8 @@ static QofLogModule log_module = G_LOG_DOMAIN; #define PGSQL_DEFAULT_PORT 5432 static void adjust_sql_options (dbi_conn connection); -static bool save_may_clobber_data (dbi_conn conn, const std::string& dbname); +template bool save_may_clobber_data (dbi_conn conn, + const std::string& dbname); template class QofDbiBackendProvider : public QofBackendProvider @@ -882,7 +883,7 @@ GncDbiBackend::load (QofBook* book, QofBackendLoadType loadType) /* ================================================================= */ /* This is used too early to call GncDbiProvider::get_table_list(). */ -static bool +template bool save_may_clobber_data (dbi_conn conn, const std::string& dbname) { @@ -897,6 +898,23 @@ save_may_clobber_data (dbi_conn conn, const std::string& dbname) return retval; } +template <> bool +save_may_clobber_data (dbi_conn conn, + const std::string& dbname) +{ + + /* Data may be clobbered iff the number of tables != 0 */ + const char* query = "SELECT relname FROM pg_class WHERE relname !~ '^(pg|sql)_' AND relkind = 'r' ORDER BY relname"; + auto result = dbi_conn_query (conn, query); + bool retval = false; + if (result) + { + retval = dbi_result_get_numrows (result) > 0; + dbi_result_free (result); + } + return retval; +} + /** * Safely resave a database by renaming all of its tables, recreating diff --git a/libgnucash/backend/dbi/gnc-dbiproviderimpl.hpp b/libgnucash/backend/dbi/gnc-dbiproviderimpl.hpp index 32f3ec604b..107984dd9a 100644 --- a/libgnucash/backend/dbi/gnc-dbiproviderimpl.hpp +++ b/libgnucash/backend/dbi/gnc-dbiproviderimpl.hpp @@ -262,19 +262,30 @@ template<> StrVec GncDbiProviderImpl::get_table_list (dbi_conn conn, const std::string& table) { - std::string dbname (dbi_conn_get_option (conn, "dbname")); - auto list = conn_get_table_list (conn, dbname, table); - auto end = std::remove_if (list.begin(), list.end(), - [](std::string& table_name){ - return table_name == "sql_features" || - table_name == "sql_implementation_info" || - table_name == "sql_languages" || - table_name == "sql_packages" || - table_name == "sql_parts" || - table_name == "sql_sizing" || - table_name == "sql_sizing_profiles"; - }); - list.erase(end, list.end()); + const char* query_no_regex = "SELECT relname FROM pg_class WHERE relname" + "!~ '^(pg|sql)_' AND relkind = 'r' ORDER BY relname"; + std::string query_with_regex = "SELECT relname FROM pg_class WHERE relname LIKE '"; + query_with_regex += table + "' AND relkind = 'r' ORDER BY relname"; + dbi_result result; + if (table.empty()) + result = dbi_conn_query (conn, query_no_regex); + else + result = dbi_conn_query (conn, query_with_regex.c_str()); + + StrVec list; + const char* errmsg; + if (dbi_conn_error (conn, &errmsg) != DBI_ERROR_NONE) + { + PWARN ("Table List Retrieval Error: %s\n", errmsg); + return list; + } + + while (dbi_result_next_row (result) != 0) + { + std::string index_name {dbi_result_get_string_idx (result, 1)}; + list.push_back(index_name); + } + dbi_result_free (result); return list; }