~ubuntu-branches/debian/sid/pgadmin3/sid

« back to all changes in this revision

Viewing changes to pgadmin/frm/frmStatus.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Gerfried Fuchs
  • Date: 2009-07-30 12:27:16 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090730122716-fddbh42on721bbs2
Tags: 1.10.0-1
* New upstream release.
* Adjusted watch file to match release candidates.
* Updated to Standards-Version 3.8.2:
  - Moved to Section: database.
  - Add DEB_BUILD_OPTIONS support for parallel building.
  - Move from findstring to filter suggestion for DEB_BUILD_OPTIONS parsing.
* pgagent got split into its own separate source package by upstream.
* Exclude Docs.vcproj from installation.
* Move doc-base.enus from pgadmin3 to pgadmin3-data package, the files are
  in there too.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
//////////////////////////////////////////////////////////////////////////
2
2
//
3
3
// pgAdmin III - PostgreSQL Tools
4
 
// RCS-ID:      $Id: frmStatus.cpp 6930 2008-01-02 00:10:01Z dpage $
5
 
// Copyright (C) 2002 - 2008, The pgAdmin Development Team
6
 
// This software is released under the Artistic Licence
 
4
// RCS-ID:      $Id: frmStatus.cpp 7908 2009-06-10 09:01:00Z dpage $
 
5
// Copyright (C) 2002 - 2009, The pgAdmin Development Team
 
6
// This software is released under the BSD Licence
7
7
//
8
8
// frmStatus.cpp - Status Screen
9
9
//
16
16
#include <wx/xrc/xmlres.h>
17
17
#include <wx/image.h>
18
18
#include <wx/textbuf.h>
 
19
#include <wx/clipbrd.h>
 
20
 
 
21
// wxAUI
 
22
#include <wx/aui/aui.h>
 
23
#include <wx/aui/auibook.h>
19
24
 
20
25
// App headers
21
26
#include "frm/frmStatus.h"
23
28
#include "frm/frmMain.h"
24
29
#include "utils/pgfeatures.h"
25
30
#include "schema/pgServer.h"
26
 
 
27
 
 
28
 
#define TIMER_ID 333
29
 
BEGIN_EVENT_TABLE(frmStatus, pgDialog)
30
 
    EVT_BUTTON(wxID_REFRESH,                                    frmStatus::OnRefresh)
31
 
    EVT_BUTTON(wxID_CLOSE,                                              frmStatus::OnCloseBtn)
32
 
    EVT_BUTTON(wxID_CANCEL,                                     frmStatus::OnCancelBtn)
33
 
    EVT_BUTTON(wxID_STOP,                                       frmStatus::OnTerminateBtn)
34
 
    EVT_BUTTON(XRCID("btnCommit"),                  frmStatus::OnCommit)
35
 
    EVT_BUTTON(XRCID("btnRollback"),                frmStatus::OnRollback)
36
 
    EVT_CLOSE(                                                                          frmStatus::OnClose)
37
 
    EVT_COMMAND_SCROLL(XRCID("slRate"),             frmStatus::OnRateChange)
38
 
        EVT_NOTEBOOK_PAGE_CHANGING(XRCID("nbStatus"),   frmStatus::OnNotebookPageChanged)
39
 
    EVT_TIMER(TIMER_ID,                                                         frmStatus::OnRefreshTimer)
40
 
        EVT_LIST_ITEM_SELECTED(XRCID("lstStatus"),              frmStatus::OnSelStatusItem)
41
 
        EVT_LIST_ITEM_DESELECTED(XRCID("lstStatus"),    frmStatus::OnSelStatusItem)
42
 
        EVT_LIST_ITEM_SELECTED(XRCID("lstLocks"),               frmStatus::OnSelLockItem)
43
 
        EVT_LIST_ITEM_DESELECTED(XRCID("lstLocks"),             frmStatus::OnSelLockItem)
44
 
        EVT_LIST_ITEM_SELECTED(XRCID("lstXacts"),               frmStatus::OnSelXactItem)
45
 
        EVT_LIST_ITEM_DESELECTED(XRCID("lstXacts"),             frmStatus::OnSelXactItem)
46
 
    EVT_COMBOBOX(XRCID("cbLogfiles"),               frmStatus::OnLoadLogfile)
47
 
    EVT_BUTTON(XRCID("btnRotateLog"),               frmStatus::OnRotateLogfile)
 
31
#include "ctl/ctlMenuToolbar.h"
 
32
#include "utils/csvfiles.h"
 
33
 
 
34
// Icons
 
35
#include "images/clip_copy.xpm"
 
36
#include "images/readdata.xpm"
 
37
#include "images/query_cancel.xpm"
 
38
#include "images/terminate_backend.xpm"
 
39
#include "images/delete.xpm"
 
40
#include "images/storedata.xpm"
 
41
 
 
42
 
 
43
BEGIN_EVENT_TABLE(frmStatus, pgFrame)
 
44
    EVT_MENU(MNU_EXIT,                               frmStatus::OnExit)
 
45
    
 
46
    EVT_MENU(MNU_COPY,                               frmStatus::OnCopy)
 
47
 
 
48
    EVT_MENU(MNU_HELP,                               frmStatus::OnHelp)
 
49
    EVT_MENU(MNU_STATUSPAGE,                        frmStatus::OnToggleStatusPane)
 
50
    EVT_MENU(MNU_LOCKPAGE,                            frmStatus::OnToggleLockPane)
 
51
    EVT_MENU(MNU_XACTPAGE,                             frmStatus::OnToggleXactPane)
 
52
    EVT_MENU(MNU_LOGPAGE,                             frmStatus::OnToggleLogPane)
 
53
    EVT_MENU(MNU_TOOLBAR,                             frmStatus::OnToggleToolBar)
 
54
    EVT_MENU(MNU_DEFAULTVIEW,                        frmStatus::OnDefaultView)
 
55
 
 
56
    EVT_AUI_PANE_CLOSE(                             frmStatus::OnPaneClose)
 
57
    
 
58
    EVT_COMBOBOX(CTL_RATECBO,                       frmStatus::OnRateChange)
 
59
    EVT_MENU(MNU_REFRESH,                             frmStatus::OnRefresh)
 
60
    EVT_MENU(MNU_CANCEL,                             frmStatus::OnCancelBtn)
 
61
    EVT_MENU(MNU_TERMINATE,                              frmStatus::OnTerminateBtn)
 
62
    EVT_MENU(MNU_COMMIT,                            frmStatus::OnCommit)
 
63
    EVT_MENU(MNU_ROLLBACK,                            frmStatus::OnRollback)
 
64
    EVT_COMBOBOX(CTL_LOGCBO,                        frmStatus::OnLoadLogfile)
 
65
    EVT_BUTTON(CTL_ROTATEBTN,                       frmStatus::OnRotateLogfile)
 
66
    
 
67
    EVT_TIMER(TIMER_REFRESHUI_ID,                    frmStatus::OnRefreshUITimer)
 
68
 
 
69
    EVT_TIMER(TIMER_STATUS_ID,                        frmStatus::OnRefreshStatusTimer)
 
70
    EVT_LIST_ITEM_SELECTED(CTL_STATUSLIST,            frmStatus::OnSelStatusItem)
 
71
    EVT_LIST_ITEM_DESELECTED(CTL_STATUSLIST,        frmStatus::OnSelStatusItem)
 
72
    
 
73
    EVT_TIMER(TIMER_LOCKS_ID,                        frmStatus::OnRefreshLocksTimer)
 
74
    EVT_LIST_ITEM_SELECTED(CTL_LOCKLIST,            frmStatus::OnSelLockItem)
 
75
    EVT_LIST_ITEM_DESELECTED(CTL_LOCKLIST,            frmStatus::OnSelLockItem)
 
76
    
 
77
    EVT_TIMER(TIMER_XACT_ID,                        frmStatus::OnRefreshXactTimer)
 
78
    EVT_LIST_ITEM_SELECTED(CTL_XACTLIST,            frmStatus::OnSelXactItem)
 
79
    EVT_LIST_ITEM_DESELECTED(CTL_XACTLIST,            frmStatus::OnSelXactItem)
 
80
    
 
81
    EVT_TIMER(TIMER_LOG_ID,                            frmStatus::OnRefreshLogTimer)
 
82
    EVT_LIST_ITEM_SELECTED(CTL_LOGLIST,                frmStatus::OnSelLogItem)
 
83
    EVT_LIST_ITEM_DESELECTED(CTL_LOGLIST,            frmStatus::OnSelLogItem)
 
84
 
 
85
    EVT_CLOSE(                                        frmStatus::OnClose)
48
86
END_EVENT_TABLE();
49
87
 
50
88
 
51
 
#define statusList      CTRL_LISTVIEW("lstStatus")
52
 
#define lockList        CTRL_LISTVIEW("lstLocks")
53
 
#define xactList        CTRL_LISTVIEW("lstXacts")
54
 
#define logList         CTRL_LISTVIEW("lstLog")
55
 
#define slRate          CTRL_SLIDER("slRate")
56
 
#define stRate          CTRL_STATIC("stRate")
57
 
#define nbStatus                CTRL_NOTEBOOK("nbStatus")
58
 
#define cbLogfiles      CTRL_COMBOBOX("cbLogfiles")
59
 
#define btnRotateLog    CTRL_BUTTON("btnRotateLog")
60
 
 
61
 
 
62
 
void frmStatus::OnCloseBtn(wxCommandEvent &event)
63
 
{
64
 
    Destroy();
65
 
}
66
 
 
67
 
void frmStatus::OnClose(wxCloseEvent &event)
68
 
{
69
 
    Destroy();
70
 
}
71
 
 
72
 
 
73
 
void ChangeButtonId(wxButton *btn, int id, const wxChar *txt)
74
 
{
75
 
    btn->SetId(id);
76
 
    btn->SetLabel(txt);
77
 
}
78
 
 
79
 
 
80
 
frmStatus::frmStatus(frmMain *form, const wxString& _title, pgConn *conn)
81
 
{
82
 
        loaded = false;
83
 
    xactPage=2;
84
 
    logPage=3;
85
 
 
86
 
    wxWindowBase::SetFont(settings->GetSystemFont());
87
 
    LoadResource(0, wxT("frmStatus")); 
88
 
 
89
 
    RestorePosition(-1, -1, 400, 240, 200, 150);
 
89
int frmStatus::cboToRate()
 
90
{
 
91
    int rate = 0;
 
92
 
 
93
    if (cbRate->GetValue() == _("Don't refresh"))
 
94
        rate = 0;
 
95
    if (cbRate->GetValue() == _("1 second"))
 
96
        rate = 1;
 
97
    if (cbRate->GetValue() == _("5 seconds"))
 
98
        rate = 5;
 
99
    if (cbRate->GetValue() == _("10 seconds"))
 
100
        rate = 10;
 
101
    if (cbRate->GetValue() == _("30 seconds"))
 
102
        rate = 30;
 
103
    if (cbRate->GetValue() == _("1 minute"))
 
104
        rate = 60;
 
105
    if (cbRate->GetValue() == _("5 minutes"))
 
106
        rate = 300;
 
107
    if (cbRate->GetValue() == _("10 minutes"))
 
108
        rate = 600;
 
109
    if (cbRate->GetValue() == _("30 minutes"))
 
110
        rate = 1800;
 
111
    if (cbRate->GetValue() == _("1 hour"))
 
112
        rate = 3600;
 
113
 
 
114
    return rate;
 
115
}
 
116
 
 
117
 
 
118
wxString frmStatus::rateToCboString(int rate)
 
119
{
 
120
    wxString rateStr;
 
121
 
 
122
    if (rate == 0)
 
123
        rateStr = _("Don't refresh");
 
124
    if (rate == 1)
 
125
        rateStr = _("1 second");
 
126
    if (rate == 5)
 
127
        rateStr = _("5 seconds");
 
128
    if (rate == 10)
 
129
        rateStr = _("10 seconds");
 
130
    if (rate == 30)
 
131
        rateStr = _("30 seconds");
 
132
    if (rate == 60)
 
133
        rateStr = _("1 minute");
 
134
    if (rate == 300)
 
135
        rateStr = _("5 minutes");
 
136
    if (rate == 600)
 
137
        rateStr = _("10 minutes");
 
138
    if (rate == 1800)
 
139
        rateStr = _("30 minutes");
 
140
    if (rate == 3600)
 
141
        rateStr = _("1 hour");
 
142
 
 
143
    return rateStr;
 
144
}
 
145
 
 
146
 
 
147
frmStatus::frmStatus(frmMain *form, const wxString& _title, pgConn *conn) : pgFrame(NULL, _title)
 
148
{
 
149
    dlgName = wxT("frmStatus");
 
150
    
 
151
    loaded = false;
 
152
 
 
153
    mainForm = form;
 
154
    connection = conn;
 
155
 
 
156
    statusTimer = 0;
 
157
    locksTimer = 0;
 
158
    xactTimer = 0;
 
159
    logTimer = 0;
 
160
    
 
161
    logHasTimestamp = false;
 
162
    logFormatKnown = false;
 
163
 
 
164
    // Notify wxAUI which frame to use
 
165
    manager.SetManagedWindow(this);
 
166
    manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG | wxAUI_MGR_ALLOW_ACTIVE_PANE);
 
167
 
 
168
    // Set different window's attributes
90
169
    SetTitle(_title);
91
170
    appearanceFactory->SetIcons(this);
92
 
 
93
 
    mainForm=form;
94
 
    timer=0;
95
 
    connection=conn;
96
 
    logHasTimestamp = false;
97
 
    logFormatKnown = false;
98
 
    btnCancelSt = CTRL_BUTTON("btnCancelSt");
99
 
    btnCancelLk = CTRL_BUTTON("btnCancelLk");
100
 
    btnTerminateSt = CTRL_BUTTON("btnTerminateSt");
101
 
    btnTerminateLk = CTRL_BUTTON("btnTerminateLk");
102
 
    btnCommit = CTRL_BUTTON("btnCommit");
103
 
    btnRollback = CTRL_BUTTON("btnRollback");
104
 
    ChangeButtonId(btnCancelSt, wxID_CANCEL, _("Cancel"));
105
 
    ChangeButtonId(btnCancelLk, wxID_CANCEL, _("Cancel"));
106
 
    ChangeButtonId(btnTerminateSt, wxID_STOP, _("Terminate"));
107
 
    ChangeButtonId(btnTerminateLk, wxID_STOP, _("Terminate"));
108
 
 
109
 
    logfileLength = 0;
110
 
    backend_pid=conn->GetBackendPID();
111
 
 
 
171
    RestorePosition(-1, -1, 700, 500, 700, 500);
 
172
    SetMinSize(wxSize(700,500));
 
173
    wxWindowBase::SetFont(settings->GetSystemFont());
 
174
 
 
175
    // Build menu bar
 
176
    menuBar = new wxMenuBar();
 
177
 
 
178
    fileMenu = new wxMenu();
 
179
    fileMenu->Append(MNU_EXIT, _("E&xit\tAlt-F4"), _("Exit query window"));
 
180
 
 
181
    menuBar->Append(fileMenu, _("&File"));
 
182
 
 
183
    editMenu = new wxMenu();
 
184
    editMenu->Append(MNU_COPY, _("&Copy\tCtrl-C"), _("Copy selected text to clipboard"), wxITEM_NORMAL);
 
185
 
 
186
    menuBar->Append(editMenu, _("&Edit"));
 
187
 
 
188
    viewMenu = new wxMenu();
 
189
    viewMenu->Append(MNU_STATUSPAGE, _("&Activity\tCtrl-Alt-A"), _("Show or hide the activity tab."), wxITEM_CHECK);
 
190
    viewMenu->Append(MNU_LOCKPAGE, _("&Locks\tCtrl-Alt-L"), _("Show or hide the locks tab."), wxITEM_CHECK);
 
191
    viewMenu->Append(MNU_XACTPAGE, _("&Transactions\tCtrl-Alt-T"), _("Show or hide the transactions tab."), wxITEM_CHECK);
 
192
    viewMenu->Append(MNU_LOGPAGE, _("Log&file\tCtrl-Alt-F"), _("Show or hide the logfile tab."), wxITEM_CHECK);
 
193
    viewMenu->AppendSeparator();
 
194
    viewMenu->Append(MNU_TOOLBAR, _("Tool&bar\tCtrl-Alt-B"), _("Show or hide the toolbar."), wxITEM_CHECK);
 
195
    viewMenu->AppendSeparator();
 
196
    viewMenu->Append(MNU_DEFAULTVIEW, _("&Default view\tCtrl-Alt-V"), _("Restore the default view."));
 
197
 
 
198
    menuBar->Append(viewMenu, _("&View"));
 
199
 
 
200
    wxMenu *helpMenu=new wxMenu();
 
201
    helpMenu->Append(MNU_CONTENTS, _("&Help"), _("Open the helpfile."));
 
202
 
 
203
    menuBar->Append(helpMenu, _("&Help"));
 
204
    
 
205
    // Setup edit menu
 
206
    editMenu->Enable(MNU_COPY, false);
 
207
 
 
208
    // Finish menu bar
 
209
    SetMenuBar(menuBar);
 
210
    
 
211
    // Set statusBar
 
212
    statusBar = CreateStatusBar(1);
 
213
    SetStatusBarPane(-1);
 
214
    
 
215
    // Set up toolbar
 
216
    toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER);
 
