Bug 796967 - gnclock table not removed when using PostgreSQL.

Because of https://sourceforge.net/p/libdbi-drivers/bugs/24.
This issue causes trouble in save_may_clobber_data() as well, so
work around it by using a SQL query instead of dbi_conn_get_table_list.
This commit is contained in:
John Ralls 2018-12-28 13:16:41 -08:00
parent 267852ba76
commit 1116ce909b
2 changed files with 44 additions and 15 deletions

View File

@ -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<DbType Type> bool save_may_clobber_data (dbi_conn conn,
const std::string& dbname);
template <DbType Type>
class QofDbiBackendProvider : public QofBackendProvider
@ -882,7 +883,7 @@ GncDbiBackend<Type>::load (QofBook* book, QofBackendLoadType loadType)
/* ================================================================= */
/* This is used too early to call GncDbiProvider::get_table_list(). */
static bool
template <DbType T> 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 <DbType::DBI_PGSQL>(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

View File

@ -262,19 +262,30 @@ template<> StrVec
GncDbiProviderImpl<DbType::DBI_PGSQL>::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;
}