1 //////////////////////////////////////////////////////////////////////////
2 //
3 // pgAdmin III - PostgreSQL Tools
4 //
5 // Copyright (C) 2002 - 2016, The pgAdmin Development Team
6 // This software is released under the PostgreSQL Licence
7 //
8 // frmQuery.h - The SQL Query form
9 //
10 //////////////////////////////////////////////////////////////////////////
11 
12 #ifndef __FRM_QUERY_H
13 #define __FRM_QUERY_H
14 
15 #include "ctl/ctlAuiNotebook.h"
16 #include "db/pgQueryResultEvent.h"
17 #include "dlg/dlgClasses.h"
18 #include "gqb/gqbViewController.h"
19 #include "gqb/gqbModel.h"
20 #include "frm/frmExport.h"
21 #include "utils/factory.h"
22 #include "utils/favourites.h"
23 #include "utils/macros.h"
24 
25 #include <wx/sstream.h>
26 #include <wx/txtstrm.h>
27 #include <wx/bmpcbox.h>
28 
29 // wxAUI
30 #include <wx/aui/aui.h>
31 #include <wx/textctrl.h>
32 #include <wx/dcbuffer.h>
33 #include <wx/timer.h>
34 
35 //
36 // This number MUST be incremented if changing any of the default perspectives
37 //
38 #define FRMQUERY_PERSPECTIVE_VER wxT("8320")
39 #ifdef __WXMAC__
40 #define FRMQUERY_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=465;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=databaseBar;caption=Database bar;state=16788208;dir=1;layer=10;row=0;pos=396;prop=100000;bestw=300;besth=21;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlQuery;caption=SQL query;state=17404;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=200|dock_size(3,0,0)=290|dock_size(2,0,0)=255|")
41 #else
42 #ifdef __WXGTK__
43 #define FRMQUERY_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=590;besth=30;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=databaseBar;caption=Database bar;state=16788208;dir=1;layer=10;row=0;pos=396;prop=100000;bestw=300;besth=30;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlQuery;caption=SQL query;state=17404;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=200|dock_size(3,0,0)=290|dock_size(2,0,0)=255|")
44 #else
45 #define FRMQUERY_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=465;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=databaseBar;caption=Database bar;state=16788208;dir=1;layer=10;row=0;pos=396;prop=100000;bestw=300;besth=21;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlQuery;caption=SQL query;state=17404;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=200|dock_size(3,0,0)=290|dock_size(2,0,0)=255|")
46 #endif
47 #endif
48 
49 class ExplainCanvas;
50 class ctlSQLResult;
51 class pgsApplication;
52 class pgScriptTimer;
53 
54 class QueryExecInfo
55 {
56 public:
QueryExecInfo()57 	QueryExecInfo()
58 	{
59 		toFileExportForm = NULL;
60 	}
~QueryExecInfo()61 	~QueryExecInfo()
62 	{
63 		if (toFileExportForm)
64 			delete toFileExportForm;
65 	}
66 
67 	int queryOffset;
68 	frmExport *toFileExportForm;
69 	bool singleResult;
70 	bool explain;
71 	bool verbose;
72 };
73 
74 enum
75 {
76 	ORIGIN_MANUAL,
77 	ORIGIN_FILE,
78 	ORIGIN_INITIAL,
79 	ORIGIN_HISTORY,
80 	ORIGIN_GQB
81 };
82 
83 class frmQuery : public pgFrame
84 {
85 public:
86 	frmQuery(frmMain *form, const wxString &_title, pgConn *conn, const wxString &qry, const wxString &file = wxEmptyString);
87 	~frmQuery();
88 	void Go();
89 
90 	void writeScriptOutput();
91 	void setExtendedTitle();
92 	void SetLineEndingStyle();
93 
SetQueryText(wxString str)94 	void SetQueryText(wxString str)
95 	{
96 		sqlQuery->SetText(str);
97 	}
ColouriseQuery(int start,int stop)98 	void ColouriseQuery(int start, int stop)
99 	{
100 		sqlQuery->Colourise(start, stop);
101 	}
SetChanged(bool p_changed)102 	void SetChanged(bool p_changed)
103 	{
104 		changed = p_changed;
105 	}
SetOrigin(int p_origin)106 	void SetOrigin(int p_origin)
107 	{
108 		origin = p_origin;
109 	}
SetLastPath(wxString p_lastpath)110 	void SetLastPath(wxString p_lastpath)
111 	{
112 		lastPath = p_lastpath;
113 	}
114 	bool CheckChanged(bool canVeto);
115 
116 	void UpdateFavouritesList();
117 	void UpdateMacrosList();
118 
119 	void UpdateAllRecentFiles();
120 	void UpdateAllFavouritesList();
121 	void UpdateAllMacrosList();
122 
123 private:
124 	frmMain *mainForm;
125 	wxAuiManager manager;
126 	ctlSQLBox *sqlQuery;
127 	ctlAuiNotebook *outputPane;
128 	ctlSQLResult *sqlResult;
129 	ExplainCanvas *explainCanvas;
130 	wxTextCtrl *msgResult, *msgHistory;
131 	wxBitmapComboBox *cbConnection;
132 	wxTextCtrl *scratchPad;
133 	wxComboBox *sqlQueries;
134 	wxButton *btnDeleteCurrent;
135 	wxButton *btnDeleteAll;
136 	wxArrayString histoQueries;
137 
138 	// Query timing/status update
139 	wxTimer timer;
140 	wxLongLong elapsedQuery, startTimeQuery;
141 
142 	// pgScript interface
143 	pgsApplication *pgScript;
144 	wxString pgsOutputString;
145 	wxStringOutputStream pgsStringOutput;
146 	wxTextOutputStream pgsOutput;
147 	pgScriptTimer *pgsTimer;
148 
149 	//GQB related
150 	void OnChangeNotebook(wxAuiNotebookEvent &event);
151 	void OnAdjustSizesTimer(wxTimerEvent &event);
152 	void OnResizeHorizontally(wxSplitterEvent &event);
153 	void adjustGQBSizes();
154 	bool updateFromGqb(bool executing);
155 	ctlAuiNotebook *sqlNotebook;
156 	gqbModel *model;
157 	gqbController *controller;
158 	bool firstTime;
159 	bool gqbUpdateRunning;
160 	wxTimer *adjustSizesTimer;
161 
162 	// Our connection
163 	pgConn *conn;
164 
165 	// These status flags are required to work round some wierdness on wxGTK,
166 	// particularly on Solaris.
167 	bool closing, loading;
168 
169 	void OnEraseBackground(wxEraseEvent &event);
170 	void OnSize(wxSizeEvent &event);
171 
172 	void OnChangeStc(wxStyledTextEvent &event);
173 	void OnPositionStc(wxStyledTextEvent &event);
174 	void DoUpdatePositionStc(const wxStyledTextEvent &event);
175 	void OnClose(wxCloseEvent &event);
176 	void OnSetFocus(wxFocusEvent &event);
177 	void OnContents(wxCommandEvent &event);
178 	void OnHelp(wxCommandEvent &event);
179 	void OnCancel(wxCommandEvent &event);
180 	void OnExecute(wxCommandEvent &event);
181 	void OnExecScript(wxCommandEvent &event);
182 	void OnExecFile(wxCommandEvent &event);
183 	void OnExplain(wxCommandEvent &event);
184 	void OnCommit(wxCommandEvent &event);
185 	void OnRollback(wxCommandEvent &event);
186 	void OnBuffers(wxCommandEvent &event);
187 	void OnTiming(wxCommandEvent &event);
188 	void OnNew(wxCommandEvent &event);
189 	void OnOpen(wxCommandEvent &event);
190 	void OnSave(wxCommandEvent &event);
191 	void OnSaveAs(wxCommandEvent &event);
192 	void SaveExplainAsImage(wxCommandEvent &event);
193 	void OnExport(wxCommandEvent &event);
194 	void OnExit(wxCommandEvent &event);
195 	void OnCut(wxCommandEvent &event);
196 	void OnCopy(wxCommandEvent &event);
197 	void OnPaste(wxCommandEvent &event);
198 	void OnClear(wxCommandEvent &event);
199 	void OnSearchReplace(wxCommandEvent &event);
200 	void OnUndo(wxCommandEvent &event);
201 	void OnRedo(wxCommandEvent &event);
202 	void OnSaveHistory(wxCommandEvent &event);
203 	void OnAutoRollback(wxCommandEvent &event);
204 	void OnAutoCommit(wxCommandEvent &event);
205 	void OnChangeConnection(wxCommandEvent &ev);
206 	void OnClearHistory(wxCommandEvent &event);
207 	void OnActivate(wxActivateEvent &event);
208 	void OnFocus(wxFocusEvent &event);
209 	void OnSelectAll(wxCommandEvent &event);
210 	void OnAddFavourite(wxCommandEvent &event);
211 	void OnInjectFavourite(wxCommandEvent &event);
212 	void OnManageFavourites(wxCommandEvent &event);
213 	void OnSelectFavourite(wxCommandEvent &event);
214 	void OnQuickReport(wxCommandEvent &event);
215 	void OnAutoIndent(wxCommandEvent &event);
216 	void OnWordWrap(wxCommandEvent &event);
217 	void OnShowIndentGuides(wxCommandEvent &event);
218 	void OnShowWhitespace(wxCommandEvent &event);
219 	void OnShowLineEnds(wxCommandEvent &event);
220 	void OnShowLineNumber(wxCommandEvent &event);
221 
222 	void OnToggleScratchPad(wxCommandEvent &event);
223 	void OnToggleDatabaseBar(wxCommandEvent &event);
224 	void OnToggleToolBar(wxCommandEvent &event);
225 	void OnToggleOutputPane(wxCommandEvent &event);
226 	void OnAuiUpdate(wxAuiManagerEvent &event);
227 	void OnDefaultView(wxCommandEvent &event);
228 	void OnBlockIndent(wxCommandEvent &event);
229 	void OnBlockOutDent(wxCommandEvent &event);
230 	void OnChangeToUpperCase(wxCommandEvent &event);
231 	void OnChangeToLowerCase(wxCommandEvent &event);
232 	void OnCommentText(wxCommandEvent &event);
233 	void OnUncommentText(wxCommandEvent &event);
234 	void OnExternalFormat(wxCommandEvent &event);
235 
236 	void OnDeleteCurrent(wxCommandEvent &event);
237 	void OnDeleteAll(wxCommandEvent &event);
238 
239 	void OnTimer(wxTimerEvent &event);
240 
241 	void OpenLastFile();
242 	void updateMenu(bool allowUpdateModelSize = true);
243 	void execQuery(const wxString &query, int resultToRetrieve = 0, bool singleResult = false, const int queryOffset = 0, bool toFile = false, bool explain = false, bool verbose = false);
244 	void OnQueryComplete(pgQueryResultEvent &ev);
245 	void completeQuery(bool done, bool explain, bool verbose);
246 	bool isBeginNotRequired(wxString query);
247 	void OnScriptComplete(wxCommandEvent &ev);
248 	void setTools(const bool running);
249 	void showMessage(const wxString &msg, const wxString &msgShort = wxT(""));
250 	int GetLineEndingStyle();
251 	void OnSetEOLMode(wxCommandEvent &event);
252 	void SetEOLModeDisplay(int mode);
253 	void OnMacroInvoke(wxCommandEvent &event);
254 	void OnMacroManage(wxCommandEvent &event);
255 
256 	void LoadQueries();
257 	void SaveQueries();
258 	void OnChangeQuery(wxCommandEvent &event);
259 
260 	wxBitmap CreateBitmap(const wxColour &colour);
261 	wxColour GetServerColour(pgConn *connection);
262 
263 	bool relatesToWindow(wxWindow *which, wxWindow *related);
264 
265 	wxWindow *currentControl();
266 	wxMenu *queryMenu;
267 	wxMenu *favouritesMenu;
268 	wxMenu *macrosMenu;
269 	wxMenu *lineEndMenu;
270 	wxMenu *formatMenu;
271 	wxMenu *saveasImageMenu;
272 
273 	wxString title;
274 	wxString lastFilename, lastDir;
275 
276 	queryFavouriteFolder *favourites;
277 	queryMacroList *macros;
278 
279 	bool aborted;
280 	bool lastFileFormat;
281 	bool m_loadingfile;
282 
283 	// Complements dirty flag, showing last origin of query's modification (see enum ORIGIN_..)
284 	int origin;
285 
286 	// A simple mutex-like flag to prevent concurrent script execution.
287 	// Required because the pgScript parser isn't currently thread-safe :-(
288 	static bool    ms_pgScriptRunning;
289 
290 	DECLARE_EVENT_TABLE()
291 };
292 
293 // Position of status line fields
294 enum
295 {
296 	STATUSPOS_MSGS = 1,
297 	STATUSPOS_FORMAT,
298 	STATUSPOS_POS,
299 	STATUSPOS_SEL,
300 	STATUSPOS_ROWS,
301 	STATUSPOS_SECS
302 };
303 
304 enum
305 {
306 	CTL_SQLQUERY = 331,
307 	CTL_SQLRESULT,
308 	CTL_MSGRESULT,
309 	CTL_MSGHISTORY,
310 	CTL_NTBKCENTER,
311 	CTL_COLSGRID,
312 	CTL_TIMERSIZES,
313 	CTL_TIMERFRM,
314 	CTL_NTBKGQB,
315 	CTL_SQLQUERYCBOX,
316 	CTL_DELETECURRENTBTN,
317 	CTL_DELETEALLBTN,
318 	CTL_SCRATCHPAD
319 };
320 
321 ///////////////////////////////////////////////////////
322 
323 class queryToolBaseFactory : public actionFactory
324 {
325 protected:
queryToolBaseFactory(menuFactoryList * list)326 	queryToolBaseFactory(menuFactoryList *list) : actionFactory(list) {}
327 	wxWindow *StartDialogSql(frmMain *form, pgObject *obj, const wxString &sql);
328 public:
329 	bool CheckEnable(pgObject *obj);
330 };
331 
332 class queryToolDataFactory : public queryToolBaseFactory
333 {
334 protected:
queryToolDataFactory(menuFactoryList * list)335 	queryToolDataFactory(menuFactoryList *list) : queryToolBaseFactory(list) {}
336 public:
337 	bool CheckEnable(pgObject *obj);
338 };
339 
340 class queryToolFactory : public queryToolBaseFactory
341 {
342 public:
343 	queryToolFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
344 	wxWindow *StartDialog(frmMain *form, pgObject *obj);
345 };
346 
347 class queryToolSqlFactory : public queryToolBaseFactory
348 {
349 public:
350 	queryToolSqlFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
351 	wxWindow *StartDialog(frmMain *form, pgObject *obj);
352 	bool CheckEnable(pgObject *obj);
353 };
354 
355 class queryToolSelectFactory : public queryToolDataFactory
356 {
357 public:
358 	queryToolSelectFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
359 	wxWindow *StartDialog(frmMain *form, pgObject *obj);
360 	bool CheckEnable(pgObject *obj);
361 };
362 
363 class queryToolExecFactory : public queryToolDataFactory
364 {
365 public:
366 	queryToolExecFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
367 	wxWindow *StartDialog(frmMain *form, pgObject *obj);
368 	bool CheckEnable(pgObject *obj);
369 };
370 
371 class queryToolDeleteFactory : public queryToolDataFactory
372 {
373 public:
374 	queryToolDeleteFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
375 	wxWindow *StartDialog(frmMain *form, pgObject *obj);
376 	bool CheckEnable(pgObject *obj);
377 };
378 
379 class queryToolInsertFactory : public queryToolDataFactory
380 {
381 public:
382 	queryToolInsertFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
383 	wxWindow *StartDialog(frmMain *form, pgObject *obj);
384 	bool CheckEnable(pgObject *obj);
385 };
386 
387 class queryToolUpdateFactory : public queryToolDataFactory
388 {
389 public:
390 	queryToolUpdateFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
391 	wxWindow *StartDialog(frmMain *form, pgObject *obj);
392 	bool CheckEnable(pgObject *obj);
393 };
394 
395 ///////////////////////////////////////////////////////
396 class pgScriptTimer : public wxTimer
397 {
398 private:
399 	frmQuery *m_parent;
400 
401 public:
402 	pgScriptTimer(frmQuery *parent);
403 	void Notify();
404 };
405 
406 #endif // __FRM_QUERY_H
407