217
    toolBar->SetToolBitmapSize(wxSize(16, 16));
 
218
    toolBar->AddTool(MNU_REFRESH, _("Refresh"), wxBitmap(readdata_xpm), _("Refresh"), wxITEM_NORMAL);
 
219
    toolBar->AddSeparator();
 
220
    toolBar->AddTool(MNU_COPY, _("Copy"), wxBitmap(clip_copy_xpm), _("Copy selected text to clipboard"), wxITEM_NORMAL);
 
221
    toolBar->AddSeparator();
 
222
    toolBar->AddTool(MNU_CANCEL, _("Cancel"), wxBitmap(query_cancel_xpm), _("Cancel query"), wxITEM_NORMAL);
 
223
    toolBar->AddTool(MNU_TERMINATE, _("Terminate"), wxBitmap(terminate_backend_xpm), _("Terminate backend"), wxITEM_NORMAL);
 
224
    toolBar->AddTool(MNU_COMMIT, _("Commit"), wxBitmap(storedata_xpm), _("Commit transaction"), wxITEM_NORMAL);
 
225
    toolBar->AddTool(MNU_ROLLBACK, _("Rollback"), wxBitmap(delete_xpm), _("Rollback transaction"), wxITEM_NORMAL);
 
226
    toolBar->AddSeparator();
 
227
    cbLogfiles = new wxComboBox(toolBar, CTL_LOGCBO, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL,
 
228
    wxCB_READONLY|wxCB_DROPDOWN);
 
229
    toolBar->AddControl(cbLogfiles);
 
230
    btnRotateLog = new wxButton(toolBar, CTL_ROTATEBTN, _("Rotate"));
 
231
    toolBar->AddControl(btnRotateLog);
 
232
    toolBar->AddSeparator();
 
233
    cbRate = new ctlComboBoxFix(toolBar, CTL_RATECBO, wxDefaultPosition, wxSize(-1, -1), wxCB_READONLY|wxCB_DROPDOWN);
 
234
    toolBar->AddControl(cbRate);
 
235
    toolBar->Realize();
 
236
 
 
237
    // Append items to cbo
 
238
    cbRate->Append(_("Don't refresh"));
 
239
    cbRate->Append(_("1 second"));
 
240
    cbRate->Append(_("5 seconds"));
 
241
    cbRate->Append(_("10 seconds"));
 
242
    cbRate->Append(_("30 seconds"));
 
243
    cbRate->Append(_("1 minute"));
 
244
    cbRate->Append(_("5 minutes"));
 
245
    cbRate->Append(_("10 minutes"));
 
246
    cbRate->Append(_("30 minutes"));
 
247
    cbRate->Append(_("1 hour"));
 
248
    
 
249
    // Disable toolbar's items
 
250
    toolBar->EnableTool(MNU_CANCEL, false);
 
251
    toolBar->EnableTool(MNU_TERMINATE, false);
 
252
    toolBar->EnableTool(MNU_COMMIT, false);
 
253
    toolBar->EnableTool(MNU_ROLLBACK, false);
 
254
    cbLogfiles->Enable(false);
 
255
    btnRotateLog->Enable(false);
 
256
    
 
257
    // Create panel
 
258
    AddStatusPane();
 
259
    AddLockPane();
 
260
    AddXactPane();
 
261
    AddLogPane();
 
262
    manager.AddPane(toolBar, wxAuiPaneInfo().Name(wxT("toolBar")).Caption(_("Tool bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false));
 
263
 
 
264
    // Now load the layout
 
265
    wxString perspective;
 
266
    settings->Read(wxT("frmStatus/Perspective-") + VerFromRev(FRMSTATUS_PERSPECTIVE_VER), &perspective, FRMSTATUS_DEFAULT_PERSPECTIVE);
 
267
    manager.LoadPerspective(perspective, true);
 
268
 
 
269
    // Reset the captions for the current language
 
270
    manager.GetPane(wxT("toolBar")).Caption(_("Tool bar"));
 
271
    manager.GetPane(wxT("Activity")).Caption(_("Activity"));
 
272
    manager.GetPane(wxT("Locks")).Caption(_("Locks"));
 
273
    manager.GetPane(wxT("Transactions")).Caption(_("Transactions"));
 
274
    manager.GetPane(wxT("Logfile")).Caption(_("Logfile"));
 
275
 
 
276
    // Tell the manager to "commit" all the changes just made
 
277
    manager.Update();
 
278
 
 
279
    // Sync the View menu options
 
280
    viewMenu->Check(MNU_STATUSPAGE, manager.GetPane(wxT("Activity")).IsShown());
 
281
    viewMenu->Check(MNU_LOCKPAGE, manager.GetPane(wxT("Locks")).IsShown());
 
282
    viewMenu->Check(MNU_XACTPAGE, manager.GetPane(wxT("Transactions")).IsShown());
 
283
    viewMenu->Check(MNU_LOGPAGE, manager.GetPane(wxT("Logfile")).IsShown());
 
284
    viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown());
 
285
 
 
286
    // Get our PID
 
287
    backend_pid = connection->GetBackendPID();
 
288
    
 
289
    // Create the refresh timer (quarter of a second)
 
290
    // This is a horrible hack to get around the lack of a 
 
291
    // PANE_ACTIVATED event in wxAUI.
 
292
    refreshUITimer = new wxTimer(this, TIMER_REFRESHUI_ID);
 
293
    refreshUITimer->Start(250);
 
294
 
 
295
    // We're good now
 
296
    loaded = true;
 
297
}
 
298
 
 
299
 
 
300
frmStatus::~frmStatus()
 
301
{
 
302
    // Delete the refresh timer
 
303
    delete refreshUITimer;
 
304
    
 
305
    // If the status window wasn't launched in standalone mode...
 
306
    if (mainForm)
 
307
        mainForm->RemoveFrame(this);
 
308
 
 
309
    // Save the window's position
 
310
    settings->Write(wxT("frmStatus/Perspective-") + VerFromRev(FRMSTATUS_PERSPECTIVE_VER), manager.SavePerspective());
 
311
    manager.UnInit();
 
312
    SavePosition();
 
313
    
 
314
    // For each current page, save the slider's position and delete the timer
 
315
    settings->Write(wxT("frmStatus/RefreshStatusRate"), statusRate);
 
316
    delete statusTimer;
 
317
    settings->Write(wxT("frmStatus/RefreshLockRate"), locksRate);
 
318
    delete locksTimer;
 
319
    if (viewMenu->IsEnabled(MNU_XACTPAGE))
 
320
    {
 
321
        settings->Write(wxT("frmStatus/RefreshXactRate"), xactRate);
 
322
        if (xactTimer)
 
323
        {
 
324
            delete xactTimer;
 
325
            xactTimer = NULL;
 
326
        }
 
327
    }
 
328
    if (viewMenu->IsEnabled(MNU_LOGPAGE))
 
329
    {
 
330
        settings->Write(wxT("frmStatus/RefreshLogRate"), logRate);
 
331
        emptyLogfileCombo();
 
332
        if (logTimer)
 
333
        {
 
334
            delete logTimer;
 
335
            logTimer = NULL;
 
336
        }
 
337
    }
 
338
 
 
339
    // If connection is still available, delete it
 
340
    if (connection)
 
341
        delete connection;
 
342
}
 
343
 
 
344
 
 
345
void frmStatus::Go()
 
346
{
 
347
    // Show the window
 
348
    Show(true);
 
349
    
 
350
    // Send RateChange event to launch each timer
 
351
    wxScrollEvent nullScrollEvent;
 
352
    if (viewMenu->IsChecked(MNU_STATUSPAGE))
 
353
    {
 
354
        currentPane = PANE_STATUS;
 
355
        cbRate->SetValue(rateToCboString(statusRate));
 
356
        OnRateChange(nullScrollEvent);
 
357
    }
 
358
    if (viewMenu->IsChecked(MNU_LOCKPAGE))
 
359
    {
 
360
        currentPane = PANE_LOCKS;
 
361
        cbRate->SetValue(rateToCboString(locksRate));
 
362
        OnRateChange(nullScrollEvent);
 
363
    }
 
364
    if (viewMenu->IsEnabled(MNU_XACTPAGE) && viewMenu->IsChecked(MNU_XACTPAGE))
 
365
    {
 
366
        currentPane = PANE_XACT;
 
367
        cbRate->SetValue(rateToCboString(xactRate));
 
368
        OnRateChange(nullScrollEvent);
 
369
    }
 
370
    if (viewMenu->IsEnabled(MNU_LOGPAGE) && viewMenu->IsChecked(MNU_LOGPAGE))
 
371
    {
 
372
        currentPane = PANE_LOG;
 
373
        cbRate->SetValue(rateToCboString(logRate));
 
374
        OnRateChange(nullScrollEvent);
 
375
    }
 
376
 
 
377
    // Refresh all pages
 
378
    wxCommandEvent nullEvent;
 
379
    OnRefresh(nullEvent);
 
380
}
 
381
 
 
382
 
 
383
void frmStatus::OnClose(wxCloseEvent &event)
 
384
{
 
385
    Destroy();
 
386
}
 
387
 
 
388
 
 
389
void frmStatus::OnExit(wxCommandEvent& event)
 
390
{
 
391
    Destroy();
 
392
}
 
393
 
 
394
 
 
395
void frmStatus::AddStatusPane()
 
396
{
 
397
    // Create panel
 
398
    wxPanel *pnlActivity = new wxPanel(this);
 
399
    
 
400
    // Create flex grid
 
401
    wxFlexGridSizer *grdActivity = new wxFlexGridSizer(1, 1, 5, 5);
 
402
    grdActivity->AddGrowableCol(0);
 
403
    grdActivity->AddGrowableRow(0);
 
404
 
 
405
    // Add the list control
 
406
    wxListCtrl *lstStatus = new wxListCtrl(pnlActivity, CTL_STATUSLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxSUNKEN_BORDER);
 
407
    grdActivity->Add(lstStatus, 0, wxGROW, 3);
 
408
 
 
409
    // Add the panel to the notebook
 
410
    manager.AddPane(pnlActivity,
 
411
      wxAuiPaneInfo().
 
412
      Name(wxT("Activity")).Caption(_("Activity")).
 
413
      CaptionVisible(true).CloseButton(true).MaximizeButton(true).
 
414
      Dockable(true).Movable(true));
 
415
    
 
416
    // Auto-sizing
 
417
    pnlActivity->SetSizer(grdActivity);
 
418
    grdActivity->Fit(pnlActivity);
 
419
    
 
420
    // Add each column to the list control
 
421
    statusList = (ctlListView*)lstStatus;
112
422
    statusList->AddColumn(wxT("PID"), 35);
113
423
    statusList->AddColumn(_("Database"), 70);
114
424
    statusList->AddColumn(_("User"), 70);
115
425
    if (connection->BackendMinimumVersion(8, 1))
116
 
        {
 
426
    {
117
427
        statusList->AddColumn(_("Client"), 70);
118
 
                statusList->AddColumn(_("Client start"), 80);
119
 
        }
120
 
 
 
428
        statusList->AddColumn(_("Client start"), 80);
 
429
    }
121
430
    if (connection->BackendMinimumVersion(7, 4))
122
431
        statusList->AddColumn(_("Query start"), 50);
123
 
 
124
432
    if (connection->BackendMinimumVersion(8, 3))
125
433
        statusList->AddColumn(_("TX start"), 50);
126
 
 
 
434
    statusList->AddColumn(_("Blocked by"), 35);
127
435
    statusList->AddColumn(_("Query"), 500);
128
436
 
 
437
    // Read statusRate configuration
 
438
    settings->Read(wxT("frmStatus/RefreshStatusRate"), &statusRate, 10);
 
439
    
 
440
    // Create the timer
 
441
    statusTimer = new wxTimer(this, TIMER_STATUS_ID);
 
442
}
 
443
 
 
444
 
 
445
void frmStatus::AddLockPane()
 
446
{
 
447
    // Create panel
 
448
    wxPanel *pnlLock = new wxPanel(this);
 
449
    
 
450
    // Create flex grid
 
451
    wxFlexGridSizer *grdLock = new wxFlexGridSizer(1, 1, 5, 5);
 
452
    grdLock->AddGrowableCol(0);
 
453
    grdLock->AddGrowableRow(0);
 
454
 
 
455
    // Add the list control
 
456
    wxListCtrl *lstLocks = new wxListCtrl(pnlLock, CTL_LOCKLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxSUNKEN_BORDER);
 
457
    grdLock->Add(lstLocks, 0, wxGROW, 3);
 
458
 
 
459
    // Add the panel to the notebook
 
460
    manager.AddPane(pnlLock,
 
461
      wxAuiPaneInfo().
 
462
      Name(wxT("Locks")).Caption(_("Locks")).
 
463
      CaptionVisible(true).CloseButton(true).MaximizeButton(true).
 
464
      Dockable(true).Movable(true));
 
465
    
 
466
    // Auto-sizing
 
467
    pnlLock->SetSizer(grdLock);
 
468
    grdLock->Fit(pnlLock);
 
469
 
 
470
    // Add each column to the list control
 
471
    lockList = (ctlListView*)lstLocks;
129
472
    lockList->AddColumn(wxT("PID"), 35);
130
473
    lockList->AddColumn(_("Database"), 50);
131
474
    lockList->AddColumn(_("Relation"), 50);
137
480
    lockList->AddColumn(_("Granted"), 50);
138
481
    if (connection->BackendMinimumVersion(7, 4))
139
482
        lockList->AddColumn(_("Start"), 50);
140
 
 
141
483
    lockList->AddColumn(_("Query"), 500);
142
484
 
143
 
    if (connection->BackendMinimumVersion(8, 1))
144
 
    {
145
 
        xactList->AddColumn(wxT("XID"), 50);
146
 
        xactList->AddColumn(_("Global ID"), 200);
147
 
        xactList->AddColumn(_("Time"), 100);
148
 
        xactList->AddColumn(_("Owner"), 50);
149
 
        xactList->AddColumn(_("Database"), 50);
150
 
    }
151
 
    else
152
 
    {
153
 
        nbStatus->DeletePage(xactPage);
154
 
        logPage--;
155
 
        xactPage=-5;
156
 
    }
157
 
 
158
 
    if (connection->BackendMinimumVersion(8, 0) && 
159
 
                 connection->HasFeature(FEATURE_FILEREAD))
160
 
    {
161
 
        logFormat = connection->ExecuteScalar(wxT("SHOW log_line_prefix"));
162
 
        if (logFormat == wxT("unset"))
163
 
            logFormat = wxEmptyString;
164
 
        logFmtPos=logFormat.Find('%', true);
165
 
 
166
 
        if (logFmtPos < 0)
167
 
            logFormatKnown = true;
168
 
        else if (!logFmtPos && logFormat.Mid(logFmtPos, 2) == wxT("%t") && logFormat.Length() > 2)
169
 
        {
170
 
            logFormatKnown = true;
171
 
            logHasTimestamp = true;
 
485
    // Read locksRate configuration
 
486
    settings->Read(wxT("frmStatus/RefreshLockRate"), &locksRate, 10);
 
487
    
 
488
    // Create the timer
 
489
    locksTimer = new wxTimer(this, TIMER_LOCKS_ID);
 
490
}
 
491
 
 
492
 
 
493
void frmStatus::AddXactPane()
 
494
{
 
495
    // Create panel
 
496
    wxPanel *pnlXacts = new wxPanel(this);
 
497
    
 
498
    // Create flex grid
 
499
    wxFlexGridSizer *grdXacts = new wxFlexGridSizer(1, 1, 5, 5);
 
500
    grdXacts->AddGrowableCol(0);
 
501
    grdXacts->AddGrowableRow(0);
 
502
 
 
503
    // Add the list control
 
504
    wxListCtrl *lstXacts = new wxListCtrl(pnlXacts, CTL_LOCKLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxSUNKEN_BORDER);
 
505
    grdXacts->Add(lstXacts, 0, wxGROW, 3);
 
506
 
 
507
    // Add the panel to the notebook
 
508
    manager.AddPane(pnlXacts,
 
509
      wxAuiPaneInfo().
 
510
      Name(wxT("Transactions")).Caption(_("Transactions")).
 
511
      CaptionVisible(true).CloseButton(true).MaximizeButton(true).
 
512
      Dockable(true).Movable(true));
 
513
 
 
514
    // Auto-sizing
 
515
    pnlXacts->SetSizer(grdXacts);
 
516
    grdXacts->Fit(pnlXacts);
 
517
 
 
518
    // Add the xact list
 
519
    xactList = (ctlListView*)lstXacts;
 
520
 
 
521
    // We don't need this report if server release is less than 8.1
 
522
    // GPDB doesn't have external global transactions.
 
523
    // Perhaps we should use this display to show our
 
524
    // global xid to local xid mappings?
 
525
    if (!connection->BackendMinimumVersion(8, 1) || connection->GetIsGreenplum())
 
526
    {
 
527
        // manager.GetPane(wxT("Transactions")).Show(false);
 
528
        lstXacts->InsertColumn(lstXacts->GetColumnCount(), _("Message"), wxLIST_FORMAT_LEFT, 800);
 
529
        lstXacts->InsertItem(lstXacts->GetItemCount(), _("Prepared transactions not available on this server."));
 
530
        lstXacts->Enable(false);
 
531
        xactTimer = NULL;
 
532
        
 
533
        // We're done
 
534
        return;
 
535
    }
 
536
 
 
537
    // Add each column to the list control
 
538
    xactList->AddColumn(wxT("XID"), 50);
 
539
    xactList->AddColumn(_("Global ID"), 200);
 
540
    xactList->AddColumn(_("Time"), 100);
 
541
    xactList->AddColumn(_("Owner"), 50);
 
542
    xactList->AddColumn(_("Database"), 50);
 
543
 
 
544
    // Read xactRate configuration
 
545
    settings->Read(wxT("frmStatus/RefreshXactRate"), &xactRate, 10);
 
546
    
 
547
    // Create the timer
 
548
    xactTimer = new wxTimer(this, TIMER_XACT_ID);
 
549
}
 
550
 
 
551
 
 
552
void frmStatus::AddLogPane()
 
553
{
 
554
    // Create panel
 
555
    wxPanel *pnlLog = new wxPanel(this);
 
556
 
 
557
    // Create flex grid
 
558
    wxFlexGridSizer *grdLog = new wxFlexGridSizer(1, 1, 5, 5);
 
559
    grdLog->AddGrowableCol(0);
 
560
    grdLog->AddGrowableRow(0);
 
561
 
 
562
    // Add the list control
 
563
    wxListCtrl *lstLog = new wxListCtrl(pnlLog, CTL_LOGLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxSUNKEN_BORDER);
 
564
    grdLog->Add(lstLog, 0, wxGROW, 3);
 
565
    
 
566
    // Add the panel to the notebook
 
567
    manager.AddPane(pnlLog,
 
568
      wxAuiPaneInfo().Center().
 
569
      Name(wxT("Logfile")).Caption(_("Logfile")).
 
570
      CaptionVisible(true).CloseButton(true).MaximizeButton(true).
 
571
      Dockable(true).Movable(true));
 
572
 
 
573
    // Auto-sizing
 
574
    pnlLog->SetSizer(grdLog);
 
575
    grdLog->Fit(pnlLog);
 
576
 
 
577
    // Add the log list
 
578
    logList = (ctlListView*)lstLog;
 
579
 
 
580
    // We don't need this report (but we need the pane)
 
581
    // if server release is less than 8.0 or if server has no adminpack
 
582
    if (!(connection->BackendMinimumVersion(8, 0) && 
 
583
         connection->HasFeature(FEATURE_FILEREAD)))
 
584
    {
 
585
        if (connection->BackendMinimumVersion(8, 0))
 
586
            frmHint::ShowHint(this, HINT_INSTRUMENTATION);
 
587
        
 
588
        logList->InsertColumn(logList->GetColumnCount(), _("Message"), wxLIST_FORMAT_LEFT, 800);
 
589
        logList->InsertItem(logList->GetItemCount(), _("Logs are not available for this server."));
 
590
        logList->Enable(false);
 
591
        logTimer = NULL;
 
592
        // We're done
 
593
        return;
 
594
    }
 
595
 
 
596
    // Add each column to the list control
 
597
    logFormat = connection->ExecuteScalar(wxT("SHOW log_line_prefix"));
 
598
    if (logFormat == wxT("unset"))
 
599
        logFormat = wxEmptyString;
 
600
    logFmtPos=logFormat.Find('%', true);
 
601
 
 
602
    if (logFmtPos < 0)
 
603
        logFormatKnown = true;  // log_line_prefix not specified.
 
604
    else if (!logFmtPos && logFormat.Mid(logFmtPos, 2) == wxT("%t") && logFormat.Length() > 2)  // Timestamp at end of log_line_prefix?
 
605
    {
 
606
        logFormatKnown = true;
 
607
        logHasTimestamp = true;
 
608
    }
 
609
    else if (connection->GetIsGreenplum())  
 
610
    {
 
611
        // Always %m|%u|%d|%p|%I|%X|:- (timestamp w/ millisec) for 3.2.x
 
612
        // Usually CSV formatted for 3.3
 
613
        logFormatKnown = true;
 
614
        logHasTimestamp = true;
 
615
    }
 
616
 
 
617
 
 
618
    if (connection->GetIsGreenplum() && connection->BackendMinimumVersion(8,2,13))
 
619
    {
 
620
        // Be ready for GPDB CSV format log file
 
621
        logList->AddColumn(_("Timestamp"), 120);  // Room for millisecs
 
622
        logList->AddColumn(_("Level"), 35);
 
623
        logList->AddColumn(_("Log entry"), 400);
 
624
        logList->AddColumn(_("Connection"), 45);
 
625
        logList->AddColumn(_("Cmd number"), 48);
 
626
        logList->AddColumn(_("Dbname"), 48);
 
627
        logList->AddColumn(_("Segment"), 45);
 
628
    }
 
629
    else    // Non-GPDB or non-CSV format log
 
630
    {
 
631
        if (logHasTimestamp)
172
632
            logList->AddColumn(_("Timestamp"), 100);
173
 
        }
174
633
 
175
634
        if (logFormatKnown)
176
635
            logList->AddColumn(_("Level"), 35);
177
636
 
178
637
        logList->AddColumn(_("Log entry"), 800);
179
 
 
180
 
        if (!connection->HasFeature(FEATURE_ROTATELOG))
181
 
            btnRotateLog->Disable();
182
 
    }
183
 
    else
184
 
    {
185
 
        if (connection->BackendMinimumVersion(8, 0))
186
 
            frmHint::ShowHint(this, HINT_INSTRUMENTATION);
187
 
 
188
 
        nbStatus->DeletePage(logPage);
189
 
        logPage=-5;
190
 
    }
191
 
    long rate;
192
 
    settings->Read(wxT("frmStatus/Refreshrate"), &rate, 1);
193
 
    slRate->SetValue(rate);
194
 
 
195
 
    wxString msg;
196
 
    switch (rate)
197
 
    {
198
 
    case 0:
199
 
        msg.Printf(_("Stopped"));
200
 
        break;
201
 
    case 1:
202
 
        msg.Printf(_("1 second"));
203
 
        break;
204
 
    default:
205
 
        msg.Printf(_("%d seconds"), rate);
206
 
        break;
207
 
    }
208
 
    stRate->SetLabel(msg);
209
 
 
210
 
    timer=new wxTimer(this, TIMER_ID);
211
 
 
212
 
        btnCancelSt->Enable(false);
213
 
        btnTerminateSt->Enable(false);
214
 
        btnCancelLk->Enable(false);
215
 
        btnTerminateLk->Enable(false);
216
 
    if (connection->BackendMinimumVersion(8, 1))
217
 
    {
218
 
            btnCommit->Enable(false);
219
 
            btnRollback->Enable(false);
220
 
    }
221
 
 
222
 
        loaded = true;
223
 
}
224
 
 
225
 
 
226
 
frmStatus::~frmStatus()
227
 
{
228
 
    mainForm->RemoveFrame(this);
229
 
 
230
 
    SavePosition();
231
 
    settings->Write(wxT("frmStatus/Refreshrate"), slRate->GetValue());
232
 
 
233
 
    delete timer;
234
 
    if (connection)
235
 
        delete connection;
236
 
 
237
 
    if (logPage > 0)
238
 
        emptyLogfileCombo();
239
 
}
240
 
 
241
 
 
242
 
void frmStatus::Go()
243
 
{
244
 
    Show(true);
245
 
    wxCommandEvent nullEvent;
246
 
 
247
 
    long rate = slRate->GetValue();
248
 
    
249
 
    wxString msg;
250
 
    switch (rate)
251
 
    {
252
 
    case 0:
253
 
        msg.Printf(_("Stopped"));
254
 
        break;
255
 
    case 1:
256
 
        msg.Printf(_("1 second"));
257
 
        break;
258
 
    default:
259
 
        msg.Printf(_("%d seconds"), rate);
260
 
        break;
261
 
    }
262
 
    stRate->SetLabel(msg);
263
 
 
264
 
    if (rate)
265
 
        timer->Start(rate*1000L);
266
 
 
267
 
    OnRefresh(nullEvent);
268
 
}
269
 
 
270
 
 
271
 
void frmStatus::OnNotebookPageChanged(wxNotebookEvent& event)
272
 
{
273
 
        if (!loaded) return;
274
 
        wxCommandEvent buttonEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_REFRESH);
275
 
    AddPendingEvent(buttonEvent);
276
 
        
277
 
    // Disable the buttons. They'll get re-enabled if a suitable item is selected.
278
 
        btnCancelSt->Enable(false);
279
 
        btnTerminateSt->Enable(false);
280
 
        btnCancelLk->Enable(false);
281
 
        btnTerminateLk->Enable(false);
282
 
    if (connection->BackendMinimumVersion(8, 1))
283
 
    {
284
 
        btnCommit->Enable(false);
285
 
            btnRollback->Enable(false);
286
 
    }
287
 
}
288
 
 
289
 
 
290
 
void frmStatus::OnRateChange(wxScrollEvent &event)
291
 
{
 
638
    }
 
639
 
 
640
    if (!connection->HasFeature(FEATURE_ROTATELOG))
 
641
        btnRotateLog->Disable();
 
642
 
 
643
    // Re-initialize variables
 
644
    logfileLength = 0;
 
645
        
 
646
    // Read logRate configuration
 
647
    settings->Read(wxT("frmStatus/RefreshLogRate"), &logRate, 10);
 
648
        
 
649
    // Create the timer
 
650
    logTimer = new wxTimer(this, TIMER_LOG_ID);
 
651
}
 
