mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 14:15:49 -06:00
317 lines
7.7 KiB
C++
317 lines
7.7 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin III - PostgreSQL Tools
|
|
//
|
|
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
// dlgRepTable.cpp - PostgreSQL Slony-I Table Property
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// wxWindows headers
|
|
#include <wx/wx.h>
|
|
|
|
// App headers
|
|
#include "pgAdmin3.h"
|
|
|
|
#include "slony/dlgRepTable.h"
|
|
#include "slony/slCluster.h"
|
|
#include "slony/slSet.h"
|
|
#include "slony/slTable.h"
|
|
#include "schema/pgDatatype.h"
|
|
|
|
|
|
// pointer to controls
|
|
#define txtID CTRL_TEXT("txtID")
|
|
#define cbTable CTRL_COMBOBOX2("cbTable")
|
|
#define cbIndex CTRL_COMBOBOX("cbIndex")
|
|
#define chkTrigger CTRL_CHECKLISTBOX("chkTrigger")
|
|
|
|
|
|
|
|
BEGIN_EVENT_TABLE(dlgRepTable, dlgRepProperty)
|
|
EVT_TEXT(XRCID("txtID"), dlgRepTable::OnChange)
|
|
EVT_COMBOBOX(XRCID("cbTable"), dlgRepTable::OnChangeTableSel)
|
|
EVT_TEXT(XRCID("cbTable"), dlgRepTable::OnChangeTable)
|
|
EVT_COMBOBOX(XRCID("cbIndex"), dlgRepTable::OnChange)
|
|
EVT_CHECKLISTBOX(XRCID("chkTrigger"), dlgRepTable::OnChange)
|
|
END_EVENT_TABLE();
|
|
|
|
|
|
dlgProperty *slSlTableFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
|
|
{
|
|
return new dlgRepTable(this, frame, (slTable *)node, (slSet *)parent);
|
|
}
|
|
|
|
|
|
dlgRepTable::dlgRepTable(pgaFactory *f, frmMain *frame, slTable *node, slSet *s)
|
|
: dlgRepProperty(f, frame, s->GetCluster(), wxT("dlgRepTable"))
|
|
{
|
|
table = node;
|
|
set = s;
|
|
}
|
|
|
|
|
|
pgObject *dlgRepTable::GetObject()
|
|
{
|
|
return table;
|
|
}
|
|
|
|
|
|
int dlgRepTable::Go(bool modal)
|
|
{
|
|
txtID->SetValidator(numericValidator);
|
|
|
|
if (table)
|
|
{
|
|
// edit mode
|
|
cbTable->Append(table->GetName(), (void *)0);
|
|
cbTable->SetSelection(0);
|
|
cbIndex->Append(table->GetIndexName());
|
|
cbIndex->SetSelection(0);
|
|
|
|
txtID->SetValue(NumToStr(table->GetSlId()));
|
|
|
|
cbTable->Disable();
|
|
cbIndex->Disable();
|
|
txtComment->Disable();
|
|
txtID->Disable();
|
|
|
|
LoadTrigger(table->GetOid());
|
|
|
|
size_t i;
|
|
for (i = 0 ; i < table->GetTriggers().GetCount() ; i++)
|
|
{
|
|
int sel = chkTrigger->FindString(table->GetTriggers()[i]);
|
|
if (sel >= 0)
|
|
chkTrigger->Check(sel);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// create mode
|
|
|
|
wxString restriction;
|
|
if (!settings->GetShowSystemObjects())
|
|
restriction = wxT("\n AND ") + connection->SystemNamespaceRestriction(wxT("nspname"));
|
|
|
|
pgSet *tabs = connection->ExecuteSet(
|
|
wxT("SELECT DISTINCT cl.oid, nspname, relname\n")
|
|
wxT(" FROM pg_class cl\n")
|
|
wxT(" JOIN pg_namespace nsp ON relnamespace=nsp.oid\n")
|
|
wxT(" JOIN pg_index on indrelid=cl.oid AND indisunique\n")
|
|
wxT(" LEFT JOIN ") + cluster->GetSchemaPrefix() + wxT("sl_table t ON t.tab_reloid=cl.oid\n")
|
|
wxT(" WHERE t.tab_id IS NULL AND cl.relkind = 'r'") + restriction + wxT("\n")
|
|
wxT(" ORDER BY nspname, relname")
|
|
);
|
|
|
|
if (tabs)
|
|
{
|
|
while (!tabs->Eof())
|
|
{
|
|
cbTable->Append(tabs->GetVal(wxT("nspname")) + wxT(".") + tabs->GetVal(wxT("relname")), (void *)tabs->GetOid(wxT("oid")));
|
|
tabs->MoveNext();
|
|
}
|
|
delete tabs;
|
|
}
|
|
}
|
|
|
|
return dlgProperty::Go(modal);
|
|
}
|
|
|
|
|
|
pgObject *dlgRepTable::CreateObject(pgCollection *collection)
|
|
{
|
|
pgObject *obj = slTableFactory.CreateObjects(collection, 0,
|
|
wxT(" WHERE tab_reloid = ") + NumToStr((long long)cbTable->wxItemContainer::GetClientData(cbTable->GetGuessedSelection())));
|
|
|
|
return obj;
|
|
}
|
|
|
|
|
|
|
|
void dlgRepTable::OnChangeTableSel(wxCommandEvent &ev)
|
|
{
|
|
cbTable->GuessSelection(ev);
|
|
OnChangeTable(ev);
|
|
}
|
|
|
|
|
|
void dlgRepTable::OnChangeTable(wxCommandEvent &ev)
|
|
{
|
|
int sel = cbTable->GetGuessedSelection();
|
|
|
|
cbIndex->Clear();
|
|
chkTrigger->Clear();
|
|
|
|
if (sel >= 0)
|
|
{
|
|
OID relid = (long long)cbTable->wxItemContainer::GetClientData(sel);
|
|
|
|
pgSet *idx = connection->ExecuteSet(
|
|
wxT("SELECT relname\n")
|
|
wxT(" FROM pg_index JOIN pg_class cl ON cl.oid=indexrelid\n")
|
|
wxT(" WHERE indrelid=") + NumToStr(relid) + wxT("\n")
|
|
wxT(" ORDER BY NOT indisprimary, relname")
|
|
);
|
|
if (idx)
|
|
{
|
|
while (!idx->Eof())
|
|
{
|
|
cbIndex->Append(idx->GetVal(wxT("relname")));
|
|
idx->MoveNext();
|
|
}
|
|
delete idx;
|
|
|
|
cbIndex->SetSelection(0);
|
|
}
|
|
|
|
LoadTrigger(relid);
|
|
}
|
|
|
|
OnChange(ev);
|
|
}
|
|
|
|
|
|
void dlgRepTable::LoadTrigger(OID relid)
|
|
{
|
|
wxString sql = wxT("SELECT tgname FROM pg_trigger\n")
|
|
wxT(" JOIN pg_proc pr ON pr.oid=tgfoid\n")
|
|
wxT(" JOIN pg_namespace ns ON ns.oid=pronamespace\n")
|
|
wxT(" WHERE tgrelid=") + NumToStr(relid);
|
|
if (connection->BackendMinimumVersion(8, 5))
|
|
sql += wxT(" AND tgconstraint=0\n");
|
|
else
|
|
sql += wxT(" AND NOT tgisconstraint\n");
|
|
sql += wxT(" AND nspname <> ") + qtDbString(wxT("_") + set->GetCluster()->GetName()) + wxT("\n")
|
|
wxT(" ORDER BY tgname");
|
|
|
|
pgSet *trg = connection->ExecuteSet(sql);
|
|
|
|
if (trg)
|
|
{
|
|
while (!trg->Eof())
|
|
{
|
|
chkTrigger->Append(trg->GetVal(wxT("tgname")));
|
|
trg->MoveNext();
|
|
}
|
|
delete trg;
|
|
}
|
|
}
|
|
|
|
void dlgRepTable::CheckChange()
|
|
{
|
|
if (table)
|
|
{
|
|
bool tgChanged = false;
|
|
|
|
unsigned int i;
|
|
int cnt = 0;
|
|
|
|
for (i = 0 ; !tgChanged && i < chkTrigger->GetCount() ; i++)
|
|
{
|
|
if (chkTrigger->IsChecked(i))
|
|
{
|
|
cnt++;
|
|
if (table->GetTriggers().Index(chkTrigger->GetString(i)) < 0)
|
|
tgChanged = true;
|
|
|
|
}
|
|
}
|
|
|
|
EnableOK(tgChanged
|
|
|| (int)table->GetTriggers().GetCount() != cnt
|
|
|| txtComment->GetValue() != table->GetComment());
|
|
}
|
|
else
|
|
{
|
|
bool enable = true;
|
|
CheckValid(enable, cbTable->GetGuessedSelection() >= 0, _("Please select table to replicate."));
|
|
CheckValid(enable, cbIndex->GetCurrentSelection() >= 0, _("Please select index."));
|
|
|
|
EnableOK(enable);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
wxString dlgRepTable::GetSql()
|
|
{
|
|
wxString sql;
|
|
wxString id = txtID->GetValue();;
|
|
|
|
wxArrayString newTriggers;
|
|
|
|
unsigned int i;
|
|
for (i = 0 ; i < chkTrigger->GetCount() ; i++)
|
|
{
|
|
if (chkTrigger->IsChecked(i))
|
|
newTriggers.Add(chkTrigger->GetString(i));
|
|
}
|
|
|
|
if (table)
|
|
{
|
|
// edit mode
|
|
|
|
wxArrayString oldTriggers = table->GetTriggers();
|
|
|
|
i = oldTriggers.GetCount();
|
|
while (i--)
|
|
{
|
|
int j = newTriggers.Index(oldTriggers[i]);
|
|
if (j >= 0)
|
|
{
|
|
newTriggers.RemoveAt(j);
|
|
oldTriggers.RemoveAt(i);
|
|
}
|
|
}
|
|
|
|
// these triggers have been deleted
|
|
for (i = 0 ; i < (unsigned int)oldTriggers.GetCount() ; i++)
|
|
{
|
|
sql += wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("droptrigger(")
|
|
+ id + wxT(", ")
|
|
+ qtDbString(oldTriggers[i]) + wxT(");\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// create mode
|
|
sql = wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("setaddtable(")
|
|
+ NumToStr(set->GetSlId()) + wxT(", ");
|
|
|
|
if (StrToLong(id) > 0)
|
|
{
|
|
sql += id;
|
|
}
|
|
else
|
|
{
|
|
sql += wxT("(SELECT COALESCE(MAX(tab_id), 0) + 1 FROM ") + cluster->GetSchemaPrefix() + wxT("sl_table)");
|
|
|
|
|
|
id = wxT("(SELECT tab_id FROM ") + cluster->GetSchemaPrefix() + wxT("sl_table\n")
|
|
wxT(" JOIN pg_class cl ON cl.oid=tab_reloid\n")
|
|
wxT(" JOIN pg_namespace nsp ON nsp.oid=relnamespace\n")
|
|
wxT(" WHERE tab_set = ") + NumToStr(set->GetSlId()) +
|
|
wxT(" AND nspname ||'.' || relname = ") + qtDbString(cbTable->GetGuessedStringSelection()) +
|
|
wxT(")");
|
|
|
|
}
|
|
sql += wxT(", ") + qtDbString(cbTable->GetGuessedStringSelection())
|
|
+ wxT(", ") + qtDbString(cbIndex->GetStringSelection())
|
|
+ wxT(", ") + qtDbString(txtComment->GetValue())
|
|
+ wxT(");\n");
|
|
}
|
|
|
|
|
|
// these triggers have been added
|
|
for (i = 0 ; i < (unsigned int)newTriggers.GetCount() ; i++)
|
|
{
|
|
sql += wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("storetrigger(")
|
|
+ id + wxT(", ")
|
|
+ qtDbString(newTriggers[i]) + wxT(");\n");
|
|
}
|
|
|
|
return sql;
|
|
}
|