glom r1845 - in trunk: . glom/libglom glom/libglom/connectionpool_backends glom/mode_design/fields



Author: arminb
Date: Tue Jan 13 20:42:25 2009
New Revision: 1845
URL: http://svn.gnome.org/viewvc/glom?rev=1845&view=rev

Log:
2009-01-13  Armin Burgmeier  <armin openismus com>

	* glom/libglom/connectionpool.h: 
	* glom/libglom/connectionpool.cc: Explain that when changing a table's
	primary key we are changing two columns, in response to Murray's
	previously added TODO comment. Don't compile add_column(),
	drop_column(), change_columns() in client only mode.

	* glom/libglom/connectionpool_backends/postgres.h:
	* glom/libglom/connectionpool_backends/postgres.cc: Added
	postgres-specific code for changing a column's type, to allow
	conversions from/to date and time fields.

	* glom/mode_design/fields/box_db_table_definition.h:
	* glom/mode_design/fields/box_db_table_definition.cc: Removed
	commented-out code that did the same before I moved the functionality
	to the connectionpool backend.


Modified:
   trunk/ChangeLog
   trunk/glom/libglom/connectionpool.cc
   trunk/glom/libglom/connectionpool.h
   trunk/glom/libglom/connectionpool_backends/postgres.cc
   trunk/glom/libglom/connectionpool_backends/postgres.h
   trunk/glom/mode_design/fields/box_db_table_definition.cc
   trunk/glom/mode_design/fields/box_db_table_definition.h

Modified: trunk/glom/libglom/connectionpool.cc
==============================================================================
--- trunk/glom/libglom/connectionpool.cc	(original)
+++ trunk/glom/libglom/connectionpool.cc	Tue Jan 13 20:42:25 2009
@@ -362,6 +362,7 @@
 #endif
 }
 
+#ifndef GLOM_ENABLE_CLIENT_ONLY
 bool ConnectionPoolBackend::add_column(const Glib::RefPtr<Gnome::Gda::Connection>& connection, const Glib::ustring& table_name, const sharedptr<const Field>& field, std::auto_ptr<Glib::Error>& error)
 {
   Glib::RefPtr<Gnome::Gda::ServerProvider> provider = connection->get_provider();
@@ -393,6 +394,12 @@
 }
 
 //TODO: Why/When do we need to change multiple columns instead of a single one? murrayc.
+//When changing a table's primary key, we unset the primary key for the old
+//column and set it for the new column. Using a single call to the
+//ConnectionPoolBackend for this, the backend can do all the required
+//operations at once, maybe optimizing them. For example, for SQLite we need
+//to recreate the whole table when changing columns, so we only need to do
+//this once instead of twice when changing the primary key. armin.
 bool ConnectionPoolBackend::change_columns(const Glib::RefPtr<Gnome::Gda::Connection>& connection, const Glib::ustring& table_name, const type_vecConstFields& old_fields, const type_vecConstFields& new_fields, std::auto_ptr<Glib::Error>& error)
 {
   static const char* TRANSACTION_NAME = "glom_change_columns_transaction";
@@ -435,6 +442,7 @@
 
   return true;
 }
+#endif // !GLOM_ENABLE_CLIENT_ONLY
 
 //init_db_details static data:
 ConnectionPool* ConnectionPool::m_instance = 0;
@@ -869,6 +877,7 @@
   previous_sig_handler = SIG_DFL; /* Arbitrary default */
 }
 
+#ifndef GLOM_ENABLE_CLIENT_ENLY
 #ifdef GLIBMM_EXCEPTIONS_ENABLED
 bool ConnectionPool::add_column(const Glib::ustring& table_name, const sharedptr<const Field>& field)
 #else
@@ -995,6 +1004,7 @@
 
   return result;
 }