652
 
 
653
 
 
654
void frmStatus::OnCopy(wxCommandEvent& ev)
 
655
{
 
656
    ctlListView *list;
 
657
    int row, col;
 
658
    wxString text;
 
659
    
 
660
    switch(currentPane)
 
661
    {
 
662
        case PANE_STATUS:
 
663
            list = statusList;
 
664
            break;
 
665
        case PANE_LOCKS:
 
666
            list = lockList;
 
667
            break;
 
668
        case PANE_XACT:
 
669
            list = xactList;
 
670
            break;
 
671
        case PANE_LOG:
 
672
            list = logList;
 
673
            break;
 
674
        default:
 
675
            // This shouldn't happen.
 
676
            // If it does, it's no big deal, we just need to get out.
 
677
            return;
 
678
            break;
 
679
    }
 
680
    
 
681
    row = list->GetFirstSelected();
 
682
    
 
683
    while (row >= 0)
 
684
    {
 
685
        for (col = 0; col < list->GetColumnCount(); col++)
 
686
        {
 
687
            text.Append(list->GetText(row, col) + wxT("\t"));
 
688
        }
 
689
#ifdef __WXMSW__
 
690
        text.Append(wxT("\r\n"));
 
691
#else
 
692
        text.Append(wxT("\n"));
 
693
#endif
 
694
        row = list->GetNextSelected(row);
 
695
    }
 
696
    
 
697
    if (text.Length() > 0 && wxTheClipboard->Open())
 
698
    {
 
699
        wxTheClipboard->SetData(new wxTextDataObject(text));
 
700
        wxTheClipboard->Close();
 
701
    }
 
702
}
 
703
 
 
704
 
 
705
void frmStatus::OnPaneClose(wxAuiManagerEvent& evt)
 
706
{
 
707
    if (evt.pane->name == wxT("Activity"))
 
708
    {
 
709
        viewMenu->Check(MNU_STATUSPAGE, false);
 
710
        statusTimer->Stop();
 
711
    }
 
712
    if (evt.pane->name == wxT("Locks"))
 
713
    {
 
714
        viewMenu->Check(MNU_LOCKPAGE, false);
 
715
        locksTimer->Stop();
 
716
    }
 
717
    if (evt.pane->name == wxT("Transactions"))
 
718
    {
 
719
        viewMenu->Check(MNU_XACTPAGE, false);
 
720
        if (xactTimer)
 
721
            xactTimer->Stop();
 
722
    }
 
723
    if (evt.pane->name == wxT("Logfile"))
 
724
    {
 
725
        viewMenu->Check(MNU_LOGPAGE, false);
 
726
        if (logTimer)
 
727
            logTimer->Stop();
 
728
    }
 
729
}
 
730
 
 
731
 
 
732
void frmStatus::OnToggleStatusPane(wxCommandEvent& event)
 
733
{
 
734
    if (viewMenu->IsChecked(MNU_STATUSPAGE))
 
735
    {
 
736
        manager.GetPane(wxT("Activity")).Show(true);
 
737
        cbRate->SetValue(rateToCboString(statusRate));
 
738
        if (statusRate > 0)
 
739
            statusTimer->Start(statusRate*1000L);
 
740
    }
 
741
    else
 
742
    {
 
743
        manager.GetPane(wxT("Activity")).Show(false);
 
744
        statusTimer->Stop();
 
745
    }
 
746
 
 
747
    // Tell the manager to "commit" all the changes just made
 
748
    manager.Update();
 
749
}
 
750
 
 
751
 
 
752
void frmStatus::OnToggleLockPane(wxCommandEvent& event)
 
753
{
 
754
    if (viewMenu->IsChecked(MNU_LOCKPAGE))
 
755
    {
 
756
        manager.GetPane(wxT("Locks")).Show(true);
 
757
        cbRate->SetValue(rateToCboString(locksRate));
 
758
        if (locksRate > 0)
 
759
            locksTimer->Start(locksRate*1000L);
 
760
    }
 
761
    else
 
762
    {
 
763
        manager.GetPane(wxT("Locks")).Show(false);
 
764
        locksTimer->Stop();
 
765
    }
 
766
    
 
767
    // Tell the manager to "commit" all the changes just made
 
768
    manager.Update();
 
769
}
 
770
 
 
771
 
 
772
void frmStatus::OnToggleXactPane(wxCommandEvent& event)
 
773
{
 
774
    if (viewMenu->IsEnabled(MNU_XACTPAGE) && viewMenu->IsChecked(MNU_XACTPAGE))
 
775
    {
 
776
        manager.GetPane(wxT("Transactions")).Show(true);
 
777
        cbRate->SetValue(rateToCboString(xactRate));
 
778
        if (xactRate > 0 && xactTimer)
 
779
            xactTimer->Start(xactRate*1000L);
 
780
    }
 
781
    else
 
782
    {
 
783
        manager.GetPane(wxT("Transactions")).Show(false);
 
784
        if (xactTimer)
 
785
            xactTimer->Stop();
 
786
    }
 
787
    
 
788
    // Tell the manager to "commit" all the changes just made
 
789
    manager.Update();
 
790
}
 
791
 
 
792
 
 
793
void frmStatus::OnToggleLogPane(wxCommandEvent& event)
 
