[glom/feature_backup2: 2/6] In progress



commit de5b41ea309656ddc503d2c0a847d68632fe8e79
Author: Murray Cumming <murrayc murrayc com>
Date:   Tue Jun 29 17:25:22 2010 +0200

    In progress

 ChangeLog                                          |   13 ++
 glom/application.cc                                |   25 ++++-
 glom/application.h                                 |    1 +
 glom/libglom/connectionpool.cc                     |    6 +
 glom/libglom/connectionpool.h                      |   13 ++-
 glom/libglom/connectionpool_backends/backend.h     |    6 +
 glom/libglom/connectionpool_backends/postgres.cc   |  134 +++++++++++++++++---
 glom/libglom/connectionpool_backends/postgres.h    |   20 +++-
 .../connectionpool_backends/postgres_central.cc    |    8 +-
 .../connectionpool_backends/postgres_central.h     |    3 -
 .../connectionpool_backends/postgres_self.cc       |  114 +++++------------
 .../connectionpool_backends/postgres_self.h        |    9 +-
 glom/libglom/connectionpool_backends/sqlite.cc     |    5 +
 glom/libglom/connectionpool_backends/sqlite.h      |    2 +
 glom/libglom/utils.cc                              |    2 +-
 15 files changed, 238 insertions(+), 123 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index c9e049b..9331b69 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,19 @@
 	
 2010-06-29  Murray Cumming  <murrayc murrayc com>
 
+	* glom/application.[h|cc]: Developer menu: Added an Export Backup menu item.
+
+	* glom/libglom/connectionpool_backends/postgres_central.[h|cc]:
+	* glom/libglom/connectionpool_backends/postgres_self.[h|cc]: Moved
+    m_host and m_port into the base class:
+	* glom/libglom/connectionpool_backends/postgres.[h|cc]:
+    because they are used in both derived classes. Therefore remove port
+    parameter from attempt_connect().
+    Also move get_path_to_postgres_executable() and port_as_string() there
+    so they can be used in the base class.
+
+2010-06-29  Murray Cumming  <murrayc murrayc com>
+
 	Improve stderr message.
 
 	* glom/libglom/spawn_with_feedback.cc:
diff --git a/glom/application.cc b/glom/application.cc
index 9ce1ff0..7261fb7 100644
--- a/glom/application.cc
+++ b/glom/application.cc
@@ -1,6 +1,6 @@
 /* Glom
  *
- * Copyright (C) 2001-2004 Murray Cumming
+ * Copyright (C) 2001-2010 Murray Cumming
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -544,6 +544,10 @@ void Application::init_menus()
   m_refActionGroup_Others->add(action, sigc::mem_fun(*this, &Application::on_menu_developer_active_platform_maemo));
 
 
+  action = Gtk::Action::create("GlomAction_Menu_Developer_ExportBackup", _("_Export Backup"));
+  m_listDeveloperActions.push_back(action);
+  m_refActionGroup_Others->add(action, sigc::mem_fun(*this, &Application::on_menu_developer_export_backup));
+
   m_action_show_layout_toolbar = Gtk::ToggleAction::create("GlomAction_Menu_Developer_ShowLayoutToolbar", _("_Show Layout Toolbar"));
   m_listDeveloperActions.push_back(m_action_show_layout_toolbar);
   m_refActionGroup_Others->add(m_action_show_layout_toolbar, sigc::mem_fun(*this, &Application::on_menu_developer_show_layout_toolbar));
@@ -600,6 +604,7 @@ void Application::init_menus()
     "          <menuitem action='GlomAction_Menu_Developer_ActivePlatform_Normal' />"
     "          <menuitem action='GlomAction_Menu_Developer_ActivePlatform_Maemo' />"
     "        </menu>"
+    "        <menuitem action='GlomAction_Menu_Developer_ExportBackup' />"
     "        <menuitem action='GlomAction_Menu_Developer_ShowLayoutToolbar' />"
     "      </menu>"
 #endif // !GLOM_ENABLE_CLIENT_ONLY
@@ -2480,6 +2485,24 @@ void Application::on_menu_developer_active_platform_maemo()
   m_pFrame->show_table_refresh();
 }
 
+void Application::on_menu_developer_export_backup()
+{
+  Gtk::FileChooserDialog dialog(*this, _("Save Backup"), Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER);
+  dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+  dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT); 
+  const int result = dialog.run();
+  if(result != Gtk::RESPONSE_ACCEPT)
+    return;
+    
+  const std::string& filepath_output = dialog.get_filename() + G_DIR_SEPARATOR + "backup";
+  if(filepath_output.empty())
+    return; 
+    
+  ConnectionPool* connection_pool = ConnectionPool::get_instance();
+  const bool saved = connection_pool->save_backup(ConnectionPool::SlotProgress() /* TODO */, filepath_output);
+  std::cout << "debug: saved=" << saved << std::endl;
+}
+
 void Application::on_menu_developer_show_layout_toolbar()
 {
   m_pFrame->show_layout_toolbar(m_action_show_layout_toolbar->get_active());
diff --git a/glom/application.h b/glom/application.h
index 332f0b9..04c90c0 100644
--- a/glom/application.h
+++ b/glom/application.h
@@ -169,6 +169,7 @@ private:
   void on_menu_developer_translations();
   void on_menu_developer_active_platform_normal();
   void on_menu_developer_active_platform_maemo();
+  void on_menu_developer_export_backup();
   void on_menu_developer_show_layout_toolbar();
 
   void on_window_translations_hide();
diff --git a/glom/libglom/connectionpool.cc b/glom/libglom/connectionpool.cc
index 9c572b7..210639b 100644
--- a/glom/libglom/connectionpool.cc
+++ b/glom/libglom/connectionpool.cc
@@ -415,6 +415,12 @@ void ConnectionPool::set_user(const Glib::ustring& value)
   invalidate_connection();
 }
 
