////////////////////////////////////////////////////////////////////////// // // pgAdmin III - PostgreSQL Tools // // Copyright (C) 2002 - 2016, The pgAdmin Development Team // This software is released under the PostgreSQL Licence // // dlgColumns.cpp - PostgreSQL Columns Property // ////////////////////////////////////////////////////////////////////////// // wxWindows headers #include // App headers #include "pgAdmin3.h" #include "utils/misc.h" #include "utils/pgDefs.h" #include "dlg/dlgColumn.h" #include "schema/pgSchema.h" #include "schema/pgColumn.h" #include "schema/pgTable.h" #include "schema/pgDatatype.h" #include "frm/frmMain.h" #include "schema/pgUser.h" #include "schema/pgGroup.h" #include "ctl/ctlSeclabelPanel.h" // pointer to controls #define txtDefault CTRL_TEXT("txtDefault") #define chkNotNull CTRL_CHECKBOX("chkNotNull") #define txtAttstattarget CTRL_TEXT("txtAttstattarget") #define lstVariables CTRL_LISTVIEW("lstVariables") #define cbVarname CTRL_COMBOBOX2("cbVarname") #define txtValue CTRL_TEXT("txtValue") #define btnAdd CTRL_BUTTON("wxID_ADD") #define btnRemove CTRL_BUTTON("wxID_REMOVE") #define cbStorage CTRL_COMBOBOX1("cbStorage") #define cbCollation CTRL_COMBOBOX("cbCollation") BEGIN_EVENT_TABLE(dlgColumn, dlgTypeProperty) EVT_TEXT(XRCID("txtLength"), dlgProperty::OnChange) EVT_TEXT(XRCID("txtPrecision"), dlgProperty::OnChange) EVT_TEXT(XRCID("txtDefault"), dlgProperty::OnChange) EVT_CHECKBOX(XRCID("chkNotNull"), dlgProperty::OnChange) EVT_TEXT(XRCID("txtAttstattarget"), dlgProperty::OnChange) EVT_TEXT(XRCID("cbDatatype"), dlgColumn::OnSelChangeTyp) EVT_COMBOBOX(XRCID("cbDatatype"), dlgColumn::OnSelChangeTyp) EVT_COMBOBOX(XRCID("cbCollation"), dlgColumn::OnSelChangeTyp) EVT_BUTTON(CTL_ADDPRIV, dlgColumn::OnAddPriv) EVT_BUTTON(CTL_DELPRIV, dlgColumn::OnDelPriv) EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgColumn::OnVarSelChange) EVT_BUTTON(wxID_ADD, dlgColumn::OnVarAdd) EVT_BUTTON(wxID_REMOVE, dlgColumn::OnVarRemove) EVT_TEXT(XRCID("cbVarname"), dlgColumn::OnVarnameSelChange) EVT_COMBOBOX(XRCID("cbVarname"), dlgColumn::OnVarnameSelChange) EVT_TEXT(XRCID("cbStorage"), dlgProperty::OnChange) EVT_COMBOBOX(XRCID("cbStorage"), dlgProperty::OnChange) #ifdef __WXMAC__ EVT_SIZE( dlgColumn::OnChangeSize) #endif END_EVENT_TABLE(); dlgProperty *pgColumnFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) { return new dlgColumn(this, frame, (pgColumn *)node, (pgTable *)parent); } dlgColumn::dlgColumn(pgaFactory *f, frmMain *frame, pgColumn *node, pgTable *parentNode) : dlgTypeProperty(f, frame, wxT("dlgColumn")) { column = node; table = parentNode; wxASSERT(!table || (table->GetMetaType() == PGM_TABLE || table->GetMetaType() == PGM_VIEW || table->GetMetaType() == GP_EXTTABLE || table->GetMetaType() == GP_PARTITION)); changedColumn = NULL; dirtyVars = false; txtAttstattarget->SetValidator(numericValidator); lstVariables->CreateColumns(0, _("Variable"), _("Value")); cbStorage->Append(wxT("PLAIN")); cbStorage->Append(wxT("MAIN")); cbStorage->Append(wxT("EXTERNAL")); cbStorage->Append(wxT("EXTENDED")); /* Column Level Privileges */ securityChanged = false; if (node) connection = node->GetConnection(); securityPage = new ctlSecurityPanel(nbNotebook, wxT("INSERT,SELECT,UPDATE,REFERENCES"), "arwx", frame->GetImageList()); if (connection && connection->BackendMinimumVersion(8, 4) && (!node || node->CanCreate())) { // Fetch Groups Information pgSet *setGrp = connection->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); if (setGrp) { while (!setGrp->Eof()) { groups.Add(setGrp->GetVal(0)); setGrp->MoveNext(); } delete setGrp; } SetSecurityPage(node); } else securityPage->Disable(); seclabelPage = new ctlSeclabelPanel(nbNotebook); } #ifdef __WXMAC__ void dlgColumn::OnChangeSize(wxSizeEvent &ev) { securityPage->lbPrivileges->SetSize(wxDefaultCoord, wxDefaultCoord, ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 550); if (GetAutoLayout()) { Layout(); } } #endif pgObject *dlgColumn::GetObject() { return column; } void dlgColumn::SetSecurityPage(const pgColumn *node) { if (node) { wxString strAcl = node->GetAcl(); securityPage->lbPrivileges->DeleteAllItems(); if (!strAcl.IsEmpty()) { wxArrayString aclArray; strAcl = strAcl.Mid(1, strAcl.Length() - 2); getArrayFromCommaSeparatedList(strAcl, aclArray); wxString roleName; for (unsigned int index = 0; index < aclArray.Count(); index++) { wxString strCurrAcl = aclArray[index]; /* * In rare case, we can have ',' (comma) in the user name. * But, we need to handle them also */ if (strCurrAcl.Find(wxChar('=')) == wxNOT_FOUND) { // Check it is start of the ACL if (strCurrAcl[0U] == (wxChar)'"') roleName = strCurrAcl + wxT(","); continue; } else strCurrAcl = roleName + strCurrAcl; if (strCurrAcl[0U] == (wxChar)'"') strCurrAcl = strCurrAcl.Mid(1, strCurrAcl.Length() - 1); roleName = strCurrAcl.BeforeLast('='); wxString value = strCurrAcl.Mid(roleName.Length() + 1).BeforeLast('/'); int icon = userFactory.GetIconId(); if (roleName.Left(6).IsSameAs(wxT("group "), false)) { icon = groupFactory.GetIconId(); roleName = wxT("group ") + qtStrip(roleName.Mid(6)); } else if (roleName.IsEmpty()) { icon = PGICON_PUBLIC; roleName = wxT("public"); } else { roleName = qtStrip(roleName); for (unsigned int index = 0; index < groups.Count(); index++) if (roleName == groups[index]) { roleName = wxT("group ") + roleName; icon = groupFactory.GetIconId(); break; } } securityPage->lbPrivileges->AppendItem(icon, roleName, value); if(changedColumn == NULL) currentAcl.Add(roleName + wxT("=") + value); // Reset roleName roleName.Empty(); } } } } int dlgColumn::Go(bool modal) { if (connection->BackendMinimumVersion(8, 4)) { securityPage->SetConnection(connection); if (securityPage->cbGroups) { // Fetch Groups Information for ( unsigned int index = 0; index < groups.Count();) securityPage->cbGroups->Append(wxT("group ") + groups[index++]); // Fetch Users Information if (settings->GetShowUsersForPrivileges()) { securityPage->stGroup->SetLabel(_("Group/User")); dlgProperty::AddUsers(securityPage->cbGroups); Layout(); } } securityPage->lbPrivileges->GetParent()->Layout(); } if (connection->BackendMinimumVersion(8, 5)) { cbVarname->Append(wxT("n_distinct")); cbVarname->Append(wxT("n_distinct_inherited")); cbVarname->SetSelection(0); } else { lstVariables->Enable(false); btnAdd->Enable(false); btnRemove->Enable(false); cbVarname->Enable(false); txtValue->Enable(false); } if (connection->BackendMinimumVersion(9, 1)) { seclabelPage->SetConnection(connection); seclabelPage->SetObject(column); this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgColumn::OnChange)); } else seclabelPage->Disable(); cbStorage->Enable(true); if (connection->BackendMinimumVersion(9, 1)) { // fill collation combobox cbCollation->Append(wxEmptyString); pgSet *set = connection->ExecuteSet( wxT("SELECT nspname, collname\n") wxT(" FROM pg_collation c, pg_namespace n\n") wxT(" WHERE c.collnamespace=n.oid\n") wxT(" ORDER BY nspname, collname")); if (set) { cbCollation->Freeze(); while (!set->Eof()) { wxString name = qtIdent(set->GetVal(wxT("nspname"))) + wxT(".") + qtIdent(set->GetVal(wxT("collname"))); cbCollation->Append(name); set->MoveNext(); } cbCollation->Thaw(); delete set; } cbCollation->SetSelection(0); } else cbCollation->Disable(); if (column) { // edit mode if (column->GetLength() > 0) txtLength->SetValue(NumToStr(column->GetLength())); if (column->GetPrecision() >= 0) txtPrecision->SetValue(NumToStr(column->GetPrecision())); txtDefault->SetValue(column->GetDefault()); chkNotNull->SetValue(column->GetNotNull()); txtAttstattarget->SetValue(NumToStr(column->GetAttstattarget())); wxString fullType = column->GetRawTypename(); if (column->GetIsArray()) fullType += wxT("[]"); cbDatatype->Append(fullType); AddType(wxT("?"), column->GetAttTypId(), fullType); if (!column->IsReferenced()) { wxString typeSql = wxT("SELECT tt.oid, format_type(tt.oid,NULL) AS typname\n") wxT(" FROM pg_cast\n") wxT(" JOIN pg_type tt ON tt.oid=casttarget\n") wxT(" WHERE castsource=") + NumToStr(column->GetAttTypId()) + wxT("\n"); if (connection->BackendMinimumVersion(8, 0)) typeSql += wxT(" AND castcontext IN ('i', 'a')"); else typeSql += wxT(" AND castfunc=0"); pgSetIterator set(connection, typeSql); while (set.RowsLeft()) { if (set.GetVal(wxT("typname")) != column->GetRawTypename()) { cbDatatype->Append(set.GetVal(wxT("typname"))); AddType(wxT("?"), set.GetOid(wxT("oid")), set.GetVal(wxT("typname"))); } } } if (cbDatatype->GetCount() <= 1) cbDatatype->Disable(); cbDatatype->SetSelection(0); wxNotifyEvent ev; OnSelChangeTyp(ev); previousDefinition = GetDefinition(); if (column->GetColNumber() < 0) // Disable controls not valid for system columns { txtName->Disable(); txtDefault->Disable(); chkNotNull->Disable(); txtLength->Disable(); cbDatatype->Disable(); txtAttstattarget->Disable(); cbStorage->Disable(); cbCollation->Disable(); } else if (column->GetTable()->GetMetaType() == PGM_VIEW) // Disable controls not valid for view columns { txtName->Disable(); chkNotNull->Disable(); txtLength->Disable(); cbDatatype->Disable(); txtAttstattarget->Disable(); cbStorage->Disable(); cbCollation->Disable(); } else if (column->GetTable()->GetMetaType() == GP_EXTTABLE) // Disable controls not valid for external table columns { txtName->Disable(); chkNotNull->Disable(); txtLength->Disable(); cbDatatype->Disable(); txtAttstattarget->Disable(); txtDefault->Disable(); cbStorage->Disable(); cbCollation->Disable(); } else if (table->GetOfTypeOid() > 0) { txtName->Disable(); chkNotNull->Enable(); txtLength->Disable(); cbDatatype->Disable(); txtAttstattarget->Enable(); txtDefault->Enable(); cbStorage->Enable(); cbCollation->Disable(); } cbStorage->SetValue(column->GetStorage()); cbCollation->SetValue(column->GetCollation()); size_t i; for (i = 0 ; i < column->GetVariables().GetCount() ; i++) { wxString item = column->GetVariables().Item(i); lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('=')); } } else { // create mode FillDatatype(cbDatatype, true, true); if (!table) { cbClusterSet->Disable(); cbClusterSet = 0; } txtAttstattarget->Disable(); cbStorage->Disable(); } if (changedColumn) ApplyChangesToDlg(); return dlgTypeProperty::Go(modal); } wxString dlgColumn::GetSql() { wxString sql; wxString name = GetName(); bool isSerial = (cbDatatype->GetValue() == wxT("serial") || cbDatatype->GetValue() == wxT("bigserial") || cbDatatype->GetValue() == wxT("smallserial")); if (table) { if (column) { if (name != column->GetName()) sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + wxT(" RENAME ") + qtIdent(column->GetName()) + wxT(" TO ") + qtIdent(name) + wxT(";\n"); wxString len; if (txtLength->IsEnabled()) len = txtLength->GetValue(); wxString prec; if (txtPrecision->IsEnabled()) prec = txtPrecision->GetValue(); if (connection->BackendMinimumVersion(7, 5)) { if ((cbDatatype->GetValue() != column->GetRawTypename() && !column->GetIsArray()) || (cbDatatype->GetValue() != column->GetRawTypename() + wxT("[]") && column->GetIsArray()) || (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != column->GetCollation()) || (isVarLen && txtLength->IsEnabled() && StrToLong(len) != column->GetLength()) || (isVarPrec && txtPrecision->IsEnabled() && StrToLong(prec) != column->GetPrecision())) { sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + wxT("\n ALTER COLUMN ") + qtIdent(name) + wxT(" TYPE ") + GetQuotedTypename(cbDatatype->GetGuessedSelection()); if (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != column->GetCollation()) sql += wxT(" COLLATE ") + cbCollation->GetValue(); sql += wxT(";\n"); } } else { wxString sqlPart; if (cbDatatype->GetCount() > 1 && cbDatatype->GetValue() != column->GetRawTypename()) sqlPart = wxT("atttypid=") + dlgTypeProperty::GetTypeOid(cbDatatype->GetGuessedSelection()); if (!sqlPart.IsEmpty() || (isVarLen && txtLength->IsEnabled() && StrToLong(prec) != column->GetLength()) || (isVarPrec && txtPrecision->IsEnabled() && StrToLong(prec) != column->GetPrecision())) { long typmod = pgDatatype::GetTypmod(column->GetRawTypename(), len, prec); if (!sqlPart.IsEmpty()) sqlPart += wxT(", "); sqlPart += wxT("atttypmod=") + NumToStr(typmod); } if (!sqlPart.IsEmpty()) { sql += wxT("UPDATE pg_attribute\n") wxT(" SET ") + sqlPart + wxT("\n") wxT(" WHERE attrelid=") + table->GetOidStr() + wxT(" AND attnum=") + NumToStr(column->GetColNumber()) + wxT(";\n"); } } if (txtDefault->GetValue() != column->GetDefault()) { sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + wxT("\n ALTER COLUMN ") + qtIdent(name); if (txtDefault->GetValue().IsEmpty()) sql += wxT(" DROP DEFAULT"); else sql += wxT(" SET DEFAULT ") + txtDefault->GetValue(); sql += wxT(";\n"); } if (chkNotNull->GetValue() != column->GetNotNull()) { sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + wxT("\n ALTER COLUMN ") + qtIdent(name); if (chkNotNull->GetValue()) sql += wxT(" SET"); else sql += wxT(" DROP"); sql += wxT(" NOT NULL;\n"); } if (txtAttstattarget->GetValue() != NumToStr(column->GetAttstattarget())) { sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + wxT("\n ALTER COLUMN ") + qtIdent(name); if (txtAttstattarget->GetValue().IsEmpty()) if (connection->BackendMinimumVersion(17, 0)) sql += wxT(" SET STATISTICS DEFAULT"); else sql += wxT(" SET STATISTICS -1"); else sql += wxT(" SET STATISTICS ") + txtAttstattarget->GetValue(); sql += wxT(";\n"); } wxArrayString vars; size_t index; for (index = 0 ; index < column->GetVariables().GetCount() ; index++) vars.Add(column->GetVariables().Item(index)); int cnt = lstVariables->GetItemCount(); int pos; // check for changed or added vars for (pos = 0 ; pos < cnt ; pos++) { wxString newVar = lstVariables->GetText(pos); wxString newVal = lstVariables->GetText(pos, 1); wxString oldVal; for (index = 0 ; index < vars.GetCount() ; index++) { wxString var = vars.Item(index); if (var.BeforeFirst('=').IsSameAs(newVar, false)) { oldVal = var.Mid(newVar.Length() + 1); vars.RemoveAt(index); break; } } if (oldVal != newVal) { sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + wxT("\n ALTER COLUMN ") + qtIdent(name) + wxT("\n SET (") + newVar + wxT("=") + newVal + wxT(");\n"); } } // check for removed vars for (pos = 0 ; pos < (int)vars.GetCount() ; pos++) { sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + wxT("\n ALTER COLUMN ") + qtIdent(name) + wxT("\n RESET (") + vars.Item(pos).BeforeFirst('=') + wxT(");\n"); } if (cbStorage->GetValue() != column->GetStorage()) { sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + wxT("\n ALTER COLUMN ") + qtIdent(name) + wxT(" SET STORAGE ") + cbStorage->GetValue() + wxT(";\n"); } } else { sql = wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + wxT("\n ADD COLUMN ") + qtIdent(name) + wxT(" ") + GetQuotedTypename(cbDatatype->GetGuessedSelection()); if (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != wxT("pg_catalog.\"default\"")) sql += wxT(" COLLATE ") + cbCollation->GetValue(); if (chkNotNull->GetValue()) sql += wxT(" NOT NULL"); if (!isSerial && !txtDefault->GetValue().IsEmpty()) sql += wxT(" DEFAULT ") + txtDefault->GetValue(); sql += wxT(";\n"); if (!txtAttstattarget->GetValue().IsEmpty()) sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + wxT("\n ALTER COLUMN ") + qtIdent(name) + wxT(" SET STATISTICS ") + txtAttstattarget->GetValue() + wxT(";\n"); // check for added vars for (int pos = 0 ; pos < lstVariables->GetItemCount() ; pos++) { sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + wxT("\n ALTER COLUMN ") + qtIdent(name) + wxT("\n SET (") + lstVariables->GetText(pos) + wxT("=") + lstVariables->GetText(pos, 1) + wxT(");\n"); } } AppendComment(sql, wxT("COLUMN ") + table->GetQuotedFullIdentifier() + wxT(".") + qtIdent(name), column); if (seclabelPage && connection->BackendMinimumVersion(9, 1)) sql += seclabelPage->GetSqlForSecLabels(wxT("COLUMN"), table->GetQuotedFullIdentifier() + wxT(".") + qtIdent(name)); // securityPage will exists only for PG 8.4 and later if (connection->BackendMinimumVersion(8, 4)) sql += securityPage->GetGrant(wxT("arwx"), table->GetQuotedFullIdentifier(), ¤tAcl, qtIdent(name)); } return sql; } void dlgColumn::SetChangedCol(pgColumn *changedCol) { changedColumn = changedCol; } void dlgColumn::ApplyChangesToObj(pgColumn *changedCol) { changedCol->iSetName(txtName->GetValue()); changedCol->iSetComment(txtComment->GetValue()); changedCol->iSetRawTypename(cbDatatype->GetValue()); if (!txtLength->GetValue().IsEmpty()) changedCol->iSetLength(StrToLong(txtLength->GetValue())); if (!txtPrecision->GetValue().IsEmpty()) changedCol->iSetPrecision(StrToLong(txtPrecision->GetValue())); changedCol->iSetCollation(cbCollation->GetValue()); changedCol->iSetStorage(cbStorage->GetValue()); changedCol->iSetAttstattarget(StrToLong(txtAttstattarget->GetValue())); changedCol->iSetNotNull(chkNotNull->GetValue()); changedCol->iSetDefault(txtDefault->GetValue()); changedCol->GetVariables().Clear(); for (int pos = 0 ; pos < lstVariables->GetItemCount() ; pos++) { changedCol->GetVariables().Add(lstVariables->GetText(pos) + wxT("=") + lstVariables->GetText(pos, 1)); } if(securityPage && connection->BackendMinimumVersion(8, 4)) { changedCol->iSetAcl(securityPage->GetUserPrivileges()); } if(seclabelPage && connection->BackendMinimumVersion(9, 1)) { wxArrayString secLabels; wxString providers; wxString labels; seclabelPage->GetCurrentProviderLabelArray(secLabels); if(!secLabels.IsEmpty()) { for(size_t pos = 0; pos < secLabels.Count(); pos += 2) { if(pos == 0) { providers += wxT("{") + secLabels.Item(pos); labels += wxT("{") + secLabels.Item(pos + 1); } else { providers += wxT(",") + secLabels.Item(pos); labels += wxT(",") + secLabels.Item(pos + 1); } } providers += wxT("}"); labels += wxT("}"); } changedCol->iSetProviders(providers); changedCol->iSetLabels(labels); } } void dlgColumn::ApplyChangesToDlg() { txtName->SetValue(changedColumn->GetName()); txtComment->SetValue(changedColumn->GetComment()); cbDatatype->SetValue(changedColumn->GetRawTypename()); txtLength->SetValue(NumToStr(changedColumn->GetLength())); txtPrecision->SetValue(NumToStr(changedColumn->GetPrecision())); cbCollation->SetValue(changedColumn->GetCollation()); cbStorage->SetValue(changedColumn->GetStorage()); txtAttstattarget->SetValue(NumToStr(changedColumn->GetAttstattarget())); chkNotNull->SetValue(changedColumn->GetNotNull()); txtDefault->SetValue(changedColumn->GetDefault()); lstVariables->DeleteAllItems(); for (size_t i = 0 ; i < changedColumn->GetVariables().GetCount() ; i++) { wxString item = changedColumn->GetVariables().Item(i); lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('=')); } //setting privileges to changed values SetSecurityPage(changedColumn); if (connection->BackendMinimumVersion(9, 1)) { wxArrayString seclabels = changedColumn->GetProviderLabelArray(); if (seclabels.GetCount() > 0) { for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) { seclabelPage->lbSeclabels->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); } } } else if (seclabelPage != NULL) { seclabelPage->Disable(); } } void dlgColumn::GetVariableList(wxArrayString &variableList) { wxString name; wxString value; for(int pos = 0; pos < lstVariables->GetItemCount(); pos++) { name = lstVariables->GetText(pos); value = lstVariables->GetText(pos, 1); variableList.Add(name + wxT("=") + value); } } void dlgColumn::GetSecLabelList(wxArrayString &secLabelList) { if (seclabelPage && connection->BackendMinimumVersion(9, 1)) seclabelPage->GetCurrentProviderLabelArray(secLabelList); } wxString dlgColumn::GetDefinition() { wxString sql; sql = GetQuotedTypename(cbDatatype->GetGuessedSelection()); if (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != wxT("pg_catalog.\"default\"")) sql += wxT(" COLLATE ") + cbCollation->GetValue(); if (chkNotNull->GetValue()) sql += wxT(" NOT NULL"); AppendIfFilled(sql, wxT(" DEFAULT "), txtDefault->GetValue()); return sql; } wxString dlgColumn::GetTypeOid() { return dlgTypeProperty::GetTypeOid(cbDatatype->GetGuessedSelection()); } pgObject *dlgColumn::CreateObject(pgCollection *collection) { pgObject *obj; obj = columnFactory.CreateObjects(collection, 0, wxT("\n AND attname=") + qtDbString(GetName()) + wxT("\n AND cl.relname=") + qtDbString(table->GetName()) + wxT("\n AND cl.relnamespace=") + table->GetSchema()->GetOidStr() + wxT("\n")); return obj; } void dlgColumn::OnSelChangeTyp(wxCommandEvent &ev) { cbDatatype->GuessSelection(ev); CheckLenEnable(); txtLength->Enable(isVarLen); bool isSerial = (cbDatatype->GetValue() == wxT("serial") || cbDatatype->GetValue() == wxT("bigserial") || cbDatatype->GetValue() == wxT("smallserial")); txtDefault->Enable(!isSerial); CheckChange(); } void dlgColumn::CheckChange() { bool enable = true; long varlen = StrToLong(txtLength->GetValue()), varprec = StrToLong(txtPrecision->GetValue()); if (column) { txtPrecision->Enable(column->GetTable()->GetMetaType() != PGM_VIEW && isVarPrec && varlen > 0); CheckValid(enable, cbDatatype->GetGuessedSelection() >= 0, _("Please select a datatype.")); if (!connection->BackendMinimumVersion(7, 5)) { CheckValid(enable, !isVarLen || !txtLength->GetValue().IsEmpty() || varlen >= column->GetLength(), _("New length must not be less than old length.")); CheckValid(enable, !txtPrecision->IsEnabled() || varprec >= column->GetPrecision(), _("New precision must not be less than old precision.")); CheckValid(enable, !txtPrecision->IsEnabled() || varlen - varprec >= column->GetLength() - column->GetPrecision(), _("New total digits must not be less than old total digits.")); } if (enable) enable = GetName() != column->GetName() || txtDefault->GetValue() != column->GetDefault() || txtComment->GetValue() != column->GetComment() || chkNotNull->GetValue() != column->GetNotNull() || (cbDatatype->GetCount() > 1 && cbDatatype->GetGuessedStringSelection() != column->GetRawTypename() && !column->GetIsArray()) || (cbDatatype->GetCount() > 1 && cbDatatype->GetGuessedStringSelection() != column->GetRawTypename() + wxT("[]") && column->GetIsArray()) || (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != column->GetCollation()) || (isVarLen && varlen != column->GetLength()) || (isVarPrec && varprec != column->GetPrecision()) || txtAttstattarget->GetValue() != NumToStr(column->GetAttstattarget()) || cbStorage->GetValue() != column->GetStorage() || dirtyVars; if (seclabelPage && connection->BackendMinimumVersion(9, 1)) enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); EnableOK(enable || securityChanged); } else { txtPrecision->Enable(isVarPrec && varlen > 0); wxString name = GetName(); CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); CheckValid(enable, cbDatatype->GetGuessedSelection() >= 0, _("Please select a datatype.")); CheckValid(enable, !isVarLen || txtLength->GetValue().IsEmpty() || (varlen >= minVarLen && varlen <= maxVarLen && NumToStr(varlen) == txtLength->GetValue()), _("Please specify valid length.")); CheckValid(enable, !txtPrecision->IsEnabled() || (varprec >= 0 && varprec <= varlen && NumToStr(varprec) == txtPrecision->GetValue()), _("Please specify valid numeric precision (0..") + NumToStr(varlen) + wxT(").")); EnableOK(enable); } } void dlgColumn::OnAddPriv(wxCommandEvent &ev) { securityChanged = true; CheckChange(); } void dlgColumn::OnDelPriv(wxCommandEvent &ev) { securityChanged = true; CheckChange(); } void dlgColumn::OnVarnameSelChange(wxCommandEvent &ev) { cbVarname->GuessSelection(ev); } void dlgColumn::OnVarSelChange(wxListEvent &ev) { long pos = lstVariables->GetSelection(); if (pos >= 0) { wxString value = lstVariables->GetText(pos, 1); cbVarname->SetValue(lstVariables->GetText(pos)); cbVarname->FindString(lstVariables->GetText(pos)); txtValue->SetValue(value); } } void dlgColumn::OnVarAdd(wxCommandEvent &ev) { wxString name = cbVarname->GetValue(); wxString value = txtValue->GetValue().Strip(wxString::both); if (value.IsEmpty()) value = wxT("DEFAULT"); if (!name.IsEmpty()) { long pos = lstVariables->FindItem(-1, name); if (pos < 0) { pos = lstVariables->GetItemCount(); lstVariables->InsertItem(pos, name, 0); } lstVariables->SetItem(pos, 1, value); } dirtyVars = true; CheckChange(); } void dlgColumn::OnVarRemove(wxCommandEvent &ev) { if (lstVariables->GetSelection() >= 0) { lstVariables->DeleteCurrentItem(); dirtyVars = true; CheckChange(); } } void dlgColumn::OnChange(wxCommandEvent &event) { CheckChange(); }