794
{
 
795
    if (viewMenu->IsEnabled(MNU_LOGPAGE) && viewMenu->IsChecked(MNU_LOGPAGE))
 
796
    {
 
797
        manager.GetPane(wxT("Logfile")).Show(true);
 
798
        cbRate->SetValue(rateToCboString(logRate));
 
799
        if (logRate > 0 && logTimer)
 
800
            logTimer->Start(logRate*1000L);
 
801
    }
 
802
    else
 
803
    {
 
804
        manager.GetPane(wxT("Logfile")).Show(false);
 
805
        if (logTimer)
 
806
            logTimer->Stop();
 
807
    }
 
808
    
 
809
    // Tell the manager to "commit" all the changes just made
 
810
    manager.Update();
 
811
}
 
812
 
 
813
 
 
814
void frmStatus::OnToggleToolBar(wxCommandEvent& event)
 
815
{
 
816
    if (viewMenu->IsChecked(MNU_TOOLBAR))
 
817
    {
 
818
        manager.GetPane(wxT("toolBar")).Show(true);
 
819
    }
 
820
    else
 
821
    {
 
822
        manager.GetPane(wxT("toolBar")).Show(false);
 
823
    }
 
824
    
 
825
    // Tell the manager to "commit" all the changes just made
 
826
    manager.Update();
 
827
}
 
828
 
 
829
 
 
830
void frmStatus::OnDefaultView(wxCommandEvent& event)
 
831
{
 
832
    manager.LoadPerspective(FRMSTATUS_DEFAULT_PERSPECTIVE, true);
 
833
 
 
834
    // Reset the captions for the current language
 
835
    manager.GetPane(wxT("toolBar")).Caption(_("Tool bar"));
 
836
    manager.GetPane(wxT("Activity")).Caption(_("Activity"));
 
837
    manager.GetPane(wxT("Locks")).Caption(_("Locks"));
 
838
    manager.GetPane(wxT("Transactions")).Caption(_("Transactions"));
 
839
    manager.GetPane(wxT("Logfile")).Caption(_("Logfile"));
 
840
 
 
841
    // tell the manager to "commit" all the changes just made
 
842
    manager.Update();
 
843
 
 
844
    // Sync the View menu options
 
845
    viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown());
 
846
    viewMenu->Check(MNU_STATUSPAGE, manager.GetPane(wxT("Activity")).IsShown());
 
847
    viewMenu->Check(MNU_LOCKPAGE, manager.GetPane(wxT("Locks")).IsShown());
 
848
    viewMenu->Check(MNU_XACTPAGE, manager.GetPane(wxT("Transactions")).IsShown());
 
849
    viewMenu->Check(MNU_LOGPAGE, manager.GetPane(wxT("Logfile")).IsShown());
 
850
}
 
851
 
 
852
 
 
853
void frmStatus::OnHelp(wxCommandEvent& event)
 
854
{
 
855
    wxString page;
 
856
    if (page.IsEmpty())
 
857
        page=wxT("sql-commands");
 
858
 
 
859
    if (connection->GetIsEdb())
 
860
        DisplayHelp(page, HELP_ENTERPRISEDB);
 
861
    else
 
862
        DisplayHelp(page, HELP_POSTGRESQL);
 
863
}
 
864
 
 
865
 
 
866
void frmStatus::OnRateChange(wxCommandEvent &event)
 
867
{
 
868
    wxTimer *timer;
 
869
    int rate;
 
870
    
 
871
    switch(currentPane)
 
872
    {
 
873
        case PANE_STATUS:
 
874
            timer = statusTimer;
 
875
            rate = cboToRate();
 
876
            statusRate = rate;
 
877
            break;
 
878
        case PANE_LOCKS:
 
879
            timer = locksTimer;
 
880
            rate = cboToRate();
 
881
            locksRate = rate;
 
882
            break;
 
883
        case PANE_XACT:
 
884
            timer = xactTimer;
 
885
            rate = cboToRate();
 
886
            xactRate = rate;
 
887
            break;
 
888
        case PANE_LOG:
 
889
            timer = logTimer;
 
890
            rate = cboToRate();
 
891
            logRate = rate;
 
892
            break;
 
893
        default:
 
894
            // This shouldn't happen.
 
895
            // If it does, it's no big deal, we just need to get out.
 
896
            return;
 
897
            break;
 
898
    }
 
899
 
292
900
    if (timer)
293
901
    {
294
902
        timer->Stop();
295
 
 
296
 
        long rate = slRate->GetValue();
297
 
        
298
 
        wxString msg;
299
 
        switch (rate)
300
 
        {
301
 
        case 0:
302
 
            msg.Printf(_("Stopped"));
303
 
            break;
304
 
        case 1:
305
 
            msg.Printf(_("1 second"));
306
 
            break;
307
 
        default:
308
 
            msg.Printf(_("%d seconds"), rate);
309
 
            break;
310
 
        }
311
 
        stRate->SetLabel(msg);
312
 
 
313
 
        if (rate)
314
 
        {
 
903
        if (rate > 0)
315
904
            timer->Start(rate*1000L);
316
 
            OnRefresh(event);
317
 
        }
318
 
    }
319
 
}
320
 
 
321
 
 
322
 
void frmStatus::OnRefreshTimer(wxTimerEvent &event)
323
 
{
324
 
        OnRefresh(*(wxCommandEvent*)&event);
325
 
}
326
 
 
327
 
 
328
 
void frmStatus::OnRefresh(wxCommandEvent &event)
329
 
{
330
 
    long pid=0;
331
 
        // To avoid hammering the lock manager (and the network for that matter),
332
 
        // only query for the required tab.
333
 
 
334
 
        wxLogNull nolog;
335
 
 
336
 
        if (!connection)
337
 
            return;
338
 
 
339
 
    connection->ExecuteVoid(wxT("SET log_statement='none';"));
340
 
 
341
 
        if (nbStatus->GetSelection() == 0)
342
 
    {
343
 
        // Status
344
 
                long row=0;
345
 
                pgSet *dataSet1=connection->ExecuteSet(wxT("SELECT * FROM pg_stat_activity ORDER BY procpid"));
346
 
                if (dataSet1)
347
 
                {
348
 
            statusList->Freeze();
349
 
                        statusBar->SetStatusText(_("Refreshing."));
350
 
                        while (!dataSet1->Eof())
351
 
                        {
352
 
                                pid=dataSet1->GetLong(wxT("procpid"));
353
 
 
354
 
                                if (pid != backend_pid)
355
 
                                {
356
 
                                        long itempid=0;
357
 
 
358
 
                                        while (row < statusList->GetItemCount())
359
 
                                        {
360
 
                                                itempid=StrToLong(statusList->GetItemText(row));
361
 
                                                if (itempid && itempid < pid)
362
 
                                                        statusList->DeleteItem(row);
363
 
                                                else
364
 
                                                        break;
365
 
                                        }
366
 
 
367
 
                                        if (!itempid || itempid > pid)
368
 
                                        {
369
 
                                                statusList->InsertItem(row, NumToStr(pid), 0);
370
 
                                        }
371
 
                                        wxString qry=dataSet1->GetVal(wxT("current_query"));
372
 
 
373
 
                    int colpos=1;
374
 
                                        statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("datname")));
375
 
                                        statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("usename")));
376
 
 
377
 
                    if (connection->BackendMinimumVersion(8, 1))
378
 
                    {
379
 
                        wxString client=dataSet1->GetVal(wxT("client_addr")) + wxT(":") + dataSet1->GetVal(wxT("client_port"));
380
 
                        if (client == wxT(":-1"))
381
 
                            client = _("local pipe");
382
 
                        statusList->SetItem(row, colpos++, client);
383
 
 
384
 
                                                statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("backend_start")));
385
 
                    }
386
 
                    if (connection->BackendMinimumVersion(7, 4))
387
 
                                        {
388
 
                                                if (qry.IsEmpty() || qry == wxT("<IDLE>"))
389
 
                                                        statusList->SetItem(row, colpos++, wxEmptyString);
390
 
                        else
391
 
                                                        statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("query_start")));
392
 
                                        }
393
 
 
394
 
                    if (connection->BackendMinimumVersion(8, 3))
395
 
                                            statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("xact_start")));
396
 
 
397
 
                                statusList->SetItem(row, colpos, qry.Left(250));
398
 
                                        row++;
399
 
                                }
400
 
                                dataSet1->MoveNext();
401
 
                        }
402
 
            delete dataSet1;
403
 
                        
404
 
            while (row < statusList->GetItemCount())
405
 
                                statusList->DeleteItem(row);
406
 
 
407
 
            statusList->Thaw();
408
 
                        statusBar->SetStatusText(_("Done."));
409
 
                }
410
 
        else
411
 
                    checkConnection();
412
 
 
413
 
        row=0;
414
 
                while (row < statusList->GetItemCount())
415
 
                {
416
 
                        long itempid=StrToLong(statusList->GetItemText(row));
417
 
                        if (itempid && itempid > pid)
418
 
                                statusList->DeleteItem(row);
419
 
            else
420
 
                row++;
421
 
                }
422
 
        }
423
 
        else if (nbStatus->GetSelection() == 1)
424
 
    {
425
 
                // Locks
426
 
                long row=0;
427
 
                wxString sql;
428
 
                if (connection->BackendMinimumVersion(8, 3)) 
429
 
        {
430
 
            sql = wxT("SELECT ")
431
 
                  wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ")
432
 
                  wxT("pgl.relation::regclass AS class, ")
433
 
                  wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ")
434
 
                  wxT("pgl.virtualxid, pgl.virtualtransaction AS transaction, pg_stat_get_backend_pid(svrid) AS pid, pgl.mode, pgl.granted, ")
435
 
                  wxT("pg_stat_get_backend_activity(svrid) AS current_query, ")
436
 
                  wxT("pg_stat_get_backend_activity_start(svrid) AS query_start ")
437
 
                  wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ")
438
 
                  wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ")
439
 
                  wxT("ORDER BY pid;");
440
 
                } 
441
 
        else if (connection->BackendMinimumVersion(7, 4)) 
442
 
        {
443
 
            sql = wxT("SELECT ")
444
 
                  wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ")
445
 
                  wxT("pgl.relation::regclass AS class, ")
446
 
                  wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ")
447
 
                  wxT("pgl.transaction, pg_stat_get_backend_pid(svrid) AS pid, pgl.mode, pgl.granted, ")
448
 
                  wxT("pg_stat_get_backend_activity(svrid) AS current_query, ")
449
 
                  wxT("pg_stat_get_backend_activity_start(svrid) AS query_start ")
450
 
                  wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ")
451
 
                  wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ")
452
 
                  wxT("ORDER BY pid;");
453
 
                } 
454
 
        else 
455
 
        {
456
 
            sql = wxT("SELECT ")
457
 
                  wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ")
458
 
                  wxT("pgl.relation::regclass AS class, ")
459
 
                  wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ")
460
 
                  wxT("pgl.transaction, pg_stat_get_backend_pid(svrid) AS pid, pgl.mode, pgl.granted, ")
461
 
                  wxT("pg_stat_get_backend_activity(svrid) AS current_query ")
462
 
                  wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ")
463
 
                  wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ")
464
 
                  wxT("ORDER BY pid;");
465
 
                }
466
 
 
467
 
                pgSet *dataSet2=connection->ExecuteSet(sql);
468
 
                if (dataSet2)
469
 
                {
470
 
                        statusBar->SetStatusText(_("Refreshing."));
471
 
            lockList->Freeze();
472
 
 
473
 
                        while (!dataSet2->Eof())
474
 
                        {
475
 
                                pid=dataSet2->GetLong(wxT("pid"));
476
 
 
477
 
                                if (pid != backend_pid)
478
 
                                {
479
 
                                        long itempid=0;
480
 
 
481
 
                                        while (row < lockList->GetItemCount())
482
 
                                        {
483
 
                                                itempid=StrToLong(lockList->GetItemText(row));
484
 
                                                if (itempid && itempid < pid)
485
 
                                                        lockList->DeleteItem(row);
486
 
                                                else
487
 
                                                        break;
488
 
                                        }
489
 
 
490
 
                                        if (!itempid || itempid > pid)
491
 
                                        {
492
 
                                                lockList->InsertItem(row, NumToStr(pid), 0);
493
 
                                        }
494
 
 
495
 
                    int colpos=1;
496
 
                                        lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("dbname")));
497
 
                                        lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("class")));
498
 
                                        lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("user")));
499
 
                            if (connection->BackendMinimumVersion(8, 3)) 
500
 
                        lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("virtualxid")));
501
 
                                        lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("transaction")));
502
 
                                        lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("mode")));
503
 
                                        
504
 
                    if (dataSet2->GetVal(wxT("granted")) == wxT("t"))
505
 
                                                lockList->SetItem(row, colpos++, _("Yes"));
506
 
                                        else
507
 
                                                lockList->SetItem(row, colpos++, _("No"));
508
 
 
509
 
                                        wxString qry=dataSet2->GetVal(wxT("current_query"));
510
 
 
511
 
                                        if (connection->BackendMinimumVersion(7, 4))
512
 
                                        {
513
 
                                                if (qry.IsEmpty() || qry == wxT("<IDLE>"))
514
 
                                                        lockList->SetItem(row, colpos++, wxEmptyString);
515
 
                                                else
516
 
                                                        lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("query_start")));
517
 
                                        }
518
 
                    lockList->SetItem(row, colpos++, qry.Left(250));
519
 
 
520
 
 
521
 
                                        row++;
522
 
                                }
523
 
                                dataSet2->MoveNext();
524
 
                        }
525
 
 
526
 
            delete dataSet2;
527
 
                        
528
 
            while (row < lockList->GetItemCount())
529
 
                                lockList->DeleteItem(row);
530
 
 
531
 
            lockList->Thaw();
532
 
                        statusBar->SetStatusText(_("Done."));
533
 
                }
534
 
        else
535
 
            checkConnection();
536
 
 
537
 
        row=0;
538
 
                while (row < lockList->GetItemCount())
539
 
                {
540
 
                        long itempid=StrToLong(lockList->GetItemText(row));
541
 
                        if (itempid && itempid > pid)
542
 
                                lockList->DeleteItem(row);
543
 
            else
544
 
                row++;
545
 
                }
546
 
        }
547
 
    else if (nbStatus->GetSelection() == xactPage)
548
 
    {
549
 
                // Transactions
550
 
                long row=0;
551
 
                wxString sql = wxT("SELECT * FROM pg_prepared_xacts");
552
 
 
553
 
                pgSet *dataSet3=connection->ExecuteSet(sql);
554
 
                if (dataSet3)
555
 
                {
556
 
                        statusBar->SetStatusText(_("Refreshing."));
557
 
            xactList->Freeze();
558
 
 
559
 
                        while (!dataSet3->Eof())
560
 
                        {
561
 
                                long xid=dataSet3->GetLong(wxT("transaction"));
562
 
 
563
 
                                long itemxid=0;
564
 
 
565
 
                                while (row < xactList->GetItemCount())
566
 
                                {
567
 
                                        itemxid=StrToLong(xactList->GetItemText(row));
568
 
                                        if (itemxid && itemxid < xid)
569
 
                                                xactList->DeleteItem(row);
570
 
                                        else
571
 
                                                break;
572
 
                                }
573
 
 
574
 
                                if (!itemxid || itemxid > xid)
575
 
                                {
576
 
                                        xactList->InsertItem(row, NumToStr(xid), 0);
577
 
                                }
578
 
 
579
 
                int colpos=1;
580
 
                                xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("gid")));
581
 
                                xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("prepared")));
582
 
                                xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("owner")));
583
 
                                xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("database")));
584
 
 
585
 
                            row++;
586
 
                        dataSet3->MoveNext();
587
 
                        }
588
 
            delete dataSet3;
589
 
                        
 
905
    }
 
906
    OnRefresh(event);
 
907
}
 
908
 
 
909
 
 
910
void frmStatus::OnRefreshUITimer(wxTimerEvent &event)
 
911
{
 
912
    wxListEvent evt;
 
913
    
 
914
    refreshUITimer->Stop();
 
915
    
 
916
    for (unsigned int i = 0; i < manager.GetAllPanes().GetCount(); i++)
 
917
    {
 
918
        wxAuiPaneInfo& pane = manager.GetAllPanes()[i];
 
919
 
 
920
        if (pane.HasFlag(wxAuiPaneInfo::optionActive))
 
921
        {
 
922
            if (pane.name == wxT("Activity") && currentPane != PANE_STATUS)
 
923
            {
 
924
                OnSelStatusItem(evt);
 
925
            }
 
926
            if (pane.name == wxT("Locks") && currentPane != PANE_LOCKS)
 
927
            {
 
928
                OnSelLockItem(evt);
 
929
            }
 
930
            if (pane.name == wxT("Transactions") && currentPane != PANE_XACT)
 
931
            {
 
932
                OnSelXactItem(evt);
 
933
            }
 
934
            if (pane.name == wxT("Logfile") && currentPane != PANE_LOG)
 
935
            {
 
936
                OnSelLogItem(evt);
 
937
            }
 
938
        }
 
939
    }
 
940
    
 
941
    refreshUITimer->Start(250);
 
942
}
 
