/***** * * TOra - An Oracle Toolkit for DBA's and developers * Copyright (C) 2003-2005 Quest Software, Inc * Portions Copyright (C) 2005 Other Contributors * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; only version 2 of * the License is valid for this program. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * As a special exception, you have permission to link this program * with the Oracle Client libraries and distribute executables, as long * as you follow the requirements of the GNU GPL in regard to all of the * software in the executable aside from Oracle client libraries. * * Specifically you are not permitted to link this program with the * Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech. * And you are not permitted to distribute binaries compiled against * these libraries without written consent from Quest Software, Inc. * Observe that this does not disallow linking to the Qt Free Edition. * * You may link this product with any GPL'd Qt library such as Qt/Free * * All trademarks belong to their respective owners. * *****/ #include "utils.h" #include "tochangeconnection.h" #include "toconf.h" #include "tohighlightedtext.h" #include "tomain.h" #include "toparamget.h" #include "toresultbar.h" #include "toresultcols.h" #include "toresultcombo.h" #include "toresultlong.h" #include "toresultplan.h" #include "toresultresources.h" #include "toresultstats.h" #include "toresultview.h" #include "tosession.h" #include "tosgatrace.h" #include "totabwidget.h" #include "totool.h" #include "totabwidget.h" #include "tovisualize.h" #include "toworksheet.h" #include "toworksheetsetupui.h" #include "toworksheetstatistic.h" #ifdef TO_KDE #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "toworksheet.moc" #include "toworksheetsetupui.moc" #include "icons/clock.xpm" #include "icons/recall.xpm" #include "icons/describe.xpm" #include "icons/eraselog.xpm" #include "icons/execute.xpm" #include "icons/executeall.xpm" #include "icons/executestep.xpm" #include "icons/explainplan.xpm" #include "icons/filesave.xpm" #include "icons/insertsaved.xpm" #include "icons/previous.xpm" #include "icons/refresh.xpm" #include "icons/stop.xpm" #include "icons/toworksheet.xpm" #include "icons/up.xpm" #include "icons/down.xpm" #ifdef TO_KDE_KACCELMANAGER # include #endif #define TO_ID_STATISTICS (toMain::TO_TOOL_MENU_ID+ 0) #define TO_ID_STOP (toMain::TO_TOOL_MENU_ID+ 1) #define TO_ID_PLAN (toMain::TO_TOOL_MENU_ID+ 2) #define CONF_AUTO_SAVE "AutoSave" #define CONF_CHECK_SAVE "CheckSave" #define CONF_AUTO_LOAD "AutoLoad" #define CONF_LOG_AT_END "LogAtEnd" #define CONF_LOG_MULTI "LogMulti" #define CONF_STATISTICS "Statistics" #define CONF_TIMED_STATS "TimedStats" #define CONF_NUMBER "Number" #define CONF_MOVE_TO_ERR "MoveToError" #define CONF_HISTORY "History" #define CONF_EXEC_LOG "ExecLog" #define CONF_TOPLEVEL_DESCRIBE "ToplevelDescribe" class toWorksheetSetup : public toWorksheetSetupUI, public toSettingTab { toTool *Tool; public: toWorksheetSetup(toTool *tool, QWidget* parent = 0, const char* name = 0) : toWorksheetSetupUI(parent, name), toSettingTab("worksheet.html#preferences"), Tool(tool) { if (!tool->config(CONF_AUTO_SAVE, "").isEmpty()) AutoSave->setChecked(true); if (!tool->config(CONF_CHECK_SAVE, "Yes").isEmpty()) CheckSave->setChecked(true); if (!tool->config(CONF_LOG_AT_END, "Yes").isEmpty()) LogAtEnd->setChecked(true); if (!tool->config(CONF_LOG_MULTI, "Yes").isEmpty()) LogMulti->setChecked(true); MoveToError->setChecked(!tool->config(CONF_MOVE_TO_ERR, "Yes").isEmpty()); if (!tool->config(CONF_STATISTICS, "").isEmpty()) Statistics->setChecked(true); TimedStatistics->setChecked(!tool->config(CONF_TIMED_STATS, "Yes").isEmpty()); History->setChecked(!tool->config(CONF_HISTORY, "").isEmpty()); if (!tool->config(CONF_NUMBER, "Yes").isEmpty()) DisplayNumber->setChecked(true); if (!tool->config(CONF_TOPLEVEL_DESCRIBE, "Yes").isEmpty()) ToplevelDescribe->setChecked(true); DefaultFile->setText(tool->config(CONF_AUTO_LOAD, "")); ExecLog->setChecked(!tool->config(CONF_EXEC_LOG, "").isEmpty()); #ifdef TO_NO_ORACLE TimedStatistics->hide(); MoveToError->hide(); Statistics->hide(); #endif } virtual void saveSetting(void) { if (AutoSave->isChecked()) Tool->setConfig(CONF_AUTO_SAVE, "Yes"); else Tool->setConfig(CONF_AUTO_SAVE, ""); if (CheckSave->isChecked()) Tool->setConfig(CONF_CHECK_SAVE, "Yes"); else Tool->setConfig(CONF_CHECK_SAVE, ""); if (LogAtEnd->isChecked()) Tool->setConfig(CONF_LOG_AT_END, "Yes"); else Tool->setConfig(CONF_LOG_AT_END, ""); if (LogMulti->isChecked()) Tool->setConfig(CONF_LOG_MULTI, "Yes"); else Tool->setConfig(CONF_LOG_MULTI, ""); Tool->setConfig(CONF_TOPLEVEL_DESCRIBE, ToplevelDescribe->isChecked() ? "Yes" : ""); Tool->setConfig(CONF_MOVE_TO_ERR, MoveToError->isChecked() ? "Yes" : ""); Tool->setConfig(CONF_STATISTICS, Statistics->isChecked() ? "Yes" : ""); Tool->setConfig(CONF_HISTORY, History->isChecked() ? "Yes" : ""); Tool->setConfig(CONF_TIMED_STATS, TimedStatistics->isChecked() ? "Yes" : ""); Tool->setConfig(CONF_NUMBER, DisplayNumber->isChecked() ? "Yes" : ""); Tool->setConfig(CONF_EXEC_LOG, ExecLog->isChecked() ? "Yes" : ""); Tool->setConfig(CONF_AUTO_LOAD, DefaultFile->text()); } public slots: void chooseFile(void) { QString str = toOpenFilename(DefaultFile->text(), QString::null, this); if (!str.isEmpty()) DefaultFile->setText(str); } }; class toWorksheetTool : public toTool { protected: virtual const char **pictureXPM(void) { return const_cast(toworksheet_xpm); } public: toWorksheetTool() : toTool(10, "SQL Editor") { } virtual const char *menuItem() { return "SQL Editor"; } virtual QWidget *toolWindow(QWidget *main, toConnection &connection) { return new toWorksheet(main, connection); } virtual QWidget *configurationTab(QWidget *parent) { return new toWorksheetSetup(this, parent); } virtual bool canHandle(toConnection &) { return true; } }; static toWorksheetTool WorksheetTool; class toWorksheetText : public toHighlightedText { toWorksheet *Worksheet; public: toWorksheetText(toWorksheet *worksheet, QWidget *parent, const char *name = NULL) : toHighlightedText(parent, name), Worksheet(worksheet) { } /** Reimplemented for internal reasons. */ virtual void keyPressEvent(QKeyEvent *e) { if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "Ctrl+Return", "Worksheet|Execute current")))) { Worksheet->execute(); e->accept(); } else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "F8", "Worksheet|Execute all")))) { Worksheet->executeAll(); e->accept(); } else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "F9", "Worksheet|Execute next")))) { Worksheet->executeStep(); e->accept(); } else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "Shift+F9", "Worksheet|Execute newline separated")))) { Worksheet->executeNewline(); e->accept(); } else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "F7", "Worksheet|Execute saved SQL")))) { Worksheet->executeSaved(); e->accept(); } else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "Shift+F7", "Worksheet|Insert saved SQL")))) { Worksheet->insertSaved(); e->accept(); } else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "F4", "Worksheet|Describe under cursor")))) { Worksheet->describe(); e->accept(); } else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "Alt+Up", "Worksheet|Previous log entry")))) { Worksheet->executePreviousLog(); e->accept(); } else if (toCheckKeyEvent(e, QKeySequence(qApp->translate("toWorksheet", "Alt+Down", "Worksheet|Next log entry")))) { Worksheet->executeNextLog(); e->accept(); } else { toHighlightedText::keyPressEvent(e); } } virtual bool editSave(bool askfile) { bool ret = toHighlightedText::editSave(askfile); Worksheet->setCaption(); return ret; } virtual bool editOpen(QString suggestedFile) { int ret = 1; if (isModified()) { ret = TOMessageBox::information(this, qApp->translate("toWorksheetText", "Save changes?"), qApp->translate("toWorksheetText", "The editor has been changed. Do you want to save them,\n" "discard changes or open file in new worksheet?"), qApp->translate("toWorksheetText", "&Save"), qApp->translate("toWorksheetText", "&Discard"), qApp->translate("toWorksheetText", "&New worksheet"), 0); if (ret < 0) return false; else if (ret == 0) { if (!editSave(false)) return false; } } QString fname; if (suggestedFile != QString::null) fname = suggestedFile; else { QFileInfo file(filename()); fname = toOpenFilename(file.dirPath(), QString::null, this); } if (fname.isEmpty()) return false; try { if (ret == 2) toWorksheet::fileWorksheet(fname); else { openFilename(fname); Worksheet->setCaption(); } return true; } TOCATCH return false; } }; void toWorksheet::viewResources(void) { try { QString address = toSQLToAddress(connection(), QueryString); Resources->changeParams(address); QString sql = toSQL::string(TOSQL_LONGOPS, connection()); sql += " AND b.SQL_Address||':'||b.SQL_Hash_Value = :addr"; LongOps->setSQL(sql); LongOps->clearParams(); LongOps->changeParams(address); } TOCATCH } #define TOWORKSHEET "toWorksheet:" void toWorksheet::setup(bool autoLoad) { QToolBar *toolbar = toAllocBar(this, tr("SQL worksheet")); new QToolButton(QPixmap(const_cast(execute_xpm)), tr("Execute current statement"), tr("Execute current statement"), this, SLOT(execute(void)), toolbar); new QToolButton(QPixmap(const_cast(executestep_xpm)), tr("Step through statements"), tr("Step through statements"), this, SLOT(executeStep(void)), toolbar); new QToolButton(QPixmap(const_cast(executeall_xpm)), tr("Execute all statements"), tr("Execute all statements"), this, SLOT(executeAll(void)), toolbar); toolbar->addSeparator(); new QToolButton(QPixmap(const_cast(refresh_xpm)), tr("Reexecute Last Statement"), tr("Reexecute Last Statement"), this, SLOT(refreshSetup(void)), toolbar); RefreshSeconds = 60; connect(&RefreshTimer, SIGNAL(timeout()), this, SLOT(refresh())); LastLine = LastOffset = -1; LastID = 0; if (Light) { Editor = new toWorksheetText(this, this); #ifdef TO_KDE_KACCELMANAGER KAcceleratorManager::setNoAccel( Editor ); #endif Current = Result = new toResultLong(this); Result->hide(); connect(Result, SIGNAL(done(void)), this, SLOT(queryDone(void))); connect(Result, SIGNAL(firstResult(const QString &, const toConnection::exception &, bool)), this, SLOT(addLog(const QString &, const toConnection::exception &, bool))); ResultTab = NULL; Plan = NULL; CurrentTab = NULL; Resources = NULL; Statistics = NULL; Logging = NULL; LastLogItem = NULL; StatisticButton = NULL; StatTab = NULL; Columns = NULL; Refresh = NULL; ToolMenu = NULL; Visualize = NULL; WaitChart = IOChart = NULL; toolbar->addSeparator(); StopButton = new QToolButton(QPixmap(const_cast(stop_xpm)), tr("Stop execution"), tr("Stop execution"), Result, SLOT(stop(void)), toolbar); StopButton->setEnabled(false); toolbar->setStretchableWidget(Started = new QLabel(toolbar, TO_KDE_TOOLBAR_WIDGET)); Started->setAlignment(AlignRight | AlignVCenter | ExpandTabs); } else { QSplitter *splitter = new QSplitter(Vertical, this); Editor = new toWorksheetText(this, splitter); #ifdef TO_KDE_KACCELMANAGER KAcceleratorManager::setNoAccel( Editor ); #endif ResultTab = new toTabWidget(splitter); QVBox *box = new QVBox(ResultTab); ResultTab->addTab(box, tr("&Result")); Current = Result = new toResultLong(box); connect(Result, SIGNAL(done(void)), this, SLOT(queryDone(void))); connect(Result, SIGNAL(firstResult(const QString &, const toConnection::exception &, bool)), this, SLOT(addLog(const QString &, const toConnection::exception &, bool))); bool toplevel = !WorksheetTool.config(CONF_TOPLEVEL_DESCRIBE, "Yes").isEmpty(); Columns = new toResultCols(box, "description", toplevel ? WType_TopLevel : 0); Columns->hide(); ResultTab->setTabEnabled(Columns, false); Plan = new toResultPlan(ResultTab); ResultTab->addTab(Plan, tr("E&xecution plan")); ResourceSplitter = new QSplitter(Vertical, ResultTab); Resources = new toResultResources(ResourceSplitter); LongOps = new toResultLong(ResourceSplitter); Visualize = new toVisualize(Result, ResultTab); ResultTab->addTab(Visualize, tr("&Visualize")); ResultTab->addTab(ResourceSplitter, tr("&Information")); ResultTab->setTabShown(ResourceSplitter, Resources->handled()); StatTab = new QVBox(ResultTab); { QToolBar *stattool = toAllocBar(StatTab, tr("Worksheet Statistics")); new QToolButton(QPixmap(const_cast(filesave_xpm)), tr("Save statistics for later analysis"), tr("Save statistics for later analysis"), this, SLOT(saveStatistics(void)), stattool); stattool->setStretchableWidget(new QLabel(stattool)); } splitter = new QSplitter(Horizontal, StatTab); Statistics = new toResultStats(true, splitter); Statistics->setTabWidget(ResultTab); WaitChart = new toResultBar(splitter); try { WaitChart->setSQL(toSQL::sql(TO_SESSION_WAIT)); } catch (...) {} WaitChart->setTitle(tr("Wait states")); WaitChart->setYPostfix(QString::fromLatin1("ms/s")); WaitChart->setSamples( -1); WaitChart->start(); connect(Statistics, SIGNAL(sessionChanged(const QString &)), WaitChart, SLOT(changeParams(const QString &))); IOChart = new toResultBar(splitter); try { IOChart->setSQL(toSQL::sql(TO_SESSION_IO)); } catch (...) {} IOChart->setTitle(tr("I/O")); IOChart->setYPostfix(tr("blocks/s")); IOChart->setSamples( -1); IOChart->start(); connect(Statistics, SIGNAL(sessionChanged(const QString &)), IOChart, SLOT(changeParams(const QString &))); ResultTab->addTab(StatTab, tr("&Statistics")); ResultTab->setTabEnabled(StatTab, false); Logging = new toListView(ResultTab); ResultTab->addTab(Logging, tr("&Logging")); Logging->addColumn(tr("SQL")); Logging->addColumn(tr("Result")); Logging->addColumn(tr("Timestamp")); Logging->addColumn(tr("Duration")); Logging->setColumnAlignment(3, AlignRight); Logging->setSelectionMode(QListView::Single); connect(Logging, SIGNAL(selectionChanged(QListViewItem *)), this, SLOT(executeLog())); LastLogItem = NULL; toolbar->addSeparator(); new QToolButton(QPixmap(const_cast(describe_xpm)), tr("Describe under cursor"), tr("Describe under cursor"), this, SLOT(describe(void)), toolbar); PlanButton = new QToolButton(QPixmap(const_cast(explainplan_xpm)), tr("Explain plan of current statement"), tr("Explain plan of current statement"), this, SLOT(explainPlan(void)), toolbar); PlanButton->setEnabled(Plan->handled()); StopButton = new QToolButton(QPixmap(const_cast(stop_xpm)), tr("Stop execution"), tr("Stop execution"), this, SLOT(stop(void)), toolbar); StopButton->setEnabled(false); toolbar->addSeparator(); new QToolButton(QPixmap(const_cast(eraselog_xpm)), tr("Clear execution log"), tr("Clear execution log"), this, SLOT(eraseLogButton(void)), toolbar); toolbar->addSeparator(); StatisticButton = new QToolButton(toolbar); StatisticButton->setToggleButton(true); StatisticButton->setIconSet(QIconSet(QPixmap(const_cast(clock_xpm)))); connect(StatisticButton, SIGNAL(toggled(bool)), this, SLOT(enableStatistic(bool))); QToolTip::add (StatisticButton, tr("Gather session statistic of execution")); #ifdef TO_NO_ORACLE QLabel *label = #endif new QLabel(tr("Refresh") + " ", toolbar, TO_KDE_TOOLBAR_WIDGET); Refresh = toRefreshCreate(toolbar, TO_KDE_TOOLBAR_WIDGET); #ifdef TO_NO_ORACLE label->hide(); Refresh->hide(); #else toolbar->addSeparator(); #endif connect(Refresh, SIGNAL(activated(const QString &)), this, SLOT(changeRefresh(const QString &))); connect(StatisticButton, SIGNAL(toggled(bool)), Refresh, SLOT(setEnabled(bool))); Refresh->setEnabled(false); Refresh->setFocusPolicy(NoFocus); new QToolButton(QPixmap(const_cast(up_xpm)), tr("Previous log entry"), tr("Previous log entry"), this, SLOT(executePreviousLog()), toolbar); new QToolButton(QPixmap(const_cast(down_xpm)), tr("Next log entry"), tr("Next log entry"), this, SLOT(executeNextLog()), toolbar); toolbar->addSeparator(); InsertSavedButton = new toPopupButton(QPixmap(const_cast(insertsaved_xpm)), tr("Insert current saved SQL"), tr("Insert current saved SQL"), toolbar); InsertSavedMenu = new QPopupMenu(InsertSavedButton); InsertSavedButton->setPopup(InsertSavedMenu); connect(InsertSavedMenu, SIGNAL(aboutToShow()), this, SLOT(showInsertSaved())); connect(InsertSavedMenu, SIGNAL(activated(int)), this, SLOT(insertSaved(int))); SavedButton = new toPopupButton(QPixmap(const_cast(recall_xpm)), tr("Run current saved SQL"), tr("Run current saved SQL"), toolbar); SavedMenu = new QPopupMenu(SavedButton); SavedButton->setPopup(SavedMenu); connect(SavedMenu, SIGNAL(aboutToShow()), this, SLOT(showSaved())); connect(SavedMenu, SIGNAL(activated(int)), this, SLOT(executeSaved(int))); new QToolButton(QPixmap(const_cast(previous_xpm)), tr("Save last SQL"), tr("Save last SQL"), this, SLOT(saveLast(void)), toolbar); toolbar->setStretchableWidget(Started = new QLabel(toolbar, TO_KDE_TOOLBAR_WIDGET)); Started->setAlignment(AlignRight | AlignVCenter | ExpandTabs); Schema = new toResultCombo(toolbar); Schema->setSQL(toSQL::sql(toSQL::TOSQL_USERLIST)); if (toIsMySQL(connection())) Schema->setSelected(connection().database()); else if (toIsOracle(connection()) || toIsSapDB(connection())) Schema->setSelected(connection().user().upper()); else Schema->setSelected(connection().user()); connect(Schema, SIGNAL(activated(int)), this, SLOT(changeSchema())); try { Schema->refresh(); } catch (...) {} new toChangeConnection(toolbar, TO_KDE_TOOLBAR_WIDGET); connect(ResultTab, SIGNAL(currentChanged(QWidget *)), this, SLOT(changeResult(QWidget *))); if (autoLoad) { Editor->setFilename(WorksheetTool.config(CONF_AUTO_LOAD, "")); if (!Editor->filename().isEmpty()) { try { QCString data = toReadFile(Editor->filename()); Editor->setText(QString::fromLocal8Bit(data)); Editor->setModified(false); } TOCATCH } } ToolMenu = NULL; connect(toMainWidget()->workspace(), SIGNAL(windowActivated(QWidget *)), this, SLOT(windowActivated(QWidget *))); try { if (connection().provider() == "Oracle") { if (!WorksheetTool.config(CONF_STATISTICS, "").isEmpty()) { show(); StatisticButton->setOn(true); } } else { StatisticButton->setShown(false); } } TOCATCH connect(this, SIGNAL(connectionChange()), this, SLOT(connectionChanged())); } Editor->setAnalyzer(connection().analyzer()); connect(Editor, SIGNAL(displayMenu(QPopupMenu *)), this, SLOT(displayMenu(QPopupMenu *))); connect(&Poll, SIGNAL(timeout()), this, SLOT(poll())); setFocusProxy(Editor); } toWorksheet::toWorksheet(QWidget *main, toConnection &connection, bool autoLoad) : toToolWidget(WorksheetTool, "worksheet.html", main, connection), Light(false) { setup(autoLoad); } toWorksheet::toWorksheet(QWidget *main, const char *name, toConnection &connection) : toToolWidget(WorksheetTool, "worksheetlight.html", main, connection, name), Light(true) { setup(false); } void toWorksheet::changeRefresh(const QString &str) { try { if (!Light && StopButton->isEnabled() && StatisticButton->isOn()) toRefreshParse(timer(), str); } TOCATCH } void toWorksheet::windowActivated(QWidget *widget) { if (Light) return ; QWidget *w = this; while (w && w != widget) { w = w->parentWidget(); } if (widget == w) { if (!ToolMenu) { ToolMenu = new QPopupMenu(this); ToolMenu->insertItem(QPixmap(const_cast(execute_xpm)), tr("&Execute Current"), this, SLOT(execute(void)), toKeySequence(tr("Ctrl+Return", "Worksheet|Execute current"))); ToolMenu->insertItem(QPixmap(const_cast(executestep_xpm)), tr("Execute &Next"), this, SLOT(executeStep(void)), toKeySequence(tr("F9", "Worksheet|Execute next"))); ToolMenu->insertItem(QPixmap(const_cast(executeall_xpm)), tr("Execute &All"), this, SLOT(executeAll(void)), toKeySequence(tr("F8", "Worksheet|Execute all"))); ToolMenu->insertItem(tr("Execute &Newline Separated"), this, SLOT(executeNewline(void)), toKeySequence(tr("Shift+F9", "Worksheet|Execute newline separated"))); ToolMenu->insertItem(QPixmap(const_cast(refresh_xpm)), tr("&Reexecute Last Statement"), this, SLOT(refresh(void)), toKeySequence(tr("F5", "Worksheet|Reexecute last statement"))); if (connection().provider() == "Oracle") ToolMenu->insertItem(tr("Check syntax of buffer"), this, SLOT(parseAll()), toKeySequence(tr("Ctrl+F9", "Worksheet|Check syntax of buffer"))); ToolMenu->insertSeparator(); ToolMenu->insertItem(QPixmap(const_cast(describe_xpm)), tr("&Describe Under Cursor"), this, SLOT(describe(void)), toKeySequence(tr("F4", "Worksheet|Describe under cursor"))); ToolMenu->insertItem(tr("&Explain current statement"), this, SLOT(explainPlan(void)), toKeySequence(tr("F3", "Worksheet|Explain plan")), TO_ID_PLAN); if (connection().provider() == "Oracle") ToolMenu->insertItem(tr("&Enable Statistics"), this, SLOT(toggleStatistic(void)), 0, TO_ID_STATISTICS); ToolMenu->insertItem(QPixmap(const_cast(stop_xpm)), tr("&Stop Execution"), Result, SLOT(stop(void)), 0, TO_ID_STOP); ToolMenu->insertSeparator(); ToolMenu->insertItem(tr("Execute Saved SQL"), this, SLOT(executeSaved()), toKeySequence(tr("F7", "Worksheet|Execute saved SQL"))); ToolMenu->insertItem(tr("Select Saved SQL"), this, SLOT(selectSaved()), toKeySequence(tr("Ctrl+Shift+S", "Worksheet|Select saved SQL"))); ToolMenu->insertItem(QPixmap(const_cast(previous_xpm)), tr("Save last SQL"), this, SLOT(saveLast())); ToolMenu->insertItem(tr("Edit Saved SQL..."), this, SLOT(editSaved())); ToolMenu->insertSeparator(); ToolMenu->insertItem(tr("Previous Log Entry"), this, SLOT(executePreviousLog()), toKeySequence(tr("Alt+Up", "Worksheet|Previous log entry"))); ToolMenu->insertItem(tr("Next Log Entry"), this, SLOT(executeNextLog()), toKeySequence(tr("Alt+Down", "Worksheet|Next log entry"))); ToolMenu->insertItem(QPixmap(const_cast(eraselog_xpm)), tr("Erase &Log"), this, SLOT(eraseLogButton(void))); toMainWidget()->menuBar()->insertItem(tr("Edit&or"), ToolMenu, -1, toToolMenuIndex()); ToolMenu->setItemEnabled(TO_ID_STOP, StopButton->isEnabled()); ToolMenu->setItemChecked(TO_ID_STATISTICS, StatisticButton->isOn()); ToolMenu->setItemEnabled(TO_ID_PLAN, Plan->handled()); } } else { delete ToolMenu; ToolMenu = NULL; } } void toWorksheet::connectionChanged(void) { try { StatisticButton->setShown(connection().provider() == "Oracle"); ResultTab->setTabShown(ResourceSplitter, Resources->handled()); Editor->setAnalyzer(connection().analyzer()); PlanButton->setEnabled(Plan->handled()); delete ToolMenu; ToolMenu = NULL; windowActivated(this); } TOCATCH } bool toWorksheet::checkSave(bool input) { if (Light) return true; if (Editor->isModified()) { if (WorksheetTool.config(CONF_AUTO_SAVE, "").isEmpty() || Editor->filename().isEmpty()) { if (!WorksheetTool.config(CONF_CHECK_SAVE, "Yes").isEmpty()) { if (input) { QString conn; try { conn = connection().description(); } catch (...) { conn += QString::fromLatin1("unknown connection"); } QString str = tr("Save changes to editor for %1").arg(conn); if (!Editor->filename().isEmpty()) str += QString::fromLatin1("\n(") + Editor->filename() + QString::fromLatin1(")"); int ret = TOMessageBox::information(this, tr("Save file"), str, tr("&Yes"), tr("&No"), tr("Cancel"), 0, 2); if (ret == 1) return true; else if (ret == 2) return false; } else return true; } else return true; if (Editor->filename().isEmpty() && input) Editor->setFilename(toSaveFilename(Editor->filename(), QString::null, this)); if (Editor->filename().isEmpty()) return false; } if (!toWriteFile(Editor->filename(), Editor->text())) return false; Editor->setModified(false); } return true; } bool toWorksheet::close(bool del) { if (checkSave(true)) { Result->stop(); return QVBox::close(del); } return false; } toWorksheet::~toWorksheet() { checkSave(false); eraseLogButton(); } #define LARGE_BUFFER 4096 void toWorksheet::changeResult(QWidget *widget) { CurrentTab = widget; if (QueryString.length()) { if (CurrentTab == Plan) Plan->query(QueryString); else if (CurrentTab == ResourceSplitter) viewResources(); else if (CurrentTab == Statistics && Result->running()) Statistics->refreshStats(false); } } void toWorksheet::refresh(void) { if (!QueryString.isEmpty()) query(QueryString, Normal); if (RefreshSeconds > 0) RefreshTimer.start(RefreshSeconds*1000, true); } static QString unQuote(const QString &str) { if (str.at(0).latin1() == '\"' && str.at(str.length() - 1).latin1() == '\"') return str.left(str.length() - 1).right(str.length() - 2); return str.upper(); } bool toWorksheet::describe(const QString &query) { try { QRegExp white(QString::fromLatin1("[ \r\n\t.]+")); QStringList part = QStringList::split(white, query); if (part[0].upper() == QString::fromLatin1("DESC") || part[0].upper() == QString::fromLatin1("DESCRIBE")) { if (Light) return true; if (toIsOracle(connection())) { if (part.count() == 2) { Columns->changeParams(unQuote(part[1])); } else if (part.count() == 3) { Columns->changeParams(unQuote(part[1]), unQuote(part[2])); } else throw tr("Wrong number of parameters for describe"); } else if (connection().provider() == "MySQL") { if (part.count() == 2) { Columns->changeParams(part[1]); } else throw tr("Wrong number of parameters for describe"); } Current->hide(); Columns->show(); Current = Columns; return true; } else { if (Light) return false; QWidget *curr = ResultTab->currentPage(); Current->hide(); Result->show(); Current = Result; if (curr == Columns) ResultTab->showPage(Result); return false; } } TOCATCH return false; } void toWorksheet::query(const QString &str, execType type) { Result->stop(); RefreshTimer.stop(); QRegExp strq(QString::fromLatin1("'[^']*'")); QString chk = str.lower(); chk.replace(strq, QString::fromLatin1(" ")); bool code = false; static QRegExp codere(QString::fromLatin1("[^a-z0-9]end\\s+[a-z0-9_-]*;$"), true); static QRegExp codere2(QString::fromLatin1("[^a-z0-9]end;"), true); if (codere.match(chk) >= 0 || codere2.match(chk) >= 0) code = true; QueryString = str; if (!code && QueryString.length() > 0 && QueryString.at(QueryString.length() - 1) == ';') QueryString.truncate(QueryString.length() - 1); bool nobinds = false; chk = str.lower(); chk.replace(strq, QString::fromLatin1(" ")); chk = chk.simplifyWhiteSpace(); chk.replace(QRegExp(QString::fromLatin1(" or replace ")), QString::fromLatin1(" ")); if (chk.startsWith(QString::fromLatin1("create trigger "))) nobinds = true; if (type == OnlyPlan) { ResultTab->showPage(Plan); Plan->query(str); } else if (!describe(QueryString)) { toSQLParse::stringTokenizer tokens(str); QString first = tokens.getToken(true).upper(); if (first == QString::fromLatin1("REM") || first == QString::fromLatin1("ASSIGN") || first == QString::fromLatin1("PROMPT") || first == QString::fromLatin1("COLUMN") || first == QString::fromLatin1("SPOOL") || first == QString::fromLatin1("STORE")) { QString t = tr("Ignoring SQL*Plus command"); Timer.start(); addLog(QueryString, toConnection::exception(t), false); toStatusMessage(t, true); return ; } toQList param; if (!nobinds) try { param = toParamGet::getParam(connection(), this, QueryString); } catch (...) { return ; } toStatusMessage(tr("Processing query"), true); if (type == Parse) { try { First = false; Timer.start(); connection().parse(QueryString); } catch (const QString &exc) { addLog(QueryString, exc, true); } } else if (type == Direct) { try { First = false; Timer.start(); QString buffer; if (WorksheetTool.config(CONF_HISTORY, "").isEmpty() && !Light) { toQuery query(connection(), toQuery::Long, QueryString, param); if (query.rowsProcessed() > 0) buffer = tr("%1 rows processed").arg((int)query.rowsProcessed()); else buffer = tr("Query executed"); } else { toResultView *query = new toResultView(Current->parentWidget()); try { query->query(QueryString, param); if (query->query() && query->query()->rowsProcessed() > 0) buffer = tr("%1 rows processed").arg((int)query->query()->rowsProcessed()); else buffer = tr("Query executed"); Current->hide(); Current = query; Current->show(); } catch (...) { delete query; throw; } } addLog(QueryString, toConnection::exception(buffer), false); } catch (const QString &exc) { addLog(QueryString, exc, true); } } else { First = false; Timer.start(); StopButton->setEnabled(true); Poll.start(1000); QToolTip::add (Started, tr("Duration while query has been running\n\n") + QueryString); if (ToolMenu) ToolMenu->setItemEnabled(TO_ID_STOP, true); Result->setNumberColumn(!WorksheetTool.config(CONF_NUMBER, "Yes").isEmpty()); try { saveHistory(); Result->setSQL(QString::null); Result->query(QueryString, param); if (Light) return ; if (CurrentTab == Visualize) Visualize->display(); else if (CurrentTab == Plan) Plan->query(QueryString); else if (CurrentTab == ResourceSplitter) viewResources(); } catch (const toConnection::exception &exc) { addLog(QueryString, exc, true); } catch (const QString &exc) { addLog(QueryString, exc, true); } if (!Light) { try { if (StatisticButton->isOn()) toRefreshParse(timer(), Refresh->currentText()); } TOCATCH } Result->setSQLName(QueryString.simplifyWhiteSpace().left(40)); } } } void toWorksheet::saveHistory(void) { if (WorksheetTool.config(CONF_HISTORY, "").isEmpty()) return ; if (Result->firstChild() && Current == Result && !Light) { History[LastID] = Result; Result->hide(); Result->stop(); disconnect(Result, SIGNAL(done(void)), this, SLOT(queryDone(void))); disconnect(Result, SIGNAL(firstResult(const QString &, const toConnection::exception &, bool)), this, SLOT(addLog(const QString &, const toConnection::exception &, bool))); disconnect(StopButton, SIGNAL(clicked(void)), Result, SLOT(stop(void))); Result = new toResultLong(Result->parentWidget()); if (StatisticButton->isOn()) enableStatistic(true); Result->show(); Current = Result; connect(StopButton, SIGNAL(clicked(void)), Result, SLOT(stop(void))); connect(Result, SIGNAL(done(void)), this, SLOT(queryDone(void))); connect(Result, SIGNAL(firstResult(const QString &, const toConnection::exception &, bool)), this, SLOT(addLog(const QString &, const toConnection::exception &, bool))); } } QString toWorksheet::duration(int dur, bool hundreds) { char buf[100]; if (dur >= 3600000) { if (hundreds) sprintf(buf, "%d:%02d:%02d.%02d", dur / 3600000, (dur / 60000) % 60, (dur / 1000) % 60, (dur / 10) % 100); else sprintf(buf, "%d:%02d:%02d", dur / 3600000, (dur / 60000) % 60, (dur / 1000) % 60); } else { if (hundreds) sprintf(buf, "%d:%02d.%02d", dur / 60000, (dur / 1000) % 60, (dur / 10) % 100); else sprintf(buf, "%d:%02d", dur / 60000, (dur / 1000) % 60); } return QString::fromLatin1(buf); } void toWorksheet::addLog(const QString &sql, const toConnection::exception &result, bool error) { QString now; try { now = toNow(connection()); } catch (...) { now = QString::fromLatin1("Unknown"); } toResultViewItem *item = NULL; LastID++; int dur = 0; if (!Timer.isNull()) dur = Timer.elapsed(); First = true; if (!Light) { if (WorksheetTool.config(CONF_LOG_MULTI, "Yes").isEmpty()) { if (WorksheetTool.config(CONF_LOG_AT_END, "Yes").isEmpty()) item = new toResultViewItem(Logging, NULL); else item = new toResultViewItem(Logging, LastLogItem); } else if (WorksheetTool.config(CONF_LOG_AT_END, "Yes").isEmpty()) item = new toResultViewMLine(Logging, NULL); else item = new toResultViewMLine(Logging, LastLogItem); item->setText(0, sql); LastLogItem = item; item->setText(1, result); item->setText(2, now); if (!WorksheetTool.config(CONF_HISTORY, "").isEmpty()) item->setText(4, QString::number(LastID)); item->setText(5, QString::number(result.offset())); } if (result.offset() >= 0 && LastLine >= 0 && LastOffset >= 0 && !WorksheetTool.config(CONF_MOVE_TO_ERR, "Yes").isEmpty()) { QChar cmp = '\n'; int lastnl = 0; int lines = 0; for (int i = 0;i < result.offset();i++) { if (sql.at(i) == cmp) { LastOffset = 0; lastnl = i + 1; lines++; } } Editor->setCursorPosition(LastLine + lines, LastOffset + result.offset() - lastnl); LastLine = LastOffset = -1; } QString buf = duration(dur); if (!Light) { item->setText(3, buf); QListViewItem *last = Logging->currentItem(); toResultViewItem *citem = NULL; if (last) citem = dynamic_cast(last); if (!citem || citem->allText(0) != sql) { disconnect(Logging, SIGNAL(selectionChanged(QListViewItem *)), this, SLOT(executeLog())); Logging->setSelected(item, true); connect(Logging, SIGNAL(selectionChanged(QListViewItem *)), this, SLOT(executeLog())); Logging->ensureItemVisible(item); } } { QString str = result; str += "\n" + tr("(Duration %1)").arg(buf); if (error) toStatusMessage(str); else toStatusMessage(str, false, false); } if (!Light && !error) changeResult(CurrentTab); static QRegExp re(QString::fromLatin1("^[1-9]\\d* rows processed$")); try { if (result.contains(re)) { if (!toTool::globalConfig(CONF_AUTO_COMMIT, "").isEmpty()) connection().commit(); else toMainWidget()->setNeedCommit(connection()); } } TOCATCH saveDefaults(); } void toWorksheet::execute(toSQLParse::tokenizer &tokens, int line, int pos, execType type) { LastLine = line; LastOffset = pos; Editor->setSelection(line, pos, tokens.line(), tokens.offset()); QString t = Editor->selectedText(); bool comment = false; bool multiComment = false; int oline = line; int opos = pos; unsigned int i; for (i = 0;i < t.length() - 1;i++) { if (comment) { if (t.at(i).latin1() == '\n') comment = false; } else if (multiComment) { if (t.at(i).latin1() == '*' && t.at(i + 1).latin1() == '/') { multiComment = false; i++; } } else if (t.at(i).latin1() == '-' && t.at(i + 1).latin1() == '-') comment = true; else if (t.at(i).latin1() == '/' && t.at(i + 1).latin1() == '/') comment = true; else if (t.at(i).latin1() == '/' && t.at(i + 1).latin1() == '*') multiComment = true; else if (!t.at(i).isSpace() && t.at(i) != '/') break; if (t.at(i).latin1() == '\n') { line++; pos = 0; } else pos++; } if (line != oline || pos != opos) { LastLine = line; LastOffset = pos; Editor->setSelection(line, pos, tokens.line(), tokens.offset()); t = t.mid(i); } if (t.length()) query(t, type); } void toWorksheet::execute() { if (Editor->hasSelectedText()) { query(Editor->selectedText(), Normal); return ; } toSQLParse::editorTokenizer tokens(Editor); int cpos, cline; Editor->getCursorPosition(&cline, &cpos); int line; int pos; do { line = tokens.line(); pos = tokens.offset(); toSQLParse::parseStatement(tokens); } while (tokens.line() < cline || (tokens.line() == cline && tokens.offset() < cpos)); execute(tokens, line, pos, Normal); } void toWorksheet::explainPlan() { if (Editor->hasSelectedText()) { query(Editor->selectedText(), OnlyPlan); return ; } toSQLParse::editorTokenizer tokens(Editor); int cpos, cline; Editor->getCursorPosition(&cline, &cpos); int line; int pos; do { line = tokens.line(); pos = tokens.offset(); toSQLParse::parseStatement(tokens); } while (tokens.line() < cline || (tokens.line() == cline && tokens.offset() < cpos)); execute(tokens, line, pos, OnlyPlan); } void toWorksheet::executeStep() { toSQLParse::editorTokenizer tokens(Editor); int cpos, cline; Editor->getCursorPosition(&cline, &cpos); int line; int pos; do { line = tokens.line(); pos = tokens.offset(); toSQLParse::parseStatement(tokens); } while (tokens.line() < cline || (tokens.line() == cline && tokens.offset() <= cpos)); execute(tokens, line, pos, Normal); } void toWorksheet::executeAll() { toSQLParse::editorTokenizer tokens(Editor); int cpos, cline; Editor->getCursorPosition(&cline, &cpos); QProgressDialog dialog(tr("Executing all statements"), tr("Cancel"), Editor->lines(), this, "Progress", true); int line; int pos; bool ignore = true; do { line = tokens.line(); pos = tokens.offset(); dialog.setProgress(line); qApp->processEvents(); if (dialog.wasCancelled()) break; toSQLParse::parseStatement(tokens); if (ignore && (tokens.line() > cline || (tokens.line() == cline && tokens.offset() >= cpos))) { ignore = false; cline = line; cpos = pos; } if (tokens.line() < Editor->lines() && !ignore) { execute(tokens, line, pos, Direct); if (Current) { toResultView *last = dynamic_cast(Current); if (!WorksheetTool.config(CONF_HISTORY, "").isEmpty() && last && last->firstChild()) History[LastID] = last; } } } while (tokens.line() < Editor->lines()); Editor->setSelection(cline, cpos, tokens.line(), tokens.offset()); } void toWorksheet::parseAll() { toSQLParse::editorTokenizer tokens(Editor); int cpos, cline; Editor->getCursorPosition(&cline, &cpos); QProgressDialog dialog(tr("Parsing all statements"), tr("Cancel"), Editor->lines(), this, "Progress", true); int line; int pos; bool ignore = true; do { line = tokens.line(); pos = tokens.offset(); dialog.setProgress(line); qApp->processEvents(); if (dialog.wasCancelled()) break; toSQLParse::parseStatement(tokens); if (ignore && (tokens.line() > cline || (tokens.line() == cline && tokens.offset() >= cpos))) { ignore = false; cline = line; cpos = pos; } if (tokens.line() < Editor->lines() && !ignore) { execute(tokens, line, pos, Parse); if (Current) { toResultView *last = dynamic_cast(Current); if (!WorksheetTool.config(CONF_HISTORY, "").isEmpty() && last && last->firstChild()) History[LastID] = last; } } } while (tokens.line() < Editor->lines()); Editor->setSelection(cline, cpos, tokens.line(), tokens.offset()); } void toWorksheet::eraseLogButton() { if (Light) return ; Logging->clear(); LastLogItem = NULL; for (std::map::iterator i = History.begin();i != History.end();i++) delete (*i).second; History.clear(); } void toWorksheet::queryDone(void) { if (!First && !QueryString.isEmpty()) addLog(QueryString, toConnection::exception(tr("Aborted")), false); else emit executed(); try { timer()->stop(); } TOCATCH StopButton->setEnabled(false); Poll.stop(); if (ToolMenu) ToolMenu->setItemEnabled(TO_ID_STOP, false); saveDefaults(); } void toWorksheet::saveDefaults(void) { QListViewItem *item = Result->firstChild(); if (item) { QHeader *head = Result->header(); for (int i = 0;i < Result->columns();i++) { toResultViewItem *resItem = dynamic_cast(item); QString str; if (resItem) str = resItem->allText(i); else if (item) str = item->text(i); try { toParamGet::setDefault(connection(), head->label(i).lower(), toUnnull(toQValue(str))); } TOCATCH } } } #define ENABLETIMED "ALTER SESSION SET TIMED_STATISTICS = TRUE" void toWorksheet::enableStatistic(bool ena) { if (ena) { Result->setStatistics(Statistics); ResultTab->setTabEnabled(StatTab, true); if (ToolMenu) ToolMenu->setItemChecked(TO_ID_STATISTICS, true); Statistics->clear(); if (!WorksheetTool.config(CONF_TIMED_STATS, "Yes").isEmpty()) { try { connection().allExecute(QString::fromLatin1(ENABLETIMED)); connection().addInit(QString::fromLatin1(ENABLETIMED)); } TOCATCH } } else { try { connection().delInit(QString::fromLatin1(ENABLETIMED)); } catch (...) {} Result->setStatistics(NULL); ResultTab->setTabEnabled(StatTab, false); if (ToolMenu) ToolMenu->setItemChecked(TO_ID_STATISTICS, false); } } void toWorksheet::executeNewline(void) { int cline, epos; Editor->getCursorPosition(&cline, &epos); if (cline > 0) cline--; while (cline > 0) { QString data = Editor->text(cline).simplifyWhiteSpace(); if (data.length() == 0 || data == QString::fromLatin1(" ")) { cline++; break; } cline--; } while (cline < Editor->lines()) { QString data = Editor->text(cline).simplifyWhiteSpace(); if (data.length() != 0 && data != QString::fromLatin1(" ")) break; cline++; } int eline = cline; while (eline < Editor->lines()) { QString data = Editor->text(eline).simplifyWhiteSpace(); if (data.length() == 0 || data == QString::fromLatin1(" ")) { eline--; break; } epos = Editor->text(eline).length(); eline++; } Editor->setSelection(cline, 0, eline, epos); LastLine = cline; LastOffset = 0; if (Editor->hasSelectedText()) query(Editor->selectedText(), Normal); } void toWorksheet::describe(void) { if (Light) return ; QString owner, table; Editor->tableAtCursor(owner, table); if (owner.isNull()) Columns->changeParams(table); else Columns->changeParams(owner, table); if (!Columns->isTopLevel()) Current->hide(); Columns->show(); Current = Columns; } void toWorksheet::executeSaved(void) { if (Light) return ; LastLine = LastOffset = -1; if (SavedLast.length() > 0) { try { query(toSQL::string(SavedLast, connection()), Normal); } TOCATCH } } void toWorksheet::insertSaved(void) { if (Light) return ; LastLine = LastOffset = -1; if (InsertSavedLast.length() > 0) { try { Editor->setText(toSQL::string(InsertSavedLast, connection())); } TOCATCH } } void toWorksheet::executeSaved(int id) { std::list def = toSQL::range(TOWORKSHEET); for (std::list::iterator i = def.begin();i != def.end();i++) { id--; if (id == 0) { SavedLast = *i; executeSaved(); break; } } } void toWorksheet::insertSaved(int id) { std::list def = toSQL::range(TOWORKSHEET); for (std::list::iterator i = def.begin();i != def.end();i++) { id--; if (id == 0) { InsertSavedLast = *i; insertSaved(); break; } } } void toWorksheet::showSaved(void) { static QRegExp colon(QString::fromLatin1(":")); std::list def = toSQL::range(TOWORKSHEET); SavedMenu->clear(); std::map menues; int id = 0; for (std::list::iterator sql = def.begin();sql != def.end();sql++) { id++; QStringList spl = QStringList::split(colon, QString::fromLatin1(*sql)); spl.remove(spl.begin()); if (spl.count() > 0) { QString name = spl.last(); spl.remove(spl.fromLast()); QPopupMenu *menu; if (spl.count() == 0) menu = SavedMenu; else { QStringList exs = spl; while (exs.count() > 0 && menues.find(exs.join(QString::fromLatin1(":"))) == menues.end()) exs.remove(exs.fromLast()); if (exs.count() == 0) menu = SavedMenu; else menu = menues[exs.join(QString::fromLatin1(":"))]; QString subname = exs.join(QString::fromLatin1(":")); for (unsigned int i = exs.count();i < spl.count();i++) { QPopupMenu *next = new QPopupMenu(this); connect(next, SIGNAL(activated(int)), this, SLOT(executeSaved(int))); if (i != 0) subname += QString::fromLatin1(":"); subname += spl[i]; menu->insertItem(spl[i], next); menu = next; menues[subname] = menu; } } menu->insertItem(name, id); } } } void toWorksheet::showInsertSaved(void) { static QRegExp colon(QString::fromLatin1(":")); std::list def = toSQL::range(TOWORKSHEET); InsertSavedMenu->clear(); std::map menues; int id = 0; for (std::list::iterator sql = def.begin();sql != def.end();sql++) { id++; QStringList spl = QStringList::split(colon, QString::fromLatin1(*sql)); spl.remove(spl.begin()); if (spl.count() > 0) { QString name = spl.last(); spl.remove(spl.fromLast()); QPopupMenu *menu; if (spl.count() == 0) menu = InsertSavedMenu; else { QStringList exs = spl; while (exs.count() > 0 && menues.find(exs.join(QString::fromLatin1(":"))) == menues.end()) exs.remove(exs.fromLast()); if (exs.count() == 0) menu = InsertSavedMenu; else menu = menues[exs.join(QString::fromLatin1(":"))]; QString subname = exs.join(QString::fromLatin1(":")); for (unsigned int i = exs.count();i < spl.count();i++) { QPopupMenu *next = new QPopupMenu(this); connect(next, SIGNAL(activated(int)), this, SLOT(insertSaved(int))); if (i != 0) subname += QString::fromLatin1(":"); subname += spl[i]; menu->insertItem(spl[i], next); menu = next; menues[subname] = menu; } } menu->insertItem(name, id); } } } void toWorksheet::editSaved(void) { QCString sql = TOWORKSHEET; sql += "Untitled"; toMainWidget()->editSQL(QString::fromLatin1(sql)); } void toWorksheet::selectSaved() { SavedMenu->popup(SavedButton->mapToGlobal(QPoint(0, SavedButton->height()))); } void toWorksheet::insertStatement(const QString &str) { QString txt = Editor->text(); int i = txt.find(str); if (i >= 0) { int startCol, endCol; int startRow, endRow; Editor->findPosition(i, startRow, startCol); Editor->findPosition(i + str.length(), endRow, endCol); if (Editor->text(endRow).at(endCol) == ';') endCol++; Editor->setSelection(startRow, startCol, endRow, endCol); } else { QString t = str; if (str.right(1) != ";") { t += ";"; } Editor->insert(t, true); } } void toWorksheet::executePreviousLog(void) { if (Light) return ; Result->stop(); LastLine = LastOffset = -1; saveHistory(); QListViewItem *item = Logging->currentItem(); if (item) { QListViewItem *pt = Logging->firstChild(); while (pt && pt->nextSibling() != item) pt = pt->nextSibling(); if (pt) Logging->setSelected(pt, true); } } void toWorksheet::executeLog(void) { if (Light) return ; Result->stop(); LastLine = LastOffset = -1; saveHistory(); QListViewItem *ci = Logging->currentItem(); toResultViewItem *item = dynamic_cast(ci); if (item) { insertStatement(item->allText(0)); if (item->text(4).isEmpty()) { if (!WorksheetTool.config(CONF_EXEC_LOG, "").isEmpty()) query(item->allText(0), Normal); } else { std::map::iterator i = History.find(item->text(4).toInt()); QueryString = item->allText(0); changeResult(ResultTab->currentPage()); if (i != History.end() && (*i).second) { Current->hide(); Current = (*i).second; Current->show(); } } } } void toWorksheet::executeNextLog(void) { if (Light) return ; Result->stop(); LastLine = LastOffset = -1; saveHistory(); QListViewItem *item = Logging->currentItem(); if (item && item->nextSibling()) { toResultViewItem *next = dynamic_cast(item->nextSibling()); if (next) Logging->setSelected(next, true); } } void toWorksheet::poll(void) { Started->setText(duration(Timer.elapsed(), false)); } void toWorksheet::saveLast(void) { if (QueryString.isEmpty()) { TOMessageBox::warning(this, tr("No SQL to save"), tr("You haven't executed any SQL yet"), tr("&Ok")); return ; } bool ok = false; QCString name = QInputDialog::getText(tr("Enter title"), tr("Enter the title in the menu of the saved SQL,\n" "submenues are separated by a ':' character."), QLineEdit::Normal, QString::null, &ok, this).latin1(); if (ok && !name.isEmpty()) { try { toSQL::updateSQL(TOWORKSHEET + name, QueryString, tr("Undescribed"), "Any", connection().provider()); toSQL::saveSQL(toTool::globalConfig(CONF_SQL_FILE, DEFAULT_SQL_FILE)); } TOCATCH } } void toWorksheet::saveStatistics(void) { std::map stat; Statistics->exportData(stat, "Stat"); IOChart->exportData(stat, "IO"); WaitChart->exportData(stat, "Wait"); if (Plan->firstChild()) Plan->exportData(stat, "Plan"); else toStatusMessage(tr("No plan available to save"), false, false); stat["Description"] = QueryString; toWorksheetStatistic::saveStatistics(stat); } void toWorksheet::exportData(std::map &data, const QCString &prefix) { Editor->exportData(data, prefix + ":Edit"); if (StatisticButton->isOn()) data[prefix + ":Stats"] = Refresh->currentText(); toToolWidget::exportData(data, prefix); } void toWorksheet::importData(std::map &data, const QCString &prefix) { Editor->importData(data, prefix + ":Edit"); QString stat = data[prefix + ":Stats"]; if (stat) { for (int i = 0;i < Refresh->count();i++) { if (Refresh->text(i) == stat) { Refresh->setCurrentItem(i); break; } } StatisticButton->setOn(true); } else StatisticButton->setOn(false); toToolWidget::importData(data, prefix); setCaption(); } void toWorksheet::setCaption(void) { QString name = WorksheetTool.name(); if (! Editor->filename().isEmpty()) { QFileInfo file(Editor->filename()); name += QString::fromLatin1(" ") + file.fileName(); } toToolCaption(this, name); } toWorksheet *toWorksheet::fileWorksheet(const QString &file) { toWorksheet *worksheet = new toWorksheet(toMainWidget()->workspace(), toMainWidget()->currentConnection(), false); worksheet->editor()->openFilename(file); worksheet->setCaption(); worksheet->show(); toMainWidget()->windowsMenu(); return worksheet; } void toWorksheet::refreshSetup(void) { bool ok = false; int num = QInputDialog::getInteger(tr("Enter refreshrate"), tr("Refresh rate of query in seconds"), RefreshSeconds, 0, 1000000, 1, &ok, this); if (ok) { RefreshSeconds = num; RefreshTimer.start(num*1000); } else RefreshTimer.stop(); } void toWorksheet::stop(void) { RefreshTimer.stop(); Result->stop(); } void toWorksheet::displayMenu(QPopupMenu *menu) { menu->insertSeparator(0); if (!Light) { menu->insertItem(tr("&Explain current statement"), this, SLOT(explainPlan(void)), toKeySequence(tr("F3", "Worksheet|Explain plan")), TO_ID_PLAN, 0); menu->insertItem(QPixmap(const_cast(describe_xpm)), tr("&Describe Under Cursor"), this, SLOT(describe(void)), toKeySequence(tr("F4", "Worksheet|Describe under cursor")), 0, 0); menu->insertSeparator(0); } if (connection().provider() == "Oracle") menu->insertItem(tr("Check syntax of buffer"), this, SLOT(parseAll()), toKeySequence(tr("Ctrl+F9", "Worksheet|Check syntax of buffer")), 0, 0); menu->insertItem(QPixmap(const_cast(refresh_xpm)), tr("&Reexecute Last Statement"), this, SLOT(refresh(void)), toKeySequence(tr("F5", "Worksheet|Reexecute last statement")), 0, 0); menu->insertItem(tr("Execute &Newline Separated"), this, SLOT(executeNewline(void)), toKeySequence(tr("Shift+F9", "Worksheet|Execute newline separated")), 0, 0); menu->insertItem(QPixmap(const_cast(executeall_xpm)), tr("Execute &All"), this, SLOT(executeAll(void)), toKeySequence(tr("F8", "Worksheet|Execute all")), 0, 0); menu->insertItem(QPixmap(const_cast(executestep_xpm)), tr("Execute &Next"), this, SLOT(executeStep(void)), toKeySequence(tr("F9", "Worksheet|Execute next")), 0, 0); menu->insertItem(QPixmap(const_cast(execute_xpm)), tr("&Execute Current"), this, SLOT(execute(void)), toKeySequence(tr("Ctrl+Return", "Worksheet|Execute current")), 0, 0); menu->insertSeparator(); if (!Light) { if (connection().provider() == "Oracle") menu->insertItem(tr("&Enable Statistics"), this, SLOT(toggleStatistic(void)), 0, TO_ID_STATISTICS); } menu->insertItem(QPixmap(const_cast(stop_xpm)), tr("&Stop Execution"), Result, SLOT(stop(void)), 0, TO_ID_STOP); if (!Light) { menu->insertSeparator(); menu->insertItem(tr("Execute Saved SQL"), this, SLOT(executeSaved()), toKeySequence(tr("F7", "Worksheet|Execute saved SQL"))); menu->insertItem(tr("Insert Saved SQL"), this, SLOT(insertSaved()), toKeySequence(tr("Shift+F7", "Worksheet|Insert saved SQL"))); menu->insertItem(tr("Select Saved SQL"), this, SLOT(selectSaved()), toKeySequence(tr("Ctrl+Shift+S", "Worksheet|Select saved SQL"))); menu->insertItem(QPixmap(const_cast(previous_xpm)), tr("Save last SQL"), this, SLOT(saveLast())); } } #define CHANGE_CURRENT_SCHEMA QString("ALTER SESSION SET CURRENT_SCHEMA = ") void toWorksheet::changeSchema(void) { try { QString schema = Schema->selected(); toConnection &conn = connection(); if (toIsOracle(conn)) { QString sql = CHANGE_CURRENT_SCHEMA + schema; conn.allExecute(sql); for (std::list::const_iterator i = conn.initStrings().begin();i != conn.initStrings().end();i++) { if ((*i).startsWith(CHANGE_CURRENT_SCHEMA)) { conn.delInit(*i); break; } } conn.addInit(sql); } else if (toIsMySQL(conn)) { conn.allExecute(QString("USE %1").arg(schema)); conn.setDatabase(schema); } else throw QString("No support for changing schema for this database"); } TOCATCH }