3
* TOra - An Oracle Toolkit for DBA's and developers
4
* Copyright (C) 2003-2005 Quest Software, Inc
5
* Portions Copyright (C) 2005 Other Contributors
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; only version 2 of
10
* the License is valid for this program.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
* As a special exception, you have permission to link this program
22
* with the Oracle Client libraries and distribute executables, as long
23
* as you follow the requirements of the GNU GPL in regard to all of the
24
* software in the executable aside from Oracle client libraries.
26
* Specifically you are not permitted to link this program with the
27
* Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech.
28
* And you are not permitted to distribute binaries compiled against
29
* these libraries without written consent from Quest Software, Inc.
30
* Observe that this does not disallow linking to the Qt Free Edition.
32
* You may link this product with any GPL'd Qt library such as Qt/Free
34
* All trademarks belong to their respective owners.
40
#include "toconnection.h"
42
#include "todebugtext.h"
44
#include "todebugtext.moc"
46
#include <qapplication.h>
50
#include "icons/breakpoint.xpm"
51
#include "icons/disbreakpoint.xpm"
53
#define TO_BREAK_COL 5
55
int toDebugText::ID = 0;
57
toBreakpointItem::toBreakpointItem(QListView *parent, QListViewItem *after,
58
const QString &schema, const QString &type,
59
const QString &object, int line)
60
: QListViewItem(parent, after)
63
setText(2, QString::null);
67
setText(0, QString::null);
71
setText(3, QString::null);
74
setText(1, QString::number(line + 1));
75
if (type == QString::fromLatin1("PACKAGE") ||
76
type == QString::fromLatin1("PROCEDURE") ||
77
type == QString::fromLatin1("FUNCTION") ||
78
type == QString::fromLatin1("TYPE"))
79
Namespace = TO_NAME_TOPLEVEL;
80
else if (type == QString::fromLatin1("PACKAGE BODY") ||
81
type == QString::fromLatin1("TYPE BODY"))
82
Namespace = TO_NAME_BODY;
84
Namespace = TO_NAME_NONE;
86
setText(4, qApp->translate("toDebug", "DEFERED"));
89
static toSQL SQLBreakpoint("toDebug:SetBreakpoint",
91
" proginf SYS.DBMS_DEBUG.PROGRAM_INFO;\n"
92
" bnum BINARY_INTEGER;\n"
93
" ret BINARY_INTEGER;\n"
95
" proginf.Namespace:=:type<int,in>;\n"
96
" proginf.Name:=:name<char[100],in>;\n"
97
" proginf.Owner:=:schema<char[100],in>;\n"
98
" proginf.DbLink:=NULL;\n"
99
" proginf.LibUnitType:=SYS.DBMS_DEBUG.LibUnitType_Procedure;\n"
100
" proginf.EntryPointName:=NULL;\n"
101
" proginf.Line#:=:line<int,in>;\n"
102
" ret:=SYS.DBMS_DEBUG.SET_BREAKPOINT(proginf,proginf.Line#,bnum,0,1);\n"
103
" SELECT ret,bnum INTO :ret<int,out>,:bnum<int,out> FROM sys.DUAL;\n"
105
"Set breakpoint, must have same bindings");
108
void toBreakpointItem::setBreakpoint(void)
117
TOCATCH // I don't the removal of the breakpoint to interact with the setting of the breakpoint
118
toConnection &conn = toCurrentConnection(listView());
120
toPush(args, toQValue(Namespace));
121
toPush(args, toQValue(text(0)));
122
toPush(args, toQValue(text(2)));
123
toPush(args, toQValue(Line + 1));
124
toQuery query(conn, SQLBreakpoint, args);
125
int ret = query.readValue().toInt();
126
if (ret == TO_SUCCESS)
128
setText(TO_BREAK_COL, query.readValue());
129
setText(4, qApp->translate("toDebug", "ENABLED"));
132
else if (ret == TO_ERROR_ILLEGAL_LINE)
134
toStatusMessage(qApp->translate("toDebug", "Can not enable breakpoint, not a valid line. Perhaps needs to recompile."));
136
else if (ret == TO_ERROR_BAD_HANDLE)
138
toStatusMessage(qApp->translate("toDebug", "Can not enable breakpoint, not a valid object. Perhaps needs to compile."));
143
setText(4, qApp->translate("toDebug", "NOT SET"));
146
static toSQL SQLClearBreakpoint("toDebug:ClearBreakpoint",
148
" bnum BINARY_INTEGER;\n"
149
" ret BINARY_INTEGER;\n"
151
" bnum:=:bnum<int,in>;\n"
152
" ret:=SYS.DBMS_DEBUG.DELETE_BREAKPOINT(bnum);\n"
153
" SELECT ret INTO :ret<int,out> FROM sys.DUAL;\n"
155
"Clear breakpoint, must have same bindings");
157
/** If something goes wrong it throws an exception (type QString with the error message */
158
void toBreakpointItem::clearBreakpoint()
160
if (text(4) == qApp->translate("toDebug", "ENABLED") && !text(TO_BREAK_COL).isEmpty())
162
toConnection &conn = toCurrentConnection(listView());
164
toPush(args, toQValue(text(TO_BREAK_COL)));
165
toQuery query(conn, SQLClearBreakpoint, args);
166
int res = query.readValue().toInt();
168
if (res != TO_SUCCESS && res != TO_NO_SUCH_BREAKPOINT)
170
QString message = qApp->translate("toDebug", "Failed to remove breakpoint (Reason %1)").arg(res);
171
toStatusMessage(message);
176
setText(4, qApp->translate("toDebug", "DISABLED"));
179
#define DEBUG_INDENT 10
181
static toSQL SQLReadSource("toDebug:ReadSource",
182
"SELECT Text FROM SYS.All_Source\n"
183
" WHERE OWNER = :f1<char[101]>\n"
184
" AND NAME = :f2<char[101]>\n"
185
" AND TYPE = :f3<char[101]>\n"
186
" ORDER BY Type,Line",
187
"Read sourcecode for object");
188
static toSQL SQLReadErrors("toDebug:ReadErrors",
189
"SELECT Line-1,Text FROM SYS.All_Errors\n"
190
" WHERE OWNER = :f1<char[101]>\n"
191
" AND NAME = :f2<char[101]>\n"
192
" AND TYPE = :f3<char[101]>\n"
193
" ORDER BY Type,Line",
194
"Get lines with errors in object (Observe first line 0)");
196
bool toDebugText::readErrors(toConnection &conn)
200
toQuery errors(conn, SQLReadErrors, Schema, Object, Type);
201
std::map<int, QString> Errors;
203
while (!errors.eof())
205
int line = errors.readValue().toInt();
206
Errors[line] += QString::fromLatin1(" ");
207
Errors[line] += errors.readValue();
215
bool toDebugText::readData(toConnection &conn, QListView *Stack)
217
QListViewItem *item = NULL;
218
if (Stack && Stack->firstChild())
219
for (item = Stack->firstChild();item->firstChild();item = item->firstChild())
223
toQuery lines(conn, SQLReadSource, Schema, Object, Type);
227
str += lines.readValue();
237
Schema == item->text(2) &&
238
Object == item->text(0) &&
239
Type == item->text(3))
240
setCurrent(item->text(1).toInt() - 1);
242
return readErrors(conn);
249
void toDebugText::setData(const QString &schema, const QString &type, const QString &object)
254
CurrentItem = FirstItem = NULL;
255
NoBreakpoints = false;
259
toDebugText::toDebugText(QListView *breakpoints,
262
: toHighlightedText(parent, QString::number(++ID).latin1()),
264
Breakpoints(breakpoints)
266
//setLeftIgnore(DEBUG_INDENT);
267
setMarginWidth(0, 25);
268
setMarginWidth(1, 10);
269
setMarginSensitivity(0,true);
270
setMarginSensitivity(1,true);
271
CurrentItem = FirstItem = NULL;
272
NoBreakpoints = false;
273
connect(this,SIGNAL(marginClicked(int, int, Qt::ButtonState)),this, SLOT(toggleBreakpoint(int, int, Qt::ButtonState)));
274
breakMarker=markerDefine(new QPixmap(const_cast<const char**>(breakpoint_xpm)));
275
disabledBreakMarker=markerDefine(new QPixmap(const_cast<const char**>(disbreakpoint_xpm)));
276
setMarginMarkerMask(1,2^breakMarker|2^disabledBreakMarker);
279
bool toDebugText::checkItem(toBreakpointItem *item)
283
if (item->text(2) == Schema &&
284
item->text(3) == Type &&
285
item->text(0) == Object)
290
void toDebugText::clear(void)
292
setData(QString::null, QString::null, QString::null);
293
FirstItem = CurrentItem = NULL;
294
NoBreakpoints = false;
295
toHighlightedText::clear();
298
bool toDebugText::hasBreakpoint(int row) // This has to leave CurrentItem on the breakpoint
300
if (!FirstItem && !NoBreakpoints)
302
FirstItem = dynamic_cast<toBreakpointItem *>(Breakpoints->firstChild());
303
while (!checkItem(FirstItem) && FirstItem)
304
FirstItem = dynamic_cast<toBreakpointItem *>(FirstItem->nextSibling());
306
NoBreakpoints = true;
307
CurrentItem = FirstItem;
312
toBreakpointItem *next = dynamic_cast<toBreakpointItem *>(CurrentItem->nextSibling());
313
bool hasNext = checkItem(next);
314
int nextLine = hasNext ? next->line() : row + 1;
316
if (CurrentItem->line() == row)
323
if (!hasNext && row > CurrentItem->line())
325
if (row < CurrentItem->line())
327
if (CurrentItem == FirstItem)
329
CurrentItem = FirstItem;
330
return hasBreakpoint(row);
335
return hasBreakpoint(row);
341
void toDebugText::mouseMoveEvent(QMouseEvent *me)
343
QRect view = childrenRect ();
344
if (me->x() > DEBUG_INDENT + view.left())
346
if (LastX <= DEBUG_INDENT + view.left())
347
setCursor(Qt::ibeamCursor);
348
if (me->state() != 0)
349
toHighlightedText::mouseMoveEvent(me);
353
if (LastX > DEBUG_INDENT + view.left())
354
setCursor(Qt::ibeamCursor);
355
setCursor(Qt::arrowCursor);
360
void toDebugText::toggleBreakpoint(int row, bool enable)
362
if (Schema.isEmpty() ||
369
getCursorPosition (&row, &curcol);
372
if (hasBreakpoint(row))
378
if (CurrentItem->text(4) == qApp->translate("toDebug", "DISABLED")){
379
CurrentItem->setText(4, qApp->translate("toDebug", "DEFERED"));
380
markerDelete(row,disabledBreakMarker);
381
markerAdd(row,breakMarker);
383
CurrentItem->clearBreakpoint();
384
markerDelete(row,breakMarker);
385
markerAdd(row,disabledBreakMarker);
390
CurrentItem->clearBreakpoint();
392
markerDelete(row,breakMarker);
393
markerDelete(row,disabledBreakMarker);
394
if (FirstItem == CurrentItem)
396
NoBreakpoints = false;
397
CurrentItem = FirstItem = NULL;
400
CurrentItem = FirstItem;
408
markerAdd(row,breakMarker);
409
if (CurrentItem && CurrentItem->line() > row)
410
new toBreakpointItem(Breakpoints, NULL,
411
Schema, Type, Object, row);
413
new toBreakpointItem(Breakpoints, CurrentItem,
414
Schema, Type, Object, row);
415
FirstItem = CurrentItem = NULL;
416
NoBreakpoints = false;
418
//updateCell(row, 0, false);
423
void toDebugText::toggleBreakpoint(int margin, int line, Qt::ButtonState state){
425
toggleBreakpoint(line);
429
void toDebugText::exportData(std::map<QCString, QString> &data, const QCString &prefix)
431
toHighlightedText::exportData(data, prefix);
432
data[prefix + ":Schema"] = Schema;
433
data[prefix + ":Object"] = Object;
434
data[prefix + ":Type"] = Type;
437
void toDebugText::importData(std::map<QCString, QString> &data, const QCString &prefix)
439
toHighlightedText::importData(data, prefix);
440
Schema = data[prefix + ":Schema"];
441
Object = data[prefix + ":Object"];
442
Type = data[prefix + ":Type"];
443
NoBreakpoints = false;