943
 
 
944
 
 
945
void frmStatus::OnRefreshStatusTimer(wxTimerEvent &event)
 
946
{
 
947
    long pid=0;
 
948
    
 
949
    if (! viewMenu->IsChecked(MNU_STATUSPAGE))
 
950
        return;
 
951
    
 
952
    if (!connection)
 
953
    {
 
954
        statusTimer->Stop();
 
955
        locksTimer->Stop();
 
956
        if (xactTimer)
 
957
            xactTimer->Stop();
 
958
        if (logTimer)
 
959
            logTimer->Stop();
 
960
        statusBar->SetStatusText(wxT("Connection broken."));
 
961
        return;
 
962
    }
 
963
 
 
964
    checkConnection();
 
965
    if (!connection)
 
966
        return;
 
967
    
 
968
    wxCriticalSectionLocker lock(gs_critsect);
 
969
 
 
970
    connection->ExecuteVoid(wxT("SET log_statement='none';SET log_duration='off';"),false);
 
971
 
 
972
    long row=0;
 
973
    pgSet *dataSet1=connection->ExecuteSet(wxT("SELECT *,(SELECT min(pid) FROM pg_locks l1 WHERE GRANTED AND relation IN (SELECT relation FROM pg_locks l2 WHERE l2.pid=procpid AND NOT granted)) AS blockedby FROM pg_stat_activity ORDER BY procpid"));
 
974
    if (dataSet1)
 
975
    {
 
976
        statusList->Freeze();
 
977
        statusBar->SetStatusText(_("Refreshing status list."));
 
978
        while (!dataSet1->Eof())
 
979
        {
 
980
            pid=dataSet1->GetLong(wxT("procpid"));
 
981
 
 
982
            if (pid != backend_pid)
 
983
            {
 
984
                long itempid=0;
 
985
 
 
986
                while (row < statusList->GetItemCount())
 
987
                {
 
988
                    itempid=StrToLong(statusList->GetItemText(row));
 
989
                    if (itempid && itempid < pid)
 
990
                        statusList->DeleteItem(row);
 
991
                    else
 
992
                        break;
 
993
                }
 
994
 
 
995
                if (!itempid || itempid > pid || row >= statusList->GetItemCount())
 
996
                {
 
997
                    statusList->InsertItem(row, NumToStr(pid), 0);
 
998
                }
 
999
                wxString qry=dataSet1->GetVal(wxT("current_query"));
 
1000
 
 
1001
                int colpos=1;
 
1002
                statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("datname")));
 
1003
                statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("usename")));
 
1004
 
 
1005
                if (connection->BackendMinimumVersion(8, 1))
 
1006
                {
 
1007
                     wxString client=dataSet1->GetVal(wxT("client_addr")) + wxT(":") + dataSet1->GetVal(wxT("client_port"));
 
1008
                     if (client == wxT(":-1"))
 
1009
                         client = _("local pipe");
 
1010
                     statusList->SetItem(row, colpos++, client);
 
1011
 
 
1012
                    statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("backend_start")));
 
1013
                }
 
1014
                if (connection->BackendMinimumVersion(7, 4))
 
1015
                {
 
1016
                    if (qry.IsEmpty() || qry == wxT("<IDLE>"))
 
1017
                        statusList->SetItem(row, colpos++, wxEmptyString);
 
1018
                    else
 
1019
                        statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("query_start")));
 
1020
                }
 
1021
 
 
1022
                if (connection->BackendMinimumVersion(8, 3))
 
1023
                    statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("xact_start")));
 
1024
 
 
1025
                statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("blockedby")));
 
1026
                   statusList->SetItem(row, colpos, qry.Left(250));
 
1027
                row++;
 
1028
            }
 
1029
            dataSet1->MoveNext();
 
1030
        }
 
1031
        delete dataSet1;
 
1032
            
 
1033
        while (row < statusList->GetItemCount())
 
1034
            statusList->DeleteItem(row);
 
1035
 
 
1036
        statusList->Thaw();
 
1037
        statusBar->SetStatusText(_("Done."));
 
1038
    }
 
1039
    else
 
1040
        checkConnection();
 
1041
 
 
1042
    row=0;
 
1043
    while (row < statusList->GetItemCount())
 
1044
    {
 
1045
        long itempid=StrToLong(statusList->GetItemText(row));
 
1046
        if (itempid && itempid > pid)
 
1047
            statusList->DeleteItem(row);
 
1048
        else
 
1049
            row++;
 
1050
    }
 
1051
}
 
1052
 
 
1053
 
 
1054
void frmStatus::OnRefreshLocksTimer(wxTimerEvent &event)
 
1055
{
 
1056
    long pid=0;
 
1057
 
 
1058
    if (! viewMenu->IsChecked(MNU_LOCKPAGE))
 
1059
        return;
 
1060
 
 
1061
    if (!connection)
 
1062
    {
 
1063
        statusTimer->Stop();
 
1064
        locksTimer->Stop();
 
1065
        if (xactTimer)
 
1066
            xactTimer->Stop();
 
1067
        if (logTimer)
 
1068
            logTimer->Stop();
 
1069
        statusBar->SetStatusText(wxT("Connection broken."));
 
1070
        return;
 
1071
    }
 
1072
 
 
1073
    checkConnection();
 
1074
    if (!connection)
 
1075
        return;
 
1076
    
 
1077
    wxCriticalSectionLocker lock(gs_critsect);
 
1078
 
 
1079
    connection->ExecuteVoid(wxT("SET log_statement='none';SET log_duration='off';"),false);
 
1080
 
 
1081
    long row=0;
 
1082
    wxString sql;
 
1083
    if (connection->BackendMinimumVersion(8, 3)) 
 
1084
    {
 
1085
        sql = wxT("SELECT ")
 
1086
              wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ")
 
1087
              wxT("pgl.relation::regclass AS class, ")
 
1088
              wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ")
 
1089
              wxT("pgl.virtualxid, pgl.virtualtransaction AS transaction, pg_stat_get_backend_pid(svrid) AS pid, pgl.mode, pgl.granted, ")
 
1090
              wxT("pg_stat_get_backend_activity(svrid) AS current_query, ")
 
1091
              wxT("pg_stat_get_backend_activity_start(svrid) AS query_start ")
 
1092
              wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ")
 
1093
              wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ")
 
1094
              wxT("ORDER BY pid;");
 
1095
    } 
 
1096
    else if (connection->BackendMinimumVersion(7, 4)) 
 
1097
    {
 
1098
           sql = wxT("SELECT ")
 
1099
              wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ")
 
1100
              wxT("pgl.relation::regclass AS class, ")
 
1101
              wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ")
 
1102
              wxT("pgl.transaction, pg_stat_get_backend_pid(svrid) AS pid, pgl.mode, pgl.granted, ")
 
1103
              wxT("pg_stat_get_backend_activity(svrid) AS current_query, ")
 
1104
              wxT("pg_stat_get_backend_activity_start(svrid) AS query_start ")
 
1105
              wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ")
 
1106
              wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ")
 
1107
              wxT("ORDER BY pid;");
 
1108
    } 
 
1109
    else 
 
1110
    {
 
1111
        sql = wxT("SELECT ")
 
1112
              wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ")
 
1113
              wxT("pgl.relation::regclass AS class, ")
 
1114
              wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ")
 
1115
              wxT("pgl.transaction, pg_stat_get_backend_pid(svrid) AS pid, pgl.mode, pgl.granted, ")
 
1116
              wxT("pg_stat_get_backend_activity(svrid) AS current_query ")
 
1117
              wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ")
 
1118
              wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ")
 
1119
              wxT("ORDER BY pid;");
 
1120
    }
 
1121
 
 
1122
    pgSet *dataSet2=connection->ExecuteSet(sql);
 
1123
    if (dataSet2)
 
1124
    {
 
1125
        statusBar->SetStatusText(_("Refreshing locks list."));
 
1126
        lockList->Freeze();
 
1127
 
 
1128
        while (!dataSet2->Eof())
 
1129
        {
 
1130
            pid=dataSet2->GetLong(wxT("pid"));
 
1131
 
 
1132
            if (pid != backend_pid)
 
1133
            {
 
1134
                long itempid=0;
 
1135
 
 
1136
                while (row < lockList->GetItemCount())
 
1137
                {
 
1138
                    itempid=StrToLong(lockList->GetItemText(row));
 
1139
                    if (itempid && itempid < pid)
 
1140
                        lockList->DeleteItem(row);
 
1141
                    else
 
1142
                        break;
 
1143
                }
 
1144
 
 
1145
                if (!itempid || itempid > pid || lockList->GetItemCount() == 0)
 
1146
                {
 
1147
                    lockList->InsertItem(row, NumToStr(pid), 0);
 
1148
                }
 
1149
 
 
1150
                int colpos=1;
 
1151
                lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("dbname")));
 
1152
                lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("class")));
 
1153
                lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("user")));
 
1154
                if (connection->BackendMinimumVersion(8, 3)) 
 
1155
                    lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("virtualxid")));
 
1156
                lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("transaction")));
 
1157
                lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("mode")));
 
1158
                    
 
1159
                if (dataSet2->GetVal(wxT("granted")) == wxT("t"))
 
1160
                    lockList->SetItem(row, colpos++, _("Yes"));
 
1161
                else
 
1162
                    lockList->SetItem(row, colpos++, _("No"));
 
1163
 
 
1164
                wxString qry=dataSet2->GetVal(wxT("current_query"));
 
1165
 
 
1166
                if (connection->BackendMinimumVersion(7, 4))
 
1167
                {
 
1168
                    if (qry.IsEmpty() || qry == wxT("<IDLE>"))
 
1169
                        lockList->SetItem(row, colpos++, wxEmptyString);
 
1170
                    else
 
1171
                        lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("query_start")));
 
1172
                }
 
1173
                lockList->SetItem(row, colpos++, qry.Left(250));
 
1174
 
 
1175
                row++;
 
1176
            }
 
1177
            dataSet2->MoveNext();
 
1178
        }
 
1179
 
 
1180
        delete dataSet2;
 
1181
        
 
1182
        while (row < lockList->GetItemCount())
 
1183
            lockList->DeleteItem(row);
 
1184
 
 
1185
        lockList->Thaw();
 
1186
        statusBar->SetStatusText(_("Done."));
 
1187
    }
 
1188
    else
 
1189
        checkConnection();
 
1190
 
 
1191
    row=0;
 
1192
    while (row < lockList->GetItemCount())
 
1193
    {
 
1194
        long itempid=StrToLong(lockList->GetItemText(row));
 
1195
        if (itempid && itempid > pid)
 
1196
            lockList->DeleteItem(row);
 
1197
        else
 
1198
            row++;
 
1199
    }
 
1200
}
 
1201
 
 
1202
 
 
1203
void frmStatus::OnRefreshXactTimer(wxTimerEvent &event)
 
1204
{
 
1205
    long pid=0;
 
1206
 
 
1207
    if (! viewMenu->IsEnabled(MNU_XACTPAGE) || ! viewMenu->IsChecked(MNU_XACTPAGE) || !xactTimer)
 
1208
        return;
 
1209
 
 
1210
    if (!connection)
 
1211
    {
 
1212
        statusTimer->Stop();
 
1213
        locksTimer->Stop();
 
1214
        xactTimer->Stop();
 
1215
        if (logTimer)
 
1216
            logTimer->Stop();
 
1217
        statusBar->SetStatusText(wxT("Connection broken."));
 
1218
        return;
 
1219
    }
 
1220
 
 
1221
    checkConnection();
 
1222
    if (!connection)
 
1223
        return;
 
1224
    
 
1225
    wxCriticalSectionLocker lock(gs_critsect);
 
1226
 
 
1227
    connection->ExecuteVoid(wxT("SET log_statement='none';SET log_duration='off';"),false);
 
1228
 
 
1229
    long row=0;
 
1230
    wxString sql = wxT("SELECT * FROM pg_prepared_xacts");
 
1231
 
 
1232
    pgSet *dataSet3=connection->ExecuteSet(sql);
 
1233
    if (dataSet3)
 
1234
    {
 
1235
        statusBar->SetStatusText(_("Refreshing transactions list."));
 
1236
        xactList->Freeze();
 
1237
 
 
1238
        while (!dataSet3->Eof())
 
1239
        {
 
1240
            long xid=dataSet3->GetLong(wxT("transaction"));
 
1241
 
 
1242
            long itemxid=0;
 
1243
 
590
1244
            while (row < xactList->GetItemCount())
591
 
                                xactList->DeleteItem(row);
592
 
 
593
 
            xactList->Thaw();
594
 
                        statusBar->SetStatusText(_("Done."));
595
 
                }
 
1245
            {
 
1246
                itemxid=StrToLong(xactList->GetItemText(row));
 
1247
                if (itemxid && itemxid < xid)
 
1248
                    xactList->DeleteItem(row);
 
1249
                else
 
1250
                    break;
 
1251
            }
 
1252
 
 
1253
            if (!itemxid || itemxid > xid)
 
1254
            {
 
1255
                xactList->InsertItem(row, NumToStr(xid), 0);
 
1256
            }
 
1257
 
 
1258
            int colpos=1;
 
1259
            xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("gid")));
 
1260
            xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("prepared")));
 
1261
            xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("owner")));
 
1262
            xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("database")));
 
1263
 
 
1264
            row++;
 
1265
               dataSet3->MoveNext();
 
1266
        }
 
1267
        delete dataSet3;
 
1268
            
 
1269
        while (row < xactList->GetItemCount())
 
1270
            xactList->DeleteItem(row);
 
1271
 
 
1272
        xactList->Thaw();
 
1273
        statusBar->SetStatusText(_("Done."));
 
1274
    }
 
1275
    else
 
1276
        checkConnection();
 
1277
 
 
1278
    row=0;
 
1279
    while (row < xactList->GetItemCount())
 
1280
    {
 
1281
    long itempid=StrToLong(lockList->GetItemText(row));
 
1282
    if (itempid && itempid > pid)
 
1283
        xactList->DeleteItem(row);
 
1284
    else
 
1285
        row++;
 
1286
    }
 
1287
}
 
1288
 
 
1289
 
 
1290
void frmStatus::OnRefreshLogTimer(wxTimerEvent &event)
 