+bool ConnectionPool::save_backup(const SlotProgress& slot_progress, const std::string& filepath_output)
+{
+  g_assert(m_backend.get());
+  return m_backend->save_backup(slot_progress, filepath_output, m_user, m_password, m_database);
+}
+  
 void ConnectionPool::set_password(const Glib::ustring& value)
 {
   m_password = value;
diff --git a/glom/libglom/connectionpool.h b/glom/libglom/connectionpool.h
index a881229..18c59e9 100644
--- a/glom/libglom/connectionpool.h
+++ b/glom/libglom/connectionpool.h
@@ -149,6 +149,12 @@ public:
   static sharedptr<SharedConnection> get_and_connect(std::auto_ptr<ExceptionConnection>& error);
 #endif
 
+  /** This callback should show UI to indicate that work is still happening.
+   * For instance, a pulsing ProgressBar.
+   */
+  typedef Backend::SlotProgress SlotProgress;
+
+ //TODO: Add SlotProgress?
   /** Creates a new database.
    */
 #ifdef GLIBMM_EXCEPTIONS_ENABLED
@@ -157,6 +163,8 @@ public:
   void create_database(const Glib::ustring& database_name, std::auto_ptr<Glib::Error>& error);
 #endif
 
+  bool save_backup(const SlotProgress& slot_progress, const std::string& filepath_output);
+
   void set_user(const Glib::ustring& value);
   void set_password(const Glib::ustring& value);
   void set_database(const Glib::ustring& value);
@@ -168,11 +176,6 @@ public:
   Field::sql_format get_sql_format() const;
   const FieldTypes* get_field_types() const;
   Glib::ustring get_string_find_operator() const;
-
-  /** This callback should show UI to indicate that work is still happening.
-   * For instance, a pulsing ProgressBar.
-   */
-  typedef Backend::SlotProgress SlotProgress;
  
   typedef Backend::InitErrors InitErrors;
   
diff --git a/glom/libglom/connectionpool_backends/backend.h b/glom/libglom/connectionpool_backends/backend.h
index ed85395..ad71fc5 100644
--- a/glom/libglom/connectionpool_backends/backend.h
+++ b/glom/libglom/connectionpool_backends/backend.h
@@ -180,6 +180,12 @@ protected:
   /** This method is called to create a new database on the
    * database server. */
   virtual bool create_database(const Glib::ustring& database_name, const Glib::ustring& username, const Glib::ustring& password, std::auto_ptr<Glib::Error>& error) = 0;
+  
+  /** Save a backup of the database in a tarball.
+   * This backup can later be used to recreate the database,
+   * for instance with a later version of PostgreSQL.
+   */
+  virtual bool save_backup(const SlotProgress& slot_progress, const std::string& filepath_output, const Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& database_name) = 0;
 };
 
 } // namespace ConnectionPoolBackends
diff --git a/glom/libglom/connectionpool_backends/postgres.cc b/glom/libglom/connectionpool_backends/postgres.cc
index 2a75d5f..b51413c 100644
--- a/glom/libglom/connectionpool_backends/postgres.cc
+++ b/glom/libglom/connectionpool_backends/postgres.cc
@@ -18,9 +18,11 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#include <config.h> // For POSTGRES_UTILS_PATH
 #include <libglom/libglom_config.h>
 
 #include <libglom/connectionpool_backends/postgres.h>
+#include <libglom/spawn_with_feedback.h>
 #include <libglom/utils.h>
 #include <glibmm/i18n.h>
 
@@ -47,7 +49,7 @@ namespace ConnectionPoolBackends
 {
 
 Postgres::Postgres()
-:
+: m_port(0),
   m_postgres_server_version(0.0f)
 {
 }
@@ -57,21 +59,21 @@ float Postgres::get_postgres_server_version() const
   return m_postgres_server_version;
 }
 
