28
28
///////////////////////////////////////////////////
29
29
debuggerFactory::debuggerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list)
31
mnu->Append(id, _("&Debug"), _("Debug the selected object"));
31
mnu->Append(id, _("&Debug"), _("Debug the selected object"));
34
34
wxWindow *debuggerFactory::StartDialog(frmMain *form, pgObject *obj)
36
// Check here to make sure the function still exists before proceeding.
37
// There is still a very small window in which it might be dropped, but
38
// that will be handled by a cache lookup failure error in the database
39
// We also make sure the function name doesn't contain a : as that will
40
// sent the debugger API nuts.
41
pgSet *res = obj->GetConnection()->ExecuteSet(wxT("SELECT count(*) AS count, proname FROM pg_proc WHERE oid = ") + NumToStr((long)obj->GetOid()) + wxT(" GROUP BY proname"));
42
if (res->GetVal(wxT("proname")).Contains(wxT(":")))
44
wxLogError(_("Functions with a colon in the name cannot be debugged."));
48
if (res->GetLong(wxT("count")) != 1)
50
wxLogError(_("The selected function could not be found."));
51
ctlTree *browser = form->GetBrowser();
52
wxTreeItemId item=browser->GetSelection();
53
if (obj == browser->GetObject(item))
55
pgCollection *coll=browser->GetParentCollection(obj->GetId());
56
browser->DeleteChildren(coll->GetId());
57
coll->ShowTreeDetail(browser);
62
// Setup the debugger frame
63
frmDebugger *debugger = new frmDebugger(form, wxString::Format(_("Debugger - %s"), obj->GetFullIdentifier().c_str()));
65
// Setup the connection properties to be used by the debugger
67
cp.m_database = obj->GetDatabase()->GetIdentifier();
68
cp.m_host = obj->GetServer()->GetName();
69
cp.m_password = obj->GetDatabase()->GetServer()->GetPassword();
70
cp.m_port = NumToStr((long)obj->GetServer()->GetPort());
71
cp.m_sslMode = obj->GetServer()->GetSSL();
72
cp.m_userName = obj->GetServer()->GetUsername();
74
// Setup the debugging session
75
dlgDirectDbg *directDebugger = NULL;
76
directDebugger = debugger->addDirectDbg(cp);
77
if (directDebugger == NULL)
82
dbgBreakPointList &breakpoints = directDebugger->getBreakpointList();
83
breakpoints.Append(new dbgBreakPoint(dbgBreakPoint::OID, NumToStr((long)obj->GetOid()), wxT("'NULL'")));
84
if (!directDebugger->startDebugging())
86
ctlTree *browser = form->GetBrowser();
87
wxTreeItemId item=browser->GetSelection();
88
if (obj == browser->GetObject(item))
90
pgCollection *coll=browser->GetParentCollection(obj->GetId());
91
browser->DeleteChildren(coll->GetId());
92
coll->ShowTreeDetail(browser);
97
// Return the debugger window to frmMain.
98
if (debugger && !directDebugger->GetCancelled())
36
// Check here to make sure the function still exists before proceeding.
37
// There is still a very small window in which it might be dropped, but
38
// that will be handled by a cache lookup failure error in the database
39
// We also make sure the function name doesn't contain a : as that will
40
// sent the debugger API nuts.
41
pgSet *res = obj->GetConnection()->ExecuteSet(wxT("SELECT count(*) AS count, proname FROM pg_proc WHERE oid = ") + NumToStr((long)obj->GetOid()) + wxT(" GROUP BY proname"));
42
if (res->GetVal(wxT("proname")).Contains(wxT(":")))
44
wxLogError(_("Functions with a colon in the name cannot be debugged."));
48
if (res->GetLong(wxT("count")) != 1)
50
wxLogError(_("The selected function could not be found."));
51
ctlTree *browser = form->GetBrowser();
52
wxTreeItemId item = browser->GetSelection();
53
if (obj == browser->GetObject(item))
55
pgCollection *coll = browser->GetParentCollection(obj->GetId());
56
browser->DeleteChildren(coll->GetId());
57
coll->ShowTreeDetail(browser);
62
// Setup the debugger frame
63
frmDebugger *debugger = new frmDebugger(form, wxString::Format(_("Debugger - %s"), obj->GetFullIdentifier().c_str()));
65
// Setup the connection properties to be used by the debugger
67
cp.m_database = obj->GetDatabase()->GetIdentifier();
68
cp.m_host = obj->GetServer()->GetName();
69
cp.m_password = obj->GetDatabase()->GetServer()->GetPassword();
70
cp.m_port = NumToStr((long)obj->GetServer()->GetPort());
71
cp.m_sslMode = obj->GetServer()->GetSSL();
72
cp.m_userName = obj->GetServer()->GetUsername();
74
// Setup the debugging session
75
dlgDirectDbg *directDebugger = NULL;
76
directDebugger = debugger->addDirectDbg(cp);
77
if (directDebugger == NULL)
82
dbgBreakPointList &breakpoints = directDebugger->getBreakpointList();
83
breakpoints.Append(new dbgBreakPoint(dbgBreakPoint::OID, NumToStr((long)obj->GetOid()), wxT("'NULL'")));
84
if (!directDebugger->startDebugging())
86
ctlTree *browser = form->GetBrowser();
87
wxTreeItemId item = browser->GetSelection();
88
if (obj == browser->GetObject(item))
90
pgCollection *coll = browser->GetParentCollection(obj->GetId());
91
browser->DeleteChildren(coll->GetId());
92
coll->ShowTreeDetail(browser);
97
// Return the debugger window to frmMain.
98
if (debugger && !directDebugger->GetCancelled())
104
104
bool debuggerFactory::CheckEnable(pgObject *obj)
109
// Can't debug catalog objects.
110
if (obj->GetSchema() && obj->GetSchema()->GetMetaType() == PGM_CATALOG)
113
// Must be a super user or object owner to create breakpoints of any kind.
114
if (!obj->GetServer() || !(obj->GetServer()->GetSuperUser() || obj->GetServer()->GetUsername() == obj->GetOwner()))
117
// EnterpriseDB 8.3 or earlier does not support debugging by the non-superuser
118
if (!obj->GetServer()->GetSuperUser() && !obj->GetConnection()->EdbMinimumVersion(8, 4) && obj->GetConnection()->GetIsEdb())
121
if (!obj->IsCollection())
123
switch (obj->GetMetaType())
127
pgFunction *func = (pgFunction *)obj;
129
// If this is an EDB wrapped function, no debugging allowed
130
if (obj->GetConnection()->GetIsEdb() && func->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$")))
133
if (func->GetReturnType() != wxT("trigger") && func->GetReturnType() != wxT("\"trigger\""))
135
if (func->GetLanguage() == wxT("plpgsql") && obj->GetDatabase()->CanDebugPlpgsql())
109
// Can't debug catalog objects.
110
if (obj->GetSchema() && obj->GetSchema()->GetMetaType() == PGM_CATALOG)
113
// Must be a super user or object owner to create breakpoints of any kind.
114
if (!obj->GetServer() || !(obj->GetServer()->GetSuperUser() || obj->GetServer()->GetUsername() == obj->GetOwner()))
117
// EnterpriseDB 8.3 or earlier does not support debugging by the non-superuser
118
if (!obj->GetServer()->GetSuperUser() && !obj->GetConnection()->EdbMinimumVersion(8, 4) && obj->GetConnection()->GetIsEdb())
121
if (!obj->IsCollection())
123
switch (obj->GetMetaType())
127
pgFunction *func = (pgFunction *)obj;
129
// If this is an EDB wrapped function, no debugging allowed
130
if (obj->GetConnection()->GetIsEdb() && func->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$")))
133
if (func->GetReturnType() != wxT("trigger") && func->GetReturnType() != wxT("\"trigger\""))
135
if (func->GetLanguage() == wxT("plpgsql") && obj->GetDatabase()->CanDebugPlpgsql())
137
137
#ifndef EDB_LIBPQ
139
else if (func->GetLanguage() == wxT("edbspl") &&
140
obj->GetConnection()->EdbMinimumVersion(8, 4) &&
141
!(PQiGetOutResult && PQiPrepareOut && PQiSendQueryPreparedOut))
139
else if (func->GetLanguage() == wxT("edbspl") &&
140
obj->GetConnection()->EdbMinimumVersion(8, 4) &&
141
!obj->GetConnection()->EdbMinimumVersion(9, 0) &&
142
!(PQiGetOutResult && PQiPrepareOut && PQiSendQueryPreparedOut))
144
else if (func->GetLanguage() == wxT("edbspl") && obj->GetConnection()->EdbMinimumVersion(8, 4))
148
else if (func->GetLanguage() == wxT("edbspl") && obj->GetDatabase()->CanDebugEdbspl())
158
case EDB_PACKAGEFUNCTION:
159
if (obj->GetDatabase()->GetConnection()->EdbMinimumVersion(8, 2) &&
160
obj->GetDatabase()->CanDebugEdbspl() &&
161
obj->GetName() != wxT("cons") &&
162
((edbPackageFunction *)obj)->GetSource() != wxEmptyString &&
163
(!((edbPackageFunction *)obj)->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$"))))
145
else if (func->GetLanguage() == wxT("edbspl") && obj->GetConnection()->EdbMinimumVersion(8, 4))
149
else if (func->GetLanguage() == wxT("edbspl") && obj->GetDatabase()->CanDebugEdbspl())
159
case EDB_PACKAGEFUNCTION:
160
if (obj->GetDatabase()->GetConnection()->EdbMinimumVersion(8, 2) &&
161
obj->GetDatabase()->CanDebugEdbspl() &&
162
obj->GetName() != wxT("cons") &&
163
((edbPackageFunction *)obj)->GetSource() != wxEmptyString &&
164
(!((edbPackageFunction *)obj)->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$"))))
174
175
///////////////////////////////////////////////////
176
177
///////////////////////////////////////////////////
177
178
breakpointFactory::breakpointFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list)
179
mnu->Append(id, _("&Set breakpoint"), _("Set a breakpoint on the selected object"));
180
mnu->Append(id, _("&Set breakpoint"), _("Set a breakpoint on the selected object"));
182
183
wxWindow *breakpointFactory::StartDialog(frmMain *form, pgObject *obj)
185
if (obj->GetMetaType() == PGM_TRIGGER)
186
dbgOid = NumToStr((long)((pgTrigger *)obj)->GetFunctionOid());
188
dbgOid = NumToStr((long)obj->GetOid());
190
// Check here to make sure the function still exists before proceeding.
191
// There is still a very small window in which it might be dropped, but
192
// we should be able to handle most cases here without having to do this
193
// deep down in query threads.
194
// We also make sure the function name doesn't contain a : as that will
195
// sent the debugger API nuts.
196
pgSet *res = obj->GetConnection()->ExecuteSet(wxT("SELECT count(*) AS count, proname FROM pg_proc WHERE oid = ") + dbgOid + wxT(" GROUP BY proname"));
197
if (res->GetVal(wxT("proname")).Contains(wxT(":")))
199
wxLogError(_("Functions with a colon in the name cannot be debugged."));
203
if (res->GetLong(wxT("count")) != 1)
205
wxLogError(_("The selected function could not be found."));
206
ctlTree *browser = form->GetBrowser();
207
wxTreeItemId item=browser->GetSelection();
208
if (obj == browser->GetObject(item))
210
pgCollection *coll=browser->GetParentCollection(obj->GetId());
211
browser->DeleteChildren(coll->GetId());
212
coll->ShowTreeDetail(browser);
217
// Setup the debugger frame
218
frmDebugger *debugger = new frmDebugger(form, wxString::Format(_("Debugger - %s"), obj->GetFullIdentifier().c_str()));
219
debugger->Show(true);
222
// Setup the connection properties to be used by the debugger
224
cp.m_database = obj->GetDatabase()->GetIdentifier();
225
cp.m_host = obj->GetServer()->GetName();
226
cp.m_password = obj->GetDatabase()->GetServer()->GetPassword();
227
cp.m_port = NumToStr((long)obj->GetServer()->GetPort());
228
cp.m_sslMode = obj->GetServer()->GetSSL();
229
cp.m_userName = obj->GetServer()->GetUsername();
231
// Setup the debugging session
232
ctlCodeWindow *globalDebugger = NULL;
233
globalDebugger = debugger->addDebug(cp);
186
if (obj->GetMetaType() == PGM_TRIGGER)
187
dbgOid = NumToStr((long)((pgTrigger *)obj)->GetFunctionOid());
189
dbgOid = NumToStr((long)obj->GetOid());
191
// Check here to make sure the function still exists before proceeding.
192
// There is still a very small window in which it might be dropped, but
193
// we should be able to handle most cases here without having to do this
194
// deep down in query threads.
195
// We also make sure the function name doesn't contain a : as that will
196
// sent the debugger API nuts.
197
pgSet *res = obj->GetConnection()->ExecuteSet(wxT("SELECT count(*) AS count, proname FROM pg_proc WHERE oid = ") + dbgOid + wxT(" GROUP BY proname"));
198
if (res->GetVal(wxT("proname")).Contains(wxT(":")))
200
wxLogError(_("Functions with a colon in the name cannot be debugged."));
204
if (res->GetLong(wxT("count")) != 1)
206
wxLogError(_("The selected function could not be found."));
207
ctlTree *browser = form->GetBrowser();
208
wxTreeItemId item = browser->GetSelection();
209
if (obj == browser->GetObject(item))
211
pgCollection *coll = browser->GetParentCollection(obj->GetId());
212
browser->DeleteChildren(coll->GetId());
213
coll->ShowTreeDetail(browser);
218
// Setup the debugger frame
219
frmDebugger *debugger = new frmDebugger(form, wxString::Format(_("Debugger - %s"), obj->GetFullIdentifier().c_str()));
220
debugger->Show(true);
223
// Setup the connection properties to be used by the debugger
225
cp.m_database = obj->GetDatabase()->GetIdentifier();
226
cp.m_host = obj->GetServer()->GetName();
227
cp.m_password = obj->GetDatabase()->GetServer()->GetPassword();
228
cp.m_port = NumToStr((long)obj->GetServer()->GetPort());
229
cp.m_sslMode = obj->GetServer()->GetSSL();
230
cp.m_userName = obj->GetServer()->GetUsername();
232
// Setup the debugging session
233
ctlCodeWindow *globalDebugger = NULL;
234
globalDebugger = debugger->addDebug(cp);
234
235
if (globalDebugger == NULL)
237
dbgBreakPointList &breakpoints = globalDebugger->getBreakpointList();
238
breakpoints.Append(new dbgBreakPoint(dbgBreakPoint::OID, dbgOid, wxT("'NULL'")));
240
globalDebugger->startGlobalDebugging();
242
// Return the debugger window to frmMain.
238
dbgBreakPointList &breakpoints = globalDebugger->getBreakpointList();
239
breakpoints.Append(new dbgBreakPoint(dbgBreakPoint::OID, dbgOid, wxT("'NULL'")));
241
globalDebugger->startGlobalDebugging();
243
// Return the debugger window to frmMain.
246
247
bool breakpointFactory::CheckEnable(pgObject *obj)
251
// Can't debug catalog objects.
252
if (obj->GetSchema() && obj->GetSchema()->GetMetaType() == PGM_CATALOG)
255
// Must be a super user to create breakpoints of any kind.
256
if (!obj->GetServer() || !obj->GetServer()->GetSuperUser())
259
if (!obj->IsCollection())
261
switch (obj->GetMetaType())
265
pgFunction *func = (pgFunction *)obj;
267
// If this is an EDB wrapped function, no debugging allowed
268
if (obj->GetConnection()->GetIsEdb() && func->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$")))
271
if (func->GetLanguage() == wxT("plpgsql") && obj->GetDatabase()->CanDebugPlpgsql())
252
// Can't debug catalog objects.
253
if (obj->GetSchema() && obj->GetSchema()->GetMetaType() == PGM_CATALOG)
256
// Must be a super user to create breakpoints of any kind.
257
if (!obj->GetServer() || !obj->GetServer()->GetSuperUser())
260
if (!obj->IsCollection())
262
switch (obj->GetMetaType())
266
pgFunction *func = (pgFunction *)obj;
268
// If this is an EDB wrapped function, no debugging allowed
269
if (obj->GetConnection()->GetIsEdb() && func->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$")))
272
if (func->GetLanguage() == wxT("plpgsql") && obj->GetDatabase()->CanDebugPlpgsql())
273
274
#ifndef EDB_LIBPQ
275
else if (func->GetLanguage() == wxT("edbspl") &&
276
obj->GetConnection()->EdbMinimumVersion(8, 4) &&
277
!(PQiGetOutResult && PQiPrepareOut && PQiSendQueryPreparedOut))
276
else if (func->GetLanguage() == wxT("edbspl") &&
277
obj->GetConnection()->EdbMinimumVersion(8, 4) &&
278
!(PQiGetOutResult && PQiPrepareOut && PQiSendQueryPreparedOut))
280
else if (func->GetLanguage() == wxT("edbspl") && obj->GetConnection()->EdbMinimumVersion(8, 4))
284
else if (func->GetLanguage() == wxT("edbspl") && obj->GetDatabase()->CanDebugEdbspl())
291
case EDB_PACKAGEFUNCTION:
292
if (obj->GetDatabase()->GetConnection()->EdbMinimumVersion(8, 2) &&
293
obj->GetDatabase()->CanDebugEdbspl() &&
294
obj->GetName() != wxT("cons") &&
295
((edbPackageFunction *)obj)->GetSource() != wxEmptyString &&
296
(!((edbPackageFunction *)obj)->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$"))))
302
pgTrigger *trig = (pgTrigger *)obj;
304
// If this is an EDB wrapped function, no debugging allowed
305
if (obj->GetConnection()->GetIsEdb() && trig->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$")))
308
if (trig->GetLanguage() == wxT("plpgsql") && obj->GetDatabase()->CanDebugPlpgsql())
310
else if (trig->GetLanguage() == wxT("edbspl") && obj->GetDatabase()->CanDebugEdbspl())
281
else if (func->GetLanguage() == wxT("edbspl") && obj->GetConnection()->EdbMinimumVersion(8, 4))
285
else if (func->GetLanguage() == wxT("edbspl") && obj->GetDatabase()->CanDebugEdbspl())
292
case EDB_PACKAGEFUNCTION:
293
if (obj->GetDatabase()->GetConnection()->EdbMinimumVersion(8, 2) &&
294
obj->GetDatabase()->CanDebugEdbspl() &&
295
obj->GetName() != wxT("cons") &&
296
((edbPackageFunction *)obj)->GetSource() != wxEmptyString &&
297
(!((edbPackageFunction *)obj)->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$"))))
303
pgTrigger *trig = (pgTrigger *)obj;
305
// If this is an EDB wrapped function, no debugging allowed
306
if (obj->GetConnection()->GetIsEdb() && trig->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$")))
309
if (trig->GetLanguage() == wxT("plpgsql") && obj->GetDatabase()->CanDebugPlpgsql())
311
else if (trig->GetLanguage() == wxT("edbspl") && obj->GetDatabase()->CanDebugEdbspl())