1291
{
 
1292
    if (! viewMenu->IsEnabled(MNU_LOGPAGE) || ! viewMenu->IsChecked(MNU_LOGPAGE) || !logTimer)
 
1293
        return;
 
1294
 
 
1295
    if (!connection)
 
1296
    {
 
1297
        statusTimer->Stop();
 
1298
        locksTimer->Stop();
 
1299
        if (xactTimer)
 
1300
            xactTimer->Stop();
 
1301
        logTimer->Stop();
 
1302
        statusBar->SetStatusText(wxT("Connection broken."));
 
1303
        return;
 
1304
    }
 
1305
    
 
1306
    checkConnection();
 
1307
    if (!connection)
 
1308
        return;
 
1309
    
 
1310
    wxCriticalSectionLocker lock(gs_critsect);
 
1311
 
 
1312
    connection->ExecuteVoid(wxT("SET log_statement='none';SET log_duration='off';"),false);
 
1313
 
 
1314
    if (connection->GetLastResultError().sql_state == wxT("42501"))
 
1315
    {
 
1316
        // Don't have superuser privileges, so can't do anything with the log display
 
1317
        logTimer->Stop();
 
1318
        cbLogfiles->Disable();
 
1319
        btnRotateLog->Disable();
 
1320
        manager.GetPane(wxT("Logfile")).Show(false);
 
1321
        manager.Update();
 
1322
        return;
 
1323
    }
 
1324
 
 
1325
    long newlen=0;
 
1326
 
 
1327
    if (logDirectory.IsEmpty())
 
1328
    {
 
1329
        // freshly started
 
1330
        logDirectory = connection->ExecuteScalar(wxT("SHOW log_directory"));
 
1331
        if (connection->GetLastResultError().sql_state == wxT("42501"))
 
1332
        {
 
1333
            // Don't have superuser privileges, so can't do anything with the log display
 
1334
            logTimer->Stop();
 
1335
            cbLogfiles->Disable();
 
1336
            btnRotateLog->Disable();
 
1337
            manager.GetPane(wxT("Logfile")).Show(false);
 
1338
            manager.Update();
 
1339
            return;
 
1340
        }
 
1341
        if (fillLogfileCombo())
 
1342
        {
 
1343
            savedPartialLine.Clear();
 
1344
            cbLogfiles->SetSelection(0);
 
1345
            wxCommandEvent ev;
 
1346
            OnLoadLogfile(ev);
 
1347
            return;
 
1348
        }
 
1349
        else 
 
1350
        {
 
1351
            logDirectory = wxT("-");
 
1352
            if (connection->BackendMinimumVersion(8, 3))
 
1353
                logList->AppendItem(-1, _("logging_collector not enabled or log_filename misconfigured"));
 
1354
            else
 
1355
                logList->AppendItem(-1, _("redirect_stderr not enabled or log_filename misconfigured"));
 
1356
            cbLogfiles->Disable();
 
1357
            btnRotateLog->Disable();
 
1358
        }
 
1359
    }
 
1360
        
 
1361
    if (logDirectory == wxT("-"))
 
1362
        return;
 
1363
 
 
1364
    if (isCurrent)
 
1365
    {
 
1366
        // check if the current logfile changed
 
1367
        pgSet *set = connection->ExecuteSet(wxT("SELECT pg_file_length(") + connection->qtDbString(logfileName) + wxT(") AS len"));
 
1368
        if (set)
 
1369
        {
 
1370
            newlen = set->GetLong(wxT("len"));
 
1371
            delete set;
 
1372
        }
596
1373
        else
 
1374
        {
597
1375
            checkConnection();
598
 
 
599
 
        row=0;
600
 
                while (row < lockList->GetItemCount())
601
 
                {
602
 
                        long itempid=StrToLong(lockList->GetItemText(row));
603
 
                        if (itempid && itempid > pid)
604
 
                                lockList->DeleteItem(row);
605
 
            else
606
 
                row++;
607
 
                }
608
 
    }
609
 
    else if (nbStatus->GetSelection() == logPage)
 
1376
            return;
 
1377
        }
 
1378
        if (newlen > logfileLength)
 
1379
        {
 
1380
            statusBar->SetStatusText(_("Refreshing log list."));
 
1381
            addLogFile(logfileName, logfileTimestamp, newlen, logfileLength, false);
 
1382
            statusBar->SetStatusText(_("Done."));
 
1383
 
 
1384
            // as long as there was new data, the logfile is probably the current
 
1385
            // one so we don't need to check for rotation
 
1386
            return;
 
1387
        }
 
1388
    }        
 
1389
 
 
1390
    // 
 
1391
    wxString newDirectory = connection->ExecuteScalar(wxT("SHOW log_directory"));
 
1392
 
 
1393
    int newfiles=0;
 
1394
    if (newDirectory != logDirectory)
 
1395
        cbLogfiles->Clear();
 
1396
 
 
1397
    newfiles = fillLogfileCombo();
 
1398
 
 
1399
    if (newfiles)
610
1400
    {
611
 
        long newlen=0;
612
 
 
613
 
        if (logDirectory.IsEmpty())
614
 
        {
615
 
            // freshly started
616
 
            logDirectory = connection->ExecuteScalar(wxT("SHOW log_directory"));
617
 
            if (fillLogfileCombo())
618
 
            {
619
 
                cbLogfiles->SetSelection(0);
620
 
                wxCommandEvent ev;
621
 
                OnLoadLogfile(ev);
622
 
                return;
623
 
            }
624
 
            else 
625
 
            {
626
 
                logDirectory = wxT("-");
627
 
                if (connection->BackendMinimumVersion(8, 3))
628
 
                    logList->AppendItem(-1, _("redirect_stderr not enabled or log_filename misconfigured"));
629
 
                else
630
 
                    logList->AppendItem(-1, _("logging_collector not enabled or log_filename misconfigured"));
631
 
                cbLogfiles->Disable();
632
 
                btnRotateLog->Disable();
633
 
            }
634
 
        }
 
1401
        if (!showCurrent)
 
1402
            isCurrent=false;
635
1403
        
636
 
        if (logDirectory == wxT("-"))
637
 
            return;
638
 
 
639
 
 
640
1404
        if (isCurrent)
641
1405
        {
642
 
            // check if the current logfile changed
643
 
                    pgSet *set = connection->ExecuteSet(wxT("SELECT pg_file_length(") + connection->qtDbString(logfileName) + wxT(") AS len"));
644
 
                    if (set)
645
 
                        {
646
 
                                newlen = set->GetLong(wxT("len"));
647
 
                                delete set;
648
 
                    }
649
 
                        else
650
 
                        {
651
 
                        checkConnection();
652
 
                                return;
653
 
                        }
654
 
            if (newlen > logfileLength)
655
 
            {
656
 
                            statusBar->SetStatusText(_("Refreshing."));
657
 
                addLogFile(logfileName, logfileTimestamp, newlen, logfileLength, false);
658
 
                                statusBar->SetStatusText(_("Done."));
659
 
 
660
 
                // as long as there was new data, the logfile is probably the current
661
 
                // one so we don't need to check for rotation
662
 
                return;
663
 
            }
664
 
        }        
665
 
 
666
 
        // 
667
 
        wxString newDirectory = connection->ExecuteScalar(wxT("SHOW log_directory"));
668
 
 
669
 
        int newfiles=0;
670
 
        if (newDirectory != logDirectory)
671
 
            cbLogfiles->Clear();
672
 
 
673
 
        newfiles = fillLogfileCombo();
674
 
 
675
 
        if (newfiles)
676
 
        {
677
 
            if (!showCurrent)
678
 
                isCurrent=false;
679
 
        
680
 
            if (isCurrent)
681
 
            {
682
 
                int pos = cbLogfiles->GetCount() - newfiles;
683
 
                bool skipFirst = true;
684
 
 
685
 
                while (newfiles--)
686
 
                {
687
 
                    addLogLine(_("pgadmin:Logfile rotated."), false);
688
 
                    wxDateTime *ts=(wxDateTime*)cbLogfiles->GetClientData(pos++);
689
 
                    wxASSERT(ts != 0);
690
 
 
 
1406
            int pos = cbLogfiles->GetCount() - newfiles;
 
1407
            bool skipFirst = true;
 
1408
 
 
1409
            while (newfiles--)
 
1410
            {
 
1411
                addLogLine(_("pgadmin:Logfile rotated."), false);
 
1412
                wxDateTime *ts=(wxDateTime*)cbLogfiles->GetClientData(pos++);
 
1413
                wxASSERT(ts != 0);
691
1414
                    
692
 
                    addLogFile(ts, skipFirst);
693
 
                    skipFirst = false;
 
1415
                addLogFile(ts, skipFirst);
 
1416
                skipFirst = false;
694
1417
 
695
 
                    pos++;
696
 
                }
 
1418
                pos++;
697
1419
            }
698
1420
        }
699
1421
    }
700
1422
}
701
1423
 
702
1424
 
 
1425
void frmStatus::OnRefresh(wxCommandEvent &event)
 
1426
{
 
1427
    wxTimerEvent evt;
 
1428
    
 
1429
    OnRefreshStatusTimer(evt);
 
1430
    OnRefreshLocksTimer(evt);
 
1431
    OnRefreshXactTimer(evt);
 
1432
    OnRefreshLogTimer(evt);
 
1433
}
 
1434
 
 
1435
 
703
1436
void frmStatus::checkConnection()
704
1437
{
705
1438
    if (!connection->IsAlive())
706
 
        {
707
 
            delete connection;
708
 
                connection=0;
709
 
                statusBar->SetStatusText(_("Connection broken."));
710
 
        }
 
1439
    {
 
1440
        delete connection;
 
1441
        connection=0;
 
1442
        statusTimer->Stop();
 
1443
        locksTimer->Stop();
 
1444
        if (xactTimer)
 
1445
            xactTimer->Stop();
 
1446
        if (logTimer)
 
1447
            logTimer->Stop();
 
1448
        statusBar->SetStatusText(_("Connection broken."));
 
1449
    }
711
1450
}
712
1451
 
713
1452
 
730
1469
    }
731
1470
}
732
1471
 
 
1472
 
733
1473
void frmStatus::addLogFile(const wxString &filename, const wxDateTime timestamp, long len, long &read, bool skipFirst)
734
1474
{
735
1475
    wxString line;
736
 
 
 
1476
    
737
1477
    if (skipFirst)
738
1478
    {
739
1479
        long maxServerLogSize = settings->GetMaxServerLogSize();
747
1487
            skipFirst=false;
748
1488
    }
749
1489
 
 
1490
    // If GPDB 3.3 and later, log is normally in CSV format.  Let's get a whole log line before calling addLogLine,
 
1491
    // so we can do things smarter.
 
1492
 
 
1493
    // PostgreSQL can log in CSV format, as well as regular format.  Normally, we'd only see 
 
1494
    // the regular format logs here, because pg_logdir_ls only returns those.  But if pg_logdir_ls is
 
1495
    // changed to return the csv format log files, we should handle it.
 
1496
 
 
1497
    bool csv_log_format = filename.Right(4) == wxT(".csv");
 
1498
 
 
1499
    if (csv_log_format && savedPartialLine.length() > 0)
 
1500
    {
 
1501
        if (read == 0)  // Starting at beginning of log file
 
1502
            savedPartialLine.clear();
 
1503
        else 
 
1504
            line = savedPartialLine;
 
1505
    }
750
1506
 
751
1507
    while (len > read)
752
1508
    {
 
1509
        statusBar->SetStatusText(_("Reading log from server..."));
753
1510
        pgSet *set=connection->ExecuteSet(wxT("SELECT pg_file_read(") + 
754
1511
            connection->qtDbString(filename) + wxT(", ") + NumToStr(read) + wxT(", 50000)"));
755
1512
        if (!set)
764
1521
            delete set;
765
1522
            break;
766
1523
        }
 
1524
 
767
1525
        read += strlen(raw);
768
1526
 
 
1527
        wxString str;
 
1528
        if (wxString(wxString(raw,wxConvLibc),wxConvUTF8).Len() > 0)
 
1529
            str = line + wxString(wxString(raw,wxConvLibc),wxConvUTF8);
 
1530
        else
 
1531
            str = line + wxTextBuffer::Translate(wxString(raw, set->GetConversion()), wxTextFileType_Unix);
769
1532
 
770
 
        wxString str = line + wxTextBuffer::Translate(wxString(raw, set->GetConversion()), wxTextFileType_Unix);
771
1533
        delete set;
772
1534
 
773
 
        bool hasCr = (str.Right(1) == wxT("\n"));
774
 
 
775
 
        wxStringTokenizer tk(str, wxT("\n"));
776
 
 
777
 
        logList->Freeze();
778
 
        while (tk.HasMoreTokens())
779
 
        {
780
 
            str = tk.GetNextToken();
781
 
            if (skipFirst)
782
 
            {
783
 
                // could be truncated
784
 
                skipFirst = false;
785
 
                continue;
786
 
            }
787
 
            if (tk.HasMoreTokens() || hasCr)
788
 
                addLogLine(str);
789
 
            else
790
 
                line = str;
791
 
        }
792
 
        logList->Thaw();
 
1535
        if (str.Len() == 0)
 
1536
        {
 
1537
            wxString msgstr = _("The server log contains entries in multiple encodings and cannot be displayed by pgAdmin.");
 
1538
            wxMessageBox(msgstr);
 
1539
            return;
 
1540
        }
 
1541
 
 
1542
        if (csv_log_format)
 
1543
        {
 
1544
            // This will work for any DB using CSV format logs
 
1545
 
 
1546
            if (logHasTimestamp)
 
1547
            {
 
1548
                // Right now, csv format logs from GPDB and PostgreSQL always start with a timestamp, so we count on that.
 
1549
 
 
1550
                // And the only reason we need to do that is to make sure we are in sync.  
 
1551
 
 
1552
                // Bad things happen if we start in the middle of a 
 
1553
                // double-quoted string, as we would never find a correct line terminator!
 
1554
 
 
1555
                // In CSV logs, the first field must be a Timestamp, so must start with "2009" or "201" or "202" (at least for the next 20 years).
 
1556
                if (str.length() > 4 && str.Left(4) != wxT("2009") && str.Left(3) != wxT("201") && str.Left(3) != wxT("202"))
 
1557
                {
 
1558
                    wxLogNotice(wxT("Log line does not start with timestamp: %s \n"), str.Mid(0,100).c_str());
 
1559
                    // Something isn't right, as we are not at the beginning of a csv log record.
 
1560
                    // We should never get here, but if we do, try to handle it in a smart way.
 
1561
                    str = str.Mid(str.Find(wxT("\n20"))+1);  // Try to re-sync.
 
1562
                }
 
1563
            }
 
1564
 
 
1565
            CSVLineTokenizer tk(str);
 
1566
 
 
1567
            logList->Freeze();
 
1568
 
 
1569
            while (tk.HasMoreLines())
 
1570
            {
 
1571
                line.Clear();
 
1572
 
 
1573
                bool partial;
 
1574
                str = tk.GetNextLine(partial);
 
1575
                if (partial)
 
1576
                {
 
1577
                    line = str; // Start of a log line, but not complete.  Loop back, Read more data.
 
1578
                    break;
 
1579
                }
 
1580
 
 
1581
                // Some extra debug checking, assuming csv logs line start with timestamps.
 
1582
                // Not really necessary, but it is good for debugging if something isn't right.
 
1583
                if (logHasTimestamp)
 
1584
                {
 
1585
                    // The first field must be a Timestamp, so must start with "2009" or "201" or "202" (at least for the next 20 years).
 
1586
                    // This is just an extra check to make sure we haven't gotten out of sync with the log.
 
1587
                    if (str.length() > 5 && str.Left(4) != wxT("2009") && str.Left(3) != wxT("201") && str.Left(3) != wxT("202"))
 
1588
                    {
 
1589
                        // BUG:  We are out of sync on the log
 
1590
                        wxLogNotice(wxT("Log line does not start with timestamp: %s\n"), str.c_str());;
 
1591
                    }
 
1592
                    else if (str.length() < 20)
 
1593
                    {
 
1594
                        // BUG:  We are out of sync on the log, or the log is garbled
 
1595
                        wxLogNotice(wxT("Log line too short: %s\n"), str.c_str());
 
1596
                    }
 
1597
                }
 
1598
 
 
1599
                // Looks like we have a good complete CSV log record.
 
1600
                addLogLine(str.Trim(), true, true);
 
1601
            }
 
1602
 
 
1603
            logList->Thaw();
 
1604
        }
 
1605
        else
 
1606
        {
 
1607
            // Non-csv format log file
 
1608
 
 
1609
            bool hasCr = (str.Right(1) == wxT("\n"));
 
1610
 
 
1611
            wxStringTokenizer tk(str, wxT("\n"));
 
1612
 
 
1613
            logList->Freeze();
 
1614
 
 
1615
            while (tk.HasMoreTokens())
 
1616
            {
 
1617
                str = tk.GetNextToken();
 
1618
                if (skipFirst)
 
1619
                {
 
1620
                    // could be truncated
 
1621
                    skipFirst = false;
 
1622
                    continue;
 
1623
                }
 
1624
 
 
1625
                if (tk.HasMoreTokens() || hasCr)
 
1626
                    addLogLine(str.Trim());
 
1627
                else
 
1628
                    line = str;
 
1629
            }
 
1630
 
 
1631
            logList->Thaw();
 
1632
        }
793
1633
    }
 
1634
    
 
1635
    savedPartialLine.clear();
 
1636
 
794
1637
    if (!line.IsEmpty())
795
 
        addLogLine(line);
 
1638
    {
 
1639
        // We finished reading to the end of the log file, but still have some data left
 
1640
        if (csv_log_format)
 
1641
        {
 
1642
            savedPartialLine = line;    // Save partial log line for next read of the data file.
 
1643
            line.Clear();
 
1644
        }
 
1645
        else
 
1646
            addLogLine(line.Trim());
 
1647
    }
 
1648
        
796
1649
}
797
1650
 
798
1651
 
799
 
 
800
 
void frmStatus::addLogLine(const wxString &str, bool formatted)
 
