Hi,

This patch adds support to the new ALTER TYPE syntax in 9.1.

/me extracts the log message in the patch:

I changed the Add/Change button with two buttons (Add and Change). The
rest of the patch is used to allow the change on an existing type if we
are connected to an 9.1+ release.

Rather than trying to detect new. removed, and modified members, I
simply drop all the old ones and add all the new ones. Much simpler,
same results, and hopefully less bugs.

Comments? (other than the fact that I forgot a TODO comment in that patch)


-- 
Guillaume
 http://www.postgresql.fr
 http://dalibo.com
>From 3aa414d9a80979989e1dd0248a8ed7850417f7c0 Mon Sep 17 00:00:00 2001
From: Guillaume Lelarge <[email protected]>
Date: Mon, 11 Oct 2010 16:38:28 +0200
Subject: [PATCH] Add support for 9.1 ALTER TYPE new syntax

I changed the Add/Change button with two buttons (Add and Change). The rest of
the patch is used to allow the change on an existing type if we are connected
to an 9.1+ release.

Rather than trying to detect new. removed, and modified members, I simply drop
all the old ones and add all the new ones. Much simpler, same results, and
hopefully less bugs.

Implements #242.
---
 pgadmin/dlg/dlgType.cpp       |  159 ++++++++++++++++++++++++++++++++---------
 pgadmin/include/dlg/dlgType.h |    2 +
 pgadmin/ui/dlgType.xrc        |   34 +++++-----
 3 files changed, 144 insertions(+), 51 deletions(-)

diff --git a/pgadmin/dlg/dlgType.cpp b/pgadmin/dlg/dlgType.cpp
index e9ccef6..0c75afd 100644
--- a/pgadmin/dlg/dlgType.cpp
+++ b/pgadmin/dlg/dlgType.cpp
@@ -45,6 +45,7 @@
 #define lstLabels               CTRL_LISTVIEW("lstLabels")
 #define txtLabel                CTRL_TEXT("txtLabel")
 #define btnAddMember            CTRL_BUTTON("btnAddMember")
+#define btnChangeMember         CTRL_BUTTON("btnChangeMember")
 #define btnRemoveMember         CTRL_BUTTON("btnRemoveMember")
 #define btnAddLabel             CTRL_BUTTON("btnAddLabel")
 #define btnRemoveLabel          CTRL_BUTTON("btnRemoveLabel")
@@ -65,6 +66,7 @@ BEGIN_EVENT_TABLE(dlgType, dlgTypeProperty)
     EVT_CHECKBOX(XRCID("chkVariable"),              dlgProperty::OnChange)
     
     EVT_BUTTON(XRCID("btnAddMember"),               dlgType::OnMemberAdd)
+    EVT_BUTTON(XRCID("btnChangeMember"),            dlgType::OnMemberChange)
     EVT_BUTTON(XRCID("btnRemoveMember"),            dlgType::OnMemberRemove)
     EVT_BUTTON(XRCID("btnAddLabel"),                dlgType::OnLabelAdd)
     EVT_BUTTON(XRCID("btnRemoveLabel"),             dlgType::OnLabelRemove)
