diff --git a/README.md b/README.md index 251c33d..bf02601 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,12 @@ This text Russian language. В родной схеме, секции как таблицы увидеть нельзя. * мелкие улучшения - +02.09.2020 + - добавлена возможность копировать в буфер обмена выделенные ячейки результата запроса в формате IN списка и Where конструкций. Вызывается из контекстного меню. + - в Server status окне добавлена возможность фильтровать строки по щелчку правой кнопкой мыши. + * иправлено issues #8 (dropping overloaded procedures) + + diff --git a/Release_(3.0)/pgAdmin3.exe b/Release_(3.0)/pgAdmin3.exe index c516a0d..b0de576 100644 Binary files a/Release_(3.0)/pgAdmin3.exe and b/Release_(3.0)/pgAdmin3.exe differ diff --git a/ctl/ctlSQLGrid.cpp b/ctl/ctlSQLGrid.cpp index 338a797..ac49ece 100644 --- a/ctl/ctlSQLGrid.cpp +++ b/ctl/ctlSQLGrid.cpp @@ -293,7 +293,7 @@ void ctlSQLGrid::AppendColumnHeader(wxString &str, wxArrayInt columns) bool CopyQuoting = (settings->GetCopyQuoting() == 1 || settings->GetCopyQuoting() == 2); size_t i; wxString fielddelim = ","; - if (generatesql == 3) fielddelim = " And "; + if (generatesql == 3) return; if (generatesql == 1) return; for(i = 0; i < columns.Count() ; i++) { diff --git a/frm/frmStatus.cpp b/frm/frmStatus.cpp index c99d26b..3d546c4 100644 --- a/frm/frmStatus.cpp +++ b/frm/frmStatus.cpp @@ -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) @@ -221,7 +224,10 @@ frmStatus::frmStatus(frmMain *form, const wxString &_title, pgConn *conn) : pgFr } //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; } @@ -317,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); @@ -347,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); @@ -1647,10 +1657,14 @@ void frmStatus::OnRefreshStatusTimer(wxTimerEvent &event) if (connection->BackendMinimumVersion(10, 0)) { q += wxT(",backend_type,wait_event_type,wait_event,v.heap_blks_total,v.heap_blks_vacuumed,v.heap_blks_scanned,v.phase\n"); - if (isrecovery) + 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; @@ -1684,7 +1698,7 @@ void frmStatus::OnRefreshStatusTimer(wxTimerEvent &event) // Update the UI if (pid != backend_pid) { - pids.Add(pid); + // Add the query content to the queries array queries.Add(dataSet1->GetVal(wxT("query"))); @@ -1807,7 +1821,20 @@ void frmStatus::OnRefreshStatusTimer(wxTimerEvent &event) else statusList->SetItemBackgroundColour(row, *wxWHITE); - row++; + // filter apply + bool flt = false; + for (int i = 0; i < filterColumn.size(); i++) { + int col = filterColumn[i]; + wxString tabval=statusList->GetItemText(row, col); + if (tabval != filterValue[i]) { + flt = true; + break; + } + } + if (!flt) { + pids.Add(pid); + row++; + } } dataSet1->MoveNext(); } @@ -3325,7 +3352,6 @@ void frmStatus::OnCommit(wxCommandEvent &event) OnSelXactItem(ev); } - void frmStatus::OnRollback(wxCommandEvent &event) { long item = xactList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); @@ -3586,6 +3612,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) { diff --git a/include/frm/frmStatus.h b/include/frm/frmStatus.h index c4d5fd9..ed851d2 100644 --- a/include/frm/frmStatus.h +++ b/include/frm/frmStatus.h @@ -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,7 +123,7 @@ private: long backend_pid; int wait_event_type_col; - bool isrecovery; + bool isrecovery,track_commit_timestamp; bool loaded; long logfileLength; wxColour bgColor; @@ -158,6 +159,8 @@ private: wxMenu *querystatePopupMenu; wxString queryplan; wxArrayString queries; + wxArrayInt filterColumn; + wxArrayString filterValue; int statusColWidth[12], lockColWidth[10], xactColWidth[5], querystateColWidth[5]; @@ -199,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); @@ -238,6 +242,7 @@ private: void OnRotateLogfile(wxCommandEvent &event); void OnCommit(wxCommandEvent &event); void OnRollback(wxCommandEvent &event); + void OnClearFilter(wxCommandEvent& event); void OnChangeDatabase(wxCommandEvent &ev); diff --git a/include/images/sortfilterclear.png b/include/images/sortfilterclear.png new file mode 100644 index 0000000..2fad39d Binary files /dev/null and b/include/images/sortfilterclear.png differ diff --git a/include/images/sortfilterclear.pngc b/include/images/sortfilterclear.pngc new file mode 100644 index 0000000..2a1ef0c --- /dev/null +++ b/include/images/sortfilterclear.pngc @@ -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 diff --git a/include/version.h b/include/version.h index 7af7e0a..0e487b7 100644 --- a/include/version.h +++ b/include/version.h @@ -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 "..." diff --git a/pgAdmin3.vcxproj b/pgAdmin3.vcxproj index 1007025..4739d52 100644 --- a/pgAdmin3.vcxproj +++ b/pgAdmin3.vcxproj @@ -4560,6 +4560,7 @@ + diff --git a/pgAdmin3.vcxproj.filters b/pgAdmin3.vcxproj.filters index 5de2f23..95f05e0 100644 --- a/pgAdmin3.vcxproj.filters +++ b/pgAdmin3.vcxproj.filters @@ -4564,6 +4564,9 @@ include\images + + include\images +