+#endif // !GLOM_ENABLE_CLIENT_ONLY
 
 bool ConnectionPool::initialize(Gtk::Window* parent_window)
 {

Modified: trunk/glom/libglom/connectionpool.h
==============================================================================
--- trunk/glom/libglom/connectionpool.h	(original)
+++ trunk/glom/libglom/connectionpool.h	Tue Jan 13 20:42:25 2009
@@ -158,13 +158,13 @@
     */
   virtual Glib::RefPtr<Gnome::Gda::Connection> connect(const Glib::ustring& database, const Glib::ustring& username, const Glib::ustring& password, std::auto_ptr<ExceptionConnection>& error) = 0;
 
+#ifndef GLOM_ENABLE_CLIENT_ONLY
   virtual bool add_column(const Glib::RefPtr<Gnome::Gda::Connection>& connection, const Glib::ustring& table_name, const sharedptr<const Field>& field, std::auto_ptr<Glib::Error>& error);
 
   virtual bool drop_column(const Glib::RefPtr<Gnome::Gda::Connection>& connection, const Glib::ustring& table_name, const Glib::ustring& field_name, std::auto_ptr<Glib::Error>& error);
 
   virtual bool change_columns(const Glib::RefPtr<Gnome::Gda::Connection>& connection, const Glib::ustring& table_name, const type_vecConstFields& old_fields, const type_vecConstFields& new_fields, std::auto_ptr<Glib::Error>& error);
 
-#ifndef GLOM_ENABLE_CLIENT_ONLY
   /** 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;
@@ -257,6 +257,7 @@
    */
   void cleanup(Gtk::Window* parent_window);
 
+#ifndef GLOM_ENABLE_CLIENT_ONLY
 #ifdef GLIBMM_EXCEPTIONS_ENABLED
   bool add_column(const Glib::ustring& table_name, const sharedptr<const Field>& field);
 #else
@@ -280,6 +281,7 @@
 #else
   bool change_columns(const Glib::ustring& table_name, const type_vecConstFields& old_fields, const type_vecConstFields& fields, std::auto_ptr<Glib::Error>& error);
 #endif
+#endif // !GLOM_ENABLE_CLIENT_ONLY
 
   /** Specify a callback that the ConnectionPool can call to get a pointer to the document.
    * This callback avoids Connection having to link to App_Glom,

Modified: trunk/glom/libglom/connectionpool_backends/postgres.cc
==============================================================================
--- trunk/glom/libglom/connectionpool_backends/postgres.cc	(original)
+++ trunk/glom/libglom/connectionpool_backends/postgres.cc	Tue Jan 13 20:42:25 2009
@@ -158,6 +158,228 @@
 }
 
 #ifndef GLOM_ENABLE_CLIENT_ONLY
+bool Postgres::change_columns(const Glib::RefPtr<Gnome::Gda::Connection>& connection, const Glib::ustring& table_name, const type_vecConstFields& old_fields, const type_vecConstFields& new_fields, std::auto_ptr<Glib::Error>& error)
+{
+  static const char* TRANSACTION_NAME = "glom_change_columns_transaction";
+  static const gchar* TEMP_COLUMN_NAME = "glom_temp_column"; // TODO: Find a unique name.
+
+  if(!begin_transaction(connection, TRANSACTION_NAME, Gnome::Gda::TRANSACTION_ISOLATION_UNKNOWN, error)) return false; // TODO: What does the transaction isolation do?
+
+  for(unsigned int i = 0; i < old_fields.size(); ++ i)
+  {
+    // If the type did change, then we need to recreate the column. See
+    // http://www.postgresql.org/docs/faqs.FAQ.html#item4.3
+    if(old_fields[i]->get_field_info()->get_g_type() != new_fields[i]->get_field_info()->get_g_type())
+    {
+      // Create a temporary column
+      sharedptr<Field> temp_field = glom_sharedptr_clone(new_fields[i]);
+      temp_field->set_name(TEMP_COLUMN_NAME);
+      // The temporary column must not be primary key as long as the original
+      // (primary key) column is still present, because there cannot be two
+      // primary key columns.
+      temp_field->set_primary_key(false);
+
+      if(!add_column(connection, table_name, temp_field, error)) break;
+
+      Glib::ustring conversion_command;
+      const Glib::ustring field_name_old_quoted = "\"" + old_fields[i]->get_name() + "\"";
+      const Field::glom_field_type old_field_type = old_fields[i]->get_glom_type();
+
+      // For most conversions that are not possible according to this function,
+      // we get still quite good results when doing them nevertheless, such as
+      // text to date or date to text, so I commented this out.
+//      if(Field::get_conversion_possible(old_fields[i]->get_glom_type(), new_fields[i]->get_glom_type()))
+      {
+        //TODO: postgres seems to give an error if the data cannot be converted (for instance if the text is not a numeric digit when converting to numeric) instead of using 0.
+        /*
+        Maybe, for instance:
+        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 <> '     ';  
+        */
+
+        switch(new_fields[i]->get_glom_type())
+        {
+          case Field::TYPE_BOOLEAN:
+          {
+            if(old_field_type == Field::TYPE_NUMERIC)
+            {
+              conversion_command = "(CASE WHEN " + field_name_old_quoted + " > 0 THEN true "
+                                         "WHEN " + field_name_old_quoted + " = 0 THEN false "
+                                         "WHEN " + field_name_old_quoted + " IS NULL THEN false END)";
+            }
+            else if(old_field_type == Field::TYPE_TEXT)
+              conversion_command = "(" + field_name_old_quoted + " !~~* \'false\')"; // !~~* means ! ILIKE
+            else // Dates and Times:
+              conversion_command = "(" + field_name_old_quoted + " IS NOT NULL)";
+            break;
+          }
+
+          case Field::TYPE_NUMERIC: // CAST does not work if the destination type is numeric
+          {
+            if(old_field_type == Field::TYPE_BOOLEAN)
+            {
+              conversion_command = "(CASE WHEN " + field_name_old_quoted + " = true THEN 1 "
+                                         "WHEN " + field_name_old_quoted + " = false THEN 0 "
+                                         "WHEN " + field_name_old_quoted + " IS NULL THEN 0 END)";
+            }
+            else
+            {
+              //We use to_number, with textcat() so that to_number always has usable data.
+              //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.".
+              conversion_command = "to_number( textcat(\'0\', " + field_name_old_quoted + "), '999999999.99999999' )";
+            }
+
+            break;
+          }
+
+          case Field::TYPE_DATE: // CAST does not work if the destination type is date.
+          {
+            conversion_command = "to_date( " + field_name_old_quoted + ", 'YYYYMMDD' )"; // TODO: Standardise date storage format.
+            break;
+          }
+          case Field::TYPE_TIME: // CAST does not work if the destination type is timestamp.
+          {
+            conversion_command = "to_timestamp( " + field_name_old_quoted + ", 'HHMMSS' )"; // TODO: Standardise time storage format.
+            break;
+          }
+
+          default:
+          {
+            // To Text:
+
+            // bool to text:
+            if(old_field_type == Field::TYPE_BOOLEAN)
+            {
+              conversion_command = "(CASE WHEN " + field_name_old_quoted + " = true THEN \'true\' "
+                                         "WHEN " + field_name_old_quoted + " = false THEN \'false\' "
+                                         "WHEN " + field_name_old_quoted + " IS NULL THEN \'false\' END)";
+            }
+            else
+            {
+              // This works for most to-text conversions:
+              conversion_command = "CAST(" + field_name_old_quoted + " AS " + new_fields[i]->get_sql_type() + ")";
+            }
+
+            break;
+          }
+        }
+
+        if(!query_execute(connection, "UPDATE \"" + table_name + "\" SET \"" + TEMP_COLUMN_NAME + "\" = " + conversion_command, error))
+          break;
+      }
+#if 0
+      else
+      {
+        // The conversion is not possible.
+
+        // TODO: What to do here? The old code seems to have changed the type
+        // nevertheless, losing all data in the field.
+        std::cout << "Conversion between " << old_fields[i]->get_sql_type() << " and " << new_fields[i]->get_sql_type() << " not supported, trying direct CAST" << std::endl;
+
+        conversion_command = "CAST(" + field_name_old_quoted + " AS " + new_fields[i]->get_sql_type() + ")";
+        if(!query_execute(connection, "UPDATE \"" + table_name + "\" SET \"" + TEMP_COLUMN_NAME + "\" = " + conversion_command, error))
+	{
+	  // Don't panic if this fails, for now.
+          std::cout << "  ... failed: " << error->what() << std::endl;
+	  error.reset(NULL);
+	}
+      }
+#endif
+
+      if(!drop_column(connection, table_name, old_fields[i]->get_name(), error));
+      if(!query_execute(connection, "ALTER TABLE \"" + table_name + "\" RENAME COLUMN \"" + TEMP_COLUMN_NAME + "\" TO \"" + new_fields[i]->get_name() + "\"", error)) break;
+
+      // Readd primary key constraint
+      if(new_fields[i]->get_primary_key())
+        if(!query_execute(connection, "ALTER TABLE \"" + table_name + "\" ADD PRIMARY KEY (\"" + new_fields[i]->get_name() + "\")", error))
+          break;
+    }
+    else
+    {
+      // The type did not change. What could have changed: The field being a
+      // unique key, primary key, its name or its default value.
+
+      // Primary key
+      // TODO: Test whether this is able to remove unique key constraints
+      // added via libgda's DDL API in add_column(). Maybe override
+      // add_column() if we can't.
+      bool primary_key_was_set = false;
+      bool primary_key_was_unset = false;
+      if(old_fields[i]->get_primary_key() != new_fields[i]->get_primary_key())
+      {
+        if(new_fields[i]->get_primary_key())
+        {
+          primary_key_was_set = true;
+
+          // Primary key was added
+          if(!query_execute(connection, "ALTER TABLE \"" + table_name + "\" ADD PRIMARY KEY (\"" + old_fields[i]->get_name() + "\")", error))
+            break;
+
+          // Remove unique key constraint, because this is already implied in
+          // the field being primary key.
+          if(old_fields[i]->get_unique_key())
+            if(!query_execute(connection, "ALTER TABLE \"" + table_name + "\" DROP CONSTRAINT \"" + old_fields[i]->get_name() + "_key", error))
+              break;
+        }
+        else
+        {
+          primary_key_was_unset = true;
+
+          // Primary key was removed
+          if(!query_execute(connection, "ALTER TABLE \"" + table_name + "\" DROP CONSTRAINT \"" + table_name + "_pkey\"", error))
+            break;
+        }
+      }
+
+      // Uniqueness
+      if(old_fields[i]->get_unique_key() != new_fields[i]->get_unique_key())
+      {
+        // Postgres automatically makes primary keys unique, so we do not need
+        // to do that separately if we already made it a primary key
+        if(!primary_key_was_set && new_fields[i]->get_unique_key())
+        {
+          if(!query_execute(connection, "ALTER TABLE \"" + table_name + "\" ADD CONSTRAINT \"" + old_fields[i]->get_name() + "_key\" UNIQUE (\"" + old_fields[i]->get_name() + "\")", error))
+            break;
+        }
+        else if(!primary_key_was_unset && !new_fields[i]->get_unique_key() && !new_fields[i]->get_primary_key())
+        {
+          if(!query_execute(connection, "ALTER TABLE \"" + table_name + "\" DROP CONSTRAINT \"" + old_fields[i]->get_name() + "_key\"", error))
+            break;
+        }
+      }
+
+      if(!new_fields[i]->get_auto_increment()) // Auto-increment fields have special code as their default values.
+      {
+        if(old_fields[i]->get_default_value() != new_fields[i]->get_default_value())
+        {
+          if(!query_execute(connection, "ALTER TABLE \"" + table_name + "\" ALTER COLUMN \"" + old_fields[i]->get_name() + "\" SET DEFAULT " + new_fields[i]->sql(new_fields[i]->get_default_value(), Field::SQL_FORMAT_POSTGRES), error))
+            break;
+        }
+      }
+
+      if(old_fields[i]->get_name() != new_fields[i]->get_name())
+      {
+        if(!query_execute(connection, "ALTER TABLE \"" + table_name + "\" RENAME COLUMN \"" + old_fields[i]->get_name() + "\" TO \"" + new_fields[i]->get_name() + "\"", error))
+          break;
+      }
+    }
+  }
+
+  if(error.get() || !commit_transaction(connection, TRANSACTION_NAME, error))
+  {
+    std::auto_ptr<Glib::Error> rollback_error;
+    rollback_transaction(connection, TRANSACTION_NAME, rollback_error);
+    return false;
+  }
+
+  return true;
+}
+
 bool Postgres::attempt_create_database(const Glib::ustring& database_name, const Glib::ustring& host, const Glib::ustring& port, const Glib::ustring& username, const Glib::ustring& password, std::auto_ptr<Glib::Error>& error)
 {
   Glib::RefPtr<Gnome::Gda::ServerOperation> op;

Modified: trunk/glom/libglom/connectionpool_backends/postgres.h
==============================================================================
--- trunk/glom/libglom/connectionpool_backends/postgres.h	(original)
+++ trunk/glom/libglom/connectionpool_backends/postgres.h	Tue Jan 13 20:42:25 2009
@@ -56,9 +56,9 @@
   virtual Field::sql_format get_sql_format() const { return Field::SQL_FORMAT_POSTGRES; }
   virtual bool supports_remote_access() const { return true; }
 
-  /** Creates a new database.
-   */
 #ifndef GLOM_ENABLE_CLIENT_ONLY
+  virtual bool change_columns(const Glib::RefPtr<Gnome::Gda::Connection>& connection, const Glib::ustring& table_name, const type_vecConstFields& old_fields, const type_vecConstFields& new_fields, std::auto_ptr<Glib::Error>& error);
+
   bool attempt_create_database(const Glib::ustring& database_name, const Glib::ustring& host, const Glib::ustring& port, const Glib::ustring& username, const Glib::ustring& password, std::auto_ptr<Glib::Error>& error);
 #endif
 

Modified: trunk/glom/mode_design/fields/box_db_table_definition.cc
==============================================================================
--- trunk/glom/mode_design/fields/box_db_table_definition.cc	(original)
+++ trunk/glom/mode_design/fields/box_db_table_definition.cc	Tue Jan 13 20:42:25 2009
@@ -594,192 +594,6 @@
   m_vecFields = get_fields_for_table(m_table_name);
 }
 