@@ -99,7 +101,9 @@ dlgType::dlgType(pgaFactory *f, frmMain *frame, pgType *node, pgSchema *sch)
 
 void dlgType::OnChangeMember(wxCommandEvent &ev)
 {
-    btnAddMember->Enable(!type
+    // TODO is there something to do here?
+    btnAddMember->Enable(
+        ((type && connection->BackendMinimumVersion(9, 1)) || !type)
         && !txtMembername->GetValue().Strip(wxString::both).IsEmpty()
         && cbDatatype->GetGuessedSelection() >= 0);
 }
@@ -165,28 +169,38 @@ int dlgType::Go(bool modal)
         cbTypmodin->Append(type->GetTypmodinFunction()); cbTypmodin->SetSelection(0); cbTypmodin->Disable();
         cbTypmodout->Append(type->GetTypmodoutFunction()); cbTypmodout->SetSelection(0); cbTypmodout->Disable();
 
-        chkVariable->SetValue(type->GetInternalLength() < 0); chkVariable->Disable();
+        chkVariable->SetValue(type->GetInternalLength() < 0);
+        chkVariable->Disable();
         if (type->GetInternalLength() > 0)
             txtIntLength->SetValue(NumToStr(type->GetInternalLength())); 
         txtIntLength->Disable();
-        txtDefault->SetValue(type->GetDefault()); txtDefault->Disable();
-        cbElement->Append(type->GetElement()); cbElement->SetSelection(0); cbElement->Disable();
-        txtDelimiter->SetValue(type->GetDelimiter()); txtDelimiter->Disable();
-        chkByValue->SetValue(type->GetPassedByValue()); chkByValue->Disable();
-        cbAlignment->SetValue(type->GetAlignment()); cbAlignment->Disable();
-        cbStorage->SetValue(type->GetStorage()); cbStorage->Disable();
-
-        txtMembername->Disable();
-        btnAddMember->Disable();
-        btnRemoveMember->Disable();
-
-        txtLabel->Disable();
-        btnAddLabel->Disable();
-        btnRemoveLabel->Disable();
+        txtDefault->SetValue(type->GetDefault());
+        txtDefault->Disable();
+        cbElement->Append(type->GetElement());
+        cbElement->SetSelection(0);
+        cbElement->Disable();
+        txtDelimiter->SetValue(type->GetDelimiter());
+        txtDelimiter->Disable();
+        chkByValue->SetValue(type->GetPassedByValue());
+        chkByValue->Disable();
+        cbAlignment->SetValue(type->GetAlignment());
+        cbAlignment->Disable();
+        cbStorage->SetValue(type->GetStorage());
+        cbStorage->Disable();
+
+        bool changeok = connection->BackendMinimumVersion(9, 1);
+        txtMembername->Enable(changeok);
+        btnAddMember->Enable(changeok);
+        btnChangeMember->Enable(changeok);
+        btnRemoveMember->Enable(changeok);
+
+        txtLabel->Enable(changeok);
+        btnAddLabel->Enable(changeok);
+        btnRemoveLabel->Enable(changeok);
 
         wxArrayString elements=type->GetTypesArray();
         wxString fullType, typeName, typeLength, typePrecision;
-        int pos;
+        size_t pos;
         size_t i;
 		for (i=0 ; i < elements.GetCount() ; i+=2)
         {
@@ -223,8 +237,8 @@ int dlgType::Go(bool modal)
             memberPrecisions.Add(typePrecision);
         }
 
-        cbDatatype->Disable();
-        txtLength->Disable();
+        cbDatatype->Enable(changeok);
+        txtLength->Enable(changeok);
 
         // Load the enum labels
         elements=type->GetLabelArray();
@@ -348,6 +362,9 @@ int dlgType::Go(bool modal)
 
         txtLength->SetValidator(numericValidator);
     }
+
+    txtLength->SetValidator(numericValidator);
+
     return dlgTypeProperty::Go(modal);
 }
 
@@ -363,7 +380,7 @@ void dlgType::OnSelChangeTyp(wxCommandEvent &ev)
 
 void dlgType::OnSelChangeTypOrLen(wxCommandEvent &ev)
 {
-    if (!type)
+    if ((type && connection->BackendMinimumVersion(9, 1)) || !type)
     {
         CheckLenEnable();
         txtLength->Enable(isVarLen);
@@ -379,7 +396,8 @@ void dlgType::CheckChange()
     if (type)
     {
         EnableOK(txtComment->GetValue() != type->GetComment()
-            || cbOwner->GetValue() != type->GetOwner());
+            || cbOwner->GetValue() != type->GetOwner()
+            || (rdbType->GetSelection() == TYPE_COMPOSITE && GetSqlForTypes() != wxEmptyString));
     }
     else
     {
@@ -417,9 +435,9 @@ void dlgType::OnMemberSelChange(wxListEvent &ev)
         txtMembername->SetValue(lstMembers->GetText(pos));
         cbDatatype->SetValue(memberTypes.Item(pos).AfterFirst(':'));
         txtLength->SetValue(memberLengths.Item(pos));
-        txtLength->Enable(!type && !txtLength->GetValue().IsEmpty());
+        txtLength->Enable(!txtLength->GetValue().IsEmpty());
         txtPrecision->SetValue(memberPrecisions.Item(pos));
-        txtPrecision->Enable(!type && !txtPrecision->GetValue().IsEmpty());
+        txtPrecision->Enable(!txtPrecision->GetValue().IsEmpty());
     }
 }
 
