mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 06:05:49 -06:00
Merge branch 'master' of https://github.com/levinsv/pgadmin3
This commit is contained in:
commit
d29b6de188
39 changed files with 1050 additions and 186 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1,6 +1,7 @@
|
|||
Debug/*
|
||||
x64/*
|
||||
Release/*
|
||||
Debug_(3.0)/*
|
||||
*.sbr
|
||||
*.obj
|
||||
*.cod
|
||||
|
|
@ -8,3 +9,5 @@ Release/*
|
|||
*.7z
|
||||
*.bsc
|
||||
*.pdb
|
||||
ctl/ctlMonitorWidget.cpp
|
||||
include/ctl/ctlMonitorWidget.h
|
||||
|
|
|
|||
23
README.md
23
README.md
|
|
@ -133,10 +133,27 @@ This text Russian language.
|
|||
В родной схеме, секции как таблицы увидеть нельзя.
|
||||
* мелкие улучшения
|
||||
|
||||
02.09.2020
|
||||
- добавлена возможность копировать в буфер обмена выделенные ячейки результата запроса в формате IN списка и Where конструкций. Вызывается из контекстного меню.
|
||||
- в Server status окне добавлена возможность фильтровать строки по щелчку правой кнопкой мыши.
|
||||
* иправлено issues #8 (dropping overloaded procedures)
|
||||
|
||||
05.09.2020
|
||||
- при сравнении объектов добавлена возможность исключать сравнение привелегий и комментариев.
|
||||
* исправлено копирование текста запроса из под фильтра в Server status окне. При сравнении текста из колонки Client порт не учитывается.
|
||||
|
||||
05.12.2020
|
||||
* много мелких исправлений
|
||||
* добавлены некоторые новые возможности PG13. Описание в коммитах.
|
||||
- добавлена проверка btree индекса. Проверка выполняется функцией bt_index_parent_check(regclass,true) из расширения amcheck.
|
||||
Расширение должно быть установлено в БД к которой происходит подключение pgadmin3.
|
||||
|
||||
|
||||
|
||||
|
||||
02.01.2021
|
||||
- добавлена сортировка на вкладках "свойства" , "Статистика" и других.
|
||||
- по секционированным таблицам в статистеке выводятся все потомки.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -19,13 +19,106 @@
|
|||
#include "ctl/ctlListView.h"
|
||||
#include "utils/misc.h"
|
||||
|
||||
|
||||
ctlListView::ctlListView(wxWindow *p, int id, wxPoint pos, wxSize siz, long attr)
|
||||
: wxListView(p, id, pos, siz, attr | wxLC_REPORT)
|
||||
int wxCALLBACK
|
||||
MyCompareFunction(wxIntPtr item1, wxIntPtr item2, wxIntPtr WXUNUSED(sortData))
|
||||
{
|
||||
// inverse the order
|
||||
if (item1 < item2)
|
||||
return 1;
|
||||
if (item1 > item2)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctlListView::ctlListView(wxWindow* p, int id, wxPoint pos, wxSize siz, long attr)
|
||||
: wxListView(p, id, pos, siz, attr | wxLC_REPORT)
|
||||
{
|
||||
nosort = false;
|
||||
order = 1;
|
||||
prev_col = -1;
|
||||
Connect(wxID_ANY, wxEVT_LIST_COL_CLICK, wxListEventHandler(ctlListView::OnSortGrid));
|
||||
}
|
||||
#include <map>
|
||||
void ctlListView::OnSortGrid(wxListEvent& event)
|
||||
{
|
||||
if (!nosort) {
|
||||
int col = event.GetColumn();
|
||||
if (col == prev_col) order = order * -1;
|
||||
int rows = GetItemCount();
|
||||
wxListItem listitem;
|
||||
listitem.SetMask(wxLIST_MASK_TEXT);
|
||||
GetColumn(col, listitem);
|
||||
wxString label = listitem.GetText();
|
||||
bool issize = label == _("Size");
|
||||
bool astext = true;
|
||||
if (label == _("CFS fragmentation") ||
|
||||
label == (_("Tuples inserted")) ||
|
||||
label == (_("Tuples updated")) ||
|
||||
label == (_("Tuples deleted")) ||
|
||||
label == (_("Tuples HOT updated")) ||
|
||||
label == (_("Live tuples")) ||
|
||||
label == (_("Dead tuples")) ||
|
||||
label == (_("CFS %")) ||
|
||||
label == (_("Autovacuum counter")) ||
|
||||
label == (_("Autoanalyze counter")) ||
|
||||
label == (_("Index Scans")) ||
|
||||
label == (_("Index Tuples Read")) ||
|
||||
label == (_("Index Tuples Fetched")) ||
|
||||
issize
|
||||
) {
|
||||
astext = false;
|
||||
}
|
||||
//sort numeric column
|
||||
if (astext) {
|
||||
std::multimap<wxString, int> mp;
|
||||
for (int i = 0; i < rows; i++) {
|
||||
wxString val = GetItemText(i, col);
|
||||
mp.insert(std::pair<wxString, int>(val, i));
|
||||
}
|
||||
// ñîïîñòàâèì ñîðòèðîâàííûì çíà÷åíèÿì ïîñëåäîâàòåëüíîñòü ÷èñåë äëÿ ñîðòèðîâêè SortItems
|
||||
std::multimap<wxString, int>::iterator it = mp.begin();
|
||||
for (int i = 1; it != mp.end(); it++, i++) { // âûâîäèì èõ
|
||||
int row = it->second; // row
|
||||
wxListView::SetItemData(row, (long)i * order);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
std::multimap<double, int> mp;
|
||||
double d;
|
||||
for (int i = 0; i < rows; i++) {
|
||||
wxString val = GetItemText(i, col);
|
||||
if (val == "NaN") val = "0";
|
||||
if (val.ToCDouble(&d))
|
||||
{
|
||||
// ýòî ÷èñëî
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (issize)
|
||||
if (val.Right(2) == "kB") d = d / 1024;
|
||||
else if (val.Right(2) == "GB") d = d * 1024;
|
||||
else if (val.Right(5) == "bytes") d = d / 1024 / 1024;
|
||||
}
|
||||
mp.insert(std::pair<double, int>(d, i));
|
||||
}
|
||||
// ñîïîñòàâèì ñîðòèðîâàííûì çíà÷åíèÿì ïîñëåäîâàòåëüíîñòü ÷èñåë äëÿ ñîðòèðîâêè SortItems
|
||||
std::multimap<double, int>::iterator it = mp.begin();
|
||||
for (int i = 1; it != mp.end(); it++, i++) { // âûâîäèì èõ
|
||||
int row = it->second; // row
|
||||
wxListView::SetItemData(row, (long)i * order);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SortItems(MyCompareFunction, 0);
|
||||
Refresh();
|
||||
prev_col = col;
|
||||
}
|
||||
}
|
||||
long ctlListView::GetSelection()
|
||||
{
|
||||
return GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
|
||||
|
|
@ -43,7 +136,7 @@ wxString ctlListView::GetText(long row, long col)
|
|||
};
|
||||
|
||||
|
||||
void ctlListView::AddColumn(const wxString &text, int size, int format)
|
||||
void ctlListView::AddColumn(const wxString& text, int size, int format)
|
||||
{
|
||||
if (size == wxLIST_AUTOSIZE || size == wxLIST_AUTOSIZE_USEHEADER)
|
||||
{
|
||||
|
|
@ -56,7 +149,7 @@ void ctlListView::AddColumn(const wxString &text, int size, int format)
|
|||
}
|
||||
|
||||
|
||||
long ctlListView::AppendItem(int icon, const wxString &val, const wxString &val2, const wxString &val3, const wxString &val4)
|
||||
long ctlListView::AppendItem(int icon, const wxString& val, const wxString& val2, const wxString& val3, const wxString& val4)
|
||||
{
|
||||
long pos = InsertItem(GetItemCount(), val, icon);
|
||||
if (!val2.IsEmpty())
|
||||
|
|
@ -70,7 +163,7 @@ long ctlListView::AppendItem(int icon, const wxString &val, const wxString &val2
|
|||
}
|
||||
|
||||
|
||||
void ctlListView::CreateColumns(wxImageList *images, const wxString &left, const wxString &right, int leftSize)
|
||||
void ctlListView::CreateColumns(wxImageList* images, const wxString& left, const wxString& right, int leftSize)
|
||||
{
|
||||
int rightSize;
|
||||
if (leftSize < 0)
|
||||
|
|
@ -107,7 +200,7 @@ void ctlListView::CreateColumns(wxImageList *images, const wxString &left, const
|
|||
}
|
||||
|
||||
|
||||
void ctlListView::CreateColumns(wxImageList *images, const wxString &str1, const wxString &str2, const wxString &str3, int leftSize)
|
||||
void ctlListView::CreateColumns(wxImageList* images, const wxString& str1, const wxString& str2, const wxString& str3, int leftSize)
|
||||
{
|
||||
int rightSize;
|
||||
if (leftSize < 0)
|
||||
|
|
|
|||
|
|
@ -217,10 +217,12 @@ wxString ctlSQLGrid::GetExportLine(int row, wxArrayInt cols)
|
|||
if (GetNumberCols() == 0 || GetRowSize(row)==0)
|
||||
return str;
|
||||
wxString colsep=settings->GetCopyColSeparator();
|
||||
if (generatesql) colsep=wxT(",");
|
||||
if (generatesql == 2|| generatesql == 1) colsep=wxT(",");
|
||||
if (generatesql == 3) colsep = wxT(" and ");
|
||||
wxString qtsimbol=settings->GetCopyQuoteChar();
|
||||
if (generatesql) qtsimbol=wxT("'");
|
||||
if (generatesql>0) qtsimbol=wxT("'");
|
||||
wxString head=wxT("insert into tbl(");
|
||||
if (cols.Count()>1 && generatesql > 1) str.Append("(");
|
||||
for (col = 0 ; col < cols.Count() ; col++)
|
||||
{
|
||||
if (col > 0)
|
||||
|
|
@ -228,6 +230,7 @@ wxString ctlSQLGrid::GetExportLine(int row, wxArrayInt cols)
|
|||
if (col > 0) head.Append(colsep);
|
||||
head=head+GetColumnName(cols[col]);
|
||||
wxString text = GetCellValue(row, cols[col]);
|
||||
wxString cname = GetColumnName(cols[col]);
|
||||
bool needQuote = false;
|
||||
if (settings->GetCopyQuoting() == 1)
|
||||
{
|
||||
|
|
@ -236,22 +239,29 @@ wxString ctlSQLGrid::GetExportLine(int row, wxArrayInt cols)
|
|||
else if (settings->GetCopyQuoting() == 2)
|
||||
/* Quote everything */
|
||||
needQuote = true;
|
||||
if (text.Length()==0&&generatesql) {needQuote = false;} else
|
||||
if (generatesql) needQuote = IsColText(cols[col]);
|
||||
if (text.Length()==0&&generatesql>0) {needQuote = false;} else
|
||||
if (generatesql>0) needQuote = IsColText(cols[col]);
|
||||
|
||||
if (generatesql > 0) {
|
||||
if (text.Length() != 0) {
|
||||
text.Replace(wxT("'"), wxT("''"));
|
||||
}
|
||||
else text = wxT("null");
|
||||
|
||||
}
|
||||
if (generatesql == 3) if (text == "null") str.Append(cname).Append(" is "); else
|
||||
str.Append(cname).Append("=");
|
||||
|
||||
|
||||
if (needQuote)
|
||||
str.Append(qtsimbol);
|
||||
|
||||
if (generatesql) {
|
||||
if (text.Length()!=0) {
|
||||
text.Replace(wxT("'"),wxT("''"));
|
||||
} else text=wxT("null");
|
||||
|
||||
}
|
||||
str.Append(text);
|
||||
if (needQuote)
|
||||
str.Append(qtsimbol);
|
||||
}
|
||||
if (generatesql) str=head+wxT(") values (")+str+");";
|
||||
if (cols.Count() > 1 && generatesql > 1) str.Append(")");
|
||||
if (generatesql == 1) str=head+wxT(") values (")+str+");";
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
|
@ -278,35 +288,54 @@ void ctlSQLGrid::AppendColumnHeader(wxString &str, int start, int end)
|
|||
|
||||
void ctlSQLGrid::AppendColumnHeader(wxString &str, wxArrayInt columns)
|
||||
{
|
||||
if(settings->GetColumnNames()&&!generatesql)
|
||||
if(settings->GetColumnNames()|| generatesql == 2)
|
||||
{
|
||||
bool CopyQuoting = (settings->GetCopyQuoting() == 1 || settings->GetCopyQuoting() == 2);
|
||||
size_t i;
|
||||
|
||||
wxString fielddelim = ",";
|
||||
if (generatesql == 3) return;
|
||||
if (generatesql == 1) return;
|
||||
for(i = 0; i < columns.Count() ; i++)
|
||||
{
|
||||
long columnPos = columns.Item(i);
|
||||
if(i > 0)
|
||||
str.Append(settings->GetCopyColSeparator());
|
||||
if (generatesql == 2) {
|
||||
if (i > 0) str.Append(fielddelim);
|
||||
if (i == 0 && columns.Count() > 1) str.Append("(");
|
||||
str.Append(GetColumnName(columnPos));
|
||||
if (i == columns.Count()-1 && columns.Count() > 1 && generatesql == 2) str.Append(") in (");
|
||||
if (columns.Count() == 1 && generatesql == 2) str.Append(" in (");
|
||||
|
||||
if(CopyQuoting)
|
||||
str.Append(settings->GetCopyQuoteChar());
|
||||
str.Append(GetColumnName(columnPos));
|
||||
if(CopyQuoting)
|
||||
str.Append(settings->GetCopyQuoteChar());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i > 0)
|
||||
str.Append(settings->GetCopyColSeparator());
|
||||
|
||||
if (CopyQuoting)
|
||||
str.Append(settings->GetCopyQuoteChar());
|
||||
str.Append(GetColumnName(columnPos));
|
||||
if (CopyQuoting)
|
||||
str.Append(settings->GetCopyQuoteChar());
|
||||
}
|
||||
}
|
||||
|
||||
str.Append(END_OF_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
int ctlSQLGrid::Copy(bool gensql)
|
||||
int compare_int(int* a, int* b)
|
||||
{
|
||||
wxString str,tmp;
|
||||
if (*a > * b) return 1;
|
||||
else if (*a < *b) return -1;
|
||||
else return 0;
|
||||
}
|
||||
int ctlSQLGrid::Copy(int gensql)
|
||||
{
|
||||
wxString str,tmp,linedelim="";
|
||||
int copied = 0;
|
||||
size_t i;
|
||||
generatesql=gensql;
|
||||
|
||||
if (gensql == 2) linedelim = ",";
|
||||
else if(gensql == 3) linedelim = " or ";
|
||||
|
||||
if (GetSelectedRows().GetCount())
|
||||
{
|
||||
|
|
@ -319,6 +348,7 @@ int ctlSQLGrid::Copy(bool gensql)
|
|||
tmp=GetExportLine(rows.Item(i));
|
||||
if (tmp.IsEmpty()) continue;
|
||||
str.Append(tmp);
|
||||
if (i < rows.GetCount() - 1 && (generatesql > 1)) str.Append(linedelim);
|
||||
if (rows.GetCount() > 1)
|
||||
str.Append(END_OF_LINE);
|
||||
}
|
||||
|
|
@ -335,48 +365,93 @@ int ctlSQLGrid::Copy(bool gensql)
|
|||
for (i = 0 ; i < numRows ; i++)
|
||||
{
|
||||
str.Append(GetExportLine(i, cols));
|
||||
|
||||
if (i<(numRows-1) && (generatesql > 1)) str.Append(linedelim);
|
||||
if (numRows > 1)
|
||||
str.Append(END_OF_LINE);
|
||||
}
|
||||
|
||||
copied = numRows;
|
||||
}
|
||||
else if (GetSelectionBlockTopLeft().GetCount() > 0 &&
|
||||
GetSelectionBlockBottomRight().GetCount() > 0)
|
||||
{
|
||||
unsigned int x1, x2, y1, y2;
|
||||
int count = GetSelectionBlockTopLeft().GetCount();
|
||||
|
||||
x1 = GetSelectionBlockTopLeft()[0].GetCol();
|
||||
x2 = GetSelectionBlockBottomRight()[0].GetCol();
|
||||
y1 = GetSelectionBlockTopLeft()[0].GetRow();
|
||||
y2 = GetSelectionBlockBottomRight()[0].GetRow();
|
||||
|
||||
copied = 0;
|
||||
AppendColumnHeader(str, x1, x2);
|
||||
|
||||
for (i = y1; i <= y2; i++)
|
||||
for (size_t n = 0; n < count; n++)
|
||||
{
|
||||
str.Append(GetExportLine(i, x1, x2));
|
||||
x1 = GetSelectionBlockTopLeft()[n].GetCol();
|
||||
x2 = GetSelectionBlockBottomRight()[n].GetCol();
|
||||
y1 = GetSelectionBlockTopLeft()[n].GetRow();
|
||||
y2 = GetSelectionBlockBottomRight()[n].GetRow();
|
||||
|
||||
if (y2 > y1)
|
||||
str.Append(END_OF_LINE);
|
||||
for (i = y1; i <= y2; i++)
|
||||
{
|
||||
str.Append(GetExportLine(i, x1, x2));
|
||||
if (i < y2 && (generatesql > 1)) str.Append(linedelim);
|
||||
if (y2 > y1)
|
||||
str.Append(END_OF_LINE);
|
||||
}
|
||||
copied = copied+(y2 - y1 + 1);
|
||||
}
|
||||
|
||||
copied = y2 - y1 + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int row, col;
|
||||
if (generatesql > 1) {
|
||||
wxGridCellCoordsArray cord = GetSelectedCells();
|
||||
int count = cord.GetCount();
|
||||
int curr_row = 1000000000;
|
||||
int next_row = 1000000000;
|
||||
|
||||
for (size_t n = 0; n < count; n++)
|
||||
{
|
||||
wxGridCellCoords& coords = cord[n];
|
||||
if (coords.GetRow() < curr_row) curr_row = coords.GetRow();
|
||||
}
|
||||
while (curr_row != 1000000000)
|
||||
{
|
||||
wxArrayInt colsNum;
|
||||
next_row = 1000000000;
|
||||
for (size_t n = 0; n < count; n++)
|
||||
{
|
||||
wxGridCellCoords& coords = cord[n];
|
||||
//wxString msg;
|
||||
//msg.Printf(wxT("Êîîðäèíàòû âûáðàíûõ ÿ÷ååê row=%d col=%d.\n"), coords.GetRow(), coords.GetCol());
|
||||
//wxMessageBox(msg, wxT("About coord"), wxOK | wxICON_INFORMATION, this);
|
||||
int r = coords.GetRow();
|
||||
if (r == curr_row) {
|
||||
colsNum.Add(coords.GetCol());
|
||||
}
|
||||
else if (r > curr_row && r < next_row) next_row = r;
|
||||
|
||||
row = GetGridCursorRow();
|
||||
col = GetGridCursorCol();
|
||||
}
|
||||
colsNum.Sort(compare_int);
|
||||
if (generatesql == 2) AppendColumnHeader(str, colsNum);
|
||||
str.Append(GetExportLine(curr_row, colsNum));
|
||||
if ((next_row != 1000000000) && (generatesql == 3)) str.Append(linedelim);
|
||||
if ((next_row != 1000000000) && (generatesql == 2)) str.Append(") or ");
|
||||
str.Append(END_OF_LINE);
|
||||
curr_row = next_row;
|
||||
copied++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
row = GetGridCursorRow();
|
||||
col = GetGridCursorCol();
|
||||
|
||||
AppendColumnHeader(str, col, col);
|
||||
AppendColumnHeader(str, col, col);
|
||||
|
||||
str.Append(GetExportLine(row, col, col));
|
||||
copied = 1;
|
||||
str.Append(GetExportLine(row, col, col));
|
||||
copied = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (copied && (generatesql == 2)) str.Append(")");
|
||||
if (copied && wxTheClipboard->Open())
|
||||
{
|
||||
wxTheClipboard->SetData(new wxTextDataObject(str));
|
||||
|
|
|
|||
|
|
@ -486,11 +486,13 @@ bool pgConn::BackendMinimumVersion(int major, int minor)
|
|||
if (!majorVersion)
|
||||
{
|
||||
wxString version = GetVersionString();
|
||||
minorVersion = 0;
|
||||
patchVersion = 0;
|
||||
sscanf(version.ToAscii(), "%*s %d.%d.%d", &majorVersion, &minorVersion, &patchVersion);
|
||||
isEdb = version.Upper().Matches(wxT("ENTERPRISEDB*"));
|
||||
if (version.Upper().Matches(wxT("*11BETA*"))) {
|
||||
majorVersion=11;
|
||||
minorVersion=0;
|
||||
if (!majorVersion) {
|
||||
wxString vers=ExecuteScalar(wxT("SELECT current_setting('server_version_num');"));
|
||||
sscanf(vers.ToAscii(), "%2d%04d", &majorVersion, &minorVersion);
|
||||
}
|
||||
// EnterpriseDB 8.3 beta 1 & 2 and possibly later actually have PostgreSQL 8.2 style
|
||||
// catalogs. This is expected to change either before GA, but in the meantime we
|
||||
|
|
@ -545,7 +547,7 @@ bool pgConn::HasFeature(int featureNo, bool forceCheck)
|
|||
wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n")
|
||||
wxT(" WHERE proname IN ('pg_tablespace_size', 'pg_file_read', 'pg_logfile_rotate',")
|
||||
wxT( " 'pg_postmaster_starttime', 'pg_terminate_backend', 'pg_reload_conf',")
|
||||
wxT( " 'pgstattuple', 'pgstatindex')\n")
|
||||
wxT( " 'pgstattuple', 'pgstatindex','bt_index_parent_check')\n")
|
||||
wxT(" AND nspname IN ('pg_catalog', 'public')");
|
||||
|
||||
pgSet *set = ExecuteSet(sql);
|
||||
|
|
@ -556,6 +558,7 @@ bool pgConn::HasFeature(int featureNo, bool forceCheck)
|
|||
{
|
||||
wxString proname = set->GetVal(wxT("proname"));
|
||||
long pronargs = set->GetLong(wxT("pronargs"));
|
||||
if (BackendMinimumVersion(9, 6)) features[FEATURE_FILEREAD] = true;
|
||||
|
||||
if (proname == wxT("pg_tablespace_size") && pronargs == 1 && set->GetLong(wxT("arg0")) == 26)
|
||||
features[FEATURE_SIZE] = true;
|
||||
|
|
@ -574,6 +577,8 @@ bool pgConn::HasFeature(int featureNo, bool forceCheck)
|
|||
features[FEATURE_PGSTATTUPLE] = true;
|
||||
else if (proname == wxT("pgstatindex") && pronargs == 1 && set->GetLong(wxT("arg0")) == 25)
|
||||
features[FEATURE_PGSTATINDEX] = true;
|
||||
else if (proname == wxT("bt_index_parent_check") && pronargs == 2 )
|
||||
features[FEATURE_PGCHECKINDEX] = true;
|
||||
|
||||
set->MoveNext();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ int dlgLanguage::Go(bool modal)
|
|||
else
|
||||
{
|
||||
// create mode
|
||||
if (connection->BackendMinimumVersion(8, 1))
|
||||
if (connection->BackendMinimumVersion(8, 1)&&(!connection->BackendMinimumVersion(13, 0)))
|
||||
{
|
||||
pgSetIterator languages(connection,
|
||||
wxT("SELECT tmplname FROM pg_pltemplate\n")
|
||||
|
|
|
|||
|
|
@ -20,9 +20,8 @@
|
|||
// Copyright text
|
||||
#include "copyright.h"
|
||||
#include "version.h"
|
||||
#include "svnversion.h"
|
||||
|
||||
#define VERSION_WITH_DATE_AND_SVN wxT("Version ") VERSION_STR wxT(" (") __TDATE__ wxT(", rev: ") wxT(VERSION_SVN) wxT(")")
|
||||
#define VERSION_WITH_DATE_AND_SVN wxT("Version ") VERSION_STR wxT(" (") __TDATE__ wxT(", rev: ") wxT("") wxT(")")
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE(frmAbout, wxFrame)
|
||||
|
|
|
|||
|
|
@ -315,6 +315,7 @@ void frmMain::CreateMenus()
|
|||
new refreshConcurrentlyMatViewFactory(menuFactories, viewMenu, 0);
|
||||
new executePgstattupleFactory(menuFactories, viewMenu, 0);
|
||||
new executePgstatindexFactory(menuFactories, viewMenu, 0);
|
||||
new executePgcheckindexFactory(menuFactories, viewMenu, 0);
|
||||
new enabledisableRuleFactory(menuFactories, toolsMenu, 0);
|
||||
new enabledisableTriggerFactory(menuFactories, toolsMenu, 0);
|
||||
new enabledisableEventTriggerFactory(menuFactories, toolsMenu, 0);
|
||||
|
|
@ -432,7 +433,8 @@ void frmMain::CreateMenus()
|
|||
new reportObjectDependentsFactory(menuFactories, reportMenu, 0);
|
||||
new reportObjectListFactory(menuFactories, reportMenu, 0);
|
||||
new reportCompareFactory(menuFactories, reportMenu, 0);
|
||||
|
||||
choiceSelectOpts.Add(0);
|
||||
choiceSelectOpts.Add(1);
|
||||
|
||||
toolsMenu->AppendSeparator();
|
||||
|
||||
|
|
|
|||
|
|
@ -121,6 +121,8 @@ BEGIN_EVENT_TABLE(frmQuery, pgFrame)
|
|||
EVT_MENU(MNU_CLEAR, frmQuery::OnClear)
|
||||
EVT_MENU(MNU_SUMMARY_COL, frmQuery::OnSummary_Column)
|
||||
EVT_MENU(MNU_COPY_INSERT, frmQuery::OnCopy_Insert)
|
||||
EVT_MENU(MNU_COPY_INLIST, frmQuery::OnCopy_InList)
|
||||
EVT_MENU(MNU_COPY_WHERELIST, frmQuery::OnCopy_WhereList)
|
||||
EVT_MENU(MNU_CLEAR_FILTER, frmQuery::OnClear_Filter)
|
||||
EVT_MENU(MNU_FIND, frmQuery::OnSearchReplace)
|
||||
EVT_MENU(MNU_UNDO, frmQuery::OnUndo)
|
||||
|
|
@ -1544,7 +1546,7 @@ void frmQuery::OnCopy(wxCommandEvent &ev)
|
|||
{
|
||||
if (obj == sqlResult)
|
||||
{
|
||||
sqlResult->Copy(false);
|
||||
sqlResult->Copy(0);
|
||||
break;
|
||||
}
|
||||
obj = obj->GetParent();
|
||||
|
|
@ -2011,6 +2013,9 @@ void frmQuery::OnLabelRightClick(wxGridEvent &event)
|
|||
xmenu->Append(MNU_DELETE, _("&Delete"), _("Delete selected rows."));
|
||||
xmenu->Append(MNU_SUMMARY_COL, _("Summary"), _("Summary selected cells."));
|
||||
xmenu->Append(MNU_COPY_INSERT, _("Copy Insert format"), _("Copy Insert format."));
|
||||
xmenu->Append(MNU_COPY_INLIST, _("IN LIST format copy"), _("Copy In list format."));
|
||||
xmenu->Append(MNU_COPY_WHERELIST, _("WHERE LIST format copy"), _("Copy where list format."));
|
||||
|
||||
xmenu->Append(MNU_CLEAR_FILTER, _("Clear filter"), _("Clear filter"));
|
||||
|
||||
if ((rows.GetCount()))
|
||||
|
|
@ -2033,11 +2038,29 @@ void frmQuery::OnCopy_Insert(wxCommandEvent &ev)
|
|||
// if (currentControl() == sqlResult)
|
||||
{
|
||||
wxString s=wxT("Insert into format copy buffer.");
|
||||
sqlResult->Copy(true);
|
||||
sqlResult->Copy(1);
|
||||
SetStatusText(s, STATUSPOS_POS);
|
||||
}
|
||||
}
|
||||
void frmQuery::OnCellLeftDClick(wxGridEvent &event)
|
||||
void frmQuery::OnCopy_InList(wxCommandEvent& ev)
|
||||
{
|
||||
// if (currentControl() == sqlResult)
|
||||
{
|
||||
wxString s = wxT("In list format copy buffer.");
|
||||
sqlResult->Copy(2);
|
||||
SetStatusText(s, STATUSPOS_POS);
|
||||
}
|
||||
}
|
||||
void frmQuery::OnCopy_WhereList(wxCommandEvent& ev)
|
||||
{
|
||||
// if (currentControl() == sqlResult)
|
||||
{
|
||||
wxString s = wxT("Where list format copy buffer.");
|
||||
sqlResult->Copy(3);
|
||||
SetStatusText(s, STATUSPOS_POS);
|
||||
}
|
||||
}
|
||||
void frmQuery::OnCellLeftDClick(wxGridEvent &event)
|
||||
{
|
||||
int row=event.GetRow();
|
||||
int col=event.GetCol();
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
// App headers
|
||||
#include "pgAdmin3.h"
|
||||
#include <wx/file.h>
|
||||
#include <wx/regex.h>
|
||||
|
||||
#include "frm/frmMain.h"
|
||||
#include "frm/frmReport.h"
|
||||
|
|
@ -1222,6 +1223,59 @@ wxString reportCompareFactory::GetNodePath(wxTreeItemId node) {
|
|||
|
||||
return path;
|
||||
|
||||
}
|
||||
wxString reportCompareFactory::ApplyCompareOpts(wxString sql,int metatype) {
|
||||
if (sql.IsEmpty()) return "";
|
||||
bool no_comment = parent->getChoiceSelect(1);
|
||||
bool no_priv = parent->getChoiceSelect(0);
|
||||
if (no_comment) {
|
||||
int last = 0;
|
||||
while (last!=-1) {
|
||||
last = sql.Find("\nCOMMENT ON");
|
||||
int start = last;
|
||||
int end = -1;
|
||||
while (last!=-1) {
|
||||
last++;
|
||||
if (sql.Length() == last) { last = -1; continue; }
|
||||
wxChar c = sql.GetChar(last);
|
||||
if (c == '\'') {
|
||||
last++;
|
||||
if (sql.GetChar(last) == '\'') { continue; }
|
||||
if (sql.GetChar(last) == ';') { end = last; last = -1; continue; }
|
||||
|
||||
}
|
||||
};
|
||||
if (end != -1) {
|
||||
sql=sql.Remove(start, end - start+1);
|
||||
last = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (no_priv &&(metatype != PGM_ROLE)) {
|
||||
int last = 0;
|
||||
while (last != -1) {
|
||||
last = sql.Find("\nGRANT ");
|
||||
if (last==-1) last = sql.Find("\nREVOKE ");
|
||||
int start = last;
|
||||
int end = -1;
|
||||
while (last != -1) {
|
||||
last++;
|
||||
if (sql.Length() == last) { last = -1; continue; }
|
||||
wxChar c = sql.GetChar(last);
|
||||
if (c == ';') {
|
||||
end = last; last = -1;
|
||||
}
|
||||
};
|
||||
if (end != -1) {
|
||||
sql = sql.Remove(start, end - start + 1);
|
||||
last = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return sql;
|
||||
|
||||
}
|
||||
void reportCompareFactory::GetExpandedChildNodes(wxTreeItemId node, wxArrayString &expandedNodes, ArraySQL &list, time_t *t, wxBusyInfo *w, MyHashSQL &h_path,int lvl)
|
||||
{
|
||||
|
|
@ -1312,6 +1366,7 @@ void reportCompareFactory::GetExpandedChildNodes(wxTreeItemId node, wxArrayStrin
|
|||
if (obj ) {
|
||||
wxString s=obj->GetSql(browser);
|
||||
if (obj->GetMetaType()==PGM_SEQUENCE) s="";
|
||||
s = ApplyCompareOpts(s, obj->GetMetaType());
|
||||
int c=browser->GetChildrenCount(child,false);
|
||||
if (size>0) {
|
||||
wxString srcpath(path);
|
||||
|
|
@ -1492,6 +1547,7 @@ if (lastdb!=NULL) {
|
|||
wxMessageBox(msg, _("Error"), wxOK | wxICON_INFORMATION);
|
||||
return 0;
|
||||
}
|
||||
if (!parent->StartChoiceDialog()) return 0;
|
||||
time_t timer=wxDateTime::GetTimeNow();
|
||||
wxArrayString expandedNodes;
|
||||
ArraySQL list;
|
||||
|
|
@ -1499,12 +1555,14 @@ time_t timer=wxDateTime::GetTimeNow();
|
|||
|
||||
wxWindowDisabler disableAll;
|
||||
{
|
||||
#ifndef DEBUG
|
||||
wxBusyInfo waiting(wxString::Format(" Îáõîä èñõîäíîé ÁÄ Path = %s ,Ñòàðòîâûé îáúåêò = %s",
|
||||
browser->GetItemText(obj->GetServer()->GetId()).c_str(), obj->GetName().c_str(),parent));
|
||||
// Give the UI a chance to redraw
|
||||
wxSafeYield();
|
||||
wxMilliSleep(50);
|
||||
wxSafeYield();
|
||||
#endif
|
||||
// waiting->~wxBusyInfo();
|
||||
GetExpandedChildNodes(obj->GetId(),expandedNodes,list,&timer, NULL,h_path,0);
|
||||
}
|
||||
|
|
@ -1809,7 +1867,7 @@ std::wstring reportCompareFactory::printdiff(std::wstring str1, std::wstring str
|
|||
++it;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
wxFileName fn("D:\\PostgreSQL\\cmp.txt");
|
||||
wxFileName fn("cmp_debug.txt");
|
||||
fn.MakeAbsolute();
|
||||
|
||||
wxFile file(fn.GetFullPath(), wxFile::write);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "images/terminate_backend.pngc"
|
||||
#include "images/delete.pngc"
|
||||
#include "images/storedata.pngc"
|
||||
#include "images/sortfilterclear.pngc"
|
||||
#include "images/down.pngc"
|
||||
#include "images/up.pngc"
|
||||
|
||||
|
|
@ -83,6 +84,7 @@ BEGIN_EVENT_TABLE(frmStatus, pgFrame)
|
|||
EVT_MENU(MNU_TERMINATE, frmStatus::OnTerminateBtn)
|
||||
EVT_MENU(MNU_COMMIT, frmStatus::OnCommit)
|
||||
EVT_MENU(MNU_ROLLBACK, frmStatus::OnRollback)
|
||||
EVT_MENU(MNU_CLEAR_FILTER_SERVER_STATUS, frmStatus::OnClearFilter)
|
||||
EVT_COMBOBOX(CTL_LOGCBO, frmStatus::OnLoadLogfile)
|
||||
EVT_BUTTON(CTL_ROTATEBTN, frmStatus::OnRotateLogfile)
|
||||
|
||||
|
|
@ -91,6 +93,7 @@ BEGIN_EVENT_TABLE(frmStatus, pgFrame)
|
|||
EVT_TIMER(TIMER_STATUS_ID, frmStatus::OnRefreshStatusTimer)
|
||||
EVT_LIST_ITEM_SELECTED(CTL_STATUSLIST, frmStatus::OnSelStatusItem)
|
||||
EVT_LIST_ITEM_DESELECTED(CTL_STATUSLIST, frmStatus::OnSelStatusItem)
|
||||
EVT_LIST_ITEM_RIGHT_CLICK(CTL_STATUSLIST, frmStatus::OnRightClickStatusItem)
|
||||
EVT_LIST_COL_CLICK(CTL_STATUSLIST, frmStatus::OnSortStatusGrid)
|
||||
EVT_LIST_COL_RIGHT_CLICK(CTL_STATUSLIST, frmStatus::OnRightClickStatusGrid)
|
||||
EVT_LIST_COL_END_DRAG(CTL_STATUSLIST, frmStatus::OnChgColSizeStatusGrid)
|
||||
|
|
@ -219,6 +222,12 @@ frmStatus::frmStatus(frmMain *form, const wxString &_title, pgConn *conn) : pgFr
|
|||
initquery = wxT("SET log_statement='off';SET log_duration='off';SET log_min_duration_statement=-1;");
|
||||
connection->ExecuteVoid(initquery, false);
|
||||
}
|
||||
//pg_is_in_recovery()
|
||||
wxString v = connection->ExecuteScalar(wxT("select pg_is_in_recovery()"));
|
||||
|
||||
isrecovery = (v == wxT("t"));
|
||||
v = connection->ExecuteScalar(wxT("select current_setting('track_commit_timestamp')"));
|
||||
track_commit_timestamp = (v == wxT("on"));
|
||||
delete user;
|
||||
}
|
||||
|
||||
|
|
@ -314,6 +323,9 @@ frmStatus::frmStatus(frmMain *form, const wxString &_title, pgConn *conn) : pgFr
|
|||
toolBar->AddTool(MNU_COMMIT, wxEmptyString, *storedata_png_bmp, _("Commit transaction"), wxITEM_NORMAL);
|
||||
toolBar->AddTool(MNU_ROLLBACK, wxEmptyString, *delete_png_bmp, _("Rollback transaction"), wxITEM_NORMAL);
|
||||
toolBar->AddSeparator();
|
||||
toolBar->AddTool(MNU_CLEAR_FILTER_SERVER_STATUS, wxEmptyString, *sortfilterclear_png_bmp, _("Clear filter"), wxITEM_NORMAL);
|
||||
toolBar->AddSeparator();
|
||||
|
||||
cbLogfiles = new wxComboBox(toolBar, CTL_LOGCBO, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL,
|
||||
wxCB_READONLY | wxCB_DROPDOWN);
|
||||
toolBar->AddControl(cbLogfiles);
|
||||
|
|
@ -344,6 +356,7 @@ frmStatus::frmStatus(frmMain *form, const wxString &_title, pgConn *conn) : pgFr
|
|||
toolBar->EnableTool(MNU_TERMINATE, false);
|
||||
toolBar->EnableTool(MNU_COMMIT, false);
|
||||
toolBar->EnableTool(MNU_ROLLBACK, false);
|
||||
toolBar->EnableTool(MNU_CLEAR_FILTER_SERVER_STATUS, false);
|
||||
actionMenu->Enable(MNU_CANCEL, false);
|
||||
actionMenu->Enable(MNU_TERMINATE, false);
|
||||
actionMenu->Enable(MNU_COMMIT, false);
|
||||
|
|
@ -1024,7 +1037,7 @@ void frmStatus::AddLogPane()
|
|||
|
||||
// Add the log list
|
||||
logList = (ctlListView *)lstLog;
|
||||
|
||||
bgColor = logList->GetBackgroundColour();
|
||||
// We don't need this report (but we need the pane)
|
||||
// if server release is less than 8.0 or if server has no adminpack
|
||||
if (!(connection->BackendMinimumVersion(8, 0) &&
|
||||
|
|
@ -1640,10 +1653,22 @@ void frmStatus::OnRefreshStatusTimer(wxTimerEvent &event)
|
|||
q += wxT("false");
|
||||
}
|
||||
q += wxT("AS slowquery\n");
|
||||
if (connection->BackendMinimumVersion(9, 6))
|
||||
bool iswalsend = false;
|
||||
if (connection->BackendMinimumVersion(10, 0))
|
||||
{
|
||||
q += wxT(",wait_event_type,wait_event,v.heap_blks_total,v.heap_blks_vacuumed,v.heap_blks_scanned,v.phase\n");
|
||||
q += wxT("FROM pg_stat_activity p LEFT JOIN pg_stat_progress_vacuum v ON p.pid=v.pid ");
|
||||
q += wxT(",backend_type,wait_event_type,wait_event,v.heap_blks_total,v.heap_blks_vacuumed,v.heap_blks_scanned,v.phase\n");
|
||||
wxString xact="";
|
||||
if (!track_commit_timestamp)
|
||||
q += wxT(",coalesce(sl.xmin,sl.catalog_xmin)::text xmin_slot,':'||slot_name||'['||sl.slot_type||']' slotinfo,'LagSent:'||pg_size_pretty(pg_wal_lsn_diff(pg_last_wal_receive_lsn(),coalesce(confirmed_flush_lsn,restart_lsn)))||' LagXmin: -1'||' s' xminlag,-1 xminslotdelta\n");
|
||||
else if (isrecovery)
|
||||
q += wxT(",coalesce(sl.xmin,sl.catalog_xmin)::text xmin_slot,':'||slot_name||'['||sl.slot_type||']' slotinfo,'LagSent:'||pg_size_pretty(pg_wal_lsn_diff(pg_last_wal_receive_lsn(),coalesce(confirmed_flush_lsn,restart_lsn)))||' LagXmin: '||coalesce(extract(epoch from (pg_last_committed_xact()).timestamp - pg_xact_commit_timestamp(xmin))::int,0)||' s' xminlag,coalesce(extract(epoch from (pg_last_committed_xact()).timestamp - pg_xact_commit_timestamp(xmin))::int,0) xminslotdelta\n");
|
||||
else
|
||||
q += wxT(",coalesce(sl.xmin,sl.catalog_xmin)::text xmin_slot,':'||slot_name||'['||sl.slot_type||']' slotinfo,'LagSent:'||pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(),coalesce(confirmed_flush_lsn,restart_lsn)))||' LagXmin: '||coalesce(extract(epoch from (pg_last_committed_xact()).timestamp - pg_xact_commit_timestamp(xmin))::int,0)||' s' xminlag,coalesce(extract(epoch from (pg_last_committed_xact()).timestamp - pg_xact_commit_timestamp(xmin))::int,0) xminslotdelta\n");
|
||||
|
||||
q += wxT("FROM pg_stat_activity p LEFT JOIN pg_stat_progress_vacuum v ON p.pid=v.pid\n");
|
||||
q += wxT("LEFT JOIN pg_replication_slots sl ON p.pid=sl.active_pid ");
|
||||
iswalsend = true;
|
||||
//backend_type
|
||||
} else
|
||||
{
|
||||
q += wxT("FROM pg_stat_activity p ");
|
||||
|
|
@ -1666,12 +1691,14 @@ void frmStatus::OnRefreshStatusTimer(wxTimerEvent &event)
|
|||
while (!dataSet1->Eof())
|
||||
{
|
||||
pid = dataSet1->GetLong(wxT("pid"));
|
||||
wxString slinfo=wxEmptyString;
|
||||
if (iswalsend) {
|
||||
slinfo = dataSet1->GetVal(wxT("slotinfo"));
|
||||
}
|
||||
// Update the UI
|
||||
if (pid != backend_pid)
|
||||
{
|
||||
pids.Add(pid);
|
||||
// Add the query content to the queries array
|
||||
queries.Add(dataSet1->GetVal(wxT("query")));
|
||||
|
||||
|
||||
if (row >= statusList->GetItemCount())
|
||||
{
|
||||
|
|
@ -1705,7 +1732,7 @@ void frmStatus::OnRefreshStatusTimer(wxTimerEvent &event)
|
|||
str.Printf(wxT("%s %5.2f%%"), phase, proc);
|
||||
app_name=str;
|
||||
}
|
||||
|
||||
if (!slinfo.IsEmpty()) app_name += slinfo;
|
||||
}
|
||||
int colpos = 1;
|
||||
if (connection->BackendMinimumVersion(8, 5))
|
||||
|
|
@ -1735,7 +1762,9 @@ void frmStatus::OnRefreshStatusTimer(wxTimerEvent &event)
|
|||
if (connection->BackendMinimumVersion(9, 4))
|
||||
{
|
||||
statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("backend_xid")));
|
||||
statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("backend_xmin")));
|
||||
if (!slinfo.IsEmpty()) statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("xmin_slot")));
|
||||
else
|
||||
statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("backend_xmin")));
|
||||
}
|
||||
if (connection->BackendMinimumVersion(9, 6))
|
||||
{
|
||||
|
|
@ -1745,7 +1774,11 @@ void frmStatus::OnRefreshStatusTimer(wxTimerEvent &event)
|
|||
}
|
||||
|
||||
statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("blockedby")));
|
||||
statusList->SetItem(row, colpos, qry);
|
||||
if (!slinfo.IsEmpty()) {
|
||||
statusList->SetItem(row, colpos, dataSet1->GetVal(wxT("xminlag")));
|
||||
}
|
||||
else
|
||||
statusList->SetItem(row, colpos, qry);
|
||||
|
||||
// Colorize the new line
|
||||
if (viewMenu->IsChecked(MNU_HIGHLIGHTSTATUS))
|
||||
|
|
@ -1771,11 +1804,46 @@ void frmStatus::OnRefreshStatusTimer(wxTimerEvent &event)
|
|||
blocked += dataSet1->GetVal(wxT("blockedby"));
|
||||
blocked += wxT(",");
|
||||
}
|
||||
if (!slinfo.IsEmpty()) {
|
||||
// walsender
|
||||
long xmindelta = dataSet1->GetLong(wxT("xminslotdelta"));
|
||||
|
||||
if (xmindelta>=1800)
|
||||
statusList->SetItemBackgroundColour(row,wxColour(wxT("#FF8028"))); // orange
|
||||
else
|
||||
statusList->SetItemBackgroundColour(row, wxColour(settings->GetIdleProcessColour())); // idle
|
||||
}
|
||||
if (app_name.StartsWith(wxT("pgp-s super"))||app_name.StartsWith(wxT("pgp-s manager"))) statusList->SetItemBackgroundColour(row, wxColour(settings->GetIdleProcessColour())); // idle
|
||||
|
||||
}
|
||||
else
|
||||
statusList->SetItemBackgroundColour(row, *wxWHITE);
|
||||
|
||||
row++;
|
||||
// filter apply
|
||||
bool flt = false;
|
||||
for (int i = 0; i < filterColumn.size(); i++) {
|
||||
int col = filterColumn[i];
|
||||
wxListItem listitem;
|
||||
listitem.SetMask(wxLIST_MASK_TEXT);
|
||||
statusList->GetColumn(col, listitem);
|
||||
wxString label = listitem.GetText();
|
||||
wxString tabval=statusList->GetItemText(row, col);
|
||||
wxString fval = filterValue[i];
|
||||
if (label == _("Client")) {
|
||||
tabval = tabval.BeforeLast(':');
|
||||
fval = fval.BeforeLast(':');
|
||||
}
|
||||
if (tabval != fval) {
|
||||
flt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flt) {
|
||||
// Add the query content to the queries array
|
||||
queries.Add(dataSet1->GetVal(wxT("query")));
|
||||
pids.Add(pid);
|
||||
row++;
|
||||
}
|
||||
}
|
||||
dataSet1->MoveNext();
|
||||
}
|
||||
|
|
@ -2244,7 +2312,12 @@ void frmStatus::OnRefreshLogTimer(wxTimerEvent &event)
|
|||
if (isCurrent)
|
||||
{
|
||||
// check if the current logfile changed
|
||||
pgSet *set = connection->ExecuteSet(wxT("SELECT pg_file_length(") + connection->qtDbString(logfileName) + wxT(") AS len"));
|
||||
|
||||
pgSet* set;
|
||||
if ((connection->BackendMinimumVersion(10, 0)))
|
||||
set = connection->ExecuteSet(wxT("select size len from pg_stat_file(") + connection->qtDbString(logfileName) + wxT(")"));
|
||||
else
|
||||
set = connection->ExecuteSet(wxT("SELECT pg_file_length(") + connection->qtDbString(logfileName) + wxT(") AS len"));
|
||||
if (set)
|
||||
{
|
||||
newlen = set->GetLong(wxT("len"));
|
||||
|
|
@ -2257,10 +2330,24 @@ void frmStatus::OnRefreshLogTimer(wxTimerEvent &event)
|
|||
}
|
||||
if (newlen > logfileLength)
|
||||
{
|
||||
|
||||
long lastrow = logList->GetItemCount();
|
||||
bool remote = lastrow-1 == logList->GetFocusedItem();
|
||||
statusBar->SetStatusText(_("Refreshing log list."));
|
||||
addLogFile(logfileName, logfileTimestamp, newlen, logfileLength, false);
|
||||
statusBar->SetStatusText(_("Done."));
|
||||
|
||||
if (bgColor == logList->GetBackgroundColour()) bgColor = wxColour("#afafaf"); else
|
||||
{
|
||||
bgColor = logList->GetBackgroundColour();
|
||||
}
|
||||
if (remote) {
|
||||
//logList->Select(lastrow - 1,false);
|
||||
//logList->SetScrollPos(wxGA_VERTICAL, logList->GetItemCount() - 1, true);
|
||||
//logList->Select(logList->GetItemCount() - 1);
|
||||
logList->Focus(logList->GetItemCount() - 1);
|
||||
|
||||
//logList->Show
|
||||
}
|
||||
// as long as there was new data, the logfile is probably the current
|
||||
// one so we don't need to check for rotation
|
||||
return;
|
||||
|
|
@ -2344,7 +2431,13 @@ void frmStatus::checkConnection()
|
|||
|
||||
void frmStatus::addLogFile(wxDateTime *dt, bool skipFirst)
|
||||
{
|
||||
pgSet *set = connection->ExecuteSet(
|
||||
pgSet* set;
|
||||
if (settings->GetASUTPstyle()) {
|
||||
set = connection->ExecuteSet(
|
||||
wxT("select current_setting('log_directory')||'/'||name filename,modification filetime,size len\n")
|
||||
wxT(" FROM pg_ls_logdir() where modification = '") + DateToAnsiStr(*dt) + wxT("'::timestamp"));
|
||||
} else
|
||||
set = connection->ExecuteSet(
|
||||
wxT("SELECT filetime, filename, pg_file_length(filename) AS len ")
|
||||
wxT(" FROM pg_logdir_ls() AS A(filetime timestamp, filename text) ")
|
||||
wxT(" WHERE filetime = '") + DateToAnsiStr(*dt) + wxT("'::timestamp"));
|
||||
|
|
@ -2395,11 +2488,12 @@ void frmStatus::addLogFile(const wxString &filename, const wxDateTime timestamp,
|
|||
else
|
||||
line = savedPartialLine;
|
||||
}
|
||||
|
||||
wxString funcname = "pg_read_file(";
|
||||
if (!settings->GetASUTPstyle()) funcname = "pg_file_read(";
|
||||
while (len > read)
|
||||
{
|
||||
statusBar->SetStatusText(_("Reading log from server..."));
|
||||
pgSet *set = connection->ExecuteSet(wxT("SELECT pg_file_read(") +
|
||||
pgSet *set = connection->ExecuteSet(wxT("SELECT ") + funcname +
|
||||
connection->qtDbString(filename) + wxT(", ") + NumToStr(read) + wxT(", 50000)"));
|
||||
if (!set)
|
||||
{
|
||||
|
|
@ -2417,10 +2511,13 @@ void frmStatus::addLogFile(const wxString &filename, const wxDateTime timestamp,
|
|||
read += strlen(raw);
|
||||
|
||||
wxString str;
|
||||
if (wxString(wxString(raw, wxConvLibc).wx_str(), wxConvUTF8).Len() > 0)
|
||||
str = line + wxString(wxString(raw, wxConvLibc).wx_str(), wxConvUTF8);
|
||||
else
|
||||
str = line + wxTextBuffer::Translate(wxString(raw, set->GetConversion()), wxTextFileType_Unix);
|
||||
str = line + wxTextBuffer::Translate(wxString(raw, set->GetConversion()), wxTextFileType_Unix);
|
||||
//if (wxString(wxString(raw, wxConvLibc).wx_str(), wxConvUTF8).Len() > 0)
|
||||
// str = line + wxString(wxString(raw, wxConvLibc).wx_str(), wxConvUTF8);
|
||||
//else {
|
||||
// str = line + wxTextBuffer::Translate(wxString(raw, set->GetConversion()), wxTextFileType_Unix);
|
||||
//}
|
||||
|
||||
|
||||
delete set;
|
||||
|
||||
|
|
@ -2563,8 +2660,11 @@ void frmStatus::addLogLine(const wxString &str, bool formatted, bool csv_log_for
|
|||
}
|
||||
}
|
||||
|
||||
if (!logFormatKnown)
|
||||
if (!logFormatKnown) {
|
||||
logList->AppendItem(-1, str);
|
||||
if (bgColor != logList->GetBackgroundColour()) logList->SetItemBackgroundColour(row, bgColor);
|
||||
|
||||
}
|
||||
else if ((!csv_log_format) && str.Find(':') < 0)
|
||||
{
|
||||
// Must be a continuation of a previous line.
|
||||
|
|
@ -2847,8 +2947,9 @@ void frmStatus::addLogLine(const wxString &str, bool formatted, bool csv_log_for
|
|||
|
||||
int pos = rest.Find(':');
|
||||
|
||||
if (pos < 0)
|
||||
if (pos < 0) {
|
||||
logList->InsertItem(row, rest, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
logList->InsertItem(row, rest.BeforeFirst(':'), -1);
|
||||
|
|
@ -2882,11 +2983,19 @@ int frmStatus::fillLogfileCombo()
|
|||
cbLogfiles->Append(_("Current log"));
|
||||
else
|
||||
count--;
|
||||
pgSet* set;
|
||||
if (settings->GetASUTPstyle())
|
||||
set = connection->ExecuteSet(
|
||||
wxT("select name filename,modification filetime\n")
|
||||
wxT(" FROM pg_ls_logdir() where name ~ '.csv'\n")
|
||||
wxT(" ORDER BY modification DESC"));
|
||||
|
||||
else set = connection->ExecuteSet(
|
||||
wxT("SELECT filename, filetime\n")
|
||||
wxT(" FROM pg_logdir_ls() AS A(filetime timestamp, filename text) \n")
|
||||
wxT(" ORDER BY filetime DESC"));
|
||||
|
||||
|
||||
pgSet *set = connection->ExecuteSet(
|
||||
wxT("SELECT filename, filetime\n")
|
||||
wxT(" FROM pg_logdir_ls() AS A(filetime timestamp, filename text)\n")
|
||||
wxT(" ORDER BY filetime DESC"));
|
||||
if (set)
|
||||
{
|
||||
if (set->NumRows() <= count)
|
||||
|
|
@ -3252,7 +3361,6 @@ void frmStatus::OnCommit(wxCommandEvent &event)
|
|||
OnSelXactItem(ev);
|
||||
}
|
||||
|
||||
|
||||
void frmStatus::OnRollback(wxCommandEvent &event)
|
||||
{
|
||||
long item = xactList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
|
||||
|
|
@ -3513,6 +3621,51 @@ void frmStatus::SetColumnImage(ctlListView *list, int col, int image)
|
|||
list->SetColumn(col, item);
|
||||
}
|
||||
|
||||
void frmStatus::OnRightClickStatusItem(wxListEvent& event)
|
||||
{
|
||||
int row = event.GetIndex();
|
||||
//wxString txt = event.GetText();
|
||||
|
||||
wxRect r;
|
||||
//statusList->GetItemRect(row, r);
|
||||
wxString ss = wxEmptyString;
|
||||
int col = -1;
|
||||
for (int cc = 0; cc < statusList->GetColumnCount();cc++) {
|
||||
statusList->GetSubItemRect(row, cc, r, wxLIST_RECT_BOUNDS);
|
||||
if (r.Contains(event.GetPoint())) {
|
||||
ss = wxString::Format("\rBounding rect of item %ld column %d is (%d, %d)-(%d, %d)", row,cc, r.x, r.y, r.x + r.width, r.y + r.height);
|
||||
col = cc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (col == -1) return;
|
||||
wxString val=statusList->GetItemText(row, col);
|
||||
wxString txt = wxString::Format("gettext=%s\r index=%d\r column=%d", val.c_str(), row, col);
|
||||
txt = txt + ss;
|
||||
|
||||
wxListItem listitem;
|
||||
listitem.SetMask(wxLIST_MASK_TEXT);
|
||||
statusList->GetColumn(col, listitem);
|
||||
wxString label = listitem.GetText()+" = "+val;
|
||||
//wxMessageBox(txt, "test", wxICON_WARNING | wxOK);
|
||||
wxString hint=label;
|
||||
if (filterColumn.size() > 0) hint = toolBar->GetToolShortHelp(MNU_CLEAR_FILTER_SERVER_STATUS)+"\n"+label;
|
||||
filterColumn.Add(col);
|
||||
filterValue.Add(val);
|
||||
toolBar->SetToolShortHelp(MNU_CLEAR_FILTER_SERVER_STATUS, hint);
|
||||
toolBar->EnableTool(MNU_CLEAR_FILTER_SERVER_STATUS, true);
|
||||
wxTimerEvent evt;
|
||||
OnRefreshStatusTimer(evt);
|
||||
}
|
||||
void frmStatus::OnClearFilter(wxCommandEvent& event) {
|
||||
toolBar->EnableTool(MNU_CLEAR_FILTER_SERVER_STATUS, false);
|
||||
toolBar->SetToolShortHelp(MNU_CLEAR_FILTER_SERVER_STATUS, "Clear filter");
|
||||
filterColumn.Clear();
|
||||
filterValue.Clear();
|
||||
wxTimerEvent evt;
|
||||
OnRefreshStatusTimer(evt);
|
||||
|
||||
}
|
||||
|
||||
void frmStatus::OnSortStatusGrid(wxListEvent &event)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,46 +21,53 @@ class frmMain;
|
|||
|
||||
class ctlListView : public wxListView
|
||||
{
|
||||
private:
|
||||
void OnSortGrid(wxListEvent& event);
|
||||
bool nosort; // åñëè êòî òî ïîëüçóåòñÿ SetItemData òî íå áóäåì ñîðòèðîâàòü òàêèå ctlListView
|
||||
int order, prev_col;
|
||||
public:
|
||||
ctlListView(wxWindow *p, int id, wxPoint pos, wxSize siz, long attr = 0);
|
||||
bool SetItemData(long item, long data) {
|
||||
nosort = true;
|
||||
return wxListView::SetItemData(item, data);
|
||||
}
|
||||
ctlListView(wxWindow* p, int id, wxPoint pos, wxSize siz, long attr = 0);
|
||||
long GetSelection();
|
||||
wxString GetText(long row, long col = 0);
|
||||
void CreateColumns(wxImageList* images, const wxString& left, const wxString& right, int leftSize = 60);
|
||||
void CreateColumns(wxImageList* images, const wxString& str1, const wxString& str2, const wxString& str3, int leftSize = 60);
|
||||
|
||||
void CreateColumns(wxImageList *images, const wxString &left, const wxString &right, int leftSize = 60);
|
||||
void CreateColumns(wxImageList *images, const wxString &str1, const wxString &str2, const wxString &str3, int leftSize = 60);
|
||||
void AddColumn(const wxString& text, int size = wxLIST_AUTOSIZE_USEHEADER, int format = wxLIST_FORMAT_LEFT);
|
||||
|
||||
void AddColumn(const wxString &text, int size = wxLIST_AUTOSIZE_USEHEADER, int format = wxLIST_FORMAT_LEFT);
|
||||
|
||||
long AppendItem(int icon, const wxString &val, const wxString &val2 = wxString(), const wxString &val3 = wxString(), const wxString &val4 = wxString());
|
||||
long AppendItem(const wxString &val, const wxString &val2 = wxString(), const wxString &val3 = wxString())
|
||||
long AppendItem(int icon, const wxString& val, const wxString& val2 = wxString(), const wxString& val3 = wxString(), const wxString& val4 = wxString());
|
||||
long AppendItem(const wxString& val, const wxString& val2 = wxString(), const wxString& val3 = wxString())
|
||||
{
|
||||
return AppendItem(PGICON_PROPERTY, val, val2, val3);
|
||||
}
|
||||
void AppendItem(const wxString &str, long l)
|
||||
void AppendItem(const wxString& str, long l)
|
||||
{
|
||||
AppendItem(str, NumToStr(l));
|
||||
}
|
||||
void AppendItem(const wxString &str, double d)
|
||||
void AppendItem(const wxString& str, double d)
|
||||
{
|
||||
AppendItem(str, NumToStr(d));
|
||||
}
|
||||
void AppendItem(const wxString &str, OID o)
|
||||
void AppendItem(const wxString& str, OID o)
|
||||
{
|
||||
AppendItem(str, NumToStr(o));
|
||||
}
|
||||
void AppendItem(const wxString &str, const wxDateTime &d)
|
||||
void AppendItem(const wxString& str, const wxDateTime& d)
|
||||
{
|
||||
AppendItem(str, DateToStr(d));
|
||||
}
|
||||
void AppendItem(const wxString &str, const wxLongLong &l)
|
||||
void AppendItem(const wxString& str, const wxLongLong& l)
|
||||
{
|
||||
AppendItem(str, l.ToString());
|
||||
}
|
||||
void AppendItem(const wxString &str, const wxULongLong &l)
|
||||
void AppendItem(const wxString& str, const wxULongLong& l)
|
||||
{
|
||||
AppendItem(str, l.ToString());
|
||||
}
|
||||
void AppendYesNoItem(const wxString &str, bool b)
|
||||
void AppendYesNoItem(const wxString& str, bool b)
|
||||
{
|
||||
AppendItem(str, BoolToYesNo(b));
|
||||
}
|
||||
|
|
@ -69,6 +76,7 @@ public:
|
|||
{
|
||||
DeleteItem(GetSelection());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public:
|
|||
{
|
||||
return false;
|
||||
}
|
||||
int Copy(bool gensql);
|
||||
int Copy(int gensql);
|
||||
|
||||
virtual bool CheckRowPresent(int row)
|
||||
{
|
||||
|
|
@ -55,7 +55,7 @@ public:
|
|||
wxString GetRowLabelValue( int row );
|
||||
void SetRowGroup(int row);
|
||||
GroupRows *grp;
|
||||
bool generatesql;
|
||||
int generatesql; // 0 -íåò, 1 - insert , 2 - in_list
|
||||
WX_DECLARE_STRING_HASH_MAP( int, ColKeySizeHashMap );
|
||||
|
||||
DECLARE_DYNAMIC_CLASS(ctlSQLGrid)
|
||||
|
|
|
|||
|
|
@ -107,7 +107,28 @@ public:
|
|||
currentObject = data;
|
||||
}
|
||||
bool CheckAlive();
|
||||
|
||||
//
|
||||
bool getChoiceSelect(int index) {
|
||||
for (size_t n = 0; n < choiceSelectOpts.GetCount(); n++) {
|
||||
if (choiceSelectOpts[n] == index) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool StartChoiceDialog() {
|
||||
choiceCmpOpts.Clear();
|
||||
choiceCmpOpts.Add("Priveleges ignore");
|
||||
choiceCmpOpts.Add("Comment ignore");
|
||||
wxMultiChoiceDialog dialog(this,
|
||||
wxT("A multi-choice convenience dialog"),
|
||||
wxT("Please select several compare options"),
|
||||
choiceCmpOpts);
|
||||
dialog.SetSelections(choiceSelectOpts);
|
||||
if (dialog.ShowModal() == wxID_OK) {
|
||||
choiceSelectOpts = dialog.GetSelections();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void execSelChange(wxTreeItemId item, bool currentNode);
|
||||
void Refresh(pgObject *data);
|
||||
void ExecDrop(bool cascaded);
|
||||
|
|
@ -203,6 +224,8 @@ private:
|
|||
long msgLevel;
|
||||
|
||||
bool m_refreshing;
|
||||
wxArrayString choiceCmpOpts;
|
||||
wxArrayInt choiceSelectOpts;
|
||||
|
||||
wxTreeItemId denyCollapseItem;
|
||||
pgObject *currentObject;
|
||||
|
|
|
|||
|
|
@ -212,6 +212,8 @@ private:
|
|||
void OnClear(wxCommandEvent &event);
|
||||
void OnSummary_Column(wxCommandEvent &event);
|
||||
void OnCopy_Insert(wxCommandEvent &event);
|
||||
void OnCopy_InList(wxCommandEvent& event);
|
||||
void OnCopy_WhereList(wxCommandEvent& event);
|
||||
void OnClear_Filter(wxCommandEvent &event);
|
||||
void OnSearchReplace(wxCommandEvent &event);
|
||||
void OnUndo(wxCommandEvent &event);
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ private:
|
|||
protected:
|
||||
//reportCompareFactory(menuFactoryList *list) : actionFactory(list) {}
|
||||
wxString reportCompareFactory::GetNodePath(wxTreeItemId node);
|
||||
wxString ApplyCompareOpts(wxString sql, int metatype);
|
||||
wxWindow *StartDialog(frmMain *form, pgObject *obj);
|
||||
void reportCompareFactory::GetExpandedChildNodes(wxTreeItemId node, wxArrayString &expandedNodes, ArraySQL &list,time_t *t,wxBusyInfo *w, MyHashSQL &h_path,int lvl);
|
||||
std::wstring reportCompareFactory::printdiff(std::wstring str1, std::wstring str2 );
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ enum
|
|||
MNU_COMMIT,
|
||||
MNU_ROLLBACK,
|
||||
MNU_COPY_QUERY,
|
||||
MNU_CLEAR_FILTER_SERVER_STATUS,
|
||||
MNU_COPY_QUERY_PLAN,
|
||||
MNU_HIGHLIGHTSTATUS,
|
||||
MNU_QUERYSTATEVERBOSE,
|
||||
|
|
@ -122,9 +123,10 @@ private:
|
|||
|
||||
long backend_pid;
|
||||
int wait_event_type_col;
|
||||
|
||||
bool isrecovery,track_commit_timestamp;
|
||||
bool loaded;
|
||||
long logfileLength;
|
||||
wxColour bgColor;
|
||||
|
||||
int currentPane;
|
||||
|
||||
|
|
@ -157,6 +159,8 @@ private:
|
|||
wxMenu *querystatePopupMenu;
|
||||
wxString queryplan;
|
||||
wxArrayString queries;
|
||||
wxArrayInt filterColumn;
|
||||
wxArrayString filterValue;
|
||||
|
||||
int statusColWidth[12], lockColWidth[10], xactColWidth[5], querystateColWidth[5];
|
||||
|
||||
|
|
@ -198,6 +202,7 @@ private:
|
|||
|
||||
void SetColumnImage(ctlListView *list, int col, int image);
|
||||
void OnSortStatusGrid(wxListEvent &event);
|
||||
void OnRightClickStatusItem(wxListEvent& event);
|
||||
void OnSortLockGrid(wxListEvent &event);
|
||||
void OnSortXactGrid(wxListEvent &event);
|
||||
|
||||
|
|
@ -237,6 +242,7 @@ private:
|
|||
void OnRotateLogfile(wxCommandEvent &event);
|
||||
void OnCommit(wxCommandEvent &event);
|
||||
void OnRollback(wxCommandEvent &event);
|
||||
void OnClearFilter(wxCommandEvent& event);
|
||||
|
||||
void OnChangeDatabase(wxCommandEvent &ev);
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@ enum
|
|||
MNU_AUTOSELECTQUERY,
|
||||
MNU_SUMMARY_COL,
|
||||
MNU_COPY_INSERT,
|
||||
MNU_COPY_INLIST,
|
||||
MNU_COPY_WHERELIST,
|
||||
MNU_CLEAR_FILTER,
|
||||
MNU_AUTOROLLBACK,
|
||||
MNU_AUTOCOMMIT,
|
||||
|
|
|
|||
BIN
include/images/sortfilterclear.png
Normal file
BIN
include/images/sortfilterclear.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 495 B |
106
include/images/sortfilterclear.pngc
Normal file
106
include/images/sortfilterclear.pngc
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#ifndef SORTFILTERCLEAR_PNG_H
|
||||
#define SORTFILTERCLEAR_PNG_H
|
||||
|
||||
static const unsigned char sortfilterclear_png_data[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
|
||||
0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
|
||||
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,
|
||||
0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff,
|
||||
0x61, 0x00, 0x00, 0x01, 0xb6, 0x49, 0x44, 0x41,
|
||||
0x54, 0x78, 0xda, 0xa5, 0x93, 0x4b, 0x28, 0x04,
|
||||
0x71, 0x1c, 0xc7, 0xbf, 0x7f, 0xb4, 0xd2, 0xa2,
|
||||
0xbc, 0x72, 0x71, 0x20, 0x8f, 0x90, 0x76, 0xcb,
|
||||
0xc1, 0x23, 0xef, 0x94, 0x1c, 0xb6, 0x2c, 0x89,
|
||||
0x83, 0xc7, 0xd1, 0x23, 0x7b, 0x20, 0x07, 0xa5,
|
||||
0x1c, 0x70, 0x44, 0x39, 0x28, 0x5c, 0x5c, 0x48,
|
||||
0x49, 0xb9, 0x70, 0xd0, 0x2e, 0xa5, 0x24, 0xb6,
|
||||
0x75, 0x11, 0x21, 0xd6, 0xee, 0xc5, 0x23, 0x9b,
|
||||
0x57, 0xb1, 0xe6, 0xb1, 0x3b, 0xf3, 0x37, 0x33,
|
||||
0x1a, 0x8d, 0xb5, 0x56, 0xda, 0xa9, 0x5f, 0xd3,
|
||||
0x6f, 0xfe, 0xf3, 0xf9, 0xf4, 0xfd, 0xff, 0x66,
|
||||
0xfe, 0x04, 0x61, 0x5e, 0x64, 0x71, 0x69, 0x97,
|
||||
0x9e, 0x5f, 0xbc, 0xc1, 0xeb, 0x15, 0xfe, 0x05,
|
||||
0xea, 0xf5, 0x91, 0xc8, 0xcd, 0x89, 0x05, 0x19,
|
||||
0x1d, 0xdf, 0xa6, 0x96, 0xbe, 0x52, 0x44, 0xb2,
|
||||
0x31, 0x60, 0xdf, 0x28, 0xfc, 0x7e, 0x01, 0xa2,
|
||||
0x28, 0x4a, 0x77, 0x11, 0x82, 0x20, 0x28, 0xfd,
|
||||
0x67, 0xf9, 0xe1, 0xf3, 0x09, 0x10, 0x44, 0x01,
|
||||
0xf1, 0x89, 0x3a, 0xa4, 0xa6, 0xeb, 0x31, 0x33,
|
||||
0x7b, 0xf0, 0x99, 0xc0, 0xe5, 0xe6, 0xd1, 0xd9,
|
||||
0x5c, 0x02, 0xef, 0x4d, 0x14, 0x5e, 0x9f, 0x7d,
|
||||
0x60, 0x59, 0x1f, 0x38, 0x8e, 0x07, 0x2b, 0x17,
|
||||
0x2b, 0x17, 0x07, 0x86, 0xe1, 0xc1, 0xf1, 0x3c,
|
||||
0x62, 0xe2, 0x22, 0x50, 0x50, 0x9a, 0x0c, 0xdb,
|
||||
0xfe, 0x15, 0x32, 0x33, 0x74, 0x20, 0x72, 0x1c,
|
||||
0x55, 0xd2, 0x66, 0x2e, 0xc2, 0x93, 0x9b, 0xe2,
|
||||
0xf9, 0x81, 0x51, 0x80, 0xbf, 0xe0, 0x8e, 0xf6,
|
||||
0x0a, 0x42, 0xd4, 0x3d, 0xa9, 0x92, 0x16, 0x53,
|
||||
0x21, 0x6e, 0xcf, 0x38, 0x3c, 0xdc, 0xbf, 0x83,
|
||||
0x79, 0x67, 0x43, 0xc2, 0xca, 0x10, 0xb5, 0x83,
|
||||
0x51, 0x25, 0xe6, 0x3a, 0x03, 0x9c, 0x87, 0x2f,
|
||||
0xf0, 0xdc, 0x79, 0xc1, 0x48, 0x09, 0xa2, 0xf5,
|
||||
0x04, 0x86, 0xb2, 0x14, 0x6c, 0xdb, 0x5d, 0xdf,
|
||||
0xe0, 0x1f, 0x02, 0xad, 0xc4, 0x32, 0xdf, 0xad,
|
||||
0xf4, 0x73, 0x0d, 0x0b, 0xc8, 0x36, 0x24, 0xe0,
|
||||
0xd4, 0xe3, 0xf9, 0x82, 0x1f, 0xd3, 0xb2, 0xa8,
|
||||
0xbc, 0x96, 0x74, 0xed, 0x24, 0x24, 0xd8, 0x27,
|
||||
0xea, 0x1f, 0xdc, 0xa0, 0xcd, 0xb5, 0x46, 0xe4,
|
||||
0x75, 0xd5, 0x28, 0xbd, 0x7d, 0x72, 0x03, 0x56,
|
||||
0x87, 0x13, 0xd3, 0x53, 0xa6, 0x6f, 0x70, 0xd0,
|
||||
0x04, 0xaa, 0xa0, 0xb1, 0xa6, 0x00, 0xb6, 0xb5,
|
||||
0x4b, 0x0c, 0x58, 0x7b, 0x95, 0x67, 0xe3, 0xad,
|
||||
0xd3, 0x18, 0x59, 0xe9, 0x87, 0x16, 0x0e, 0x29,
|
||||
0x30, 0x95, 0xe7, 0x62, 0x73, 0xf5, 0x5c, 0x1a,
|
||||
0x22, 0x87, 0x31, 0xc7, 0xd0, 0xd7, 0x9a, 0x16,
|
||||
0x56, 0x04, 0x94, 0xd2, 0x7c, 0x42, 0xc8, 0x69,
|
||||
0xa0, 0xa0, 0xbe, 0x24, 0x1b, 0xeb, 0xcb, 0x27,
|
||||
0xd2, 0x10, 0x79, 0x4c, 0x1c, 0x8f, 0x84, 0x14,
|
||||
0x18, 0x25, 0xc1, 0x51, 0xa0, 0x60, 0x78, 0xb0,
|
||||
0x0a, 0x7b, 0x5b, 0x6e, 0x54, 0x0e, 0x37, 0xfd,
|
||||
0x7f, 0x0b, 0x73, 0xf3, 0x3b, 0xca, 0xf9, 0x50,
|
||||
0x01, 0x19, 0x96, 0xff, 0xfb, 0x9e, 0xee, 0xea,
|
||||
0xe0, 0x43, 0x94, 0x52, 0x14, 0x4b, 0x29, 0xec,
|
||||
0x5a, 0x49, 0xe0, 0x8b, 0xbf, 0xad, 0x91, 0x70,
|
||||
0x8f, 0xf3, 0x07, 0xda, 0x28, 0x0c, 0xf1, 0xdd,
|
||||
0xa4, 0x8c, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x49,
|
||||
0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
|
||||
};
|
||||
|
||||
#include "wx/mstream.h"
|
||||
|
||||
static wxImage *sortfilterclear_png_img()
|
||||
{
|
||||
if (!wxImage::FindHandler(wxT("PNG file")))
|
||||
wxImage::AddHandler(new wxPNGHandler());
|
||||
static wxImage *img_sortfilterclear_png = new wxImage();
|
||||
if (!img_sortfilterclear_png || !img_sortfilterclear_png->IsOk())
|
||||
{
|
||||
wxMemoryInputStream img_sortfilterclear_pngIS(sortfilterclear_png_data, sizeof(sortfilterclear_png_data));
|
||||
img_sortfilterclear_png->LoadFile(img_sortfilterclear_pngIS, wxBITMAP_TYPE_PNG);
|
||||
}
|
||||
return img_sortfilterclear_png;
|
||||
}
|
||||
#define sortfilterclear_png_img sortfilterclear_png_img()
|
||||
|
||||
static wxBitmap *sortfilterclear_png_bmp()
|
||||
{
|
||||
static wxBitmap *bmp_sortfilterclear_png;
|
||||
if (!bmp_sortfilterclear_png || !bmp_sortfilterclear_png->IsOk())
|
||||
bmp_sortfilterclear_png = new wxBitmap(*sortfilterclear_png_img);
|
||||
return bmp_sortfilterclear_png;
|
||||
}
|
||||
#define sortfilterclear_png_bmp sortfilterclear_png_bmp()
|
||||
|
||||
static wxIcon *sortfilterclear_png_ico()
|
||||
{
|
||||
static wxIcon *ico_sortfilterclear_png;
|
||||
if (!ico_sortfilterclear_png || !ico_sortfilterclear_png->IsOk())
|
||||
{
|
||||
ico_sortfilterclear_png = new wxIcon();
|
||||
ico_sortfilterclear_png->CopyFromBitmap(*sortfilterclear_png_bmp);
|
||||
}
|
||||
return ico_sortfilterclear_png;
|
||||
}
|
||||
#define sortfilterclear_png_ico sortfilterclear_png_ico()
|
||||
|
||||
#endif // SORTFILTERCLEAR_PNG_H
|
||||
|
|
@ -60,8 +60,8 @@
|
|||
// Supported server minimum and maximum values.
|
||||
const short SERVER_MIN_VERSION_N = 0x0804;
|
||||
const wxString SERVER_MIN_VERSION_T = wxT("8.4");
|
||||
const short SERVER_MAX_VERSION_N = 0x0D00;
|
||||
const wxString SERVER_MAX_VERSION_T = wxT("13");
|
||||
const short SERVER_MAX_VERSION_N = 0x0E00;
|
||||
const wxString SERVER_MAX_VERSION_T = wxT("14");
|
||||
// Supported Greenplum Database and Greenplum HAWQ minimum and maximum values.
|
||||
const short GP_MIN_VERSION_N = 0x0802;
|
||||
const wxString GP_MIN_VERSION_T = wxT("8.2");
|
||||
|
|
|
|||
|
|
@ -287,6 +287,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
bool HasPgstatindex();
|
||||
bool HasPgcheckindex();
|
||||
|
||||
protected:
|
||||
void ReadColumnDetails();
|
||||
|
|
@ -345,6 +346,13 @@ public:
|
|||
bool CheckEnable(pgObject *obj);
|
||||
bool CheckChecked(pgObject *obj);
|
||||
};
|
||||
class executePgcheckindexFactory : public contextActionFactory
|
||||
{
|
||||
public:
|
||||
executePgcheckindexFactory(menuFactoryList* list, wxMenu* mnu, ctlMenuToolbar* toolbar);
|
||||
wxWindow* StartDialog(frmMain* form, pgObject* obj);
|
||||
bool CheckEnable(pgObject* obj);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -269,6 +269,7 @@ public:
|
|||
|
||||
virtual void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0) = 0;
|
||||
virtual void ShowStatistics(frmMain *form, ctlListView *statistics);
|
||||
virtual void ShowStatisticsTables(frmMain* form, ctlListView* statistics, pgObject* obj);
|
||||
virtual void ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &where = wxEmptyString);
|
||||
virtual void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where = wxEmptyString);
|
||||
virtual pgObject *Refresh(ctlTree *browser, const wxTreeItemId item)
|
||||
|
|
|
|||
|
|
@ -81,6 +81,15 @@ public:
|
|||
{
|
||||
return del;
|
||||
}
|
||||
bool GetIsViaRoot() const
|
||||
{
|
||||
return publish_via_partition_root;
|
||||
}
|
||||
void iSetIsViaRoot(const bool b)
|
||||
{
|
||||
publish_via_partition_root = b;
|
||||
}
|
||||
|
||||
wxString GetStrOper() const
|
||||
{
|
||||
wxString s = wxT("");
|
||||
|
|
@ -115,7 +124,7 @@ public:
|
|||
|
||||
private:
|
||||
wxString tables, version;
|
||||
bool all,ins,upd,del;
|
||||
bool all,ins,upd,del, publish_via_partition_root;
|
||||
};
|
||||
|
||||
class pgPublicationCollection : public pgDatabaseObjCollection
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ enum
|
|||
FEATURE_RELOAD_CONF,
|
||||
FEATURE_PGSTATTUPLE,
|
||||
FEATURE_PGSTATINDEX,
|
||||
FEATURE_PGCHECKINDEX,
|
||||
FEATURE_FUNCTION_DEFAULTS,
|
||||
FEATURE_LAST
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@
|
|||
#define VERSION_H
|
||||
|
||||
// Application Versions
|
||||
#define VERSION_STR wxT("1.25.0 Dev ASUTP version with support PG12")
|
||||
#define VERSION_NUM 1,25,0,0
|
||||
#define VERSION_PACKAGE 1.25.0-dev
|
||||
#define VERSION_STR wxT("1.26 Dev ASUTP support PG12")
|
||||
#define VERSION_NUM 1,26,0,0
|
||||
#define VERSION_PACKAGE 1.26.0-dev
|
||||
|
||||
#define PRERELEASE 1
|
||||
// #define BUILD "..."
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@
|
|||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
|
|
@ -158,6 +158,9 @@
|
|||
<IncludePath>.\wxwidgets\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);wxwidgets\lib</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_(3.0)|x64'">
|
||||
<PreBuildEventUseInBuild>false</PreBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<PreBuildEvent>
|
||||
<Message>Extracting source code repository version</Message>
|
||||
|
|
@ -479,7 +482,7 @@
|
|||
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\Debug/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<BrowseInformation>false</BrowseInformation>
|
||||
<BrowseInformationFile>.\Debug/</BrowseInformationFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
|
|
@ -491,10 +494,9 @@
|
|||
<AdditionalIncludeDirectories>$(WXWIN)/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>wxbase30ud.lib;wxbase30ud_xml.lib;wxbase30ud_net.lib;wxmsw30ud_adv.lib;wxmsw30ud_core.lib;wxmsw30ud_html.lib;wxmsw30ud_aui.lib;wxregexud.lib;wxpngd.lib;wxzlibd.lib;wxjpegd.lib;wxtiffd.lib;wxmsw30ud_stc.lib;wxmsw30ud_xrc.lib;wxexpatd.lib;libeay32MD.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;oleaut32.lib;ole32.lib;shell32.lib;odbc32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>.\Debug/pgAdmin3.exe</OutputFile>
|
||||
<AdditionalDependencies>wxbase30ud.lib;wxbase30ud_xml.lib;wxbase30ud_net.lib;wxmsw30ud_adv.lib;wxmsw30ud_core.lib;wxmsw30ud_html.lib;wxmsw30ud_aui.lib;wxregexud.lib;wxpngd.lib;wxzlibd.lib;wxjpegd.lib;wxtiffd.lib;wxmsw30ud_stc.lib;wxmsw30ud_xrc.lib;wxexpatd.lib;libssh2.lib;libeay32MD.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;oleaut32.lib;ole32.lib;shell32.lib;odbc32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>$(OPENSSL)/lib/VC;$(WXWIN)/lib/vc_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(PROJECTDIR)/../libssh2/src/Release;$(OPENSSL)/lib/VC;$(WXWIN)/lib/vc_x64_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>libcd.lib;libcid.lib;msvcrt.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>.\Debug/pgAdmin3.pdb</ProgramDatabaseFile>
|
||||
|
|
@ -2236,6 +2238,7 @@
|
|||
<png2c Include="include\images\slsubscription2.png" />
|
||||
<png2c Include="include\images\slsubscriptions.png" />
|
||||
<png2c Include="include\images\sortfilter.png" />
|
||||
<png2c Include="include\images\sortfilterclear.png" />
|
||||
<png2c Include="include\images\splash.png" />
|
||||
<png2c Include="include\images\sql-16.png" />
|
||||
<png2c Include="include\images\sql-32.png" />
|
||||
|
|
|
|||
|
|
@ -4435,6 +4435,9 @@
|
|||
<png2c Include="include\images\jobrun.png">
|
||||
<Filter>include\images</Filter>
|
||||
</png2c>
|
||||
<png2c Include="include\images\sortfilterclear.png">
|
||||
<Filter>include\images</Filter>
|
||||
</png2c>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="pgAdmin3.rc" />
|
||||
|
|
|
|||
|
|
@ -13,4 +13,14 @@
|
|||
<LocalDebuggerCommandArguments>-s mi -q</LocalDebuggerCommandArguments>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_(3.0)|x64'">
|
||||
<LocalDebuggerCommandArguments>
|
||||
</LocalDebuggerCommandArguments>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_(3.0)|x64'">
|
||||
<LocalDebuggerCommandArguments>
|
||||
</LocalDebuggerCommandArguments>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -509,7 +509,7 @@ bool pgProcedure::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded)
|
|||
if (!GetConnection()->BackendMinimumVersion(11, 0))
|
||||
return pgFunction::DropObject(frame, browser, cascaded);
|
||||
|
||||
wxString sql = wxT("DROP PROCEDURE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier();
|
||||
wxString sql = wxT("DROP PROCEDURE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier() + wxT("(") + this->GetArgSigList() + wxT(")");;
|
||||
return GetDatabase()->ExecuteVoid(sql);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -473,6 +473,36 @@ bool pgIndexBase::HasPgstatindex()
|
|||
return GetConnection()->HasFeature(FEATURE_PGSTATINDEX);
|
||||
}
|
||||
|
||||
bool pgIndexBase::HasPgcheckindex()
|
||||
{
|
||||
return GetConnection()->HasFeature(FEATURE_PGCHECKINDEX);
|
||||
}
|
||||
|
||||
executePgcheckindexFactory::executePgcheckindexFactory(menuFactoryList* list, wxMenu* mnu, ctlMenuToolbar* toolbar) : contextActionFactory(list)
|
||||
{
|
||||
mnu->Append(id, _("Check Btree index"), _("Check Btree index function bt_index_parent_check(oid,true)"));
|
||||
}
|
||||
|
||||
|
||||
wxWindow* executePgcheckindexFactory::StartDialog(frmMain* form, pgObject* obj)
|
||||
{
|
||||
pgIndexBase* i = (pgIndexBase*)obj;
|
||||
form->StartMsg(_("Check Btree index "+i->GetName()+" "));
|
||||
wxString sql = "SELECT bt_index_parent_check("+i->GetOidStr()+",true);";
|
||||
i->GetConnection()->ExecuteVoid(sql);
|
||||
form->EndMsg(true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool executePgcheckindexFactory::CheckEnable(pgObject* obj)
|
||||
{
|
||||
|
||||
return obj &&
|
||||
(obj->IsCreatedBy(indexFactory) || obj->IsCreatedBy(primaryKeyFactory)
|
||||
|| obj->IsCreatedBy(uniqueFactory) || obj->IsCreatedBy(excludeFactory)) && ((pgIndexBase*)obj)->GetIndexType()=="btree" &&
|
||||
((pgIndexBase*)obj)->HasPgcheckindex();
|
||||
}
|
||||
|
||||
executePgstatindexFactory::executePgstatindexFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list)
|
||||
{
|
||||
|
|
@ -757,4 +787,5 @@ void pgIndexBaseCollection::ShowStatistics(frmMain *form, ctlListView *statistic
|
|||
|
||||
delete stats;
|
||||
}
|
||||
statistics->SetColumnWidth(0, wxLIST_AUTOSIZE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@
|
|||
#include "agent/pgaSchedule.h"
|
||||
#include "agent/pgaStep.h"
|
||||
#include "schema/pgPartition.h"
|
||||
#include "utils/pgfeatures.h"
|
||||
|
||||
|
||||
int pgObject::GetType() const
|
||||
{
|
||||
|
|
@ -224,6 +226,120 @@ void pgObject::ShowStatistics(frmMain *form, ctlListView *statistics)
|
|||
{
|
||||
}
|
||||
|
||||
void pgObject::ShowStatisticsTables(frmMain* form, ctlListView* statistics, pgObject *obj)
|
||||
{
|
||||
wxLogInfo(wxT("Displaying statistics for tables on %s"), obj->GetSchema()->GetIdentifier().c_str());
|
||||
bool tabcoll = false;
|
||||
bool partcoll = false;
|
||||
bool onetable = false;
|
||||
if (IsCollection()) {
|
||||
wxString t = obj->GetFactory()->GetTypeName();
|
||||
if (t == ("Tables")
|
||||
//obj->IsCreatedBy(tableFactory)
|
||||
) tabcoll = true;
|
||||
if ( t == ("Partitions")) partcoll = true;
|
||||
}
|
||||
else onetable = true;
|
||||
bool hasSize = obj->GetConnection()->HasFeature(FEATURE_SIZE);
|
||||
|
||||
// Add the statistics view columns
|
||||
statistics->ClearAll();
|
||||
statistics->AddColumn(_("Table Name"));
|
||||
if (hasSize)
|
||||
statistics->AddColumn(_("Size"));
|
||||
if (obj->GetConnection()->GetIsPgProEnt()) statistics->AddColumn(_("CFS %"));
|
||||
statistics->AddColumn(_("Tuples inserted"));
|
||||
statistics->AddColumn(_("Tuples updated"));
|
||||
statistics->AddColumn(_("Tuples deleted"));
|
||||
if (obj->GetConnection()->BackendMinimumVersion(8, 3))
|
||||
{
|
||||
statistics->AddColumn(_("Tuples HOT updated"));
|
||||
statistics->AddColumn(_("Live tuples"));
|
||||
statistics->AddColumn(_("Dead tuples"));
|
||||
}
|
||||
if (obj->GetConnection()->BackendMinimumVersion(8, 2))
|
||||
{
|
||||
statistics->AddColumn(_("Last vacuum"));
|
||||
statistics->AddColumn(_("Last autovacuum"));
|
||||
statistics->AddColumn(_("Last analyze"));
|
||||
statistics->AddColumn(_("Last autoanalyze"));
|
||||
}
|
||||
if (obj->GetConnection()->BackendMinimumVersion(9, 1))
|
||||
{
|
||||
statistics->AddColumn(_("Vacuum counter"));
|
||||
statistics->AddColumn(_("Autovacuum counter"));
|
||||
statistics->AddColumn(_("Analyze counter"));
|
||||
statistics->AddColumn(_("Autoanalyze counter"));
|
||||
}
|
||||
|
||||
wxString sql = wxT("SELECT st.relname, n_tup_ins, n_tup_upd, n_tup_del");
|
||||
if (obj->GetConnection()->BackendMinimumVersion(8, 3))
|
||||
sql += wxT(", n_tup_hot_upd, n_live_tup, n_dead_tup");
|
||||
if (obj->GetConnection()->BackendMinimumVersion(8, 2))
|
||||
sql += wxT(", last_vacuum, last_autovacuum, last_analyze, last_autoanalyze");
|
||||
if (obj->GetConnection()->BackendMinimumVersion(9, 1))
|
||||
sql += wxT(", vacuum_count, autovacuum_count, analyze_count, autoanalyze_count");
|
||||
if (hasSize)
|
||||
sql += wxT(", pg_size_pretty(pg_relation_size(st.relid)")
|
||||
wxT(" + CASE WHEN cl.reltoastrelid = 0 THEN 0 ELSE pg_relation_size(cl.reltoastrelid) + COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=cl.reltoastrelid)::int8, 0) END")
|
||||
wxT(" + COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=st.relid)::int8, 0)) AS size");
|
||||
if (obj->GetConnection()->GetIsPgProEnt()) sql += wxT(",left((cfs_fragmentation(cl.oid)*100)::text,5)::text AS cfs_ratio");
|
||||
sql += wxT("\n FROM pg_stat_all_tables st")
|
||||
wxT(" JOIN pg_class cl on cl.oid=st.relid\n");
|
||||
if (partcoll) sql += wxT(" JOIN pg_inherits i ON (cl.oid = i.inhrelid) WHERE ");
|
||||
if (tabcoll) sql += wxT(" WHERE schemaname = ")+obj->qtDbString(obj->GetSchema()->GetName());
|
||||
if (partcoll) sql += wxT(" i.inhparent = ") + obj->GetOidStr();
|
||||
//+ obj->qtDbString(obj->GetSchema()->GetName()) + wxT(" AND i.inhparent = ") + obj->GetOidStr()
|
||||
if (onetable) sql += wxT("join (select t.relid::oid oid from pg_partition_tree(")+ (obj->GetOidStr())+wxT("::regclass) t where t.isleaf = 't') t on t.oid=cl.oid");
|
||||
|
||||
sql += wxT("\n ORDER BY relname");
|
||||
|
||||
pgSet* stats = obj->GetDatabase()->ExecuteSet(sql);
|
||||
|
||||
if (stats)
|
||||
{
|
||||
long pos = 0;
|
||||
int i;
|
||||
while (!stats->Eof())
|
||||
{
|
||||
i = 1;
|
||||
statistics->InsertItem(pos, stats->GetVal(wxT("relname")), PGICON_STATISTICS);
|
||||
if (hasSize)
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("size")));
|
||||
if (obj->GetConnection()->GetIsPgProEnt()) statistics->SetItem(pos, i++, stats->GetVal(wxT("cfs_ratio")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("n_tup_ins")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("n_tup_upd")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("n_tup_del")));
|
||||
if (obj->GetConnection()->BackendMinimumVersion(8, 3))
|
||||
{
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("n_tup_hot_upd")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("n_live_tup")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("n_dead_tup")));
|
||||
}
|
||||
if (obj->GetConnection()->BackendMinimumVersion(8, 2))
|
||||
{
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("last_vacuum")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("last_autovacuum")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("last_analyze")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("last_autoanalyze")));
|
||||
}
|
||||
if (obj->GetConnection()->BackendMinimumVersion(9, 1))
|
||||
{
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("vacuum_count")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("autovacuum_count")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("analyze_count")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("autoanalyze_count")));
|
||||
}
|
||||
stats->MoveNext();
|
||||
pos++;
|
||||
}
|
||||
|
||||
delete stats;
|
||||
}
|
||||
statistics->SetColumnWidth(0, wxLIST_AUTOSIZE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool pgObject::UpdateIcon(ctlTree *browser)
|
||||
{
|
||||
|
|
@ -452,6 +568,52 @@ void pgObject::CreateListColumns(ctlListView *list, const wxString &left, const
|
|||
list->AddColumn(right, list->GetSize().GetWidth() - 140);
|
||||
}
|
||||
|
||||
wxString GetClassTableName(int metatype) {
|
||||
switch (metatype)
|
||||
{
|
||||
case PGM_CONSTRAINT:
|
||||
return "pg_constraint";
|
||||
case PGM_FOREIGNKEY:
|
||||
return "pg_constraint";
|
||||
case PGM_PRIMARYKEY:
|
||||
return "pg_constraint";
|
||||
case PGM_UNIQUE:
|
||||
return "pg_constraint";
|
||||
case PGM_EXCLUDE:
|
||||
return "pg_constraint";
|
||||
case PGM_OPCLASS:
|
||||
return "pg_amop";
|
||||
case PGM_COLUMN:
|
||||
return "pg_attribute";
|
||||
case PGM_FUNCTION:
|
||||
return "pg_proc";
|
||||
case PGM_INDEX:
|
||||
return "pg_class";
|
||||
case PGM_TABLE:
|
||||
return "pg_class";
|
||||
case PGM_VIEW:
|
||||
return "pg_class";
|
||||
case PG_PARTITION:
|
||||
return "pg_class";
|
||||
case PGM_LANGUAGE:
|
||||
return "pg_language";
|
||||
case PGM_ROLE:
|
||||
return "pg_authid";
|
||||
case PGM_SCHEMA:
|
||||
return "pg_namespace";
|
||||
case PGM_SEQUENCE:
|
||||
return "pg_class";
|
||||
case PGM_TABLESPACE:
|
||||
return "pg_tablespace";
|
||||
case PGM_TRIGGER:
|
||||
return "pg_trigger";
|
||||
case PGM_OPFAMILY:
|
||||
return "pg_opfamily";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void pgObject::ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &wh)
|
||||
{
|
||||
|
|
@ -465,8 +627,12 @@ void pgObject::ShowDependencies(frmMain *form, ctlListView *Dependencies, const
|
|||
wxString where;
|
||||
if (wh.IsEmpty())
|
||||
{
|
||||
if(!GetOidStr().IsSameAs(wxT("0")))
|
||||
if (!GetOidStr().IsSameAs(wxT("0")))
|
||||
{
|
||||
wxString ts = GetClassTableName(GetMetaType());
|
||||
where = wxT(" WHERE dep.objid=") + GetOidStr();
|
||||
if (!ts.IsEmpty()) where += " and dep.classid IN(select oid from pg_class where oid=dep.classid and relname='" + ts + "')";
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
|
@ -510,25 +676,25 @@ void pgObject::ShowDependencies(frmMain *form, ctlListView *Dependencies, const
|
|||
wxT(" ELSE COALESCE(ext.extname,cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname,pub.prrelid::regclass::text)\n")
|
||||
wxT(" END AS refname,\n")
|
||||
wxT(" COALESCE(nsc.nspname, nso.nspname, nsp.nspname, nst.nspname, nsrw.nspname) AS nspname\n")
|
||||
wxT(" FROM pg_depend dep\n")
|
||||
wxT(" LEFT JOIN pg_class cl ON dep.refobjid=cl.oid\n")
|
||||
wxT(" LEFT JOIN pg_attribute att ON dep.refobjid=att.attrelid AND dep.refobjsubid=att.attnum\n")
|
||||
wxT(" FROM pg_depend dep join pg_class nc on nc.oid=dep.refclassid\n")
|
||||
wxT(" LEFT JOIN pg_class cl ON dep.refobjid=cl.oid and nc.relname='pg_class'\n")
|
||||
wxT(" LEFT JOIN pg_attribute att ON dep.refobjid=att.attrelid AND dep.refobjsubid=att.attnum and nc.relname='pg_attribute'\n")
|
||||
wxT(" LEFT JOIN pg_namespace nsc ON cl.relnamespace=nsc.oid\n")
|
||||
wxT(" LEFT JOIN pg_proc pr ON dep.refobjid=pr.oid\n")
|
||||
wxT(" LEFT JOIN pg_proc pr ON dep.refobjid=pr.oid and nc.relname='pg_proc'\n")
|
||||
wxT(" LEFT JOIN pg_namespace nsp ON pr.pronamespace=nsp.oid\n")
|
||||
wxT(" LEFT JOIN pg_trigger tg ON dep.refobjid=tg.oid\n")
|
||||
wxT(" LEFT JOIN pg_type ty ON dep.refobjid=ty.oid\n")
|
||||
wxT(" LEFT JOIN pg_trigger tg ON dep.refobjid=tg.oid and nc.relname='pg_trigger'\n")
|
||||
wxT(" LEFT JOIN pg_type ty ON dep.refobjid=ty.oid and nc.relname='pg_type'\n")
|
||||
wxT(" LEFT JOIN pg_namespace nst ON ty.typnamespace=nst.oid\n")
|
||||
wxT(" LEFT JOIN pg_constraint co ON dep.refobjid=co.oid\n")
|
||||
wxT(" LEFT JOIN pg_constraint co ON dep.refobjid=co.oid and nc.relname='pg_constraint'\n")
|
||||
wxT(" LEFT JOIN pg_class coc ON co.conrelid=coc.oid\n")
|
||||
wxT(" LEFT JOIN pg_namespace nso ON co.connamespace=nso.oid\n")
|
||||
wxT(" LEFT JOIN pg_rewrite rw ON dep.refobjid=rw.oid\n")
|
||||
wxT(" LEFT JOIN pg_rewrite rw ON dep.refobjid=rw.oid and nc.relname='pg_rewrite'\n")
|
||||
wxT(" LEFT JOIN pg_class clrw ON clrw.oid=rw.ev_class\n")
|
||||
wxT(" LEFT JOIN pg_namespace nsrw ON clrw.relnamespace=nsrw.oid\n")
|
||||
wxT(" LEFT JOIN pg_language la ON dep.refobjid=la.oid\n")
|
||||
wxT(" LEFT JOIN pg_namespace ns ON dep.refobjid=ns.oid\n")
|
||||
wxT(" LEFT JOIN pg_language la ON dep.refobjid=la.oid and nc.relname='pg_language'\n")
|
||||
wxT(" LEFT JOIN pg_namespace ns ON dep.refobjid=ns.oid and nc.relname='pg_namespace'\n")
|
||||
wxT(" LEFT JOIN pg_attrdef ad ON ad.adrelid=att.attrelid AND ad.adnum=att.attnum\n")
|
||||
wxT(" LEFT JOIN pg_publication_rel pub ON dep.objid=pub.oid AND pub.prpubid=dep.refobjid\n")
|
||||
wxT(" LEFT JOIN pg_publication_rel pub ON dep.objid=pub.oid AND pub.prpubid=dep.refobjid and nc.relname='pg_publication_rel'\n")
|
||||
wxT(" LEFT JOIN pg_extension ext ON ext.oid=dep.refobjid\n")
|
||||
+ where, wxT("refclassid"));
|
||||
|
||||
|
|
@ -627,9 +793,7 @@ void pgObject::ShowDependencies(frmMain *form, ctlListView *Dependencies, const
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void pgObject::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &wh)
|
||||
void pgObject::ShowDependents(frmMain* form, ctlListView* referencedBy, const wxString& wh)
|
||||
{
|
||||
if (this->IsCollection())
|
||||
return;
|
||||
|
|
@ -640,7 +804,11 @@ void pgObject::ShowDependents(frmMain *form, ctlListView *referencedBy, const wx
|
|||
|
||||
wxString where;
|
||||
if (wh.IsEmpty())
|
||||
{
|
||||
wxString ts = GetClassTableName(GetMetaType());
|
||||
where = wxT(" WHERE dep.refobjid=") + GetOidStr();
|
||||
if (!ts.IsEmpty()) where += " and dep.refclassid IN(select oid from pg_class where oid=dep.refclassid and relname='" + ts + "')";
|
||||
}
|
||||
else
|
||||
where = wh;
|
||||
/*
|
||||
|
|
@ -681,26 +849,26 @@ void pgObject::ShowDependents(frmMain *form, ctlListView *referencedBy, const wx
|
|||
wxT(" ELSE COALESCE(ext.extname,cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname,pub.prrelid::regclass::text) \n")
|
||||
wxT(" END AS refname,\n")
|
||||
wxT(" COALESCE(nsc.nspname, nso.nspname, nsp.nspname, nst.nspname, nsrw.nspname) AS nspname\n")
|
||||
wxT(" FROM pg_depend dep\n")
|
||||
wxT(" LEFT JOIN pg_class cl ON dep.objid=cl.oid\n")
|
||||
wxT(" LEFT JOIN pg_attribute att ON dep.objid=att.attrelid AND dep.objsubid=att.attnum\n")
|
||||
wxT(" FROM pg_depend dep join pg_class nc on nc.oid=dep.classid\n")
|
||||
wxT(" LEFT JOIN pg_class cl ON dep.objid=cl.oid and nc.relname='pg_class'\n")
|
||||
wxT(" LEFT JOIN pg_attribute att ON dep.objid=att.attrelid AND dep.objsubid=att.attnum and nc.relname='pg_attribute'\n")
|
||||
wxT(" LEFT JOIN pg_namespace nsc ON cl.relnamespace=nsc.oid\n")
|
||||
wxT(" LEFT JOIN pg_proc pr ON dep.objid=pr.oid\n")
|
||||
wxT(" LEFT JOIN pg_proc pr ON dep.objid=pr.oid and nc.relname='pg_proc'\n")
|
||||
wxT(" LEFT JOIN pg_namespace nsp ON pr.pronamespace=nsp.oid\n")
|
||||
wxT(" LEFT JOIN pg_trigger tg ON dep.objid=tg.oid\n")
|
||||
wxT(" LEFT JOIN pg_type ty ON dep.objid=ty.oid\n")
|
||||
wxT(" LEFT JOIN pg_trigger tg ON dep.objid=tg.oid and nc.relname='pg_trigger'\n")
|
||||
wxT(" LEFT JOIN pg_type ty ON dep.objid=ty.oid and nc.relname='pg_type'\n")
|
||||
wxT(" LEFT JOIN pg_namespace nst ON ty.typnamespace=nst.oid\n")
|
||||
wxT(" LEFT JOIN pg_constraint co ON dep.objid=co.oid\n")
|
||||
wxT(" LEFT JOIN pg_constraint co ON dep.objid=co.oid and nc.relname='pg_constraint'\n")
|
||||
wxT(" LEFT JOIN pg_class coc ON co.conrelid=coc.oid\n")
|
||||
wxT(" LEFT JOIN pg_namespace nso ON co.connamespace=nso.oid\n")
|
||||
wxT(" LEFT JOIN pg_rewrite rw ON dep.objid=rw.oid\n")
|
||||
wxT(" LEFT JOIN pg_rewrite rw ON dep.objid=rw.oid and nc.relname='pg_rewrite'\n")
|
||||
wxT(" LEFT JOIN pg_class clrw ON clrw.oid=rw.ev_class\n")
|
||||
wxT(" LEFT JOIN pg_namespace nsrw ON clrw.relnamespace=nsrw.oid\n")
|
||||
wxT(" LEFT JOIN pg_language la ON dep.objid=la.oid\n")
|
||||
wxT(" LEFT JOIN pg_namespace ns ON dep.objid=ns.oid\n")
|
||||
wxT(" LEFT JOIN pg_attrdef ad ON ad.oid=dep.objid\n")
|
||||
wxT(" LEFT JOIN pg_extension ext ON ext.oid=dep.objid\n")
|
||||
wxT(" LEFT JOIN pg_publication_rel pub ON dep.objid=pub.oid AND pub.prpubid=dep.refobjid\n")
|
||||
wxT(" LEFT JOIN pg_language la ON dep.objid=la.oid and nc.relname='pg_language'\n")
|
||||
wxT(" LEFT JOIN pg_namespace ns ON dep.objid=ns.oid and nc.relname='pg_namespace'\n")
|
||||
wxT(" LEFT JOIN pg_attrdef ad ON ad.oid=dep.objid and nc.relname='pg_attrdef'\n")
|
||||
wxT(" LEFT JOIN pg_extension ext ON ext.oid=dep.objid and nc.relname='pg_extension'\n")
|
||||
wxT(" LEFT JOIN pg_publication_rel pub ON dep.objid=pub.oid AND pub.prpubid=dep.refobjid and nc.relname='pg_publication_rel'\n")
|
||||
+ where, wxT("classid"));
|
||||
|
||||
/*
|
||||
|
|
@ -2055,7 +2223,7 @@ if (1==0) {
|
|||
pgaFactory *ff=oo->GetFactory();
|
||||
fn=ff->GetTypeName();
|
||||
fn=oo->GetName();
|
||||
if (fn==wxT("debug*history__0102")) {
|
||||
if (fn==wxT("debug**info_history2")) {
|
||||
fn=oo->GetFullName();
|
||||
pgaFactory *ff=oo->GetFactory();
|
||||
fn=ff->GetTypeName();
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ pgPartitionCollection::pgPartitionCollection(pgaFactory *factory, pgPartition *_
|
|||
}
|
||||
void pgPartitionCollection::ShowStatistics(frmMain *form, ctlListView *statistics)
|
||||
{
|
||||
ShowStatisticsTables(form, statistics, this);
|
||||
return;
|
||||
wxLogInfo(wxT("Displaying statistics for tables on %s"), GetSchema()->GetIdentifier().c_str());
|
||||
|
||||
bool hasSize = GetConnection()->HasFeature(FEATURE_SIZE);
|
||||
|
|
@ -104,6 +106,9 @@ void pgPartitionCollection::ShowStatistics(frmMain *form, ctlListView *statistic
|
|||
// Add the statistics view columns
|
||||
statistics->ClearAll();
|
||||
statistics->AddColumn(_("Table Name"));
|
||||
if (hasSize)
|
||||
statistics->AddColumn(_("Size"));
|
||||
if (GetConnection()->GetIsPgProEnt()) statistics->AddColumn(_("CFS %"));
|
||||
statistics->AddColumn(_("Tuples inserted"));
|
||||
statistics->AddColumn(_("Tuples updated"));
|
||||
statistics->AddColumn(_("Tuples deleted"));
|
||||
|
|
@ -127,8 +132,6 @@ void pgPartitionCollection::ShowStatistics(frmMain *form, ctlListView *statistic
|
|||
statistics->AddColumn(_("Analyze counter"));
|
||||
statistics->AddColumn(_("Autoanalyze counter"));
|
||||
}
|
||||
if (hasSize)
|
||||
statistics->AddColumn(_("Size"), 50);
|
||||
|
||||
wxString sql = wxT("SELECT st.relname, n_tup_ins, n_tup_upd, n_tup_del");
|
||||
if (GetConnection()->BackendMinimumVersion(8, 3))
|
||||
|
|
@ -141,7 +144,7 @@ void pgPartitionCollection::ShowStatistics(frmMain *form, ctlListView *statistic
|
|||
sql += wxT(", pg_size_pretty(pg_relation_size(st.relid)")
|
||||
wxT(" + CASE WHEN cl.reltoastrelid = 0 THEN 0 ELSE pg_relation_size(cl.reltoastrelid) + COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=cl.reltoastrelid)::int8, 0) END")
|
||||
wxT(" + COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=st.relid)::int8, 0)) AS size");
|
||||
|
||||
if (GetConnection()->GetIsPgProEnt()) sql += wxT(",left((cfs_fragmentation(cl.oid)*100)::text,5)::text AS cfs_ratio");
|
||||
sql += wxT("\n FROM pg_stat_all_tables st")
|
||||
wxT(" JOIN pg_class cl on cl.oid=st.relid\n")
|
||||
wxT(" JOIN pg_inherits i ON (cl.oid = i.inhrelid)")
|
||||
|
|
@ -156,11 +159,14 @@ void pgPartitionCollection::ShowStatistics(frmMain *form, ctlListView *statistic
|
|||
int i;
|
||||
while (!stats->Eof())
|
||||
{
|
||||
i = 4;
|
||||
i = 1;
|
||||
statistics->InsertItem(pos, stats->GetVal(wxT("relname")), PGICON_STATISTICS);
|
||||
statistics->SetItem(pos, 1, stats->GetVal(wxT("n_tup_ins")));
|
||||
statistics->SetItem(pos, 2, stats->GetVal(wxT("n_tup_upd")));
|
||||
statistics->SetItem(pos, 3, stats->GetVal(wxT("n_tup_del")));
|
||||
if (hasSize)
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("size")));
|
||||
if (GetConnection()->GetIsPgProEnt()) statistics->SetItem(pos, i++, stats->GetVal(wxT("cfs_ratio")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("n_tup_ins")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("n_tup_upd")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("n_tup_del")));
|
||||
if (GetConnection()->BackendMinimumVersion(8, 3))
|
||||
{
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("n_tup_hot_upd")));
|
||||
|
|
@ -181,14 +187,13 @@ void pgPartitionCollection::ShowStatistics(frmMain *form, ctlListView *statistic
|
|||
statistics->SetItem(pos, i++, stats->GetVal(wxT("analyze_count")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("autoanalyze_count")));
|
||||
}
|
||||
if (hasSize)
|
||||
statistics->SetItem(pos, i, stats->GetVal(wxT("size")));
|
||||
stats->MoveNext();
|
||||
pos++;
|
||||
}
|
||||
|
||||
delete stats;
|
||||
}
|
||||
statistics->SetColumnWidth(0, wxLIST_AUTOSIZE);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -254,7 +259,18 @@ pgObject *pgPartitionFactory::CreateObjects(pgCollection *coll, ctlTree *browser
|
|||
query += wxT(",case when lk.relation=rel.oid then 'AccessExclusiveLock' else pg_get_expr(rel.relpartbound, rel.oid) end \n AS partexp");
|
||||
query += wxT(",(select count(*)from pg_inherits ii where ii.inhparent=rel.oid)>0 AS ispartitioned");
|
||||
|
||||
|
||||
if (collection->GetDatabase()->BackendMinimumVersion(10, 0))
|
||||
{
|
||||
//query += wxT(",\n pg_get_statisticsobjdef(stat_ext.oid) AS stat_stmt");
|
||||
//query += wxT(",\nCASE WHEN stat_ext.stxowner<>rel.relowner then 'ALTER STATISTICS '||substring(pg_get_statisticsobjdef(stat_ext.oid) from 'ICS (.+?)\\s\\(')||' OWNER TO '||stat_ext.stxowner::regrole else null end AS alter_stmt");
|
||||
query += ",(select string_agg(pg_get_statisticsobjdef(stat_ext.oid)||CASE WHEN stat_ext.stxowner<>rl.relowner then E';\\nALTER STATISTICS '||substring(pg_get_statisticsobjdef(stat_ext.oid) from 'ICS (.+?)\\s')||' OWNER TO '||stat_ext.stxowner::regrole else '' end"
|
||||
;
|
||||
if (collection->GetDatabase()->BackendMinimumVersion(13, 0)) {
|
||||
query += "||CASE WHEN stat_ext.stxstattarget<>-1 then E';\\nALTER STATISTICS '||substring(pg_get_statisticsobjdef(stat_ext.oid) from 'ICS (.+?)\\s')||' SET STATISTICS '||stat_ext.stxstattarget else '' end";
|
||||
}
|
||||
query += ",E';\\n' order by stat_ext.stxrelid) stat_stmt from pg_class rl join pg_statistic_ext stat_ext on rl.oid=stat_ext.stxrelid where stat_ext.stxrelid=rel.oid) stat_stmt";
|
||||
}
|
||||
|
||||
query += wxT(" FROM pg_class rel\n")
|
||||
wxT(" JOIN pg_inherits i ON (rel.oid = i.inhrelid) \n")
|
||||
wxT(" LEFT JOIN pg_locks lk ON locktype='relation' and granted=true and mode='AccessExclusiveLock' and relation=rel.oid\n")
|
||||
|
|
@ -386,6 +402,11 @@ pgObject *pgPartitionFactory::CreateObjects(pgCollection *coll, ctlTree *browser
|
|||
table->iSetPartKeyDef(tables->GetVal(wxT("partkeydef")));
|
||||
table->iSetPartExp(tables->GetVal(wxT("partexp")));
|
||||
table->iSetIsPartitioned(tables->GetBool(wxT("ispartitioned")));
|
||||
wxString st = tables->GetVal(wxT("stat_stmt"));
|
||||
//wxString at = tables->GetVal(wxT("alter_stmt"));
|
||||
if (!st.IsEmpty()) if ((st.Right(1) != ";")) st = st + wxT(";\n");
|
||||
table->iSetStatExt(st);
|
||||
|
||||
}
|
||||
if (collection->GetConnection()->GetIsGreenplum())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -110,12 +110,21 @@ wxString pgPublication::GetSql(ctlTree *browser)
|
|||
if (!GetTablesStr().IsEmpty())
|
||||
sql += wxT("") + GetTablesStr();
|
||||
}
|
||||
if (GetIsIns()&&GetIsUpd()&&GetIsDel())
|
||||
if (GetIsIns()&&GetIsUpd()&&GetIsDel()&&!GetIsViaRoot())
|
||||
{
|
||||
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
sql += wxT("\n WITH (publish = '") + GetStrOper() + wxT("')");
|
||||
sql += wxT("\n WITH (");
|
||||
wxString opts = wxEmptyString;
|
||||
if (!(GetIsIns() && GetIsUpd() && GetIsDel())) opts =opts+ "publish = '" + GetStrOper() + wxT("'");
|
||||
if (GetIsViaRoot()) {
|
||||
if (!opts.IsEmpty()) opts += ",";
|
||||
opts += "publish_via_partition_root = on";
|
||||
}
|
||||
if (!opts.IsEmpty()) opts += ")";
|
||||
sql += opts;
|
||||
}
|
||||
|
||||
sql += wxT(";\n");
|
||||
|
|
@ -158,8 +167,13 @@ pgObject *pgPublicationFactory::CreateObjects(pgCollection *collection, ctlTree
|
|||
{
|
||||
wxString sql;
|
||||
pgPublication *publication = 0;
|
||||
wxString pg13="";
|
||||
if (collection->GetDatabase()->BackendMinimumVersion(13, 0)) {
|
||||
pg13 = ", pubviaroot";
|
||||
}
|
||||
|
||||
sql = wxT("select x.oid,x.pubname, pg_get_userbyid(x.pubowner) AS owner, x.puballtables, x.pubinsert, x.pubupdate, x.pubdelete, obj_description(x.oid,'pg_publication') AS comment, t.t")
|
||||
+ pg13 + wxT("\n")
|
||||
wxT(" FROM pg_publication x\n")
|
||||
wxT(" LEFT JOIN LATERAL (select string_agg(schemaname||'.'||tablename,', ') t from pg_publication_tables where pubname=x.pubname) t on true \n")
|
||||
wxT(" ")
|
||||
|
|
@ -183,6 +197,7 @@ pgObject *pgPublicationFactory::CreateObjects(pgCollection *collection, ctlTree
|
|||
publication->iSetIsDel(publications->GetBool(wxT("pubdelete")));
|
||||
//publication->iSetVersion(publications->GetVal(wxT("extversion")));
|
||||
publication->iSetComment(publications->GetVal(wxT("comment")));
|
||||
if (!pg13.IsEmpty()) publication->iSetIsViaRoot(publications->GetBool(wxT("pubviaroot")));
|
||||
|
||||
if (browser)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -354,19 +354,21 @@ wxT(") aa where aa.grantee='")+GetName()+("' group by type,objname,grantee order
|
|||
wxString addgrant=wxEmptyString;
|
||||
while (!roles->Eof())
|
||||
{
|
||||
bool ad = true;
|
||||
if (wxT("tables")==roles->GetVal(wxT("type")) ) {
|
||||
addgrant += wxT("\nGRANT ") + roles->GetVal(wxT("priv")) + wxT(" ON TABLE ") + qtIdent(roles->GetVal(wxT("objname")).BeforeFirst('.'))+wxT(".")+qtIdent(roles->GetVal(wxT("objname")).AfterFirst('.'))
|
||||
+ wxT(" TO ") + qtIdent(GetName());
|
||||
}
|
||||
if (wxT("routine")==roles->GetVal(wxT("type")) ) {
|
||||
addgrant += wxT("\nGRANT EXECUTE ON FUNCTION ") + qtIdent(roles->GetVal(wxT("objname")).BeforeFirst('.'))+wxT(".")+qtIdent(roles->GetVal(wxT("objname")).AfterFirst('.'))
|
||||
+ wxT(" TO ") + qtIdent(GetName());
|
||||
}
|
||||
if (wxT("schema")==roles->GetVal(wxT("type")) ) {
|
||||
addgrant += wxT("\nGRANT USAGE ON SCHEMA ") + qtIdent(roles->GetVal(wxT("objname")))
|
||||
+ wxT(" TO ") + qtIdent(GetName());
|
||||
}
|
||||
addgrant += wxT(";");
|
||||
} else if (wxT("routine")==roles->GetVal(wxT("type")) ) {
|
||||
addgrant += wxT("\nGRANT EXECUTE ON FUNCTION ") + qtIdent(roles->GetVal(wxT("objname")).BeforeFirst('.'))+wxT(".")+qtIdent(roles->GetVal(wxT("objname")).AfterFirst('.'))
|
||||
+ wxT(" TO ") + qtIdent(GetName());
|
||||
} else if (wxT("schema")==roles->GetVal(wxT("type")) ) {
|
||||
addgrant += wxT("\nGRANT USAGE ON SCHEMA ") + qtIdent(roles->GetVal(wxT("objname")))
|
||||
+ wxT(" TO ") + qtIdent(GetName());
|
||||
}
|
||||
else {
|
||||
ad = false;
|
||||
}
|
||||
if (ad) addgrant += wxT(";");
|
||||
roles->MoveNext();
|
||||
}
|
||||
sql += wxT("\n")+ addgrant + wxT("\n");
|
||||
|
|
|
|||
|
|
@ -1460,6 +1460,7 @@ bool pgServer::PauseReplay()
|
|||
{
|
||||
SetReplayPaused(true);
|
||||
wxString sql = wxT("SELECT pg_xlog_replay_pause()");
|
||||
if (conn->BackendMinimumVersion(10, 0)) sql = wxT("SELECT pg_wal_replay_pause()");
|
||||
return conn->ExecuteVoid(sql);
|
||||
}
|
||||
|
||||
|
|
@ -1468,6 +1469,7 @@ bool pgServer::ResumeReplay()
|
|||
{
|
||||
SetReplayPaused(false);
|
||||
wxString sql = wxT("SELECT pg_xlog_replay_resume()");
|
||||
if (conn->BackendMinimumVersion(10, 0)) sql = wxT("SELECT pg_wal_replay_resume()");
|
||||
return conn->ExecuteVoid(sql);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -618,7 +618,7 @@ wxString pgTable::GetSql(ctlTree *browser)
|
|||
}
|
||||
}
|
||||
}
|
||||
wxRegEx reg("vacuum_index_cleanup=[a-z]+|vacuum_truncate=[a-z]+|parallel_workers=[0-9]+|toast_tuple_target=[0-9]+|log_autovacuum_min_duration=[0-9]+|user_catalog_table=[a-z]+");
|
||||
wxRegEx reg("autovacuum_vacuum_insert_scale_factor=[0-9.]+|autovacuum_vacuum_insert_threshold=[0-9]+|vacuum_index_cleanup=[a-z]+|vacuum_truncate=[a-z]+|parallel_workers=[0-9]+|toast_tuple_target=[0-9]+|log_autovacuum_min_duration=[0-9]+|user_catalog_table=[a-z]+");
|
||||
wxString relopt=GetRelOptions();
|
||||
wxString o;
|
||||
size_t start, len;
|
||||
|
|
@ -726,7 +726,7 @@ wxString pgTable::GetSql(ctlTree *browser)
|
|||
else
|
||||
sql += GetGrant(wxT("arwdRxt"));
|
||||
wxString st=GetStatExt();
|
||||
if (!st.IsEmpty()) sql += st + wxT(";\n");
|
||||
if (!st.IsEmpty()) sql += st + wxT("\n");
|
||||
sql += GetCommentSql();
|
||||
|
||||
if (GetConnection()->BackendMinimumVersion(9, 1))
|
||||
|
|
@ -1290,6 +1290,8 @@ wxString pgTableCollection::GetTranslatedMessage(int kindOfMessage) const
|
|||
|
||||
void pgTableCollection::ShowStatistics(frmMain *form, ctlListView *statistics)
|
||||
{
|
||||
ShowStatisticsTables(form, statistics, this);
|
||||
return;
|
||||
wxLogInfo(wxT("Displaying statistics for tables on %s"), GetSchema()->GetIdentifier().c_str());
|
||||
|
||||
bool hasSize = GetConnection()->HasFeature(FEATURE_SIZE);
|
||||
|
|
@ -1299,6 +1301,8 @@ void pgTableCollection::ShowStatistics(frmMain *form, ctlListView *statistics)
|
|||
statistics->AddColumn(_("Table Name"));
|
||||
if (hasSize)
|
||||
statistics->AddColumn(_("Size"), 50);
|
||||
if (GetConnection()->GetIsPgProEnt()) statistics->AddColumn(_("CFS %"));
|
||||
|
||||
|
||||
statistics->AddColumn(_("Tuples inserted"));
|
||||
statistics->AddColumn(_("Tuples updated"));
|
||||
|
|
@ -1335,6 +1339,7 @@ void pgTableCollection::ShowStatistics(frmMain *form, ctlListView *statistics)
|
|||
sql += wxT(", pg_size_pretty(pg_relation_size(st.relid)")
|
||||
wxT(" + CASE WHEN cl.reltoastrelid = 0 THEN 0 ELSE pg_relation_size(cl.reltoastrelid) + COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=cl.reltoastrelid)::int8, 0) END")
|
||||
wxT(" + COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=st.relid)::int8, 0)) AS size");
|
||||
if (GetConnection()->GetIsPgProEnt()) sql += wxT(",left((cfs_fragmentation(cl.oid)*100)::text,5)::text AS cfs_ratio");
|
||||
|
||||
sql += wxT("\n FROM pg_stat_all_tables st")
|
||||
wxT(" JOIN pg_class cl on cl.oid=st.relid\n")
|
||||
|
|
@ -1349,13 +1354,14 @@ void pgTableCollection::ShowStatistics(frmMain *form, ctlListView *statistics)
|
|||
int i;
|
||||
while (!stats->Eof())
|
||||
{
|
||||
i = 5;
|
||||
i = 1;
|
||||
statistics->InsertItem(pos, stats->GetVal(wxT("relname")), PGICON_STATISTICS);
|
||||
if (hasSize)
|
||||
statistics->SetItem(pos, 1, stats->GetVal(wxT("size")));
|
||||
statistics->SetItem(pos, 2, stats->GetVal(wxT("n_tup_ins")));
|
||||
statistics->SetItem(pos, 3, stats->GetVal(wxT("n_tup_upd")));
|
||||
statistics->SetItem(pos, 4, stats->GetVal(wxT("n_tup_del")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("size")));
|
||||
if (GetConnection()->GetIsPgProEnt()) statistics->SetItem(pos, i++, stats->GetVal(wxT("cfs_ratio")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("n_tup_ins")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("n_tup_upd")));
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("n_tup_del")));
|
||||
if (GetConnection()->BackendMinimumVersion(8, 3))
|
||||
{
|
||||
statistics->SetItem(pos, i++, stats->GetVal(wxT("n_tup_hot_upd")));
|
||||
|
|
@ -1391,6 +1397,10 @@ void pgTableCollection::ShowStatistics(frmMain *form, ctlListView *statistics)
|
|||
|
||||
void pgTable::ShowStatistics(frmMain *form, ctlListView *statistics)
|
||||
{
|
||||
if (GetIsPartitioned()) {
|
||||
ShowStatisticsTables(form,statistics,this);
|
||||
return;
|
||||
}
|
||||
wxString sql =
|
||||
wxT("SELECT seq_scan AS ") + qtIdent(_("Sequential Scans")) +
|
||||
wxT(", seq_tup_read AS ") + qtIdent(_("Sequential Tuples Read")) +
|
||||
|
|
@ -1572,8 +1582,14 @@ pgObject *pgTableFactory::CreateObjects(pgCollection *collection, ctlTree *brows
|
|||
|
||||
if (collection->GetDatabase()->BackendMinimumVersion(10, 0))
|
||||
{
|
||||
query += wxT(",\n pg_get_statisticsobjdef(stat_ext.oid) AS stat_stmt");
|
||||
query += wxT(",\nCASE WHEN stat_ext.stxowner<>rel.relowner then 'ALTER STATISTICS '||substring(pg_get_statisticsobjdef(stat_ext.oid) from 'ICS (.+?)\\s\\(')||' OWNER TO '||stat_ext.stxowner::regrole else null end AS alter_stmt");
|
||||
//query += wxT(",\n pg_get_statisticsobjdef(stat_ext.oid) AS stat_stmt");
|
||||
//query += wxT(",\nCASE WHEN stat_ext.stxowner<>rel.relowner then 'ALTER STATISTICS '||substring(pg_get_statisticsobjdef(stat_ext.oid) from 'ICS (.+?)\\s\\(')||' OWNER TO '||stat_ext.stxowner::regrole else null end AS alter_stmt");
|
||||
query += ",(select string_agg(pg_get_statisticsobjdef(stat_ext.oid)||CASE WHEN stat_ext.stxowner<>rl.relowner then E';\\nALTER STATISTICS '||substring(pg_get_statisticsobjdef(stat_ext.oid) from 'ICS (.+?)\\s')||' OWNER TO '||stat_ext.stxowner::regrole else '' end"
|
||||
;
|
||||
if (collection->GetDatabase()->BackendMinimumVersion(13, 0)) {
|
||||
query += "||CASE WHEN stat_ext.stxstattarget<>-1 then E';\\nALTER STATISTICS '||substring(pg_get_statisticsobjdef(stat_ext.oid) from 'ICS (.+?)\\s')||' SET STATISTICS '||stat_ext.stxstattarget else '' end";
|
||||
}
|
||||
query += ",E';\\n' order by stat_ext.stxrelid) stat_stmt from pg_class rl join pg_statistic_ext stat_ext on rl.oid=stat_ext.stxrelid where stat_ext.stxrelid=rel.oid) stat_stmt";
|
||||
}
|
||||
query += wxT(" FROM pg_class rel\n")
|
||||
wxT(" LEFT JOIN pg_locks lk ON locktype='relation' and granted=true and mode='AccessExclusiveLock' and relation=rel.oid\n")
|
||||
|
|
@ -1591,8 +1607,6 @@ pgObject *pgTableFactory::CreateObjects(pgCollection *collection, ctlTree *brows
|
|||
|
||||
if (collection->GetConnection()->BackendMinimumVersion(9, 0))
|
||||
query += wxT("LEFT JOIN pg_type typ ON rel.reloftype=typ.oid\n");
|
||||
if (collection->GetConnection()->BackendMinimumVersion(10, 0))
|
||||
query += wxT("LEFT JOIN pg_statistic_ext stat_ext ON rel.oid=stat_ext.stxrelid\n");
|
||||
|
||||
query += wxT(" WHERE ")+pg10+wxT(" rel.relkind IN ('r','s','t','p') AND rel.relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n");
|
||||
|
||||
|
|
@ -1733,8 +1747,8 @@ pgObject *pgTableFactory::CreateObjects(pgCollection *collection, ctlTree *brows
|
|||
table->iSetPartExp(tables->GetVal(wxT("partexp")));
|
||||
table->iSetIsPartitioned(tables->GetBool(wxT("ispartitioned")));
|
||||
wxString st = tables->GetVal(wxT("stat_stmt"));
|
||||
wxString at = tables->GetVal(wxT("alter_stmt"));
|
||||
if (!st.IsEmpty()&&!at.IsEmpty()) st=st+wxT(";\n")+at;
|
||||
//wxString at = tables->GetVal(wxT("alter_stmt"));
|
||||
if (!st.IsEmpty()) if ((st.Right(1) != ";") ) st=st+wxT(";\n");
|
||||
table->iSetStatExt(st);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,5 +9,5 @@ REM # embed-xrc.bat - convert xrc files to c++ files
|
|||
REM #
|
||||
REM #######################################################################
|
||||
|
||||
"D:\PostgreSQL\pgadmin3\pgadmin\Debug_(3.0)\wxrc.exe" -c -o xrcDialogs.cpp *.xrc
|
||||
"C:\Users\lsv\Source\Repos\wxrc\x64\Release\wxrc.exe" -c -o xrcDialogs.cpp *.xrc
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue