gnucash maint: Multiple changes pushed

John Ralls jralls at code.gnucash.org
Fri Dec 28 16:52:31 EST 2018


Updated	 via  https://github.com/Gnucash/gnucash/commit/9bfaada3 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/1116ce90 (commit)
	from  https://github.com/Gnucash/gnucash/commit/267852ba (commit)



commit 9bfaada356e5fb8ec58347b50e96de1884797f5d
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Dec 28 13:21:16 2018 -0800

    Bug 796961 - Can't overwrite existing MYSQL database, V3.3.
    
    Because m_exists was left true after dropping it, so the new
    database wasn't created.

diff --git a/libgnucash/backend/dbi/gnc-backend-dbi.cpp b/libgnucash/backend/dbi/gnc-backend-dbi.cpp
index 97b1564..bb844fd 100644
--- a/libgnucash/backend/dbi/gnc-backend-dbi.cpp
+++ b/libgnucash/backend/dbi/gnc-backend-dbi.cpp
@@ -659,31 +659,54 @@ GncDbiBackend<Type>::session_begin (QofSession* session, const char* book_id,
             LEAVE("Error");
             return;
         }
-        if (create && save_may_clobber_data (conn, uri.quote_dbname(Type)))
+        if (create && save_may_clobber_data<Type>(conn,
+                                                   uri.quote_dbname(Type)))
         {
             if (force)
             {
                 // Drop DB
+                const char *root_db;
                 if (Type == DbType::DBI_PGSQL)
-                    dbi_conn_select_db (conn, "template1");
+                {
+                    root_db = "template1";
+                }
                 else if (Type == DbType::DBI_MYSQL)
-                    dbi_conn_select_db (conn, "mysql");
+                {
+                    root_db = "mysql";
+                }
                 else
-                    PWARN ("Unknown database type, don't know how to connect to a system database. Dropping existing database may fail.");
-
+                {
+                    PERR ("Unknown database type, can't proceed.");
+                    LEAVE("Error");
+                    return;
+                }
+                if (dbi_conn_select_db (conn, root_db) == -1)
+                {
+                    PERR ("Failed to switch out of %s, drop will fail.",
+                          uri.quote_dbname(Type).c_str());
+                    LEAVE ("Error");
+                    return;
+                }
                 if (!dbi_conn_queryf (conn, "DROP DATABASE %s",
                                  uri.quote_dbname(Type).c_str()))
-                    PWARN ("Failed to drop database %s prior to recreating it. Creation will likely fail.",
+                {
+                    PERR ("Failed to drop database %s prior to recreating it."
+                          "Proceeding would combine old and new data.",
                            uri.quote_dbname(Type).c_str());
+                    LEAVE ("Error");
+                    return;
+                }
             }
             else
             {
                 set_error (ERR_BACKEND_STORE_EXISTS);
-                PWARN ("Databse already exists, Might clobber it.");
+                PWARN ("Database already exists, Might clobber it.");
                 dbi_conn_close(conn);
                 LEAVE("Error");
                 return;
             }
+            /* Drop successful. */
+            m_exists = false;
         }
 
     }

commit 1116ce909b9827ac928ed41d68c58190a62f4546
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Dec 28 13:16:41 2018 -0800

    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.

diff --git a/libgnucash/backend/dbi/gnc-backend-dbi.cpp b/libgnucash/backend/dbi/gnc-backend-dbi.cpp
index e2aaddf..97b1564 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<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
diff --git a/libgnucash/backend/dbi/gnc-dbiproviderimpl.hpp b/libgnucash/backend/dbi/gnc-dbiproviderimpl.hpp
index 32f3ec6..107984d 100644
--- a/libgnucash/backend/dbi/gnc-dbiproviderimpl.hpp
+++ b/libgnucash/backend/dbi/gnc-dbiproviderimpl.hpp
@@ -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;
 }
 



Summary of changes:
 libgnucash/backend/dbi/gnc-backend-dbi.cpp     | 59 ++++++++++++++++++++++----
 libgnucash/backend/dbi/gnc-dbiproviderimpl.hpp | 37 ++++++++++------
 2 files changed, 74 insertions(+), 22 deletions(-)



More information about the gnucash-changes mailing list