-Glib::RefPtr<Gnome::Gda::Connection> Postgres::attempt_connect(const Glib::ustring& host, const Glib::ustring& port, const Glib::ustring& database, const Glib::ustring& username, const Glib::ustring& password, std::auto_ptr<ExceptionConnection>& error) throw()
+Glib::RefPtr<Gnome::Gda::Connection> Postgres::attempt_connect(const Glib::ustring& port, const Glib::ustring& database, const Glib::ustring& username, const Glib::ustring& password, std::auto_ptr<ExceptionConnection>& error) throw()
 {
   //We must specify _some_ database even when we just want to create a database.
   //This _might_ be different on some systems. I hope not. murrayc
   const Glib::ustring default_database = "template1";
   //const Glib::ustring& actual_database = (!database.empty()) ? database : default_database;;
-  const Glib::ustring cnc_string_main = "HOST=" + host + ";PORT=" + port;
+  const Glib::ustring cnc_string_main = "HOST=" + m_host + ";PORT=" + port;
   Glib::ustring cnc_string = cnc_string_main + ";DB_NAME=" + database;
 
   Glib::RefPtr<Gnome::Gda::Connection> connection;
   Glib::RefPtr<Gnome::Gda::DataModel> data_model;
 
-  const Glib::ustring auth_string = create_auth_string(username, password);   
- 
-#ifdef GLOM_CONNECTION_DEBUG          
+  const Glib::ustring auth_string = create_auth_string(username, password);
+
+#ifdef GLOM_CONNECTION_DEBUG
   std::cout << std::endl << "DEBUG: Glom: trying to connect on port=" << port << std::endl;
   std::cout << "DEBUG: ConnectionPoolBackends::Postgres::attempt_connect(): cnc_string=" << cnc_string << std::endl;
   std::cout << "  DEBUG: auth_string=" << auth_string << std::endl;
@@ -80,8 +82,8 @@ Glib::RefPtr<Gnome::Gda::Connection> Postgres::attempt_connect(const Glib::ustri
 #ifdef GLIBMM_EXCEPTIONS_ENABLED
   try
   {
-    connection = Gnome::Gda::Connection::open_from_string("PostgreSQL", 
-      cnc_string, auth_string, 
+    connection = Gnome::Gda::Connection::open_from_string("PostgreSQL",
+      cnc_string, auth_string,
       Gnome::Gda::CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE
       );
     connection->statement_execute_non_select("SET DATESTYLE = 'ISO'");
@@ -91,11 +93,11 @@ Glib::RefPtr<Gnome::Gda::Connection> Postgres::attempt_connect(const Glib::ustri
   {
 #else
   std::auto_ptr<Glib::Error> ex;
-  connection = Gnome::Gda::Connection::open_from_string("PostgreSQL", 
+  connection = Gnome::Gda::Connection::open_from_string("PostgreSQL",
     cnc_string, auth_string,
     Gnome::Gda::CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE,
     ex);
-  
+
   if(!ex.get())
     connection->statement_execute_non_select("SET DATESTYLE = 'ISO'", ex);
 
@@ -117,15 +119,15 @@ Glib::RefPtr<Gnome::Gda::Connection> Postgres::attempt_connect(const Glib::ustri
 #ifdef GLIBMM_EXCEPTIONS_ENABLED
     try
     {
-      temp_conn = Gnome::Gda::Connection::open_from_string("PostgreSQL", 
-        cnc_string, auth_string, 
+      temp_conn = Gnome::Gda::Connection::open_from_string("PostgreSQL",
+        cnc_string, auth_string,
         Gnome::Gda::CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE);
     }
     catch(const Glib::Error& ex)
     {}
 #else
-    temp_conn = Gnome::Gda::Connection::open_from_string("PostgreSQL", 
-      cnc_string, auth_string, 
+    temp_conn = Gnome::Gda::Connection::open_from_string("PostgreSQL",
+      cnc_string, auth_string,
       Gnome::Gda::CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE, ex);
 #endif
 
@@ -203,7 +205,7 @@ bool Postgres::change_columns(const Glib::RefPtr<Gnome::Gda::Connection>& connec
         http://groups.google.de/groups?hl=en&lr=&ie=UTF-8&frame=right&th=a7a62337ad5a8f13&seekm=23739.1073660245%40sss.pgh.pa.us#link5
         UPDATE _table
         SET _bbb = to_number(substring(_aaa from 1 for 5), '99999')
-        WHERE _aaa <> '     ';  
+        WHERE _aaa <> '     ';
         */
 
         switch(new_fields[i]->get_glom_type())
@@ -234,7 +236,7 @@ bool Postgres::change_columns(const Glib::RefPtr<Gnome::Gda::Connection>& connec
             else
             {
               //We use to_number, with textcat() so that to_number always has usable data.
-              //Otherwise, it says 
+              //Otherwise, it says
               //invalid input syntax for type numeric: " "
               //
               //We must use single quotes with the 0, otherwise it says "column 0 does not exist.".
@@ -460,6 +462,106 @@ bool Postgres::check_postgres_gda_client_is_available()
   return false;
 }
 
+std::string Postgres::get_path_to_postgres_executable(const std::string& program)
+{
+#ifdef G_OS_WIN32
+  // Add the .exe extension on Windows:
+  std::string real_program = program + EXEEXT;
+
+  // Have a look at the bin directory of the application executable first.
+  // The installer installs postgres there. postgres needs to be installed
+  // in a directory called bin for its relocation stuff to work, so that
+  // it finds the share data in share. Unfortunately it does not look into
+  // share/postgresql which would be nice to separate the postgres stuff
+  // from the other shared data. We can perhaps still change this later by
+  // building postgres with another prefix than /local/pgsql.
+  gchar* installation_directory = g_win32_get_package_installation_directory_of_module(0);
+  std::string test = Glib::build_filename(installation_directory, Glib::build_filename("bin", real_program));
+  g_free(installation_directory);
+
+  if(Glib::file_test(test, Glib::FILE_TEST_IS_EXECUTABLE))
+    return test;
+
+  // Look in PATH otherwise
+  return Glib::find_program_in_path(real_program);
+#else // G_OS_WIN32
+  // POSTGRES_UTILS_PATH is defined in config.h, based on the configure.
+  return Glib::build_filename(POSTGRES_UTILS_PATH, program + EXEEXT);
+#endif // !G_OS_WIN32
+}
+
+
+Glib::ustring Postgres::port_as_string(int port_num)
+{
+  Glib::ustring result;
+  char* cresult = g_strdup_printf("%d", port_num);
+  if(cresult)
+    result = cresult;
+  g_free(cresult);
+
+  return result;
 }
 
+bool Postgres::save_backup(const SlotProgress& slot_progress, const std::string& filepath_output, const Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& database_name)
+{
+/* TODO:
+  if(m_network_shared && !running)
+  {
+    std::cerr << G_STRFUNC << ": The self-hosted database is not running." << std::endl;
+    return;
+  }
+*/
+
+  if(m_host.empty())
+  {
+    std::cerr << G_STRFUNC << ": m_host is empty." << std::endl;
+    return false;
+  }
+
+  if(m_port == 0)
+  {
+    std::cerr << G_STRFUNC << ": m_port is empty." << std::endl;
+    return false;
+  }
+
+  //TODO: Remember the existing username and password?
+  if(username.empty())
+  {
+    std::cerr << G_STRFUNC << ": username is empty." << std::endl;
+    return false;
+  }
+
+  if(password.empty())
+  {
+    std::cerr << G_STRFUNC << ": password is empty." << std::endl;
+    return false;
+  }
+
+  //TODO: Save the password to .pgpass
+
+  // Make sure to use double quotes for the executable path, because the
+  // CreateProcess() API used on Windows does not support single quotes.
+  const std::string command_dump = "\"" + get_path_to_postgres_executable("pg_dump") + "\"" +
+    " --create --file=\"" + filepath_output + "\"" +
+    " --host=\"" + m_host + "\"" +
+    " --port=" + port_as_string(m_port) +
+    " --username=\"" + username + "\"" +
+    " " + database_name;
+
+
+  //std::cout << "DEBUG: command_dump=" << command_dump << std::endl;
+  
+  //TODO: Put the password in .pgpass
+
+  const bool result = Glom::Spawn::execute_command_line_and_wait(command_dump, slot_progress);
+  if(!result)
+  {
+    std::cerr << "Error while attempting to call pg_dump." << std::endl;
+  }
+
+  return result;
 }
+
+} //namespace ConnectionPoolBackends
+
+} //namespace Glom
diff --git a/glom/libglom/connectionpool_backends/postgres.h b/glom/libglom/connectionpool_backends/postgres.h
index 9386a6d..a887c12 100644
--- a/glom/libglom/connectionpool_backends/postgres.h
+++ b/glom/libglom/connectionpool_backends/postgres.h
@@ -39,12 +39,12 @@ public:
 
   /** Return the version number of the connected postgres server.
    * This can be used to adapt to different server features.
-   * 
+   *
    * @result The version, or 0 if no connection has been made.
    */
   float get_postgres_server_version() const;
 
-  /** Check whether the libgda postgres provider is really available, 
+  /** Check whether the libgda postgres provider is really available,
    * so we can connect to postgres servers,
    * in case the distro package has incorrect dependencies.
    *
@@ -52,6 +52,10 @@ public:
    */
   static bool check_postgres_gda_client_is_available();
 
+  virtual bool save_backup(const SlotProgress& slot_progress, const std::string& filepath_output, const Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& database_name);
+
+  static std::string get_path_to_postgres_executable(const std::string& program);
+
 private:
   virtual Field::sql_format get_sql_format() const { return Field::SQL_FORMAT_POSTGRES; }
   virtual bool supports_remote_access() const { return true; }
@@ -65,8 +69,15 @@ protected:
 
   /** Attempt to connect to the database with the specified criteria.
    * @param error An error if the correction failed.
-   */ 
-  Glib::RefPtr<Gnome::Gda::Connection> attempt_connect(const Glib::ustring& host, const Glib::ustring& port, const Glib::ustring& database, const Glib::ustring& username, const Glib::ustring& password, std::auto_ptr<ExceptionConnection>& error) throw();
+   */
+  Glib::RefPtr<Gnome::Gda::Connection> attempt_connect(const Glib::ustring& port, const Glib::ustring& database, const Glib::ustring& username, const Glib::ustring& password, std::auto_ptr<ExceptionConnection>& error) throw();
+
+
+protected:
+  static Glib::ustring port_as_string(int port_num);
+
+  Glib::ustring m_host;
+  int m_port;
 
 private:
   float m_postgres_server_version;
@@ -77,4 +88,3 @@ private:
 } //namespace Glom
 
 #endif //GLOM_BACKEND_POSTGRES_H
-
diff --git a/glom/libglom/connectionpool_backends/postgres_central.cc b/glom/libglom/connectionpool_backends/postgres_central.cc
index 3d242f8..ce77631 100644
--- a/glom/libglom/connectionpool_backends/postgres_central.cc
+++ b/glom/libglom/connectionpool_backends/postgres_central.cc
@@ -49,9 +49,7 @@ namespace ConnectionPoolBackends
 {
 
 PostgresCentralHosted::PostgresCentralHosted()
-:
-  m_port(0),
-  m_try_other_ports(true)
+: m_try_other_ports(true)
 {
   m_list_ports.push_back("5432"); //Ubuntu Breezy seems to default to this for Postgres 7.4, and this is probably the default for most postgres installations, including Fedora.
 
@@ -111,7 +109,7 @@ Glib::RefPtr<Gnome::Gda::Connection> PostgresCentralHosted::connect(const Glib::
   if(m_port == 0)
     port = *iter_port ++;
 
-  connection = attempt_connect(m_host, port, database, username, password, error);
+  connection = attempt_connect(port, database, username, password, error);
 
   // Remember port if only the database was missing
   bool connection_possible = false;
@@ -127,7 +125,7 @@ Glib::RefPtr<Gnome::Gda::Connection> PostgresCentralHosted::connect(const Glib::
     while(!connection && iter_port != m_list_ports.end())
     {
       port = *iter_port;
-      connection = attempt_connect(m_host, port, database, username, password, error);
+      connection = attempt_connect(port, database, username, password, error);
 
       // Remember port if only the database was missing
       if(error.get() && error->get_failure_type() == ExceptionConnection::FAILURE_NO_DATABASE)
diff --git a/glom/libglom/connectionpool_backends/postgres_central.h b/glom/libglom/connectionpool_backends/postgres_central.h
index d40d9b4..8d6044f 100644
--- a/glom/libglom/connectionpool_backends/postgres_central.h
+++ b/glom/libglom/connectionpool_backends/postgres_central.h
@@ -56,8 +56,6 @@ private:
   typedef std::list<Glib::ustring> type_list_ports;
   type_list_ports m_list_ports;
 
-  Glib::ustring m_host;
-  int m_port;
   bool m_try_other_ports;
 };
 
@@ -66,4 +64,3 @@ private:
 } //namespace Glom
 
 #endif //GLOM_BACKEND_POSTGRES_CENTRAL_H
-
diff --git a/glom/libglom/connectionpool_backends/postgres_self.cc b/glom/libglom/connectionpool_backends/postgres_self.cc
index 9689bbe..2d67f52 100644
--- a/glom/libglom/connectionpool_backends/postgres_self.cc
+++ b/glom/libglom/connectionpool_backends/postgres_self.cc
@@ -18,8 +18,6 @@
  * Boston, MA 02111-1307, USA.
  */
 
-#include <config.h> // For POSTGRES_UTILS_PATH
-
 #include <libglom/connectionpool_backends/postgres_self.h>
 #include <libglom/utils.h>
 #include <libglom/spawn_with_feedback.h>
@@ -36,7 +34,7 @@
 # include <winsock2.h>
 #else
 # include <sys/types.h>
-# include <sys/socket.h> 
+# include <sys/socket.h>
 # include <errno.h>
 # include <netinet/in.h> //For sockaddr_in
 #endif
@@ -46,22 +44,6 @@
 // Uncomment to see debug messages
 //#define GLOM_CONNECTION_DEBUG
 
-namespace
-{
-
-static Glib::ustring port_as_string(int port_num)
-{
-  Glib::ustring result;
-  char* cresult = g_strdup_printf("%d", port_num);
-  if(cresult)
-    result = cresult;
-  g_free(cresult);
-
-  return result;
-}
-
-} // anonymous namespace
-
 namespace Glom
 {
 
@@ -70,9 +52,9 @@ namespace ConnectionPoolBackends
 
 //TODO: Do we need these sameuser lines?
 
-// We need both <=8.3 and >=8.4 versions, because the ident line changed syntax 
+// We need both <=8.3 and >=8.4 versions, because the ident line changed syntax
 // incompatibly: http://www.postgresql.org/about/press/features84#security
- 
+
 #define DEFAULT_CONFIG_PG_HBA_LOCAL_8p3 \
 "# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD\n" \
 "\n" \
@@ -126,37 +108,9 @@ DEFAULT_CONFIG_PG_HBA_REMOTE_EXTRA
 #define DEFAULT_CONFIG_PG_IDENT ""
 
 PostgresSelfHosted::PostgresSelfHosted()
-: m_port(0),
-   m_network_shared(false)
-{
-}
-
-
-std::string PostgresSelfHosted::get_path_to_postgres_executable(const std::string& program)
+: m_network_shared(false)
 {
-#ifdef G_OS_WIN32
-  // Add the .exe extension on Windows:
-  std::string real_program = program + EXEEXT;
-    
-  // Have a look at the bin directory of the application executable first.
-  // The installer installs postgres there. postgres needs to be installed
-  // in a directory called bin for its relocation stuff to work, so that
-  // it finds the share data in share. Unfortunately it does not look into
-  // share/postgresql which would be nice to separate the postgres stuff
-  // from the other shared data. We can perhaps still change this later by
-  // building postgres with another prefix than /local/pgsql.
-  gchar* installation_directory = g_win32_get_package_installation_directory_of_module(0);
-  std::string test = Glib::build_filename(installation_directory, Glib::build_filename("bin", real_program));
-  g_free(installation_directory);
-
-  if(Glib::file_test(test, Glib::FILE_TEST_IS_EXECUTABLE))
-    return test;
-
-  // Look in PATH otherwise
-  return Glib::find_program_in_path(real_program);
-#else // G_OS_WIN32
-  return Glib::build_filename(POSTGRES_UTILS_PATH, program + EXEEXT);
-#endif // !G_OS_WIN32
+  m_host = "localhost";
 }
 
 void PostgresSelfHosted::set_self_hosting_data_uri(const std::string& data_uri)
@@ -194,14 +148,14 @@ bool PostgresSelfHosted::install_postgres(const SlotProgress& /* slot_progress *
 
   //Careful. Maybe you want a different version.
   //Also, Glom will start its own instance of PostgreSQL, on its own port, when it needs to,
-  //so there is no need to start a Glom service after installation at system startup, 
+  //so there is no need to start a Glom service after installation at system startup,
   //though it will not hurt Glom if you do that.
   const gchar *packages[] = { "postgresql-8.1", 0 };
   const bool result = gst_packages_install(parent_window->gobj() /* parent window */, packages);
   if(result)
   {
     std::cout << "Glom: gst_packages_install() reports success." << std::endl;
-    //Double-check, because gst_packages_install() incorrectly returns TRUE if it fails because 
+    //Double-check, because gst_packages_install() incorrectly returns TRUE if it fails because
     //a) synaptic is already running, or
     //b) synaptic did not know about the package (no warning is shown in this case.)
     //Maybe gst_packages_install() never returns FALSE.
@@ -226,7 +180,7 @@ Backend::InitErrors PostgresSelfHosted::initialize(const SlotProgress& slot_prog
     std::cerr << "PostgresSelfHosted::initialize: m_self_hosting_data_uri is empty." << std::endl;
     return INITERROR_OTHER;
   }
-  
+
   if(initial_username.empty())
   {
     std::cerr << "PostgresSelfHosted::initialize(). Username was empty while attempting to create self-hosting database" << std::endl;
@@ -251,7 +205,7 @@ Backend::InitErrors PostgresSelfHosted::initialize(const SlotProgress& slot_prog
   {
     std::cerr << "Error from g_mkdir_with_parents() while trying to create directory: " << dbdir << std::endl;
     perror("Error from g_mkdir_with_parents");
-    
+
     return INITERROR_COULD_NOT_CREATE_DIRECTORY;
   }
 
@@ -274,7 +228,7 @@ Backend::InitErrors PostgresSelfHosted::initialize(const SlotProgress& slot_prog
   mkdir_succeeded = g_mkdir_with_parents(dbdir_data.c_str(), 0770);
   g_assert(mkdir_succeeded != -1);
 
-  
+
   // initdb creates a new postgres database cluster:
 
   //Get file:// URI for the tmp/ directory:
@@ -298,7 +252,7 @@ Backend::InitErrors PostgresSelfHosted::initialize(const SlotProgress& slot_prog
 
   const int temp_pwfile_removed = g_remove(temp_pwfile.c_str()); //Of course, we don't want this to stay around. It would be a security risk.
   g_assert(temp_pwfile_removed == 0);
- 
+
   return result ? INITERROR_NONE : INITERROR_COULD_NOT_START_SERVER;
 }
 
@@ -320,7 +274,7 @@ Glib::ustring PostgresSelfHosted::get_postgresql_utils_version(const SlotProgres
   //Use a regex to get the version number:
   Glib::RefPtr<Glib::Regex> regex;
 
-  //We want the characters at the end:  
+  //We want the characters at the end:
   const gchar* VERSION_REGEX = "pg_ctl \\(PostgreSQL\\) (.*)";
 
   #ifdef GLIBMM_EXCEPTIONS_ENABLED
@@ -332,7 +286,7 @@ Glib::ustring PostgresSelfHosted::get_postgresql_utils_version(const SlotProgres
   {
     std::cerr << "Glom: Glib::Regex::create() failed: " << ex.what() << std::endl;
     return result;
-  } 
+  }
   #else
   std::auto_ptr<Glib::Error> ex;
   regex = Glib::Regex::create(VERSION_REGEX, static_cast<Glib::RegexCompileFlags>(0), static_cast<Glib::RegexMatchFlags>(0), ex);
@@ -342,7 +296,7 @@ Glib::ustring PostgresSelfHosted::get_postgresql_utils_version(const SlotProgres
     return result;
   }
   #endif
- 
+
   if(!regex)
     return result;
 
@@ -360,7 +314,7 @@ Glib::ustring PostgresSelfHosted::get_postgresql_utils_version(const SlotProgres
     if(!str.empty())
       return str; //Found.
   }
- 
+
   return result;
 }
 
@@ -372,7 +326,7 @@ float PostgresSelfHosted::get_postgresql_utils_version_as_number(const SlotProgr
 
   Glib::RefPtr<Glib::Regex> regex;
 
-  //We want the characters at the end:  
+  //We want the characters at the end:
   const gchar* VERSION_REGEX = "^(\\d*)\\.(\\d*)";
 
   #ifdef GLIBMM_EXCEPTIONS_ENABLED
@@ -384,7 +338,7 @@ float PostgresSelfHosted::get_postgresql_utils_version_as_number(const SlotProgr
   {
     std::cerr << "Glom: Glib::Regex::create() failed: " << ex.what() << std::endl;
     return result;
-  } 
+  }
   #else
   std::auto_ptr<Glib::Error> ex;
   regex = Glib::Regex::create(VERSION_REGEX, static_cast<Glib::RegexCompileFlags>(0), static_cast<Glib::RegexMatchFlags>(0), ex);
@@ -394,7 +348,7 @@ float PostgresSelfHosted::get_postgresql_utils_version_as_number(const SlotProgr
     return result;
   }
   #endif
- 
+
   if(!regex)
     return result;
 
@@ -482,7 +436,6 @@ bool PostgresSelfHosted::startup(const SlotProgress& slot_progress, bool network
   // -D specifies the data directory.
   // -c config_file= specifies the configuration file
   // -k specifies a directory to use for the socket. This must be writable by us.
-  // POSTGRES_UTILS_PATH is defined in config.h, based on the configure.
   // Make sure to use double quotes for the executable path, because the
   // CreateProcess() API used on Windows does not support single quotes.
   const std::string command_postgres_start = "\"" + get_path_to_postgres_executable("postgres") + "\" -D \"" + dbdir_data + "\" "
@@ -502,7 +455,7 @@ bool PostgresSelfHosted::startup(const SlotProgress& slot_progress, bool network
   //This is a big hack that we should avoid. murrayc.
   //
   //pg_ctl actually seems to return a 0 result code for "is running" and a 1 for not running, at least with Postgres 8.2,
-  //so maybe we can avoid this in future.  
+  //so maybe we can avoid this in future.
   //Please do test it with your postgres version, using "echo $?" to see the result code of the last command.
   const std::string second_command_success_text = "is running"; //TODO: This is not a stable API. Also, watch out for localisation.
 
@@ -515,7 +468,7 @@ bool PostgresSelfHosted::startup(const SlotProgress& slot_progress, bool network
   }
 
   m_port = available_port; //Remember it for later.
-  
+
   return true;
 }
 
@@ -535,13 +488,12 @@ bool PostgresSelfHosted::cleanup(const SlotProgress& slot_progress)
   const std::string dbdir_data = Glib::build_filename(dbdir, "data");
 
 
-  // TODO: Detect other instances on the same computer, and use a different port number, 
+  // TODO: Detect other instances on the same computer, and use a different port number,
   // or refuse to continue, showing an error dialog.
 
   // -D specifies the data directory.
   // -c config_file= specifies the configuration file
   // -k specifies a directory to use for the socket. This must be writable by us.
-  // POSTGRES_UTILS_PATH is defined in config.h, based on the configure.
   // We use "-m fast" instead of the default "-m smart" because that waits for clients to disconnect (and sometimes never succeeds).
   // TODO: Warn about connected clients on other computers? Warn those other users?
   // Make sure to use double quotes for the executable path, because the
@@ -581,7 +533,7 @@ bool PostgresSelfHosted::set_network_shared(const SlotProgress& slot_progress, b
   const std::string dbdir_uri_config = dbdir_uri + "/config";
   const char* default_conf_contents = 0;
 
-  // Choose the configuration contents based on the postgresql version 
+  // Choose the configuration contents based on the postgresql version
   // and whether we want to be network-shared:
   const float postgresql_version = get_postgresql_utils_version_as_number(slot_progress);
   //std::cout << "DEBUG: postgresql_version=" << postgresql_version << std::endl;
@@ -609,7 +561,7 @@ static bool on_timeout_delay(const Glib::RefPtr<Glib::MainLoop>& mainloop)
   //Allow our mainloop.run() to return:
   if(mainloop)
     mainloop->quit();
-    
+
   return false;
 }
 
@@ -630,13 +582,13 @@ Glib::RefPtr<Gnome::Gda::Connection> PostgresSelfHosted::connect(const Glib::ust
   const guint MAX_RETRIES_KNOWN_PASSWORD = 30; /* seconds */
   const guint MAX_RETRIES_EVER = 60; /* seconds */
   while(keep_trying)
-  { 
-    result = attempt_connect("localhost", port_as_string(m_port), database, username, password, ex);
-    if(!result && 
+  {
+    result = attempt_connect(port_as_string(m_port), database, username, password, ex);
+    if(!result &&
       ex.get() && (ex->get_failure_type() == ExceptionConnection::FAILURE_NO_SERVER))
     {
       //It must be using a default password, so any failure would not be due to a wrong password.
-      //However, pg_ctl sometimes reports success before it is really ready to let us connect, 
+      //However, pg_ctl sometimes reports success before it is really ready to let us connect,
       //so in this case we can just keep trying until it works, with a very long timeout.
       count_retries++;
       const guint max_retries = m_network_shared ? MAX_RETRIES_EVER : MAX_RETRIES_KNOWN_PASSWORD;
@@ -646,20 +598,20 @@ Glib::RefPtr<Gnome::Gda::Connection> PostgresSelfHosted::connect(const Glib::ust
         continue;
       }
 
-      std::cout << "DEBUG: Glom::PostgresSelfHosted::connect(): Waiting and retrying the connection due to suspected too-early success of pg_ctl." << std::endl; 
+      std::cout << "DEBUG: Glom::PostgresSelfHosted::connect(): Waiting and retrying the connection due to suspected too-early success of pg_ctl." << std::endl;
 
       //Wait:
       Glib::RefPtr<Glib::MainLoop> mainloop = Glib::MainLoop::create(false);
         sigc::connection connection_timeout = Glib::signal_timeout().connect(
-        sigc::bind(sigc::ptr_fun(&on_timeout_delay), sigc::ref(mainloop)), 
+        sigc::bind(sigc::ptr_fun(&on_timeout_delay), sigc::ref(mainloop)),
         1000 /* 1 second */);
       mainloop->run();
       connection_timeout.disconnect();
-      
+
       keep_trying = true;
       continue;
     }
-    
+
     keep_trying = false;
   }
 
@@ -669,7 +621,7 @@ Glib::RefPtr<Gnome::Gda::Connection> PostgresSelfHosted::connect(const Glib::ust
 
 bool PostgresSelfHosted::create_database(const Glib::ustring& database_name, const Glib::ustring& username, const Glib::ustring& password, std::auto_ptr<Glib::Error>& error)
 {
-  return attempt_create_database(database_name, "localhost", port_as_string(m_port), username, password, error);
+  return attempt_create_database(database_name, m_host, port_as_string(m_port), username, password, error);
 }
 
 int PostgresSelfHosted::discover_first_free_port(int start_port, int end_port)
@@ -708,7 +660,7 @@ int PostgresSelfHosted::discover_first_free_port(int start_port, int end_port)
       #endif // G_OS_WIN32
 
       //Some BSDs don't have this.
-      //But watch out - if you don't include errno.h then this won't be 
+      //But watch out - if you don't include errno.h then this won't be
       //defined on Linux either, but you really do need to check for it.
       #ifdef EADDRINUSE
       available = (errno != EADDRINUSE);
diff --git a/glom/libglom/connectionpool_backends/postgres_self.h b/glom/libglom/connectionpool_backends/postgres_self.h
index d36769f..6568ce8 100644
--- a/glom/libglom/connectionpool_backends/postgres_self.h
+++ b/glom/libglom/connectionpool_backends/postgres_self.h
@@ -59,8 +59,6 @@ public:
    */
   static bool install_postgres(const SlotProgress& slot_progress);
 
-  static std::string get_path_to_postgres_executable(const std::string& program);
-
 private:
   virtual InitErrors initialize(const SlotProgress& slot_progress, const Glib::ustring& initial_username, const Glib::ustring& password, bool network_shared = false);
 
@@ -83,8 +81,8 @@ private:
   //bool directory_exists_filepath(const std::string& filepath);
   bool directory_exists_uri(const std::string& uri);
 
-  /** Run the command-line with the --version option to discover what version 
-   * of PostgreSQL is installed, so we can use the appropriate configuration 
+  /** Run the command-line with the --version option to discover what version
+   * of PostgreSQL is installed, so we can use the appropriate configuration
    * options when self-hosting.
    */
   Glib::ustring get_postgresql_utils_version(const SlotProgress& slot_progress);
@@ -92,7 +90,7 @@ private:
   float get_postgresql_utils_version_as_number(const SlotProgress& slot_progress);
 
   std::string m_self_hosting_data_uri;
-  int m_port;
+
   bool m_network_shared;
 };
 
@@ -101,4 +99,3 @@ private:
 } //namespace Glom
 
 #endif //GLOM_BACKEND_POSTGRES_SELF_H
-
diff --git a/glom/libglom/connectionpool_backends/sqlite.cc b/glom/libglom/connectionpool_backends/sqlite.cc
index c16e115..0d95ee5 100644
--- a/glom/libglom/connectionpool_backends/sqlite.cc
+++ b/glom/libglom/connectionpool_backends/sqlite.cc
@@ -397,6 +397,11 @@ bool Sqlite::change_columns(const Glib::RefPtr<Gnome::Gda::Connection>& connecti
   return recreate_table(connection, table_name, type_vec_strings(), type_vec_const_fields(), fields_changed, error);
 }
 
+bool Sqlite::save_backup(const SlotProgress& slot_progress, const std::string& filepath_output, const Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& database_name)
+{
+  //TODO:
+  std::cerr << G_STRFUNC << ": Not implemented.";
+}
 
 } // namespace ConnectionPoolBackends
 
diff --git a/glom/libglom/connectionpool_backends/sqlite.h b/glom/libglom/connectionpool_backends/sqlite.h
index bde1a29..2461714 100644
--- a/glom/libglom/connectionpool_backends/sqlite.h
+++ b/glom/libglom/connectionpool_backends/sqlite.h
@@ -64,6 +64,8 @@ private:
   /** Creates a new database.
    */
   virtual bool create_database(const Glib::ustring& database_name, const Glib::ustring& username, const Glib::ustring& password, std::auto_ptr<Glib::Error>& error);
+  
+  virtual bool save_backup(const SlotProgress& slot_progress, const std::string& filepath_output, const Glib::ustring& username, const Glib::ustring& password, const Glib::ustring& database_name);
 
 private:
   std::string m_database_directory_uri;
diff --git a/glom/libglom/utils.cc b/glom/libglom/utils.cc
index 0eb629b..86c7af7 100644
--- a/glom/libglom/utils.cc
+++ b/glom/libglom/utils.cc
@@ -522,7 +522,7 @@ Glib::ustring Utils::string_escape_underscores(const Glib::ustring& text)
 }
 
 /** Get just the first part of a locale, such as de_DE, 
- * ignoring, for instance, .UTF-8 or @euro at the end.
+ * ignoring, for instance, .UTF-8 or \ euro at the end.
  */
 Glib::ustring Utils::locale_simplify(const Glib::ustring& locale_id)
 {



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