-// TODO: Move this to ConnectionPoolBackends::Postgres:
-#if 0
-void Box_DB_Table_Definition::postgres_change_column_type(const sharedptr<const Field>& field_old, const sharedptr<const Field>& field)
-{
-  Gtk::Window* parent_window = get_app_window();
-  if(!parent_window)
-    return;
-
-  sharedptr<SharedConnection> sharedconnection = connect_to_server(parent_window);
-  if(sharedconnection)
-  {
-    Glib::RefPtr<Gnome::Gda::Connection> gda_connection = sharedconnection->get_gda_connection();
-
-    bool new_column_created = false;
-
-    //If the datatype has changed:
-    if(field->get_field_info()->get_g_type() != field_old->get_field_info()->get_g_type())
-    {
-      //We have to create a new table, and move the data across:
-      //See http://www.postgresql.org/docs/faqs/FAQ.html#4.4
-      //     BEGIN;
-      //
-      //    UPDATE tab SET new_col = CAST(old_col AS new_data_type);
-      //    ALTER TABLE tab DROP COLUMN old_col;
-      //    COMMIT;
-
-      const Glib::ustring transaction_name = "glom_transaction_change_field_type"; 
-      const bool test = gda_connection->begin_transaction(transaction_name, Gnome::Gda::TRANSACTION_ISOLATION_UNKNOWN); // TODO: I am absolutely not sure what this transaction isolation does
-      if(test)
-      {
-        //Glib::RefPtr<Gnome::Gda::TransactionStatus> transaction = gda_connection->get_transaction_status();
-        //TODO: Warn about a delay, and possible loss of precision, before actually doing this.
-        //TODO: Try to use a unique name for the temp column:
-
-        sharedptr<Field> fieldTemp = glom_sharedptr_clone(field);
-        fieldTemp->set_name("glom_temp_column");
-        GlomPostgres::postgres_add_column(m_table_name, fieldTemp); //This might also involves several commands.
-
-
-        bool conversion_failed = false;
-        if(Field::get_conversion_possible(field_old->get_glom_type(), field->get_glom_type()))
-        {
-          //TODO: postgres seems to give an error if the data cannot be converted (for instance if the text is not a numeric digit when converting to numeric) instead of using 0.
-          /*
-          Maybe, for instance:
-          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 <> '     ';  
-          */
-          Glib::ustring conversion_command;
-          const Glib::ustring field_name_old_quoted = "\"" + field_old->get_name() + "\"";
-          const Field::glom_field_type old_field_type = field_old->get_glom_type();
-          switch(field->get_glom_type())
-          {
-            case Field::TYPE_BOOLEAN: //CAST does not work if the destination type is boolean.
-            {
-              if(old_field_type == Field::TYPE_NUMERIC)
-              {
-                conversion_command = "(CASE WHEN " + field_name_old_quoted + " >0 THEN true "
-                                           "WHEN " + field_name_old_quoted + " = 0 THEN false "
-                                           "WHEN " + field_name_old_quoted + " IS NULL THEN false END)";
-              }
-              else if(old_field_type == Field::TYPE_TEXT)
-                conversion_command = "(" + field_name_old_quoted + " !~~* \'false\')"; // !~~* means ! ILIKE.
-              else //Dates and Times:
-                conversion_command = "(" + field_name_old_quoted + " IS NOT NULL')";
-
-              break;
-            }
-            case Field::TYPE_NUMERIC: //CAST does not work if the destination type is numeric.
-            {
-              if(old_field_type == Field::TYPE_BOOLEAN)
-              {
-                conversion_command = "(CASE WHEN " + field_name_old_quoted + " = true THEN 1 "
-                                           "WHEN " + field_name_old_quoted + " = false THEN 0 "
-                                           "WHEN " + field_name_old_quoted + " IS NULL THEN 0 END)";
-              }
-              else
-              {
-                //We use to_number, with textcat() so that to_number always has usable data.
-                //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.".
-                conversion_command = "to_number( textcat(\'0\', " + field_name_old_quoted + "), '999999999.99999999' )";
-              }
-
-              break;
-            }
-            case Field::TYPE_DATE: //CAST does not work if the destination type is date.
-            {
-              conversion_command = "to_date( " + field_name_old_quoted + ", 'YYYYMMDD' )"; //TODO: standardise date storage format.
-              break;
-            }
-            case Field::TYPE_TIME: //CAST does not work if the destination type is timestamp.
-            {
-              conversion_command = "to_timestamp( " + field_name_old_quoted + ", 'HHMMSS' )";  //TODO: standardise time storage format.
-              break;
-            }
-            default:
-            {
-              //To Text:
-
-              //bool to text:
-              if(old_field_type == Field::TYPE_BOOLEAN)
-              {
-                 conversion_command = "(CASE WHEN " + field_name_old_quoted + " = true THEN \'true\' "
-                                            "WHEN " + field_name_old_quoted + " = false THEN \'false\' "
-                                            "WHEN " + field_name_old_quoted + " IS NULL THEN \'false\' END)";
-              }
-              else
-              {
-                //This works for most to-text conversions:
-                conversion_command = "CAST(\"" +  field_old->get_name() + "\" AS " + field->get_sql_type() + ")";
-              }
-              break;
-            }
-          }
-
-          //Convert the data in the field:
-          const Glib::ustring sql = "UPDATE \"" + m_table_name + "\" SET \"" + fieldTemp->get_name() + "\" = " + conversion_command;
-          try
-          {
-            const bool test = query_execute(sql, get_app_window());  //TODO: Not full type details. What does that comment mean? murrayc
-            if(!test)
-              conversion_failed = true;
-          }
-          catch(const Glib::Error& ex)
-          {
-            std::cerr << "Box_DB_Table_Definition::postgres_change_column_type(): Glib::Error exception while executing SQL:" << std::endl << "  " <<  sql << std::endl;
-            handle_error(ex);
-            conversion_failed = false;
-          }
-          catch(const std::exception& ex)
-          {
-            std::cerr << "Box_DB_Table_Definition::postgres_change_column_type(): std::exception while executing SQL:" << std::endl << "  " <<  sql << std::endl;
-            handle_error(ex);
-            conversion_failed = false;
-          }
-        }
-
-        if(!conversion_failed)
-        {
-          const bool test = query_execute( "ALTER TABLE \"" + m_table_name + "\" DROP COLUMN \"" +  field_old->get_name() + "\"", get_app_window());
-          if(test)
-          {
-            const Glib::ustring sql =  "ALTER TABLE \"" + m_table_name + "\" RENAME COLUMN \"" + fieldTemp->get_name() + "\" TO \"" + field->get_name() + "\"";
-            try
-            {
-              const bool test = query_execute(sql, get_app_window());
-              if(test)
-              {
-                const bool test = gda_connection->commit_transaction(transaction_name);
-                if(!test)
-                {
-                  std::cerr << "Box_DB_Table_Definition::postgres_change_column_type(): Error while executing SQL:" << std::endl << "  " <<  sql << std::endl;
-                  handle_error();
-                }
-                else
-                  new_column_created = true;
-              }
-            }
-            catch(const Glib::Error& ex)
-            {
-              std::cerr << "Box_DB_Table_Definition::postgres_change_column_type(): Glib::Error exception while executing SQL:" << std::endl << "  " <<  sql << std::endl;
-              handle_error(ex);
-            }
-            catch(const std::exception& ex)
-            {
-              std::cerr << "Box_DB_Table_Definition::postgres_change_column_type(): std::exception while executing SQL:" << std::endl << "  " <<  sql << std::endl;
-              handle_error(ex);
-            }
-          }
-        }
-      }   //TODO: Abandon the transaction if something failed.
-    }  /// If the datatype has changed:
-
-    if(!new_column_created) //We don't need to change anything else if everything was already correctly set as a new column:
-      GlomPostgres::postgres_change_column_extras(m_table_name, field_old, field);
-
-    //Callers should call this: update_gda_metastore_for_table();
-  }
-}
-#endif
-
 bool Box_DB_Table_Definition::field_has_null_values(const sharedptr<const Field>& field)
 {
   //Note that "= Null" doesn't work, though it doesn't error either.

Modified: trunk/glom/mode_design/fields/box_db_table_definition.h
==============================================================================
--- trunk/glom/mode_design/fields/box_db_table_definition.h	(original)
+++ trunk/glom/mode_design/fields/box_db_table_definition.h	Tue Jan 13 20:42:25 2009
@@ -58,11 +58,6 @@
 
   bool check_field_change(const sharedptr<const Field>& field_old, const sharedptr<const Field>& field_new);
 
-#if 0
-  //Postgres needs some complex stuff:
-  virtual void postgres_change_column_type(const sharedptr<const Field>& field_old, const sharedptr<const Field>& field);
-#endif
-
   mutable AddDel_WithButtons m_AddDel; //mutable because its get_ methods aren't const.
 
   guint m_colName, m_colTitle, m_colType, m_colUnique, m_colPrimaryKey;



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