@@ -446,17 +464,46 @@ void dlgType::OnMemberAdd(wxCommandEvent &ev)
 
     if (!name.IsEmpty())
     {
-        long pos=lstMembers->FindItem(-1, name);
-        if (pos < 0)
-        {
-            pos = lstMembers->GetItemCount();
-            lstMembers->InsertItem(pos, name, 0);
-            memberTypes.Add(GetTypeInfo(cbDatatype->GetGuessedSelection()));
-            memberLengths.Add(length);
-            memberPrecisions.Add(precision);
-        }
-        else
+        size_t pos = lstMembers->GetItemCount();
+        lstMembers->InsertItem(pos, name, 0);
+        lstMembers->SetItem(pos, 1, type);
+        memberTypes.Add(GetTypeInfo(cbDatatype->GetGuessedSelection()));
+        memberLengths.Add(length);
+        memberPrecisions.Add(precision);
+    }
+
+    CheckChange();
+}
+
+
+void dlgType::OnMemberChange(wxCommandEvent &ev)
+{
+    wxString name = txtMembername->GetValue().Strip(wxString::both);
+    wxString type = cbDatatype->GetValue();
+    wxString length = wxEmptyString;
+    wxString precision = wxEmptyString;
+
+    if (txtLength->GetValue() != wxT("") && txtLength->IsEnabled())
+       length = txtLength->GetValue();
+    if (txtPrecision->GetValue() != wxT("") && txtPrecision->IsEnabled())
+       precision = txtPrecision->GetValue();
+
+    if (!length.IsEmpty())
+    {
+        type += wxT("(") + length;
+        if (!precision.IsEmpty())
+            type += wxT(", ") + precision;
+        type += wxT(")");
+    }
+
+    if (!name.IsEmpty())
+    {
+        long pos=lstMembers->GetFirstSelected();
+        wxLogError(NumToStr((long)pos));
+        if (pos >= 0)
         {
+            lstMembers->SetItem(pos, 0, name);
+            lstMembers->SetItem(pos, 1, type);
             memberTypes.Insert(GetTypeInfo(cbDatatype->GetGuessedSelection()), pos);
             memberLengths.Insert(length, pos);
             memberPrecisions.Insert(precision, pos);
@@ -464,7 +511,7 @@ void dlgType::OnMemberAdd(wxCommandEvent &ev)
             memberLengths.RemoveAt(pos+1);
             memberPrecisions.RemoveAt(pos+1);
         }
-        lstMembers->SetItem(pos, 1, type);
+        wxLogError(wxT("done"));
     }
 
     CheckChange();
@@ -542,6 +589,7 @@ wxString dlgType::GetSql()
     {
         // Edit Mode
         AppendOwnerChange(sql, wxT("TYPE ") + type->GetQuotedFullIdentifier());
+        sql += GetSqlForTypes();
     }
     else
     {
@@ -664,3 +712,46 @@ wxString dlgType::GetFullTypeName(int type)
     return typname;
 }
 
+wxString dlgType::GetSqlForTypes()
+{
+    wxString sql = wxEmptyString;
+    wxString old_name, old_type, new_name, new_type;
+    wxArrayString elements=type->GetTypesArray();
+    bool modified = lstMembers->GetItemCount()*2 != elements.GetCount();
+    size_t i;
+
+    // Check if there is a change
+    for (int i=0 ; i < lstMembers->GetItemCount() && !modified; i++)
+    {
+        old_name = elements.Item(i*2);
+        old_type = elements.Item(i*2+1);
+        //wxLogError(wxT("<")+old_name+wxT("><")+old_type+wxT(">"));
+        new_name = lstMembers->GetItemText(i);
+        new_type = GetFullTypeName(i);
+        //wxLogError(wxT("<")+new_name+wxT("><")+new_type+wxT(">"));
+        modified = modified || old_name != new_name || old_type != new_type;
+        //if (modified)
+            //wxLogError(wxT("MODIFIED"));
+    }
+
+    if (modified)
+    {
+        // Drop all old attributes
+		for (i=0 ; i < elements.GetCount() ; i+=2)
+        {
+            old_name = elements.Item(i);
+            sql += wxT("ALTER TYPE type DROP ATTRIBUTE ") + old_name + wxT(";\n");
+        }
+
+        // Add all new attributes
+        for (int i=0 ; i < lstMembers->GetItemCount() ; i++)
+        {
+            new_name = lstMembers->GetItemText(i);
+            new_type = GetFullTypeName(i);
+            sql += wxT("ALTER TYPE type ADD ATTRIBUTE ")
+                   + new_name + wxT(" ") + new_type + wxT(";\n");
+        }
+    }
+
+    return sql;
+}
diff --git a/pgadmin/include/dlg/dlgType.h b/pgadmin/include/dlg/dlgType.h
index 843864b..e7481e4 100644
--- a/pgadmin/include/dlg/dlgType.h
+++ b/pgadmin/include/dlg/dlgType.h
@@ -24,6 +24,7 @@ public:
 
     void CheckChange();
     wxString GetSql();
+    wxString GetSqlForTypes();
     pgObject *CreateObject(pgCollection *collection);
     pgObject *GetObject();
 
@@ -34,6 +35,7 @@ private:
     pgType *type;
     void OnTypeChange(wxCommandEvent &ev);
     void OnMemberAdd(wxCommandEvent &ev);
+    void OnMemberChange(wxCommandEvent &ev);
     void OnMemberRemove(wxCommandEvent &ev);
     void OnMemberSelChange(wxListEvent &ev);
     void OnLabelAdd(wxCommandEvent &ev);
diff --git a/pgadmin/ui/dlgType.xrc b/pgadmin/ui/dlgType.xrc
index 3097de2..7d8b7d7 100644
--- a/pgadmin/ui/dlgType.xrc
+++ b/pgadmin/ui/dlgType.xrc
@@ -209,33 +209,33 @@
                     </object>
                     <object class="sizeritem">
                       <object class="wxFlexGridSizer">
-                        <cols>3</cols>
-                        <rows>1</rows>
-                        <vgap>5</vgap>
-                        <hgap>5</hgap>
-                        <growablecols>0</growablecols>
-                        <object class="spacer">
-                          <size>0,0d</size>
+                        <object class="sizeritem">
+                          <object class="wxButton" name="btnRemoveMember">
+                            <label>Remove</label>
+                          </object>
+                          <flag>wxALL|wxALIGN_RIGHT</flag>
+                          <border>2</border>
                         </object>
                         <object class="sizeritem">
                           <object class="wxButton" name="btnAddMember">
-                            <label>Add/Change</label>
+                            <label>Add</label>
                           </object>
-                          <flag>wxALIGN_CENTRE_VERTICAL|wxALL</flag>
-                          <border>4</border>
+                          <flag>wxALL|wxALIGN_RIGHT</flag>
+                          <border>2</border>
                         </object>
                         <object class="sizeritem">
-                          <object class="wxButton" name="btnRemoveMember">
-                            <label>Remove</label>
+                          <object class="wxButton" name="btnChangeMember">
+                            <label>Change</label>
                           </object>
-                          <flag>wxALIGN_CENTRE_VERTICAL|wxALL</flag>
-                          <border>4</border>
+                          <flag>wxALL|wxALIGN_RIGHT</flag>
+                          <border>2</border>
                         </object>
+                        <cols>3</cols>
+                        <rows>1</rows>
                       </object>
-                      <flag>wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
-                      <border>4</border>
+                      <flag>wxALIGN_RIGHT</flag>
+                    </object>
                     </object>
-                  </object>
                   </object>
                   <flag>wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
                   <border>4</border>
-- 
1.7.1

-- 
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers

Reply via email to