1652
void frmStatus::addLogLine(const wxString &str, bool formatted, bool csv_log_format)
801
1653
{
802
1654
    int row=logList->GetItemCount();
 
1655
 
803
1656
    if (!logFormatKnown)
804
1657
        logList->AppendItem(-1, str);
805
 
    else
806
 
    {
807
 
        if (str.Find(':') < 0)
808
 
        {
809
 
            logList->InsertItem(row, wxEmptyString, -1);
810
 
            logList->SetItem(row, (logHasTimestamp ? 2 : 1), str);
 
1658
    else if ((!csv_log_format) && str.Find(':') < 0)
 
1659
    {
 
1660
        // Must be a continuation of a previous line.
 
1661
        logList->InsertItem(row, wxEmptyString, -1);
 
1662
        logList->SetItem(row, 2, str);
 
1663
    }
 
1664
    else if (!formatted)
 
1665
    {
 
1666
        // Not from a log, from pgAdmin itself.
 
1667
        logList->InsertItem(row, wxEmptyString, -1);
 
1668
        logList->SetItem(row, 1, str.BeforeFirst(':'));
 
1669
        logList->SetItem(row, 2, str.AfterFirst(':'));
 
1670
    }
 
1671
    else // formatted log
 
1672
    { 
 
1673
        if (csv_log_format)
 
1674
        {
 
1675
            // Log is in CSV format (GPDB 3.3 and later, or Postgres if only csv log enabled)
 
1676
            // In this case, we are always supposed to have a complete log line in csv format in str when called.
 
1677
 
 
1678
            if (logHasTimestamp && (str.Length() < 20 || (logHasTimestamp && (str[0] != wxT('2') || str[1] != wxT('0')))))
 
1679
            {
 
1680
                // Log line too short or does not start with an expected timestamp... 
 
1681
                // Must be a continuation of the previous line or garbage,
 
1682
                // or we are out of sync in our CSV handling.
 
1683
                // We shouldn't ever get here.
 
1684
                logList->InsertItem(row, wxEmptyString, -1);
 
1685
                logList->SetItem(row, 2, str);
 
1686
            }
 
1687
            else
 
1688
            {
 
1689
                CSVTokenizer tk(str);
 
1690
 
 
1691
                bool gpdb = connection->GetIsGreenplum();
 
1692
 
 
1693
                // Get the fields from the CSV log. 
 
1694
                wxString logTime = tk.GetNextToken();         
 
1695
                wxString logUser = tk.GetNextToken();
 
1696
                wxString logDatabase = tk.GetNextToken();
 
1697
                wxString logPid = tk.GetNextToken();
 
1698
 
 
1699
                wxString logSession;
 
1700
                wxString logCmdcount;
 
1701
                wxString logSegment;
 
1702
 
 
1703
                if (gpdb)
 
1704
                {
 
1705
                    wxString logThread =  tk.GetNextToken();        // GPDB specific
 
1706
                    wxString logHost = tk.GetNextToken();
 
1707
                    wxString logPort = tk.GetNextToken();           // GPDB (Postgres puts port with Host)
 
1708
                    wxString logSessiontime = tk.GetNextToken();
 
1709
                    wxString logTransaction = tk.GetNextToken();
 
1710
                    logSession = tk.GetNextToken();
 
1711
                    logCmdcount = tk.GetNextToken();
 
1712
                    logSegment = tk.GetNextToken();
 
1713
                    wxString logSlice = tk.GetNextToken();
 
1714
                    wxString logDistxact = tk.GetNextToken();
 
1715
                    wxString logLocalxact = tk.GetNextToken();
 
1716
                    wxString logSubxact = tk.GetNextToken();
 
1717
                }
 
1718
                else
 
1719
                {
 
1720
                    wxString logHost = tk.GetNextToken();       // Postgres puts port with Hostname
 
1721
                    logSession = tk.GetNextToken();
 
1722
                    wxString logLineNumber = tk.GetNextToken();
 
1723
                    wxString logPsDisplay = tk.GetNextToken();
 
1724
                    wxString logSessiontime = tk.GetNextToken();
 
1725
                    wxString logVXid = tk.GetNextToken();
 
1726
                    wxString logTransaction = tk.GetNextToken();
 
1727
                }
 
1728
                
 
1729
                wxString logSeverity = tk.GetNextToken();
 
1730
                wxString logState = tk.GetNextToken();
 
1731
                wxString logMessage = tk.GetNextToken();
 
1732
                wxString logDetail = tk.GetNextToken();
 
1733
                wxString logHint = tk.GetNextToken();
 
1734
                wxString logQuery = tk.GetNextToken();
 
1735
                wxString logQuerypos = tk.GetNextToken();
 
1736
                wxString logContext = tk.GetNextToken();
 
1737
                wxString logDebug = tk.GetNextToken();
 
1738
                wxString logCursorpos = tk.GetNextToken();
 
1739
 
 
1740
                wxString logStack;
 
1741
                if (gpdb)
 
1742
                {
 
1743
                    wxString logFunction = tk.GetNextToken();       // GPDB.  Postgres puts func, file, and line together
 
1744
                    wxString logFile = tk.GetNextToken();
 
1745
                    wxString logLine = tk.GetNextToken();
 
1746
                    logStack = tk.GetNextToken();                   // GPDB only.
 
1747
                }
 
1748
                else
 
1749
                    wxString logFuncFileLine = tk.GetNextToken();  
 
1750
 
 
1751
                logList->InsertItem(row, logTime, -1);      // Insert timestamp (with time zone)
 
1752
            
 
1753
                logList->SetItem(row, 1, logSeverity);
 
1754
 
 
1755
                // Display the logMessage, breaking it into lines
 
1756
                wxStringTokenizer lm(logMessage,wxT("\n"));
 
1757
                logList->SetItem(row, 2, lm.GetNextToken());
 
1758
 
 
1759
                logList->SetItem(row, 3, logSession);
 
1760
                logList->SetItem(row, 4, logCmdcount);
 
1761
                logList->SetItem(row, 5, logDatabase);
 
1762
                if ((!gpdb) || (logSegment.length() > 0 && logSegment != wxT("seg-1")))
 
1763
                {
 
1764
                    logList->SetItem(row, 6, logSegment);
 
1765
                }
 
1766
                else
 
1767
                {
 
1768
                    // If we are reading the masterDB log only, the logSegment won't
 
1769
                    // have anything useful in it.  Look in the logMessage, and see if the
 
1770
                    // segment info exists in there.  It will always be at the end.
 
1771
                    if (logMessage.length() > 0 && logMessage[logMessage.length()-1] == wxT(')'))
 
1772
                    {
 
1773
                        int segpos = -1;
 
1774
                        segpos = logMessage.Find(wxT("(seg"));
 
1775
                        if (segpos <= 0)
 
1776
                            segpos = logMessage.Find(wxT("(mir"));
 
1777
                        if (segpos > 0)
 
1778
                        {
 
1779
                            logSegment = logMessage.Mid(segpos+1);
 
1780
                            if (logSegment.Find(wxT(' ')) > 0)
 
1781
                                logSegment = logSegment.Mid(0,logSegment.Find(wxT(' ')));
 
1782
                            logList->SetItem(row, 6, logSegment);
 
1783
                        }
 
1784
                    }
 
1785
                }
 
1786
                
 
1787
                // The rest of the lines from the logMessage
 
1788
                while (lm.HasMoreTokens())
 
1789
                {
 
1790
                    int controw=logList->GetItemCount();
 
1791
                    logList->InsertItem(controw, wxEmptyString, -1);
 
1792
                    logList->SetItem(controw, 2, lm.GetNextToken());
 
1793
                }
 
1794
 
 
1795
                // Add the detail
 
1796
                wxStringTokenizer ld(logDetail,wxT("\n"));
 
1797
                while (ld.HasMoreTokens())
 
1798
                {
 
1799
                    int controw=logList->GetItemCount();
 
1800
                    logList->InsertItem(controw, wxEmptyString, -1);
 
1801
                    logList->SetItem(controw, 2, ld.GetNextToken());
 
1802
                }
 
1803
 
 
1804
                // And the hint
 
1805
                wxStringTokenizer lh(logHint,wxT("\n"));
 
1806
                while (lh.HasMoreTokens())
 
1807
                {
 
1808
                    int controw=logList->GetItemCount();
 
1809
                    logList->InsertItem(controw, wxEmptyString, -1);
 
1810
                    logList->SetItem(controw, 2, lh.GetNextToken());
 
1811
                }
 
1812
 
 
1813
                if (logDebug.length() > 0)
 
1814
                {
 
1815
                    wxString logState3 = logState.Mid(0,3);
 
1816
                    if (logState3 == wxT("426") || logState3 == wxT("22P") || logState3 == wxT("427") 
 
1817
                        || logState3 == wxT("42P") || logState3 == wxT("458") 
 
1818
                        || logMessage.Mid(0,9) == wxT("duration:") || logSeverity == wxT("FATAL") || logSeverity == wxT("PANIC"))
 
1819
                    {
 
1820
                        // If not redundant, add the statement from the debug_string
 
1821
                        wxStringTokenizer lh(logDebug,wxT("\n"));
 
1822
                        if (lh.HasMoreTokens())
 
1823
                        {
 
1824
                            int controw=logList->GetItemCount();
 
1825
                            logList->InsertItem(controw, wxEmptyString, -1);
 
1826
                            logList->SetItem(controw, 2, wxT("statement: ") + lh.GetNextToken());
 
1827
                        }
 
1828
                        while (lh.HasMoreTokens())
 
1829
                        {
 
1830
                            int controw=logList->GetItemCount();
 
1831
                            logList->InsertItem(controw, wxEmptyString, -1);
 
1832
                            logList->SetItem(controw, 2, lh.GetNextToken());
 
1833
                        }
 
1834
                    }
 
1835
                }
 
1836
 
 
1837
                if (gpdb)
 
1838
                    if (logSeverity == wxT("PANIC") || 
 
1839
                        (logSeverity == wxT("FATAL") && logState != wxT("57P03") && logState != wxT("53300")))
 
1840
                    {
 
1841
                        // If this is a severe error, add the stack trace.
 
1842
                        wxStringTokenizer ls(logStack,wxT("\n"));
 
1843
                        if (ls.HasMoreTokens())
 
1844
                        {
 
1845
                            int controw=logList->GetItemCount();
 
1846
                            logList->InsertItem(controw, wxEmptyString, -1);
 
1847
                            logList->SetItem(controw, 1, wxT("STACK"));
 
1848
                            logList->SetItem(controw, 2, ls.GetNextToken());
 
1849
                        }
 
1850
                        while (ls.HasMoreTokens())
 
1851
                        {
 
1852
                            int controw=logList->GetItemCount();
 
1853
                            logList->InsertItem(controw, wxEmptyString, -1);
 
1854
                            logList->SetItem(controw, 2, ls.GetNextToken());
 
1855
                        }
 
1856
                    }
 
1857
            }
 
1858
        }
 
1859
        else if (connection->GetIsGreenplum())
 
1860
        {
 
1861
            // Greenplum 3.2 and before.  log_line_prefix =  "%m|%u|%d|%p|%I|%X|:-"
 
1862
 
 
1863
            wxString logSeverity;
 
1864
            // Skip prefix, get message.  In GPDB, always follows ":-".
 
1865
            wxString rest = str.Mid(str.Find(wxT(":-"))+1) ;
 
1866
            if (rest.Length() > 0 && rest[0] == wxT('-'))
 
1867
                rest = rest.Mid(1);
 
1868
 
 
1869
            // Separate loglevel from message
 
1870
 
 
1871
            if (rest.Length() > 1 && rest[0] != wxT(' ') && rest.Find(':') > 0)
 
1872
            {
 
1873
                logSeverity = rest.BeforeFirst(':');
 
1874
                rest = rest.AfterFirst(':').Mid(2);
 
1875
            }
 
1876
 
 
1877
            wxString ts = str.BeforeFirst(logFormat.c_str()[logFmtPos+2]);
 
1878
            if (ts.Length() < 20  || (logHasTimestamp && (ts.Left(2) != wxT("20") || str.Find(':') < 0)))
 
1879
            {
 
1880
                // No Timestamp?  Must be a continuation of a previous line?  
 
1881
                // Not sure if it is possible to get here.
 
1882
                logList->InsertItem(row, wxEmptyString, -1);
 
1883
                logList->SetItem(row, 2, rest);
 
1884
            }
 
1885
            else if (logSeverity.Length() > 1)
 
1886
            {
 
1887
                // Normal case:  Start of a new log record.
 
1888
                logList->InsertItem(row, ts, -1);
 
1889
                logList->SetItem(row, 1, logSeverity);
 
1890
                logList->SetItem(row, 2, rest);   
 
1891
            }
 
1892
            else
 
1893
            {
 
1894
                // Continuation of previous line
 
1895
                logList->InsertItem(row, wxEmptyString, -1);
 
1896
                logList->SetItem(row, 2, rest);
 
1897
            }
811
1898
        }
812
1899
        else
813
1900
        {
 
1901
            // All Non-csv-format non-GPDB PostgreSQL systems.
 
1902
 
814
1903
            wxString rest;
815
1904
 
816
1905
            if (logHasTimestamp)
873
1962
{
874
1963
    int count=cbLogfiles->GetCount();
875
1964
    if (!count)
876
 
        cbLogfiles->Append(_(" current"));
 
1965
        cbLogfiles->Append(_("Current log"));
877
1966
    else
878
1967
        count--;
879
1968
 
937
2026
 
938
2027
void frmStatus::OnCancelBtn(wxCommandEvent &event)
939
2028
{
940
 
    ctlListView *lv;
941
 
        
942
 
        if (nbStatus->GetSelection() == 0)
943
 
                 lv = statusList;
944
 
        else if (nbStatus->GetSelection() == 1)
945
 
                 lv = lockList;
946
 
        else 
947
 
        {
948
 
                wxLogError(wxT("Couldn't determine the source listview for a cancel backend operation!"));
949
 
                return;
950
 
        }
951
 
 
952
 
    long item = lv->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
953
 
    if (item < 0)
954
 
        return;
955
 
 
956
 
    if (wxMessageBox(_("Are you sure you wish to cancel the selected query(s)?"), _("Cancel query?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxNO)
957
 
                return;
958
 
 
959
 
    while  (item >= 0)
960
 
    {
961
 
                wxString pid = lv->GetItemText(item);
962
 
                wxString sql = wxT("SELECT pg_cancel_backend(") + pid + wxT(");");
963
 
                connection->ExecuteScalar(sql);
964
 
 
965
 
        item = lv->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
966
 
        }
967
 
 
968
 
        wxMessageBox(_("A cancel signal was sent to the selected server process(es)."), _("Cancel query"), wxOK | wxICON_INFORMATION);
969
 
        OnRefresh(event);
970
 
    wxListEvent ev;
971
 
    if (nbStatus->GetSelection() == 0)
972
 
        OnSelStatusItem(ev);
973
 
    else
974
 
        OnSelLockItem(ev);
 
2029
    switch(currentPane)
 
2030
    {
 
2031
        case PANE_STATUS:
 
2032
            OnStatusCancelBtn(event);
 
2033
            break;
 
2034
        case PANE_LOCKS:
 
2035
            OnLocksCancelBtn(event);
 
2036
            break;
 
2037
        default:
 
2038
            // This shouldn't happen. If it does, it's no big deal
 
2039
            break;
 
2040
    }
 
2041
}
 
2042
 
 
2043
 
 
2044
void frmStatus::OnStatusCancelBtn(wxCommandEvent &event)
 
2045
{
 
2046
    long item = statusList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
 
2047
    if (item < 0)
 
2048
        return;
 
2049
 
 
2050
    if (wxMessageBox(_("Are you sure you wish to cancel the selected query(s)?"), _("Cancel query?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxNO)
 
2051
        return;
 
2052
 
 
2053
    while  (item >= 0)
 
2054
    {
 
2055
        wxString pid = statusList->GetItemText(item);
 
2056
        wxString sql = wxT("SELECT pg_cancel_backend(") + pid + wxT(");");
 
2057
        connection->ExecuteScalar(sql);
 
2058
 
 
2059
        item = statusList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
 
2060
    }
 
2061
 
 
2062
    wxMessageBox(_("A cancel signal was sent to the selected server process(es)."), _("Cancel query"), wxOK | wxICON_INFORMATION);
 
2063
    OnRefresh(event);
 
2064
    wxListEvent ev;
 
2065
    OnSelStatusItem(ev);
 
2066
}
 
2067
 
 
2068
 
 
2069
void frmStatus::OnLocksCancelBtn(wxCommandEvent &event)
 
2070
{
 
2071
    long item = lockList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
 
2072
    if (item < 0)
 
2073
        return;
 
2074
 
 
2075
    if (wxMessageBox(_("Are you sure you wish to cancel the selected query(s)?"), _("Cancel query?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxNO)
 
2076
        return;
 
2077
 
 
2078
    while  (item >= 0)
 
2079
    {
 
2080
        wxString pid = lockList->GetItemText(item);
 
2081
        wxString sql = wxT("SELECT pg_cancel_backend(") + pid + wxT(");");
 
2082
        connection->ExecuteScalar(sql);
 
2083
 
 
2084
        item = lockList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
 
2085
    }
 
2086
 
 
2087
    wxMessageBox(_("A cancel signal was sent to the selected server process(es)."), _("Cancel query"), wxOK | wxICON_INFORMATION);
 
2088
    OnRefresh(event);
 
2089
    wxListEvent ev;
 
2090
    OnSelLockItem(ev);
975
2091
}
976
2092
 
977
2093
 
978
2094
void frmStatus::OnTerminateBtn(wxCommandEvent &event)
979
2095
{
980
 
    ctlListView *lv;
981
 
        
982
 
        if (nbStatus->GetSelection() == 0)
983
 
                 lv = statusList;
984
 
        else if (nbStatus->GetSelection() == 1)
985
 
                 lv = lockList;
986
 
        else 
987
 
        {
988
 
                wxLogError(wxT("Couldn't determine the source listview for a terminate backend operation!"));
989
 
                return;
990
 
        }
991
 
 
992
 
    long item = lv->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
993
 
    if (item < 0)
994
 
        return;
995
 
 
996
 
        if (wxMessageBox(_("Are you sure you wish to terminate the selected server process(es)?"), _("Terminate process?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxNO)
997
 
                return;
998
 
 
999
 
    while  (item >= 0)
1000
 
    {
1001
 
                wxString pid = lv->GetItemText(item);
1002
 
                wxString sql = wxT("SELECT pg_terminate_backend(") + pid + wxT(");");
1003
 
                connection->ExecuteScalar(sql);
1004
 
 
1005
 
            item = lv->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1006
 
    }
1007
 
 
1008
 
        wxMessageBox(_("A terminate signal was sent to the selected server process(es)."), _("Terminate process"), wxOK | wxICON_INFORMATION);
1009
 
        OnRefresh(event);
1010
 
    wxListEvent ev;
1011
 
    if (nbStatus->GetSelection() == 0)
1012
 
        OnSelStatusItem(ev);
1013
 
    else
1014
 
        OnSelLockItem(ev);
 
2096
    switch(currentPane)
 
2097
    {
 
2098
        case PANE_STATUS:
 
2099
            OnStatusTerminateBtn(event);
 
2100
            break;
 
2101
        case PANE_LOCKS:
 
2102
            OnLocksTerminateBtn(event);
 
2103
            break;
 
2104
        default:
 
2105
            // This shouldn't happen. If it does, it's no big deal
 
2106
            break;
 
2107
    }
 
2108
}
 
2109
 
 
2110
 
 
2111
void frmStatus::OnStatusTerminateBtn(wxCommandEvent &event)
 
2112
{
 
2113
    long item = statusList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
 
2114
    if (item < 0)
 
2115
        return;
 
2116
 
 
2117
    if (wxMessageBox(_("Are you sure you wish to terminate the selected server process(es)?"), _("Terminate process?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxNO)
 
2118
        return;
 
2119
 
 
2120
    while  (item >= 0)
 
2121
    {
 
2122
        wxString pid = statusList->GetItemText(item);
 
2123
        wxString sql = wxT("SELECT pg_terminate_backend(") + pid + wxT(");");
 
2124
        connection->ExecuteScalar(sql);
 
2125
 
 
2126
        item = statusList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
 
2127
    }
 
2128
 
 
2129
    wxMessageBox(_("A terminate signal was sent to the selected server process(es)."), _("Terminate process"), wxOK | wxICON_INFORMATION);
 
2130
    OnRefresh(event);
 
2131
    wxListEvent ev;
 
2132
    OnSelStatusItem(ev);
 
2133
}
 
2134
 
 
2135
 
 
2136
void frmStatus::OnLocksTerminateBtn(wxCommandEvent &event)
 
2137
{
 
2138
    long item = lockList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
 
2139
    if (item < 0)
 
2140
        return;
 
2141
 
 
2142
    if (wxMessageBox(_("Are you sure you wish to terminate the selected server process(es)?"), _("Terminate process?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxNO)
 
2143
        return;
 
2144
 
 
2145
    while  (item >= 0)
 
2146
    {
 
2147
        wxString pid = lockList->GetItemText(item);
 
2148
        wxString sql = wxT("SELECT pg_terminate_backend(") + pid + wxT(");");
 
2149
        connection->ExecuteScalar(sql);
 
2150
 
 
2151
        item = lockList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
 
2152
    }
 
2153
 
 
2154
    wxMessageBox(_("A terminate signal was sent to the selected server process(es)."), _("Terminate process"), wxOK | wxICON_INFORMATION);
 
2155
    OnRefresh(event);
 
2156
    wxListEvent ev;
 
2157
    OnSelLockItem(ev);
1015
2158
}
1016
2159
 
1017
2160
 
1021
2164
    if (item < 0)
1022
2165
        return;
1023
2166
 
1024
 
        if (wxMessageBox(_("Are you sure you wish to commit the selected prepared transactions?"), _("Commit transaction?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxNO)
1025
 
                return;
 
2167
    if (wxMessageBox(_("Are you sure you wish to commit the selected prepared transactions?"), _("Commit transaction?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxNO)
 
2168
        return;
1026
2169
 
1027
2170
    while  (item >= 0)
1028
2171
    {
1029
 
                wxString xid = xactList->GetText(item, 1);
1030
 
                wxString sql = wxT("COMMIT PREPARED ") + connection->qtDbString(xid);
 
2172
        wxString xid = xactList->GetText(item, 1);
 
2173
        wxString sql = wxT("COMMIT PREPARED ") + connection->qtDbString(xid);
1031
2174
 
1032
2175
        // We must execute this in the database in which the prepared transation originated.
1033
2176
        if (connection->GetDbname() != xactList->GetText(item, 4))
1039
2182
                                       connection->GetPort(), 
1040
2183
                                       connection->GetSslMode());
1041
2184
            if (tmpConn)
1042
 
                {
1043
 
                        if (tmpConn->GetStatus() != PGCONN_OK)
1044
 
                        {
1045
 
                                wxMessageBox(wxT("Connection failed: ") + tmpConn->GetLastError());
1046
 
                                return ;
1047
 
                        }
 
2185
            {
 
2186
                if (tmpConn->GetStatus() != PGCONN_OK)
 
2187
                {
 
2188
                    wxMessageBox(wxT("Connection failed: ") + tmpConn->GetLastError());
 
2189
                    return ;
 
2190
                }
1048
2191
                tmpConn->ExecuteScalar(sql);
1049
2192
 
1050
2193
                tmpConn->Close();
1052
2195
            }
1053
2196
        }
1054
2197
        else
1055
 
                    connection->ExecuteScalar(sql);
 
2198
            connection->ExecuteScalar(sql);
1056
2199
 
1057
2200
        item = xactList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1058
 
        }
 
2201
    }
1059
2202
 
1060
 
        OnRefresh(event);
 
2203
    OnRefresh(event);
1061
2204
    wxListEvent ev;
1062
2205
    OnSelXactItem(ev);
1063
2206
}
1070
2213
        return;
1071
2214
 
1072
2215
    if (wxMessageBox(_("Are you sure you wish to rollback the selected prepared transactions?"), _("Rollback transaction?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxNO)
1073
 
                return;
 
2216
        return;
1074
2217
 
1075
2218
    while  (item >= 0)
1076
2219
    {
1077
 
                wxString xid = xactList->GetText(item, 1);
1078
 
                wxString sql = wxT("ROLLBACK PREPARED ") + connection->qtDbString(xid);
 
2220
        wxString xid = xactList->GetText(item, 1);
 
2221
        wxString sql = wxT("ROLLBACK PREPARED ") + connection->qtDbString(xid);
1079
2222
 
1080
2223
        // We must execute this in the database in which the prepared transation originated.
1081
2224
        if (connection->GetDbname() != xactList->GetText(item, 4))
1087
2230
                                       connection->GetPort(), 
1088
2231
                                       connection->GetSslMode());
1089
2232
            if (tmpConn)
1090
 
                {
1091
 
                        if (tmpConn->GetStatus() != PGCONN_OK)
1092
 
                        {
1093
 
                                wxMessageBox(wxT("Connection failed: ") + tmpConn->GetLastError());
1094
 
                                return ;
1095
 
                        }
 
2233
            {
 
2234
                if (tmpConn->GetStatus() != PGCONN_OK)
 
2235
                {
 
2236
                    wxMessageBox(wxT("Connection failed: ") + tmpConn->GetLastError());
 
2237
                    return ;
 
2238
                }
1096
2239
                tmpConn->ExecuteScalar(sql);
1097
2240
 
1098
2241
                tmpConn->Close();
1100
2243
            }
1101
2244
        }
1102
2245
        else
1103
 
                    connection->ExecuteScalar(sql);
 
2246
            connection->ExecuteScalar(sql);
1104
2247
 
1105
2248
        item = xactList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1106
 
        }
 
2249
    }
1107
2250
 
1108
 
        OnRefresh(event);
 
2251
    OnRefresh(event);
1109
2252
    wxListEvent ev;
1110
2253
    OnSelXactItem(ev);
1111
2254
}
1112
2255
 
1113
2256
 
1114
 
 
1115
2257
void frmStatus::OnSelStatusItem(wxListEvent &event)
1116
2258
{
1117
 
        if (connection->BackendMinimumVersion(8, 0))
1118
 
        {
1119
 
                if(statusList->GetSelectedItemCount() > 0) 
1120
 
                {
1121
 
                        btnCancelSt->Enable(true);
 
2259
#ifdef __WXGTK__
 
2260
    manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, true);
 
2261
    manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false);
 
2262
    manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false);
 
2263
    manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false);
 
2264
    manager.Update();
 
2265
#endif
 
2266
    currentPane = PANE_STATUS;
 
2267
    cbRate->SetValue(rateToCboString(statusRate));
 
2268
    if (connection && connection->BackendMinimumVersion(8, 0))
 
2269
    {
 
2270
        if(statusList->GetSelectedItemCount() > 0) 
 
2271
        {
 
2272
            toolBar->EnableTool(MNU_CANCEL, true);
1122
2273
            if (connection->HasFeature(FEATURE_TERMINATE_BACKEND))
1123
 
                            btnTerminateSt->Enable(true);
1124
 
                } 
1125
 
                else 
1126
 
                {
1127
 
                        btnCancelSt->Enable(false);
1128
 
                        btnTerminateSt->Enable(false);
1129
 
                }
1130
 
        }
 
2274
                toolBar->EnableTool(MNU_TERMINATE, true);
 
2275
        } 
 
2276
        else 
 
2277
        {
 
2278
            toolBar->EnableTool(MNU_CANCEL, false);
 
2279
            toolBar->EnableTool(MNU_TERMINATE, false);
 
2280
        }
 
2281
    }
 
2282
    toolBar->EnableTool(MNU_COMMIT, false);
 
2283
    toolBar->EnableTool(MNU_ROLLBACK, false);
 
2284
    cbLogfiles->Enable(false);
 
2285
    btnRotateLog->Enable(false);
 
2286
    
 
2287
    editMenu->Enable(MNU_COPY, statusList->GetFirstSelected()>=0);
1131
2288
}
1132
2289
 
 
2290
 
1133
2291
void frmStatus::OnSelLockItem(wxListEvent &event)
1134
2292
{
1135
 
        if (connection->BackendMinimumVersion(8, 0))
1136
 
        {
1137
 
                if(lockList->GetSelectedItemCount() > 0) 
1138
 
                {
1139
 
                        btnCancelLk->Enable(true);
 
2293
#ifdef __WXGTK__
 
2294
    manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false);
 
2295
    manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, true);
 
2296
    manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false);
 
2297
    manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false);
 
2298
    manager.Update();
 
2299
#endif
 
2300
    currentPane = PANE_LOCKS;
 
2301
    cbRate->SetValue(rateToCboString(locksRate));
 
2302
    if (connection && connection->BackendMinimumVersion(8, 0))
 
2303
    {
 
2304
        if(lockList->GetSelectedItemCount() > 0) 
 
2305
        {
 
2306
            toolBar->EnableTool(MNU_CANCEL, true);
1140
2307
            if (connection->HasFeature(FEATURE_TERMINATE_BACKEND))
1141
 
                        btnTerminateLk->Enable(true);
1142
 
                } 
1143
 
                else 
1144
 
                {
1145
 
                        btnCancelLk->Enable(false);
1146
 
                        btnTerminateLk->Enable(false);
1147
 
                }
1148
 
        }
 
2308
                toolBar->EnableTool(MNU_TERMINATE, true);
 
2309
        } 
 
2310
        else 
 
2311
        {
 
2312
            toolBar->EnableTool(MNU_CANCEL, false);
 
2313
            toolBar->EnableTool(MNU_TERMINATE, false);
 
2314
        }
 
2315
    }
 
2316
    toolBar->EnableTool(MNU_COMMIT, false);
 
2317
    toolBar->EnableTool(MNU_ROLLBACK, false);
 
2318
    cbLogfiles->Enable(false);
 
2319
    btnRotateLog->Enable(false);
 
2320
    
 
2321
    editMenu->Enable(MNU_COPY, lockList->GetFirstSelected()>=0);
1149
2322
}
1150
2323
 
 
2324
 
1151
2325
void frmStatus::OnSelXactItem(wxListEvent &event)
1152
2326
{
 
2327
#ifdef __WXGTK__
 
2328
    manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false);
 
2329
    manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false);
 
2330
    manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, true);
 
2331
    manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false);
 
2332
    manager.Update();
 
2333
#endif
 
2334
    currentPane = PANE_XACT;
 
2335
    cbRate->SetValue(rateToCboString(xactRate));
1153
2336
    if(xactList->GetSelectedItemCount() > 0) 
1154
 
        {
1155
 
                btnCommit->Enable(true);
1156
 
        btnRollback->Enable(true);
1157
 
        } 
1158
 
        else 
1159
 
        {
1160
 
                btnCommit->Enable(false);
1161
 
        btnRollback->Enable(false);
1162
 
        }
1163
 
}
1164
 
 
1165
 
serverStatusFactory::serverStatusFactory(menuFactoryList *list, wxMenu *mnu, wxToolBar *toolbar) : actionFactory(list)
 
2337
    {
 
2338
        toolBar->EnableTool(MNU_COMMIT, true);
 
2339
        toolBar->EnableTool(MNU_ROLLBACK, true);
 
2340
    } 
 
2341
    else 
 
2342
    {
 
2343
        toolBar->EnableTool(MNU_COMMIT, false);
 
2344
        toolBar->EnableTool(MNU_ROLLBACK, false);
 
2345
    }
 
2346
    toolBar->EnableTool(MNU_CANCEL, false);
 
2347
    toolBar->EnableTool(MNU_TERMINATE, false);
 
2348
    cbLogfiles->Enable(false);
 
2349
    btnRotateLog->Enable(false);
 
2350
    
 
2351
    editMenu->Enable(MNU_COPY, xactList->GetFirstSelected()>=0);
 
2352
}
 
2353
 
 
2354
 
 
2355
void frmStatus::OnSelLogItem(wxListEvent &event)
 
2356
{
 
2357
#ifdef __WXGTK__
 
2358
    manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false);
 
2359
    manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false);
 
2360
    manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false);
 
2361
    manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, true);
 
2362
    manager.Update();
 
2363
#endif
 
2364
    currentPane = PANE_LOG;
 
2365
    cbRate->SetValue(rateToCboString(logRate));
 
2366
    
 
2367
    // if there's no log, don't enable items
 
2368
    if (logDirectory != wxT("-")) 
 
2369
    {
 
2370
        cbLogfiles->Enable(true);
 
2371
        btnRotateLog->Enable(true);
 
2372
        toolBar->EnableTool(MNU_CANCEL, false);
 
2373
        toolBar->EnableTool(MNU_TERMINATE, false);
 
2374
        toolBar->EnableTool(MNU_COMMIT, false);
 
2375
        toolBar->EnableTool(MNU_ROLLBACK, false);
 
2376
    }
 
2377
    
 
2378
    editMenu->Enable(MNU_COPY, logList->GetFirstSelected()>=0);
 
2379
}
 
2380
 
 
2381
 
 
2382
serverStatusFactory::serverStatusFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list)
1166
2383
{
1167
2384
    mnu->Append(id, _("&Server Status"), _("Displays the current database status."));
1168
2385
}