diff --git a/README.md b/README.md index ae35d22..e66103b 100644 --- a/README.md +++ b/README.md @@ -13,24 +13,31 @@ This text Russian language. Полная версия pgAdmin3 находиться тут https://github.com/postgres/pgadmin3.git Что добавлено: -Экспорт результата запроса в Excel -Добавлен выбор запроса на исполнение под курсором (Auto-Select) -Добавлена настраиваемая автозамена (в меню Правка -> Manage autoreplace) -Добавлено автосохранение содержимого закладки после выполнения запроса -Добавлена возможность задать имя для закладки и возможность сделать закладку автозагружаемой для конкретной БД + - Экспорт результата запроса в Excel + - Добавлен выбор запроса на исполнение под курсором (Auto-Select) + - Добавлена настраиваемая автозамена (в меню Правка -> Manage autoreplace) + - Добавлено автосохранение содержимого закладки после выполнения запроса + - Добавлена возможность задать имя для закладки и возможность сделать закладку автозагружаемой для конкретной БД -Добавлена поддержка процедур -Добавлена поддержка секционирования (только отображение в дереве объектов) + - Добавлена поддержка процедур + - Добавлена поддержка секционирования (только отображение в дереве объектов) -Удалено отображение узлов имеющих статус (Never execute) на закладке графического плана, но в табличном виде они присутствуют. +- Удалено отображение узлов имеющих статус (Never execute) на закладке графического плана, но в табличном виде они присутствуют. 01.11.2018 -Добавлено отображение publications. -Добавлено изменение фона при при не закоммиченой транзакции. -У Commit/Rollback измененены горячие клавиши + - Добавлено отображение publications. + - Добавлено изменение фона при при не закоммиченой транзакции. + - У Commit/Rollback измененены горячие клавиши 11.12.2018 -Добавлен поиск в дереве по F4 выделеного текста и если объект найден то его открытие. -Если запрос длится более 2 минут то после завершения запроса окно будет мигать. -При открытия функции фокус устанавливается сразу на закладку Код. + - Добавлен поиск в дереве по F4 выделеного текста и если объект найден то его открытие. + Если запрос длится более 2 минут то после завершения запроса окно будет мигать. + - При открытия функции фокус устанавливается сразу на закладку Код. +05.12.2018 + - Добавлена поддержка расширения pgpro_scheduler + + - В выводе результатов запроса ячейки со значениям содержащие символ перевода строки \n подсвечиваются + * В экспорте результатов запроса в Excel исправлена ошибка при сохранении интервалов + * При обновлении схемы не блокируется интерфейс если на таблице идет долгая операция cluster + Но при F5 на самой таблице блокировка сохраняется (это связано с блокированием функций pg_def* при получинии информации от таблицах) diff --git a/Release/pgAdmin3.exe b/Release/pgAdmin3.exe index d682c8e..74bd7e5 100644 Binary files a/Release/pgAdmin3.exe and b/Release/pgAdmin3.exe differ diff --git a/ctl/ctlSQLBox.cpp b/ctl/ctlSQLBox.cpp index 1d9cb23..6f036cc 100644 --- a/ctl/ctlSQLBox.cpp +++ b/ctl/ctlSQLBox.cpp @@ -1041,13 +1041,13 @@ CharacterRange ctlSQLBox::RegexFindText(int minPos, int maxPos, const wxString & ft.chrg.cpMax = maxPos; wxWX2MBbuf buf = text.mb_str(wxConvUTF8); ft.lpstrText = (char *)(const char *)buf; -/* - wx 2.8.12 - if (SendMsg(2150, wxSTC_FIND_REGEXP, (long)&ft) == -1) - { - ft.chrgText.cpMin = -1; - ft.chrgText.cpMax = -1; - } -*/ + +// wx 2.8.12 + //if (SendMsg(2150, wxSTC_FIND_REGEXP, (long)&ft) == -1) + //{ + // ft.chrgText.cpMin = -1; + // ft.chrgText.cpMax = -1; + //} + return ft.chrgText; } diff --git a/ctl/ctlSQLGrid.cpp b/ctl/ctlSQLGrid.cpp index b189054..ec7eedb 100644 --- a/ctl/ctlSQLGrid.cpp +++ b/ctl/ctlSQLGrid.cpp @@ -14,7 +14,7 @@ // wxWindows headers #include #include - +#include #include "db/pgConn.h" #include "ctl/ctlSQLGrid.h" #include "utils/sysSettings.h" @@ -28,6 +28,7 @@ BEGIN_EVENT_TABLE(ctlSQLGrid, wxGrid) EVT_MOUSEWHEEL(ctlSQLGrid::OnMouseWheel) EVT_GRID_COL_SIZE(ctlSQLGrid::OnGridColSize) EVT_GRID_LABEL_LEFT_CLICK(ctlSQLGrid::OnLabelClick) + EVT_GRID_CELL_RIGHT_CLICK( ctlSQLGrid::OnCellRightClick) END_EVENT_TABLE() IMPLEMENT_DYNAMIC_CLASS(ctlSQLGrid, wxGrid) @@ -51,6 +52,9 @@ ctlSQLGrid::ctlSQLGrid(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons SetDefaultRowSize(fntCells.GetPointSize() * 2 + 2); SetColLabelSize(fntLabel.GetPointSize() * 4); SetDefaultCellOverflow(false); + //SetDefaultRenderer(new wxGridCellAutoWrapStringRenderer); + SetDefaultRenderer(new CursorCellRenderer); + Connect(wxID_ANY, wxEVT_GRID_LABEL_LEFT_DCLICK, wxGridEventHandler(ctlSQLGrid::OnLabelDoubleClick)); } @@ -392,6 +396,11 @@ void ctlSQLGrid::OnLabelDoubleClick(wxGridEvent &event) } } + void ctlSQLGrid::OnCellRightClick(wxGridEvent &event) +{ + int row = event.GetRow(); + int col = event.GetCol(); +} void ctlSQLGrid::OnLabelClick(wxGridEvent &event) { int row = event.GetRow(); diff --git a/frm/frmExport.cpp b/frm/frmExport.cpp index f329943..35f8bf5 100644 --- a/frm/frmExport.cpp +++ b/frm/frmExport.cpp @@ -339,9 +339,13 @@ bool frmExport::ExportXls(ctlSQLResult *grid) case PGTYPCLASS_DATE: //type=wxT("-- ::"); xmltext=xmltext.BeforeFirst('+'); - xmltext.Replace(wxT(" "),wxT("T")); - style=wxT("dt"); - xmltext=wxT("")+xmltext+wxT(""); + if (xmltext.Replace(wxT(" "),wxT("T"))==0) { + xmltext=wxT("")+xmltext+wxT(""); + } else + { + style=wxT("dt"); + xmltext=wxT("")+xmltext+wxT(""); + } break; case PGTYPCLASS_BOOL: default: diff --git a/include/ctl/ctlSQLGrid.h b/include/ctl/ctlSQLGrid.h index 011472e..4484955 100644 --- a/include/ctl/ctlSQLGrid.h +++ b/include/ctl/ctlSQLGrid.h @@ -38,7 +38,8 @@ public: wxSize GetBestSize(int row, int col); void OnLabelDoubleClick(wxGridEvent &event); void OnLabelClick(wxGridEvent &event); - + void OnCellRightClick(wxGridEvent &event); + void AutoSizeColumn(int col, bool setAsMin = false, bool doLimit = true); void AutoSizeColumns(bool setAsMin); @@ -62,4 +63,54 @@ private: wxArrayInt colMaxSizes; }; +class CursorCellRenderer : public wxGridCellStringRenderer + { + public: + virtual void Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, + const wxRect& rect, int row, int col, bool isSelected) + { + int hAlign, vAlign; + attr.GetAlignment(&hAlign, &vAlign); + ////////////////////////////////////////////////////////////////////////////// + //CursorCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected); // + dc.SetBackgroundMode( wxSOLID ); + wxString text=grid.GetCellValue(row, col); + // grey out fields if the grid is disabled + if ( grid.IsEnabled() ) + { + if ( isSelected ) + { + wxColour clr; + if ( wxWindow::FindFocus() == grid.GetGridWindow() ) + clr = grid.GetSelectionBackground(); + else + clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW); + dc.SetBrush( wxBrush(clr, wxSOLID) ); + } + else + { + wxColor color; + color.Set(239, 228, 176); + if (text.Find(wxT('\n'))!=wxNOT_FOUND ) + dc.SetBrush( wxBrush(color, wxSOLID) ); + else + dc.SetBrush( wxBrush(attr.GetBackgroundColour(), wxSOLID) ); + } + } + else + { + dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE), wxSOLID)); + } + + dc.SetPen( *wxTRANSPARENT_PEN ); + dc.DrawRectangle(rect); + + ////////////////////////////////////////////////////////////////////////////// + SetTextColoursAndFont(grid, attr, dc, isSelected); + grid.DrawTextRectangle(dc, text, + rect, hAlign, vAlign); + } + + }; + #endif diff --git a/include/pro_scheduler/pgproJob.h b/include/pro_scheduler/pgproJob.h index ff259dd..45a4846 100644 --- a/include/pro_scheduler/pgproJob.h +++ b/include/pro_scheduler/pgproJob.h @@ -121,6 +121,16 @@ public: { runas = s; } + + wxString GetTryName() const + { + return tryname; + } + void iSetTryName(const wxString &s) + { + tryname = s; + } + wxString GetRule() const { return rule; @@ -177,7 +187,7 @@ public: private: bool enabled; wxDateTime finished, changed, nextrun, lastrun; - wxString message, crontab, runas, commands,status,rule; + wxString message, crontab, runas, commands,status,rule,tryname; long recId; }; diff --git a/schema/pgObject.cpp b/schema/pgObject.cpp index d7c7fc3..2c023d2 100644 --- a/schema/pgObject.cpp +++ b/schema/pgObject.cpp @@ -459,7 +459,7 @@ void pgObject::ShowDependencies(frmMain *form, ctlListView *Dependencies, const return; // Bail out if this is a pgAgent object, as they use the OID for IDs - if (GetMetaType() == PGM_JOB || GetMetaType() == PGM_SCHEDULE || GetMetaType() == PGM_STEP) + if (GetMetaType() == PGM_JOB || GetMetaType() == PGM_SCHEDULE || GetMetaType() == PGM_STEP || GetMetaType() == PGM_PROJOB) return; wxString where; @@ -635,7 +635,7 @@ void pgObject::ShowDependents(frmMain *form, ctlListView *referencedBy, const wx return; // Bail out if this is a pgAgent object, as they use the OID for IDs - if (GetMetaType() == PGM_JOB || GetMetaType() == PGM_SCHEDULE || GetMetaType() == PGM_STEP) + if (GetMetaType() == PGM_JOB || GetMetaType() == PGM_SCHEDULE || GetMetaType() == PGM_STEP || GetMetaType() == PGM_PROJOB) return; wxString where; diff --git a/schema/pgPartition.cpp b/schema/pgPartition.cpp index 04b5073..58cfbde 100644 --- a/schema/pgPartition.cpp +++ b/schema/pgPartition.cpp @@ -245,10 +245,11 @@ pgObject *pgPartitionFactory::CreateObjects(pgCollection *coll, ctlTree *browser query += wxT(", rel.reloftype, typ.typname\n"); query += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS labels"); query += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=rel.oid AND sl2.objsubid=0) AS providers"); - query += wxT(",pg_catalog.pg_get_partkeydef(rel.oid)\n AS partkeydef"); - query += wxT(",pg_get_expr(rel.relpartbound, rel.oid)\n AS partexp"); + query += wxT(",case when lk.relation=rel.oid then null else pg_get_partkeydef(rel.oid) end \n AS partkeydef"); + query += wxT(",case when lk.relation=rel.oid then 'AccessExclusiveLock' else pg_get_expr(rel.relpartbound, rel.oid) end \n AS partexp"); 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") wxT(" LEFT OUTER JOIN pg_tablespace spc on spc.oid=rel.reltablespace\n") wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass)\n") wxT(" LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p'\n"); diff --git a/schema/pgTable.cpp b/schema/pgTable.cpp index 0ce6cd7..1c72885 100644 --- a/schema/pgTable.cpp +++ b/schema/pgTable.cpp @@ -1520,13 +1520,15 @@ pgObject *pgTableFactory::CreateObjects(pgCollection *collection, ctlTree *brows wxString pg10=wxEmptyString; if (collection->GetDatabase()->BackendMinimumVersion(10, 1)) { - query += wxT(",pg_catalog.pg_get_partkeydef(rel.oid)\n AS partkeydef"); - query += wxT(",pg_get_expr(rel.relpartbound, rel.oid)\n AS partexp"); - pg10=wxT("pg_get_expr(rel.relpartbound, rel.oid) is null and"); + query += wxT(",case when lk.relation=rel.oid then null else pg_get_partkeydef(rel.oid) end \n AS partkeydef"); + query += wxT(",case when lk.relation=rel.oid then null else pg_get_expr(rel.relpartbound, rel.oid) end \n AS partexp"); + //pg10=wxT("pg_get_expr(rel.relpartbound, rel.oid) is null and"); + pg10=wxT("rel.relpartbound is null and"); //query += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=rel.oid AND sl2.objsubid=0) AS providers"); } - + //select relation from pg_locks where locktype='relation' and granted=true and mode='AccessExclusiveLock' 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") wxT(" LEFT OUTER JOIN pg_tablespace spc on spc.oid=rel.reltablespace\n") wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass)\n") wxT(" LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p'\n"); diff --git a/utils/sshTunnel.cpp b/utils/sshTunnel.cpp index 041a854..d97e9ce 100644 --- a/utils/sshTunnel.cpp +++ b/utils/sshTunnel.cpp @@ -370,7 +370,9 @@ bool CSSHTunnelThread::resolveDNS(const char *host, wxArrayString &arrIPAddress) struct addrinfo hints, *res, *p; int status; char ipstr[INET6_ADDRSTRLEN]; - +#ifndef AI_ADDRCONFIG +#define AI_ADDRCONFIG 0 +#endif memset(&hints, 0, sizeof hints); memset(&ipstr, 0, sizeof ipstr); hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version