[glom/glom-1-30] connection_request_password_and_choose_new_database_name(): Re-ask password.



commit fd5021eb4858100182c5e67b5983b4debf8a74dc
Author: Murray Cumming <murrayc murrayc com>
Date:   Fri Dec 18 11:25:18 2015 +0100

    connection_request_password_and_choose_new_database_name(): Re-ask password.
    
    If we are connecting to a central server, so we need to ask for a password,
    ask for it again if we fail to get an unused database name, which can
    only happen if there is a connection error.

 glom/frame_glom.cc |  257 +++++++++++++++++++++++++++-------------------------
 1 files changed, 135 insertions(+), 122 deletions(-)
---
diff --git a/glom/frame_glom.cc b/glom/frame_glom.cc
index 05f9665..5bd3ed2 100644
--- a/glom/frame_glom.cc
+++ b/glom/frame_glom.cc
@@ -2001,163 +2001,176 @@ bool Frame_Glom::connection_request_password_and_choose_new_database_name()
   auto connection_pool = ConnectionPool::get_instance();
   connection_pool->setup_from_document(document);
 
-  const auto hosting_mode = document->get_hosting_mode();
-  switch(hosting_mode)
-  {
-    case Document::HostingMode::POSTGRES_SELF:
-    case Document::HostingMode::MYSQL_SELF:
+  //Sometimes the password is automatic:
+  bool password_requested = false;
+  bool startup_done = false;
+
+  Glib::ustring database_name_possible;
+  while(database_name_possible.empty()) {
+    const auto hosting_mode = document->get_hosting_mode();
+    switch(hosting_mode)
     {
-      Glib::ustring user, password;
-
-      if(document->get_network_shared()) //Usually not the case when creating new documents.
-      {
-        const auto test = connection_request_initial_password(user, password);
-        if(!test)
-          return false;
-      }
-      else
+      case Document::HostingMode::POSTGRES_SELF:
+      case Document::HostingMode::MYSQL_SELF:
       {
-        //Use the default user because we are not network shared:
-        user = Privs::get_default_developer_user_name(password, hosting_mode);
-      }
+        Glib::ustring user, password;
 
-      // Create the requested self-hosting database:
+        if(document->get_network_shared()) //Usually not the case when creating new documents.
+        {
+          const auto test = connection_request_initial_password(user, password);
+          if(!test)
+            return false;
+        }
+        else
+        {
+          //Use the default user because we are not network shared:
+          user = Privs::get_default_developer_user_name(password, hosting_mode);
+        }
 
-      //Set the connection details in the ConnectionPool singleton.
-      //The ConnectionPool will now use these every time it tries to connect.
-      connection_pool->set_user(user);
-      connection_pool->set_password(password);
+        // Create the requested self-hosting database:
 
-      ShowProgressMessage progress_message(_("Initializing Database Data"));
-      const auto initialized = handle_connection_initialize_errors( connection_pool->initialize(
-         sigc::mem_fun(*this, &Frame_Glom::on_connection_initialize_progress) ) );
+        //Set the connection details in the ConnectionPool singleton.
+        //The ConnectionPool will now use these every time it tries to connect.
+        connection_pool->set_user(user);
+        connection_pool->set_password(password);
 
-      if(!initialized)
-        return false;
+        ShowProgressMessage progress_message(_("Initializing Database Data"));
+        const auto initialized = handle_connection_initialize_errors( connection_pool->initialize(
+           sigc::mem_fun(*this, &Frame_Glom::on_connection_initialize_progress) ) );
 
-      //std::cout << "DEBUG: after connection_pool->initialize(). The database cluster should now exist." << 
std::endl;
+        if(!initialized)
+          return false;
 
-      break;
-    }
-    case Document::HostingMode::POSTGRES_CENTRAL:
-    case Document::HostingMode::MYSQL_CENTRAL:
-    {
-      instantiate_dialog_connection();
+        //std::cout << "DEBUG: after connection_pool->initialize(). The database cluster should now exist." 
<< std::endl;
 
-      //Ask for connection details:
-      m_pDialogConnection->load_from_document(); //Get good defaults.
-      m_pDialogConnection->set_transient_for(*get_app_window());
+        break;
+      }
+      case Document::HostingMode::POSTGRES_CENTRAL:
+      case Document::HostingMode::MYSQL_CENTRAL:
+      {
+        instantiate_dialog_connection();
 
-      const auto response = Glom::UiUtils::dialog_run_with_help(m_pDialogConnection);
-      m_pDialogConnection->hide();
+        //Ask for connection details:
+        m_pDialogConnection->load_from_document(); //Get good defaults.
+        m_pDialogConnection->set_transient_for(*get_app_window());
+
+        const auto response = Glom::UiUtils::dialog_run_with_help(m_pDialogConnection);
+        m_pDialogConnection->hide();
+        password_requested = true; //So we can ask again if it didn't work.
 
-      if(response == Gtk::RESPONSE_OK)
+        if(response == Gtk::RESPONSE_OK)
+        {
+          // We are not self-hosting, but we also call initialize() for
+          // consistency (the backend will ignore it anyway).
+          ConnectionPool::SlotProgress slot_ignored;
+          if(!handle_connection_initialize_errors( connection_pool->initialize(slot_ignored)) )
+            return false;
+
+          Glib::ustring username, password;
+          m_pDialogConnection->get_username_and_password(username, password);
+          connection_pool->set_user(username);
+          connection_pool->set_password(password);
+
+          // Remember the user name in the document, to be able to open the
+          // document again later:
+          document->set_connection_user(username);
+        }
+        else
+        {
+          // The user cancelled
+          return false;
+        }
+        break;
+      }
+  #ifdef GLOM_ENABLE_SQLITE
+      case Document::HostingMode::SQLITE:
       {
-        // We are not self-hosting, but we also call initialize() for
-        // consistency (the backend will ignore it anyway).
+        // SQLite:
         ConnectionPool::SlotProgress slot_ignored;
         if(!handle_connection_initialize_errors( connection_pool->initialize(slot_ignored)) )
           return false;
 
-        Glib::ustring username, password;
-        m_pDialogConnection->get_username_and_password(username, password);
-        connection_pool->set_user(username);
-        connection_pool->set_password(password);
-
-        // Remember the user name in the document, to be able to open the
-        // document again later:
-        document->set_connection_user(username);
+        //m_pDialogConnection->load_from_document(); //Get good defaults.
+        // No authentication required
+        
+        break;
       }
-      else
+  #endif //GLOM_ENABLE_SQLITE
+      default:
+        g_assert_not_reached();
+        break;
+    }
+
+    // Do startup, such as starting the self-hosting database server.
+    if (!startup_done)
+    {
+      ShowProgressMessage progress_message(_("Starting Database Server"));
+      const ConnectionPool::StartupErrors started =
+        connection_pool->startup( sigc::mem_fun(*this, &Frame_Glom::on_connection_startup_progress) );
+      if(started != ConnectionPool::Backend::StartupErrors::NONE)
       {
-        // The user cancelled
+        std::cerr << G_STRFUNC << ": startup() failed." << std::endl;
+        //TODO: Output more exact details of the error message.
+        cleanup_connection();
         return false;
       }
-      break;
     }
-#ifdef GLOM_ENABLE_SQLITE
-    case Document::HostingMode::SQLITE:
+
+    const auto database_name = document->get_connection_database();
+    database_name_possible = DbUtils::get_unused_database_name(database_name);
+    if (database_name_possible.empty())
     {
-      // SQLite:
-      ConnectionPool::SlotProgress slot_ignored;
-      if(!handle_connection_initialize_errors( connection_pool->initialize(slot_ignored)) )
+      //This can only happen if we couldn't connect to the server at all.
+      //Warn the user, and let him try again:
+      UiUtils::show_ok_dialog(_("Connection Failed"), _("Glom could not connect to the database server. 
Maybe you entered an incorrect user name or password, or maybe the postgres database server is not 
running."), *(get_app_window()), Gtk::MESSAGE_ERROR); //TODO: Add help button.
+
+      //If we didn't ask the user for a password then there's nothing for us to try again.
+      //Otherwise let the while() loop try again.
+      if (!password_requested) {
+        cleanup_connection();
         return false;
-
-      //m_pDialogConnection->load_from_document(); //Get good defaults.
-      // No authentication required
-      
-      break;
+      }
     }
-#endif //GLOM_ENABLE_SQLITE
-    default:
-      g_assert_not_reached();
-      break;
-  }
-
-  // Do startup, such as starting the self-hosting database server
-  ShowProgressMessage progress_message(_("Starting Database Server"));
-  const ConnectionPool::StartupErrors started =
-    connection_pool->startup( sigc::mem_fun(*this, &Frame_Glom::on_connection_startup_progress) );
-  if(started != ConnectionPool::Backend::StartupErrors::NONE)
-  {
-    std::cerr << G_STRFUNC << ": startup() failed." << std::endl;
-    //TODO: Output more exact details of the error message.
-    return false;
   }
 
-  const auto database_name = document->get_connection_database();
-  const auto database_name_possible = DbUtils::get_unused_database_name(database_name);
-  if (database_name_possible.empty())
-  {
-    //This can only happen if we couldn't connect to the server at all.
-    //Warn the user, and let him try again:
-    UiUtils::show_ok_dialog(_("Connection Failed"), _("Glom could not connect to the database server. Maybe 
you entered an incorrect user name or password, or maybe the postgres database server is not running."), 
*(get_app_window()), Gtk::MESSAGE_ERROR); //TODO: Add help button.
-    return false;
-  }
-  else
-  {
-    std::cout << "debug: " << G_STRFUNC << ": unused database name successfully found: " << 
database_name_possible << std::endl;
 
-    //std::cout << "debug: unused database name found: " << database_name_possible << std::endl;
-    document->set_connection_database(database_name_possible);
+  std::cout << "debug: " << G_STRFUNC << ": unused database name successfully found: " << 
database_name_possible << std::endl;
 
-    // Remember host and port if the document is not self hosted
-    #ifdef GLOM_ENABLE_POSTGRESQL
-    if(document->get_hosting_mode() == Document::HostingMode::POSTGRES_CENTRAL)
-    {
-      auto backend = connection_pool->get_backend();
-      auto central = dynamic_cast<ConnectionPoolBackends::PostgresCentralHosted*>(backend);
-      g_assert(central);
+  //std::cout << "debug: unused database name found: " << database_name_possible << std::endl;
+  document->set_connection_database(database_name_possible);
 
-      document->set_connection_server(central->get_host());
-      document->set_connection_port(central->get_port());
-      document->set_connection_try_other_ports(false);
-    }
-
-    // Remember port if the document is self-hosted, so that remote
-    // connections to the database (usinc browse network) know what port to use.
-    // TODO: There is already similar code in
-    // connect_to_server_with_connection_settings, which is just not
-    // executed because it failed with no database present. We should
-    // somehow avoid this code duplication.
-    else if(document->get_hosting_mode() == Document::HostingMode::POSTGRES_SELF)
-    {
-      auto backend = connection_pool->get_backend();
-      auto self = dynamic_cast<ConnectionPoolBackends::PostgresSelfHosted*>(backend);
-      g_assert(self);
+  // Remember host and port if the document is not self hosted
+  #ifdef GLOM_ENABLE_POSTGRESQL
+  if(document->get_hosting_mode() == Document::HostingMode::POSTGRES_CENTRAL)
+  {
+    auto backend = connection_pool->get_backend();
+    auto central = dynamic_cast<ConnectionPoolBackends::PostgresCentralHosted*>(backend);
+    g_assert(central);
 
-      document->set_connection_port(self->get_port());
-      document->set_connection_try_other_ports(false);
-    }
+    document->set_connection_server(central->get_host());
+    document->set_connection_port(central->get_port());
+    document->set_connection_try_other_ports(false);
+  }
 
-    #endif //GLOM_ENABLE_POSTGRESQL
+  // Remember port if the document is self-hosted, so that remote
+  // connections to the database (usinc browse network) know what port to use.
+  // TODO: There is already similar code in
+  // connect_to_server_with_connection_settings, which is just not
+  // executed because it failed with no database present. We should
+  // somehow avoid this code duplication.
+  else if(document->get_hosting_mode() == Document::HostingMode::POSTGRES_SELF)
+  {
+    auto backend = connection_pool->get_backend();
+    auto self = dynamic_cast<ConnectionPoolBackends::PostgresSelfHosted*>(backend);
+    g_assert(self);
 
-    return true;
+    document->set_connection_port(self->get_port());
+    document->set_connection_try_other_ports(false);
   }
 
-  cleanup_connection();
+  #endif //GLOM_ENABLE_POSTGRESQL
 
-  return false;
+  return true;
 }
 #endif //GLOM_ENABLE_CLIENT_ONLY
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]