1 /*
2 / Main.cpp
3 / the main core of spatialite_gui  - a SQLite /SpatiaLite GUI tool
4 /
5 / version 1.7, 2013 May 8
6 /
7 / Author: Sandro Furieri a-furieri@lqt.it
8 /
9 / Copyright (C) 2008-2013  Alessandro Furieri
10 /
11 /    This program is free software: you can redistribute it and/or modify
12 /    it under the terms of the GNU General Public License as published by
13 /    the Free Software Foundation, either version 3 of the License, or
14 /    (at your option) any later version.
15 /
16 /    This program is distributed in the hope that it will be useful,
17 /    but WITHOUT ANY WARRANTY; without even the implied warranty of
18 /    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 /    GNU General Public License for more details.
20 /
21 /    You should have received a copy of the GNU General Public License
22 /    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 /
24 */
25 
26 #include "Classdef.h"
27 
28 #include "wx/menu.h"
29 #include "wx/aboutdlg.h"
30 #include "wx/filename.h"
31 #include "wx/config.h"
32 #include "wx/tokenzr.h"
33 
34 #include <spatialite.h>
35 #include <proj_api.h>
36 #include <geos_c.h>
37 
38 //
39 // ICONs in XPM format [universally portable]
40 //
41 #include "icons/icon.xpm"
42 #include "icons/icon_info.xpm"
43 #include "icons/create_new.xpm"
44 #include "icons/connect.xpm"
45 #include "icons/disconnect.xpm"
46 #include "icons/memdb_load.xpm"
47 #include "icons/memdb_new.xpm"
48 #include "icons/memdb_clock.xpm"
49 #include "icons/memdb_save.xpm"
50 #include "icons/vacuum.xpm"
51 #include "icons/sql_script.xpm"
52 #include "icons/composer.xpm"
53 #include "icons/loadshp.xpm"
54 #include "icons/virtshp.xpm"
55 #include "icons/loadtxt.xpm"
56 #include "icons/virttxt.xpm"
57 #include "icons/loaddbf.xpm"
58 #include "icons/virtdbf.xpm"
59 #include "icons/loadxl.xpm"
60 #include "icons/virtxl.xpm"
61 #include "icons/network.xpm"
62 #include "icons/exif.xpm"
63 #include "icons/loadxml.xpm"
64 #include "icons/srids.xpm"
65 #include "icons/charset.xpm"
66 #include "icons/help.xpm"
67 #include "icons/about.xpm"
68 #include "icons/exit.xpm"
69 #include "icons/attach.xpm"
70 #include "icons/sql_log.xpm"
71 #include "icons/db_status.xpm"
72 #include "icons/checkgeom.xpm"
73 #include "icons/sanegeom.xpm"
74 #include "icons/wfs.xpm"
75 #include "icons/dxf.xpm"
76 
77 
78 #if defined(_WIN32) && !defined(__MINGW32__)
79 #define unlink	_unlink
80 #endif
81 
IMPLEMENT_APP(MyApp)82 IMPLEMENT_APP(MyApp)
83      bool MyApp::OnInit()
84 {
85 //
86 // main APP implementation
87 //
88   wxString path;
89   if (argc > 1)
90     path = argv[1];
91   MyFrame *frame =
92     new MyFrame(wxT("spatialite_gui      [a GUI tool for SQLite/SpatiaLite]"),
93                 wxPoint(0, 0), wxSize(700, 480));
94   frame->Show(true);
95   SetTopWindow(frame);
96   frame->LoadConfig(path);
97   return true;
98 }
99 
MyFrame(const wxString & title,const wxPoint & pos,const wxSize & size)100 MyFrame::MyFrame(const wxString & title, const wxPoint & pos, const wxSize & size):
101 wxFrame((wxFrame *) NULL, -1, title, pos,
102         size)
103 {
104 //
105 // main GUI frame constructor
106 //
107   MemoryDatabase = false;
108   AutoSaveInterval = 0;
109   LastTotalChanges = 0;
110   TimerAutoSave = NULL;
111   SqlLogEnabled = false;
112 //
113 // initializing CHARSET lists
114 //
115   CharsetsLen = 79;
116   Charsets = new wxString[CharsetsLen];
117   CharsetsNames = new wxString[CharsetsLen];
118   *(CharsetsNames + 0) = wxT("ARMSCII-8    Armenian");
119   *(CharsetsNames + 1) = wxT("ASCII        US-ASCII");
120   *(CharsetsNames + 2) = wxT("BIG5         Chinese/Traditional");
121   *(CharsetsNames + 3) = wxT("BIG5-HKSCS   Chinese/Hong Kong");
122   *(CharsetsNames + 4) = wxT("BIG5-HKSCS:1999");
123   *(CharsetsNames + 5) = wxT("BIG5-HKSCS:2001");
124   *(CharsetsNames + 6) = wxT("CP850        DOS/OEM Western Europe");
125   *(CharsetsNames + 7) = wxT("CP862        DOS/OEM Hebrew");
126   *(CharsetsNames + 8) = wxT("CP866        DOS/OEM Cyrillic");
127   *(CharsetsNames + 9) = wxT("CP874        DOS/OEM Thai");
128   *(CharsetsNames + 10) = wxT("CP932        DOS/OEM Japanese");
129   *(CharsetsNames + 11) = wxT("CP936        DOS/OEM Chinese");
130   *(CharsetsNames + 12) = wxT("CP949        DOS/OEM Korean");
131   *(CharsetsNames + 13) = wxT("CP950        DOS/OEM Chinese/Big5");
132   *(CharsetsNames + 14) = wxT("CP1133       Laotian");
133   *(CharsetsNames + 15) = wxT("CP1250       Windows Central Europe");
134   *(CharsetsNames + 16) = wxT("CP1251       Windows Cyrillic");
135   *(CharsetsNames + 17) = wxT("CP1252       Windows Latin 1");
136   *(CharsetsNames + 18) = wxT("CP1253       Windows Greek");
137   *(CharsetsNames + 19) = wxT("CP1254       Windows Turkish");
138   *(CharsetsNames + 20) = wxT("CP1255       Windows Hebrew");
139   *(CharsetsNames + 21) = wxT("CP1256       Windows Arabic");
140   *(CharsetsNames + 22) = wxT("CP1257       Windows Baltic");
141   *(CharsetsNames + 23) = wxT("CP1258       Windows Vietnamese");
142   *(CharsetsNames + 24) = wxT("EUC-CN       Chinese");
143   *(CharsetsNames + 25) = wxT("EUC-JP       Japanese");
144   *(CharsetsNames + 26) = wxT("EUC-KR       Korean");
145   *(CharsetsNames + 27) = wxT("EUC-TW       Taiwan");
146   *(CharsetsNames + 28) = wxT("GB18030      Chinese/National Standard");
147   *(CharsetsNames + 29) = wxT("GBK          Chinese/Simplified");
148   *(CharsetsNames + 30) = wxT("Georgian-Academy");
149   *(CharsetsNames + 31) = wxT("Georgian-PS");
150   *(CharsetsNames + 32) = wxT("HZ           Chinese");
151   *(CharsetsNames + 33) = wxT("ISO-2022-CN  Chinese");
152   *(CharsetsNames + 34) = wxT("ISO-2022-CN-EXT");
153   *(CharsetsNames + 35) = wxT("ISO-2022-JP  Japanese");
154   *(CharsetsNames + 36) = wxT("ISO-2022-JP-1");
155   *(CharsetsNames + 37) = wxT("ISO-2022-JP-2");
156   *(CharsetsNames + 38) = wxT("ISO-2022-KR  Korean");
157   *(CharsetsNames + 39) = wxT("ISO-8859-1   Latin-1 Western European");
158   *(CharsetsNames + 40) = wxT("ISO-8859-2   Latin-2 Central European");
159   *(CharsetsNames + 41) = wxT("ISO-8859-3   Latin-3 South European");
160   *(CharsetsNames + 42) = wxT("ISO-8859-4   Latin-4 North European");
161   *(CharsetsNames + 43) = wxT("ISO-8859-5   Latin/Cyrillic");
162   *(CharsetsNames + 44) = wxT("ISO-8859-6   Latin/Arabic");
163   *(CharsetsNames + 45) = wxT("ISO-8859-7   Latin/Greek");
164   *(CharsetsNames + 46) = wxT("ISO-8859-8   Latin/Hebrew");
165   *(CharsetsNames + 47) = wxT("ISO-8859-9   Latin-5 Turkish");
166   *(CharsetsNames + 48) = wxT("ISO-8859-10  Latin-6 Nordic");
167   *(CharsetsNames + 49) = wxT("ISO-8859-11  Latin/Thai");
168   *(CharsetsNames + 50) = wxT("ISO-8859-13  Latin-7 Baltic Rim");
169   *(CharsetsNames + 51) = wxT("ISO-8859-14  Latin-8 Celtic");
170   *(CharsetsNames + 52) = wxT("ISO-8859-15  Latin-9");
171   *(CharsetsNames + 53) = wxT("ISO-8859-16  Latin-10 South-Eastern European");
172   *(CharsetsNames + 54) = wxT("JOHAB        Korean");
173   *(CharsetsNames + 55) = wxT("KOI8-R       Russian");
174   *(CharsetsNames + 56) = wxT("KOI8-U       Ukrainian");
175   *(CharsetsNames + 57) = wxT("KOI8-RU      Belarusian");
176   *(CharsetsNames + 58) = wxT("KOI8-T       Tajik");
177   *(CharsetsNames + 59) = wxT("MacArabic    MAC Arabic");
178   *(CharsetsNames + 60) = wxT("MacCentralEurope");
179   *(CharsetsNames + 61) = wxT("MacCroatian  MAC Croatian");
180   *(CharsetsNames + 62) = wxT("MacCyrillic  MAC Cyrillic");
181   *(CharsetsNames + 63) = wxT("MacGreek     MAC Greek");
182   *(CharsetsNames + 64) = wxT("MacHebrew    MAC Hebrew");
183   *(CharsetsNames + 65) = wxT("MacIceland   MAC Iceland");
184   *(CharsetsNames + 66) = wxT("Macintosh");
185   *(CharsetsNames + 67) = wxT("MacRoman     MAC European/Western languages");
186   *(CharsetsNames + 68) = wxT("MacRomania   MAC Romania");
187   *(CharsetsNames + 69) = wxT("MacThai      MAC Thai");
188   *(CharsetsNames + 70) = wxT("MacTurkish   MAC Turkish");
189   *(CharsetsNames + 71) = wxT("MacUkraine   MAC Ukraine");
190   *(CharsetsNames + 72) = wxT("MuleLao-1    Laotian");
191   *(CharsetsNames + 73) = wxT("PT154        Kazakh");
192   *(CharsetsNames + 74) = wxT("RK1048       Kazakh");
193   *(CharsetsNames + 75) = wxT("SHIFT_JIS    Japanese");
194   *(CharsetsNames + 76) = wxT("TCVN         Vietnamese");
195   *(CharsetsNames + 77) = wxT("TIS-620      Thai");
196   *(CharsetsNames + 77) = wxT("UTF-8        UNICODE/Universal");
197   *(CharsetsNames + 78) = wxT("VISCII       Vietnamese");
198   *(Charsets + 0) = wxT("ARMSCII-8");
199   *(Charsets + 1) = wxT("ASCII");
200   *(Charsets + 2) = wxT("BIG5");
201   *(Charsets + 3) = wxT("BIG5-HKSCS");
202   *(Charsets + 4) = wxT("BIG5-HKSCS:1999");
203   *(Charsets + 5) = wxT("BIG5-HKSCS:2001");
204   *(Charsets + 6) = wxT("CP850");
205   *(Charsets + 7) = wxT("CP862");
206   *(Charsets + 8) = wxT("CP866");
207   *(Charsets + 9) = wxT("CP874");
208   *(Charsets + 10) = wxT("CP932");
209   *(Charsets + 11) = wxT("CP936");
210   *(Charsets + 12) = wxT("CP949");
211   *(Charsets + 13) = wxT("CP950");
212   *(Charsets + 14) = wxT("CP1133");
213   *(Charsets + 15) = wxT("CP1250");
214   *(Charsets + 16) = wxT("CP1251");
215   *(Charsets + 17) = wxT("CP1252");
216   *(Charsets + 18) = wxT("CP1253");
217   *(Charsets + 19) = wxT("CP1254");
218   *(Charsets + 20) = wxT("CP1255");
219   *(Charsets + 21) = wxT("CP1256");
220   *(Charsets + 22) = wxT("CP1257");
221   *(Charsets + 23) = wxT("CP1258");
222   *(Charsets + 24) = wxT("EUC-CN");
223   *(Charsets + 25) = wxT("EUC-JP");
224   *(Charsets + 26) = wxT("EUC-KR");
225   *(Charsets + 27) = wxT("EUC-TW");
226   *(Charsets + 28) = wxT("GB18030");
227   *(Charsets + 29) = wxT("GBK");
228   *(Charsets + 30) = wxT("Georgian-Academy");
229   *(Charsets + 31) = wxT("Georgian-PS");
230   *(Charsets + 32) = wxT("HZ");
231   *(Charsets + 33) = wxT("ISO-2022-CN");
232   *(Charsets + 34) = wxT("ISO-2022-CN-EXT");
233   *(Charsets + 35) = wxT("ISO-2022-JP");
234   *(Charsets + 36) = wxT("ISO-2022-JP-1");
235   *(Charsets + 37) = wxT("ISO-2022-JP-2");
236   *(Charsets + 38) = wxT("ISO-2022-KR");
237   *(Charsets + 39) = wxT("ISO-8859-1");
238   *(Charsets + 40) = wxT("ISO-8859-2");
239   *(Charsets + 41) = wxT("ISO-8859-3");
240   *(Charsets + 42) = wxT("ISO-8859-4");
241   *(Charsets + 43) = wxT("ISO-8859-5");
242   *(Charsets + 44) = wxT("ISO-8859-6");
243   *(Charsets + 45) = wxT("ISO-8859-7");
244   *(Charsets + 46) = wxT("ISO-8859-8");
245   *(Charsets + 47) = wxT("ISO-8859-9");
246   *(Charsets + 48) = wxT("ISO-8859-10");
247   *(Charsets + 49) = wxT("ISO-8859-11");
248   *(Charsets + 50) = wxT("ISO-8859-13");
249   *(Charsets + 51) = wxT("ISO-8859-14");
250   *(Charsets + 52) = wxT("ISO-8859-15");
251   *(Charsets + 53) = wxT("ISO-8859-16");
252   *(Charsets + 54) = wxT("JOHAB");
253   *(Charsets + 55) = wxT("KOI8-R");
254   *(Charsets + 56) = wxT("KOI8-U");
255   *(Charsets + 57) = wxT("KOI8-RU");
256   *(Charsets + 58) = wxT("KOI8-T");
257   *(Charsets + 59) = wxT("MacArabic");
258   *(Charsets + 60) = wxT("MacCentralEurope");
259   *(Charsets + 61) = wxT("MacCroatian");
260   *(Charsets + 62) = wxT("MacCyrillic");
261   *(Charsets + 63) = wxT("MacGreek");
262   *(Charsets + 64) = wxT("MacHebrew");
263   *(Charsets + 65) = wxT("MacIceland");
264   *(Charsets + 66) = wxT("Macintosh");
265   *(Charsets + 67) = wxT("MacRoman");
266   *(Charsets + 68) = wxT("MacRomania");
267   *(Charsets + 69) = wxT("MacThai");
268   *(Charsets + 70) = wxT("MacTurkish");
269   *(Charsets + 71) = wxT("MacUkraine");
270   *(Charsets + 72) = wxT("MuleLao-1");
271   *(Charsets + 73) = wxT("PT154");
272   *(Charsets + 74) = wxT("RK1048");
273   *(Charsets + 75) = wxT("SHIFT_JIS");
274   *(Charsets + 76) = wxT("TCVN");
275   *(Charsets + 77) = wxT("TIS-620");
276   *(Charsets + 77) = wxT("UTF-8");
277   *(Charsets + 78) = wxT("VISCII");
278   LocaleCharset = wxString::FromUTF8(gaiaGetLocaleCharset());
279   DefaultCharset = LocaleCharset;
280   AskCharset = false;
281 
282   HelpPane = false;
283   SqliteHandle = NULL;
284   InternalCache = NULL;
285   SqlitePath = wxT("");
286   BtnConnect = new wxBitmap(connect_xpm);
287   BtnCreateNew = new wxBitmap(create_new_xpm);
288   BtnDisconnect = new wxBitmap(disconnect_xpm);
289   BtnMemDbLoad = new wxBitmap(memdb_load_xpm);
290   BtnMemDbNew = new wxBitmap(memdb_new_xpm);
291   BtnMemDbClock = new wxBitmap(memdb_clock_xpm);
292   BtnMemDbSave = new wxBitmap(memdb_save_xpm);
293   BtnVacuum = new wxBitmap(vacuum_xpm);
294   BtnSqlScript = new wxBitmap(sql_script_xpm);
295   BtnQueryComposer = new wxBitmap(composer_xpm);
296   BtnLoadShp = new wxBitmap(loadshp_xpm);
297   BtnVirtualShp = new wxBitmap(virtshp_xpm);
298   BtnLoadTxt = new wxBitmap(loadtxt_xpm);
299   BtnVirtualTxt = new wxBitmap(virttxt_xpm);
300   BtnLoadDbf = new wxBitmap(loaddbf_xpm);
301   BtnVirtualDbf = new wxBitmap(virtdbf_xpm);
302   BtnLoadXL = new wxBitmap(loadxl_xpm);
303   BtnVirtualXL = new wxBitmap(virtxl_xpm);
304   BtnNetwork = new wxBitmap(network_xpm);
305   BtnExif = new wxBitmap(exif_xpm);
306   BtnLoadXml = new wxBitmap(loadxml_xpm);
307   BtnSrids = new wxBitmap(srids_xpm);
308   BtnCharset = new wxBitmap(charset_xpm);
309   BtnHelp = new wxBitmap(help_xpm);
310   BtnAbout = new wxBitmap(about_xpm);
311   BtnExit = new wxBitmap(exit_xpm);
312   BtnAttach = new wxBitmap(attach_xpm);
313   BtnSqlLog = new wxBitmap(sql_log_xpm);
314   BtnDbStatus = new wxBitmap(db_status_xpm);
315   BtnCheckGeom = new wxBitmap(checkgeom_xpm);
316   BtnSaneGeom = new wxBitmap(sanegeom_xpm);
317   BtnWFS = new wxBitmap(wfs_xpm);
318   BtnDXF = new wxBitmap(dxf_xpm);
319 
320 //
321 // setting up the application icon
322 //
323   wxIcon MyIcon(icon_xpm);
324   SetIcon(MyIcon);
325 
326 //
327 // setting up panes
328 //
329   TableTree = new MyTableTree(this);
330   QueryView = new MyQueryView(this);
331   RsView = new MyResultSetView(this);
332   Manager.SetManagedWindow(this);
333   wxAuiPaneInfo paneSql = wxAuiPaneInfo().Top();
334   paneSql.Name(wxT("sql_stmt"));
335   paneSql.CaptionVisible(false);
336   paneSql.Floatable(true);
337   paneSql.Dockable(true);
338   paneSql.Movable(true);
339   paneSql.Gripper(true);
340   paneSql.CloseButton(false);
341   paneSql.BestSize(wxSize(200, 120));
342   Manager.AddPane(QueryView, paneSql);
343   wxAuiPaneInfo paneView = wxAuiPaneInfo().Centre();
344   paneView.Name(wxT("result_set"));
345   paneView.CaptionVisible(false);
346   paneView.Floatable(true);
347   paneView.Dockable(true);
348   paneView.Movable(true);
349   paneView.Gripper(false);
350   paneView.CloseButton(false);
351   Manager.AddPane(RsView, paneView);
352   wxAuiPaneInfo paneTree = wxAuiPaneInfo().Left();
353   paneTree.Name(wxT("tree_view"));
354   paneTree.CaptionVisible(false);
355   paneTree.Floatable(true);
356   paneTree.Dockable(true);
357   paneTree.Movable(true);
358   paneTree.Gripper(true);
359   paneTree.CloseButton(false);
360   paneTree.BestSize(wxSize(200, 480));
361   Manager.AddPane(TableTree, paneTree, wxPoint(0, 10));
362   Manager.Update();
363   Centre();
364 
365 //
366 // setting up the status bar
367 //
368   wxStatusBar *statusBar = new wxStatusBar(this);
369   SetStatusBar(statusBar);
370 
371 //
372 // setting up the menu bar
373 //
374   wxMenu *menuFile = new wxMenu;
375   wxMenuItem *menuItem;
376   menuItem =
377     new wxMenuItem(menuFile, ID_Connect,
378                    wxT("&Connecting an existing SQLite DB"));
379   menuItem->SetBitmap(*BtnConnect);
380   menuFile->Append(menuItem);
381   menuItem =
382     new wxMenuItem(menuFile, ID_CreateNew,
383                    wxT("Creating a &New (empty) SQLite DB"));
384   menuItem->SetBitmap(*BtnCreateNew);
385   menuFile->Append(menuItem);
386   wxMenu *memoryMenu = new wxMenu();
387   menuItem =
388     new wxMenuItem(memoryMenu, ID_MemoryDbLoad,
389                    wxT("&Loading an existing DB into the MEMORY-DB"));
390   menuItem->SetBitmap(*BtnMemDbLoad);
391   memoryMenu->Append(menuItem);
392   menuItem =
393     new wxMenuItem(memoryMenu, ID_MemoryDbNew,
394                    wxT("Creating a &New (empty) MEMORY-DB"));
395   menuItem->SetBitmap(*BtnMemDbNew);
396   memoryMenu->Append(menuItem);
397   menuItem =
398     new wxMenuItem(memoryMenu, ID_MemoryDbClock,
399                    wxT("&AutoSaving the current MEMORY-DB"));
400   menuItem->SetBitmap(*BtnMemDbClock);
401   memoryMenu->Append(menuItem);
402   menuItem =
403     new wxMenuItem(memoryMenu, ID_MemoryDbSave,
404                    wxT("&Saving the current MEMORY-DB"));
405   menuItem->SetBitmap(*BtnMemDbSave);
406   memoryMenu->Append(menuItem);
407   menuFile->AppendSubMenu(memoryMenu, wxT("&MEMORY-DB"));
408   menuItem =
409     new wxMenuItem(menuFile, ID_Disconnect,
410                    wxT("&Disconnecting current SQLite DB"));
411   menuItem->SetBitmap(*BtnDisconnect);
412   menuFile->Append(menuItem);
413   menuItem =
414     new wxMenuItem(menuFile, ID_Vacuum,
415                    wxT("&Optimizing current SQLite DB [VACUUM]"));
416   menuItem->SetBitmap(*BtnVacuum);
417   menuFile->Append(menuItem);
418   menuFile->AppendSeparator();
419   wxMenu *advancedMenu = new wxMenu();
420   menuItem =
421     new wxMenuItem(advancedMenu, ID_SqlScript, wxT("&Execute SQL script"));
422   menuItem->SetBitmap(*BtnSqlScript);
423   advancedMenu->Append(menuItem);
424   advancedMenu->AppendSeparator();
425   menuItem =
426     new wxMenuItem(advancedMenu, ID_QueryViewComposer,
427                    wxT("Query/View &Composer"));
428   menuItem->SetBitmap(*BtnQueryComposer);
429   advancedMenu->Append(menuItem);
430   advancedMenu->AppendSeparator();
431   menuItem = new wxMenuItem(advancedMenu, ID_LoadShp, wxT("&Load Shapefile"));
432   menuItem->SetBitmap(*BtnLoadShp);
433   advancedMenu->Append(menuItem);
434   menuItem =
435     new wxMenuItem(advancedMenu, ID_VirtualShp, wxT("&Virtual Shapefile"));
436   menuItem->SetBitmap(*BtnVirtualShp);
437   advancedMenu->Append(menuItem);
438   advancedMenu->AppendSeparator();
439   menuItem = new wxMenuItem(advancedMenu, ID_LoadTxt, wxT("Load CSV/&TXT"));
440   menuItem->SetBitmap(*BtnLoadTxt);
441   advancedMenu->Append(menuItem);
442   menuItem =
443     new wxMenuItem(advancedMenu, ID_VirtualTxt, wxT("Virtual &CSV/TXT"));
444   menuItem->SetBitmap(*BtnVirtualTxt);
445   advancedMenu->Append(menuItem);
446   advancedMenu->AppendSeparator();
447   menuItem = new wxMenuItem(advancedMenu, ID_LoadDbf, wxT("Load &DBF"));
448   menuItem->SetBitmap(*BtnLoadDbf);
449   advancedMenu->Append(menuItem);
450   menuItem = new wxMenuItem(advancedMenu, ID_VirtualDbf, wxT("Virtual &DBF"));
451   menuItem->SetBitmap(*BtnVirtualDbf);
452   advancedMenu->Append(menuItem);
453   advancedMenu->AppendSeparator();
454   menuItem = new wxMenuItem(advancedMenu, ID_LoadXL, wxT("Load &XLS"));
455   menuItem->SetBitmap(*BtnLoadXL);
456   advancedMenu->Append(menuItem);
457   menuItem = new wxMenuItem(advancedMenu, ID_VirtualXL, wxT("Virtual &XLS"));
458   menuItem->SetBitmap(*BtnVirtualXL);
459   advancedMenu->Append(menuItem);
460   advancedMenu->AppendSeparator();
461   menuItem = new wxMenuItem(advancedMenu, ID_Network, wxT("Build &Network"));
462   menuItem->SetBitmap(*BtnNetwork);
463   advancedMenu->Append(menuItem);
464   advancedMenu->AppendSeparator();
465   menuItem = new wxMenuItem(advancedMenu, ID_Exif, wxT("Import &EXIF photos"));
466   menuItem->SetBitmap(*BtnExif);
467   advancedMenu->Append(menuItem);
468   menuItem =
469     new wxMenuItem(advancedMenu, ID_LoadXml, wxT("Import &XML Documents"));
470   menuItem->SetBitmap(*BtnLoadXml);
471   advancedMenu->Append(menuItem);
472   menuItem =
473     new wxMenuItem(advancedMenu, ID_WFS,
474                    wxT("Import data from &WFS datasource"));
475   menuItem->SetBitmap(*BtnWFS);
476   advancedMenu->Append(menuItem);
477   menuItem = new wxMenuItem(advancedMenu, ID_DXF, wxT("Import &DXF drawings"));
478   menuItem->SetBitmap(*BtnDXF);
479   advancedMenu->Append(menuItem);
480   advancedMenu->AppendSeparator();
481   menuItem =
482     new wxMenuItem(advancedMenu, ID_Srids, wxT("&Search SRID by name"));
483   menuItem->SetBitmap(*BtnSrids);
484   advancedMenu->Append(menuItem);
485   menuItem =
486     new wxMenuItem(advancedMenu, ID_Charset, wxT("&Default Output Charset"));
487   menuItem->SetBitmap(*BtnCharset);
488   advancedMenu->Append(menuItem);
489   menuFile->AppendSubMenu(advancedMenu, wxT("&Advanced"));
490   menuFile->AppendSeparator();
491   menuItem = new wxMenuItem(menuFile, ID_Attach, wxT("&Attach DataBase"));
492   menuItem->SetBitmap(*BtnAttach);
493   menuFile->Append(menuItem);
494   menuFile->AppendSeparator();
495   menuItem =
496     new wxMenuItem(menuFile, ID_SqlLog, wxT("&SQL Log"), wxT("&SQL Log"),
497                    wxITEM_CHECK);
498   menuFile->Append(menuItem);
499   menuItem = new wxMenuItem(menuFile, ID_DbStatus, wxT("&DB Status"));
500   menuFile->Append(menuItem);
501   menuFile->AppendSeparator();
502   menuItem = new wxMenuItem(menuFile, ID_CheckGeom, wxT("&Check Geometries"));
503   menuFile->Append(menuItem);
504   menuItem = new wxMenuItem(menuFile, ID_SaneGeom, wxT("&Sanitize Geometries"));
505   menuFile->Append(menuItem);
506   menuFile->AppendSeparator();
507   menuItem = new wxMenuItem(menuFile, ID_Help, wxT("&Help"));
508   menuItem->SetBitmap(*BtnHelp);
509   menuItem = new wxMenuItem(menuFile, wxID_ABOUT, wxT("&About ..."));
510   menuItem->SetBitmap(*BtnAbout);
511   menuFile->Append(menuItem);
512   menuFile->AppendSeparator();
513   menuItem = new wxMenuItem(menuFile, wxID_EXIT, wxT("&Quit"));
514   menuItem->SetBitmap(*BtnExit);
515   menuFile->Append(menuItem);
516   wxMenuBar *menuBar = new wxMenuBar;
517   menuBar->Append(menuFile, wxT("&Files"));
518   SetMenuBar(menuBar);
519 
520 //
521 // setting up menu initial state
522 //
523   menuBar->Enable(ID_Disconnect, false);
524   menuBar->Enable(ID_MemoryDbClock, false);
525   menuBar->Enable(ID_MemoryDbSave, false);
526   menuBar->Enable(ID_Vacuum, false);
527   menuBar->Enable(ID_SqlScript, false);
528   menuBar->Enable(ID_QueryViewComposer, false);
529   menuBar->Enable(ID_LoadShp, false);
530   menuBar->Enable(ID_VirtualShp, false);
531   menuBar->Enable(ID_LoadTxt, false);
532   menuBar->Enable(ID_VirtualTxt, false);
533   menuBar->Enable(ID_LoadDbf, false);
534   menuBar->Enable(ID_VirtualDbf, false);
535   menuBar->Enable(ID_LoadXL, false);
536   menuBar->Enable(ID_VirtualXL, false);
537   menuBar->Enable(ID_Network, false);
538   menuBar->Enable(ID_Exif, false);
539   menuBar->Enable(ID_LoadXml, false);
540   menuBar->Enable(ID_Srids, false);
541   menuBar->Enable(ID_Attach, false);
542   menuBar->Enable(ID_SqlLog, false);
543   menuBar->Enable(ID_DbStatus, false);
544   menuBar->Enable(ID_CheckGeom, false);
545   menuBar->Enable(ID_SaneGeom, false);
546   menuBar->Enable(ID_WFS, false);
547   menuBar->Enable(ID_DXF, false);
548 
549 //
550 // setting up the toolbar
551 //
552   wxToolBar *toolBar = CreateToolBar();
553   toolBar->AddTool(ID_Connect, wxT("Connecting an existing SQLite DB"),
554                    *BtnConnect, wxNullBitmap, wxITEM_NORMAL,
555                    wxT("Connecting an existing SQLite DB"));
556   toolBar->AddTool(ID_CreateNew, wxT("Creating a &New (empty) SQLite DB"),
557                    *BtnCreateNew, wxNullBitmap, wxITEM_NORMAL,
558                    wxT("Creating a &New (empty) SQLite DB"));
559   toolBar->AddTool(ID_MemoryDbLoad,
560                    wxT("Loading an existing DB into the MEMORY-DB"),
561                    *BtnMemDbLoad, wxNullBitmap, wxITEM_NORMAL,
562                    wxT("Loading an existing DB into the MEMORY-DB"));
563   toolBar->AddTool(ID_MemoryDbNew, wxT("Creating a New (empty) MEMORY-DB"),
564                    *BtnMemDbNew, wxNullBitmap, wxITEM_NORMAL,
565                    wxT("Creating a New (empty) MEMORY-DB"));
566   toolBar->AddTool(ID_MemoryDbClock, wxT("AutoSaving the current MEMORY-DB"),
567                    *BtnMemDbClock, wxNullBitmap, wxITEM_NORMAL,
568                    wxT("AutoSaving the current MEMORY-DB"));
569   toolBar->AddTool(ID_MemoryDbSave, wxT("Saving the current MEMORY-DB"),
570                    *BtnMemDbSave, wxNullBitmap, wxITEM_NORMAL,
571                    wxT("Saving the current MEMORY-DB"));
572   toolBar->AddTool(ID_Disconnect, wxT("Disconnecting current SQLite DB"),
573                    *BtnDisconnect, wxNullBitmap, wxITEM_NORMAL,
574                    wxT("Disconnecting current SQLite DB"));
575   toolBar->AddTool(ID_Vacuum, wxT("Optimizing current SQLite DB [VACUUM]"),
576                    *BtnVacuum, wxNullBitmap, wxITEM_NORMAL,
577                    wxT("Optimizing current SQLite DB [VACUUM]"));
578   //toolBar->AddSeparator();
579   toolBar->AddTool(ID_Attach, wxT("Attach DataBase"),
580                    *BtnAttach, wxNullBitmap, wxITEM_NORMAL,
581                    wxT("Attach DataBase"));
582   //toolBar->AddSeparator();
583   toolBar->AddTool(ID_SqlLog, wxT("SQL Log"),
584                    *BtnSqlLog, wxNullBitmap, wxITEM_CHECK, wxT("SQL Log"));
585   toolBar->AddTool(ID_DbStatus, wxT("DB Status"),
586                    *BtnDbStatus, wxNullBitmap, wxITEM_NORMAL, wxT("DB Status"));
587   //toolBar->AddSeparator();
588   toolBar->AddTool(ID_CheckGeom, wxT("Check Geometries"),
589                    *BtnCheckGeom, wxNullBitmap, wxITEM_NORMAL,
590                    wxT("Check Geometries"));
591   toolBar->AddTool(ID_SaneGeom, wxT("Sanitize Geometries"), *BtnSaneGeom,
592                    wxNullBitmap, wxITEM_NORMAL, wxT("Sanitize Geometries"));
593   //toolBar->AddSeparator();
594   toolBar->AddTool(ID_SqlScript, wxT("Execute SQL script"), *BtnSqlScript,
595                    wxNullBitmap, wxITEM_NORMAL, wxT("Execute SQL script"));
596   //toolBar->AddSeparator();
597   toolBar->AddTool(ID_QueryViewComposer, wxT("Query/View Composer"),
598                    *BtnQueryComposer, wxNullBitmap, wxITEM_NORMAL,
599                    wxT("Query/View Composer"));
600   //toolBar->AddSeparator();
601   toolBar->AddTool(ID_LoadShp, wxT("Load Shapefile"), *BtnLoadShp, wxNullBitmap,
602                    wxITEM_NORMAL, wxT("Load Shapefile"));
603   toolBar->AddTool(ID_VirtualShp, wxT("Virtual Shapefile"), *BtnVirtualShp,
604                    wxNullBitmap, wxITEM_NORMAL, wxT("Virtual Shapefile"));
605   //toolBar->AddSeparator();
606   toolBar->AddTool(ID_LoadTxt, wxT("Load CSV/TXT"), *BtnLoadTxt, wxNullBitmap,
607                    wxITEM_NORMAL, wxT("Load CSV/TXT"));
608   toolBar->AddTool(ID_VirtualTxt, wxT("Virtual CSV/TXT"), *BtnVirtualTxt,
609                    wxNullBitmap, wxITEM_NORMAL, wxT("Virtual CSV/TXT"));
610   //toolBar->AddSeparator();
611   toolBar->AddTool(ID_LoadDbf, wxT("Load DBF"), *BtnLoadDbf, wxNullBitmap,
612                    wxITEM_NORMAL, wxT("Load DBF"));
613   toolBar->AddTool(ID_VirtualDbf, wxT("Virtual DBF"), *BtnVirtualDbf,
614                    wxNullBitmap, wxITEM_NORMAL, wxT("Virtual DBF"));
615   //toolBar->AddSeparator();
616   toolBar->AddTool(ID_LoadXL, wxT("Load XLS"), *BtnLoadXL, wxNullBitmap,
617                    wxITEM_NORMAL, wxT("Load XLS"));
618   toolBar->AddTool(ID_VirtualXL, wxT("Virtual XLS"), *BtnVirtualXL,
619                    wxNullBitmap, wxITEM_NORMAL, wxT("Virtual XLS"));
620   //toolBar->AddSeparator();
621   toolBar->AddTool(ID_Network, wxT("Build Network"), *BtnNetwork, wxNullBitmap,
622                    wxITEM_NORMAL, wxT("Build Network"));
623   //toolBar->AddSeparator();
624   toolBar->AddTool(ID_Exif, wxT("Import EXIF photos"), *BtnExif, wxNullBitmap,
625                    wxITEM_NORMAL, wxT("Import EXIF photos"));
626   toolBar->AddTool(ID_LoadXml, wxT("Import XML Documents"), *BtnLoadXml,
627                    wxNullBitmap, wxITEM_NORMAL, wxT("Import XML Documents"));
628   toolBar->AddTool(ID_WFS, wxT("Import data from WFS datasource"), *BtnWFS,
629                    wxNullBitmap, wxITEM_NORMAL,
630                    wxT("Import data from WFS datasource"));
631   toolBar->AddTool(ID_DXF, wxT("Import DXF drawings"), *BtnDXF,
632                    wxNullBitmap, wxITEM_NORMAL, wxT("Import DXF drawings"));
633   //toolBar->AddSeparator();
634   toolBar->AddTool(ID_Srids, wxT("Search SRID by name"), *BtnSrids,
635                    wxNullBitmap, wxITEM_NORMAL, wxT("Search SRID by name"));
636   //toolBar->AddSeparator();
637   toolBar->AddTool(ID_Charset, wxT("Default Output Charset"), *BtnCharset,
638                    wxNullBitmap, wxITEM_NORMAL, wxT("Default Output Charset"));
639   //toolBar->AddSeparator();
640   toolBar->AddTool(ID_Help, wxT("Help"), *BtnHelp, wxNullBitmap, wxITEM_NORMAL,
641                    wxT("Help"));
642   toolBar->AddTool(wxID_ABOUT, wxT("About ..."), *BtnAbout, wxNullBitmap,
643                    wxITEM_NORMAL, wxT("About ..."));
644   //toolBar->AddSeparator();
645   toolBar->AddTool(wxID_EXIT, wxT("Quit"), *BtnExit, wxNullBitmap,
646                    wxITEM_NORMAL, wxT("Quit"));
647   toolBar->Realize();
648   SetToolBar(toolBar);
649 
650 //
651 // setting up the toolbar initial state
652 //
653   toolBar->EnableTool(ID_Disconnect, false);
654   toolBar->EnableTool(ID_MemoryDbClock, false);
655   toolBar->EnableTool(ID_MemoryDbSave, false);
656   toolBar->EnableTool(ID_Vacuum, false);
657   toolBar->EnableTool(ID_SqlScript, false);
658   toolBar->EnableTool(ID_QueryViewComposer, false);
659   toolBar->EnableTool(ID_LoadShp, false);
660   toolBar->EnableTool(ID_VirtualShp, false);
661   toolBar->EnableTool(ID_LoadTxt, false);
662   toolBar->EnableTool(ID_VirtualTxt, false);
663   toolBar->EnableTool(ID_LoadDbf, false);
664   toolBar->EnableTool(ID_VirtualDbf, false);
665   toolBar->EnableTool(ID_LoadXL, false);
666   toolBar->EnableTool(ID_VirtualXL, false);
667   toolBar->EnableTool(ID_Network, false);
668   toolBar->EnableTool(ID_Exif, false);
669   toolBar->EnableTool(ID_LoadXml, false);
670   toolBar->EnableTool(ID_Srids, false);
671   toolBar->EnableTool(ID_Attach, false);
672   toolBar->EnableTool(ID_SqlLog, false);
673   toolBar->EnableTool(ID_DbStatus, false);
674   toolBar->EnableTool(ID_CheckGeom, false);
675   toolBar->EnableTool(ID_SaneGeom, false);
676   toolBar->EnableTool(ID_WFS, false);
677   toolBar->EnableTool(ID_DXF, false);
678 
679 // updating the status bar
680   UpdateStatusBar();
681 
682 //
683 // setting up event handlers for menu and toolbar
684 //
685   Connect(ID_Connect, wxEVT_COMMAND_MENU_SELECTED,
686           (wxObjectEventFunction) & MyFrame::OnConnect);
687   Connect(ID_CreateNew, wxEVT_COMMAND_MENU_SELECTED,
688           (wxObjectEventFunction) & MyFrame::OnCreateNew);
689   Connect(ID_Disconnect, wxEVT_COMMAND_MENU_SELECTED,
690           (wxObjectEventFunction) & MyFrame::OnDisconnect);
691   Connect(ID_MemoryDbLoad, wxEVT_COMMAND_MENU_SELECTED,
692           (wxObjectEventFunction) & MyFrame::OnMemoryDbLoad);
693   Connect(ID_MemoryDbNew, wxEVT_COMMAND_MENU_SELECTED,
694           (wxObjectEventFunction) & MyFrame::OnMemoryDbNew);
695   Connect(ID_MemoryDbClock, wxEVT_COMMAND_MENU_SELECTED,
696           (wxObjectEventFunction) & MyFrame::OnMemoryDbClock);
697   Connect(ID_MemoryDbSave, wxEVT_COMMAND_MENU_SELECTED,
698           (wxObjectEventFunction) & MyFrame::OnMemoryDbSave);
699   Connect(ID_Vacuum, wxEVT_COMMAND_MENU_SELECTED,
700           (wxObjectEventFunction) & MyFrame::OnVacuum);
701   Connect(ID_SqlScript, wxEVT_COMMAND_MENU_SELECTED,
702           (wxObjectEventFunction) & MyFrame::OnSqlScript);
703   Connect(ID_QueryViewComposer, wxEVT_COMMAND_MENU_SELECTED,
704           (wxObjectEventFunction) & MyFrame::OnQueryViewComposer);
705   Connect(ID_LoadShp, wxEVT_COMMAND_MENU_SELECTED,
706           (wxObjectEventFunction) & MyFrame::OnLoadShp);
707   Connect(ID_VirtualShp, wxEVT_COMMAND_MENU_SELECTED,
708           (wxObjectEventFunction) & MyFrame::OnVirtualShp);
709   Connect(ID_LoadTxt, wxEVT_COMMAND_MENU_SELECTED,
710           (wxObjectEventFunction) & MyFrame::OnLoadTxt);
711   Connect(ID_VirtualTxt, wxEVT_COMMAND_MENU_SELECTED,
712           (wxObjectEventFunction) & MyFrame::OnVirtualTxt);
713   Connect(ID_LoadDbf, wxEVT_COMMAND_MENU_SELECTED,
714           (wxObjectEventFunction) & MyFrame::OnLoadDbf);
715   Connect(ID_VirtualDbf, wxEVT_COMMAND_MENU_SELECTED,
716           (wxObjectEventFunction) & MyFrame::OnVirtualDbf);
717   Connect(ID_LoadXL, wxEVT_COMMAND_MENU_SELECTED,
718           (wxObjectEventFunction) & MyFrame::OnLoadXL);
719   Connect(ID_VirtualXL, wxEVT_COMMAND_MENU_SELECTED,
720           (wxObjectEventFunction) & MyFrame::OnVirtualXL);
721   Connect(ID_Network, wxEVT_COMMAND_MENU_SELECTED,
722           (wxObjectEventFunction) & MyFrame::OnNetwork);
723   Connect(ID_Exif, wxEVT_COMMAND_MENU_SELECTED,
724           (wxObjectEventFunction) & MyFrame::OnImportExifPhotos);
725   Connect(ID_LoadXml, wxEVT_COMMAND_MENU_SELECTED,
726           (wxObjectEventFunction) & MyFrame::OnImportXmlDocuments);
727   Connect(ID_WFS, wxEVT_COMMAND_MENU_SELECTED,
728           (wxObjectEventFunction) & MyFrame::OnImportWFS);
729   Connect(ID_DXF, wxEVT_COMMAND_MENU_SELECTED,
730           (wxObjectEventFunction) & MyFrame::OnImportDXF);
731   Connect(ID_Srids, wxEVT_COMMAND_MENU_SELECTED,
732           (wxObjectEventFunction) & MyFrame::OnSrids);
733   Connect(ID_Charset, wxEVT_COMMAND_MENU_SELECTED,
734           (wxObjectEventFunction) & MyFrame::OnCharset);
735   Connect(ID_Attach, wxEVT_COMMAND_MENU_SELECTED,
736           (wxObjectEventFunction) & MyFrame::OnAttachDatabase);
737   Connect(ID_SqlLog, wxEVT_COMMAND_MENU_SELECTED,
738           (wxObjectEventFunction) & MyFrame::OnSqlLog);
739   Connect(ID_DbStatus, wxEVT_COMMAND_MENU_SELECTED,
740           (wxObjectEventFunction) & MyFrame::OnDbStatus);
741   Connect(ID_CheckGeom, wxEVT_COMMAND_MENU_SELECTED,
742           (wxObjectEventFunction) & MyFrame::OnCheckGeometries);
743   Connect(ID_SaneGeom, wxEVT_COMMAND_MENU_SELECTED,
744           (wxObjectEventFunction) & MyFrame::OnSanitizeGeometries);
745   Connect(ID_Help, wxEVT_COMMAND_MENU_SELECTED,
746           (wxObjectEventFunction) & MyFrame::OnHelp);
747   Connect(wxID_ABOUT, wxEVT_COMMAND_MENU_SELECTED,
748           (wxObjectEventFunction) & MyFrame::OnAbout);
749   Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED,
750           (wxObjectEventFunction) & MyFrame::OnQuit);
751   Connect(wxID_ANY, wxEVT_MOTION, wxMouseEventHandler(MyFrame::OnMouseMove),
752           NULL, this);
753 
754 //
755 // setting up event handlers for mouse
756 //
757   TableTree->Connect(wxID_ANY, wxEVT_MOTION,
758                      wxMouseEventHandler(MyFrame::OnMouseMove), NULL, this);
759   GetMenuBar()->Connect(wxID_ANY, wxEVT_MOTION,
760                         wxMouseEventHandler(MyFrame::OnMouseMove), NULL, this);
761   GetStatusBar()->Connect(wxID_ANY, wxEVT_MOTION,
762                           wxMouseEventHandler(MyFrame::OnMouseMove), NULL,
763                           this);
764 //
765 // setting up a Timer event handler for AutoSave
766 //
767   Connect(ID_AUTO_SAVE_TIMER, wxEVT_TIMER,
768           wxTimerEventHandler(MyFrame::OnTimerAutoSave), NULL, this);
769 }
770 
~MyFrame()771 MyFrame::~MyFrame()
772 {
773 //
774 // main GUI frame destructor
775 //
776   if (TimerAutoSave)
777     {
778       TimerAutoSave->Stop();
779       delete TimerAutoSave;
780     }
781   LastDitchMemoryDbSave();
782   ConfigLayout = Manager.SavePerspective();
783   GetPosition(&ConfigPaneX, &ConfigPaneY);
784   GetSize(&ConfigPaneWidth, &ConfigPaneHeight);
785   SaveConfig();
786   Manager.UnInit();
787   if (SqliteHandle)
788     sqlite3_close(SqliteHandle);
789   if (InternalCache)
790     spatialite_cleanup_ex(InternalCache);
791   if (BtnConnect != NULL)
792     delete BtnConnect;
793   if (BtnCreateNew != NULL)
794     delete BtnCreateNew;
795   if (BtnDisconnect != NULL)
796     delete BtnDisconnect;
797   if (BtnMemDbLoad != NULL)
798     delete BtnMemDbLoad;
799   if (BtnMemDbNew != NULL)
800     delete BtnMemDbNew;
801   if (BtnMemDbClock != NULL)
802     delete BtnMemDbClock;
803   if (BtnMemDbSave != NULL)
804     delete BtnMemDbSave;
805   if (BtnVacuum != NULL)
806     delete BtnVacuum;
807   if (BtnSqlScript != NULL)
808     delete BtnSqlScript;
809   if (BtnQueryComposer != NULL)
810     delete BtnQueryComposer;
811   if (BtnLoadShp != NULL)
812     delete BtnLoadShp;
813   if (BtnVirtualShp != NULL)
814     delete BtnVirtualShp;
815   if (BtnLoadTxt != NULL)
816     delete BtnLoadTxt;
817   if (BtnVirtualTxt != NULL)
818     delete BtnVirtualTxt;
819   if (BtnLoadDbf != NULL)
820     delete BtnLoadDbf;
821   if (BtnVirtualDbf != NULL)
822     delete BtnVirtualDbf;
823   if (BtnLoadXL != NULL)
824     delete BtnLoadXL;
825   if (BtnVirtualXL != NULL)
826     delete BtnVirtualXL;
827   if (BtnNetwork != NULL)
828     delete BtnNetwork;
829   if (BtnExif != NULL)
830     delete BtnExif;
831   if (BtnLoadXml != NULL)
832     delete BtnLoadXml;
833   if (BtnSrids != NULL)
834     delete BtnSrids;
835   if (BtnHelp != NULL)
836     delete BtnHelp;
837   if (BtnAttach != NULL)
838     delete BtnAttach;
839   if (BtnSqlLog != NULL)
840     delete BtnSqlLog;
841   if (BtnDbStatus != NULL)
842     delete BtnDbStatus;
843   if (BtnCheckGeom != NULL)
844     delete BtnCheckGeom;
845   if (BtnSaneGeom != NULL)
846     delete BtnSaneGeom;
847   if (BtnAbout != NULL)
848     delete BtnAbout;
849   if (BtnExit != NULL)
850     delete BtnExit;
851   if (Charsets)
852     delete[]Charsets;
853   if (CharsetsNames)
854     delete[]CharsetsNames;
855 }
856 
SaveConfig()857 void MyFrame::SaveConfig()
858 {
859 //
860 // saves layout configuration
861 //
862 
863   wxConfig *config = new wxConfig(wxT("SpatialiteGui"));
864   config->Write(wxT("Layout"), ConfigLayout);
865   config->Write(wxT("PaneX"), ConfigPaneX);
866   config->Write(wxT("PaneY"), ConfigPaneY);
867   config->Write(wxT("PaneWidth"), ConfigPaneWidth);
868   config->Write(wxT("PaneHeight"), ConfigPaneHeight);
869   config->Write(wxT("SqlitePath"), SqlitePath);
870   config->Write(wxT("LastDirectory"), LastDirectory);
871   delete config;
872 }
873 
LoadConfig(wxString & externalPath)874 void MyFrame::LoadConfig(wxString & externalPath)
875 {
876 //
877 // loads layout configuration
878 //
879   ConfigLayout = wxT("");
880   ConfigDbPath = wxT("");
881   ConfigDir = wxT("");
882   wxConfig *config = new wxConfig(wxT("SpatialiteGui"));
883   config->Read(wxT("Layout"), &ConfigLayout);
884   config->Read(wxT("PaneX"), &ConfigPaneX, -1);
885   config->Read(wxT("PaneY"), &ConfigPaneY, -1);
886   config->Read(wxT("PaneWidth"), &ConfigPaneWidth, -1);
887   config->Read(wxT("PaneHeight"), &ConfigPaneHeight, -1);
888   config->Read(wxT("SqlitePath"), &ConfigDbPath);
889   config->Read(wxT("LastDirectory"), &ConfigDir);
890   delete config;
891   Hide();
892   if (externalPath.Len() > 0)
893     {
894       // applying the external path
895       wxFileName file(externalPath);
896       ConfigDir = file.GetPath();
897       ConfigDbPath = externalPath;
898     }
899   if (ConfigLayout.Len() > 0)
900     Manager.LoadPerspective(ConfigLayout, true);
901   if (ConfigPaneX >= 0 && ConfigPaneY >= 0 && ConfigPaneWidth > 0
902       && ConfigPaneHeight > 0)
903     SetSize(ConfigPaneX, ConfigPaneY, ConfigPaneWidth, ConfigPaneHeight);
904   if (ConfigDir.Len() > 0)
905     LastDirectory = ConfigDir;
906   if (ConfigDbPath.Len() > 0)
907     {
908       SqlitePath = ConfigDbPath;
909       if (OpenDB() == false)
910         SqlitePath = wxT("");
911       else
912         {
913           bool metadata = CheckMetadata();
914           wxMenuBar *menuBar = GetMenuBar();
915           menuBar->Enable(ID_Connect, false);
916           menuBar->Enable(ID_MemoryDbLoad, false);
917           menuBar->Enable(ID_MemoryDbNew, false);
918           if (MemoryDatabase == true)
919             {
920               menuBar->Enable(ID_MemoryDbSave, true);
921               menuBar->Enable(ID_MemoryDbClock, true);
922           } else
923             {
924               menuBar->Enable(ID_MemoryDbSave, false);
925               menuBar->Enable(ID_MemoryDbClock, false);
926             }
927           menuBar->Enable(ID_CreateNew, false);
928           menuBar->Enable(ID_Disconnect, true);
929           menuBar->Enable(ID_Vacuum, true);
930           menuBar->Enable(ID_SqlScript, true);
931           menuBar->Enable(ID_QueryViewComposer, HasViewsMetadata());
932           menuBar->Enable(ID_LoadShp, true);
933           menuBar->Enable(ID_VirtualShp, true);
934           menuBar->Enable(ID_LoadTxt, true);
935           menuBar->Enable(ID_VirtualTxt, true);
936           menuBar->Enable(ID_LoadDbf, true);
937           menuBar->Enable(ID_VirtualDbf, true);
938           menuBar->Enable(ID_LoadXL, true);
939           menuBar->Enable(ID_VirtualXL, true);
940           menuBar->Enable(ID_Network, true);
941           menuBar->Enable(ID_Exif, true);
942           menuBar->Enable(ID_LoadXml, true);
943           menuBar->Enable(ID_WFS, true);
944           menuBar->Enable(ID_DXF, true);
945           menuBar->Enable(ID_Srids, metadata);
946           menuBar->Enable(ID_Attach, true);
947           menuBar->Enable(ID_SqlLog, true);
948           menuBar->Enable(ID_DbStatus, true);
949           menuBar->Enable(ID_CheckGeom, true);
950           menuBar->Enable(ID_SaneGeom, true);
951           EnableSqlLog();
952           menuBar->Check(ID_SqlLog, SqlLogEnabled);
953           wxToolBar *toolBar = GetToolBar();
954           toolBar->EnableTool(ID_Connect, false);
955           toolBar->EnableTool(ID_MemoryDbLoad, false);
956           toolBar->EnableTool(ID_MemoryDbNew, false);
957           if (MemoryDatabase == true)
958             {
959               toolBar->EnableTool(ID_MemoryDbSave, true);
960               toolBar->EnableTool(ID_MemoryDbClock, true);
961           } else
962             {
963               toolBar->EnableTool(ID_MemoryDbSave, false);
964               toolBar->EnableTool(ID_MemoryDbClock, false);
965             }
966           toolBar->EnableTool(ID_CreateNew, false);
967           toolBar->EnableTool(ID_Disconnect, true);
968           toolBar->EnableTool(ID_Vacuum, true);
969           toolBar->EnableTool(ID_SqlScript, true);
970           toolBar->EnableTool(ID_QueryViewComposer, HasViewsMetadata());
971           toolBar->EnableTool(ID_LoadShp, true);
972           toolBar->EnableTool(ID_VirtualShp, true);
973           toolBar->EnableTool(ID_LoadTxt, true);
974           toolBar->EnableTool(ID_VirtualTxt, true);
975           toolBar->EnableTool(ID_LoadDbf, true);
976           toolBar->EnableTool(ID_VirtualDbf, true);
977           toolBar->EnableTool(ID_LoadXL, true);
978           toolBar->EnableTool(ID_VirtualXL, true);
979           toolBar->EnableTool(ID_Network, true);
980           toolBar->EnableTool(ID_Exif, true);
981           toolBar->EnableTool(ID_LoadXml, true);
982           toolBar->EnableTool(ID_WFS, true);
983           toolBar->EnableTool(ID_DXF, true);
984           toolBar->EnableTool(ID_Srids, metadata);
985           toolBar->EnableTool(ID_Attach, true);
986           toolBar->EnableTool(ID_SqlLog, true);
987           toolBar->ToggleTool(ID_SqlLog, SqlLogEnabled);
988           toolBar->EnableTool(ID_DbStatus, true);
989           toolBar->EnableTool(ID_CheckGeom, true);
990           toolBar->EnableTool(ID_SaneGeom, true);
991           UpdateStatusBar();
992         }
993     }
994   Show();
995   if (AutoFDOmsg.Len() > 0)
996     {
997       wxMessageBox(AutoFDOmsg, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION,
998                    this);
999       AutoFDOmsg = wxT("");
1000     }
1001 }
1002 
OnQuit(wxCommandEvent & WXUNUSED (event))1003 void MyFrame::OnQuit(wxCommandEvent & WXUNUSED(event))
1004 {
1005 //
1006 // EXIT - event handler
1007 //
1008   CloseDB();
1009   Close(true);
1010 }
1011 
OnAttachDatabase(wxCommandEvent & WXUNUSED (event))1012 void MyFrame::OnAttachDatabase(wxCommandEvent & WXUNUSED(event))
1013 {
1014 //
1015 // Attach Database - event handler
1016 //
1017   int ret;
1018   wxString lastDir;
1019   wxString path;
1020   wxString suffixList =
1021     wxT("SpatiaLite DB (*.sqlite;*.atlas)|*.sqlite;*.atlas|");
1022   suffixList += wxT("SQLite DB (*.sqlite)|*.sqlite|");
1023   suffixList += wxT("LibreAtlas DB (*.atlas)|*.atlas|");
1024   suffixList += wxT("All files (*.*)|*.*");
1025   wxFileDialog fileDialog(this, wxT("Attach DataBase"),
1026                           wxT(""), wxT("db.sqlite"), suffixList,
1027                           wxFD_OPEN | wxFD_FILE_MUST_EXIST, wxDefaultPosition,
1028                           wxDefaultSize, wxT("filedlg"));
1029   lastDir = GetLastDirectory();
1030   if (lastDir.Len() >= 1)
1031     fileDialog.SetDirectory(lastDir);
1032   ret = fileDialog.ShowModal();
1033   if (ret == wxID_OK)
1034     {
1035       path = fileDialog.GetPath();
1036       if (DoAttachDatabase(path) == true)
1037         {
1038           wxFileName file(fileDialog.GetPath());
1039           lastDir = file.GetPath();
1040           SetLastDirectory(lastDir);
1041           InitTableTree();
1042         }
1043     }
1044 }
1045 
EnableSqlLog()1046 void MyFrame::EnableSqlLog()
1047 {
1048 //
1049 // enables the SQL Log if the currently connected DB is v.4.0.0
1050 //
1051   if (GetMetaDataType() == METADATA_CURRENT)
1052     SqlLogEnabled = true;
1053   else
1054     SqlLogEnabled = false;
1055 }
1056 
OnSqlLog(wxCommandEvent & WXUNUSED (event))1057 void MyFrame::OnSqlLog(wxCommandEvent & WXUNUSED(event))
1058 {
1059 //
1060 // SQL Log - event handler
1061 //
1062   wxMenuBar *menuBar = GetMenuBar();
1063   wxToolBar *toolBar = GetToolBar();
1064   if (SqlLogEnabled == true)
1065     {
1066       SqlLogEnabled = false;
1067       menuBar->Check(ID_SqlLog, false);
1068       toolBar->ToggleTool(ID_SqlLog, false);
1069   } else
1070     {
1071       EnableSqlLog();
1072       menuBar->Check(ID_SqlLog, SqlLogEnabled);
1073       toolBar->ToggleTool(ID_SqlLog, SqlLogEnabled);
1074     }
1075 }
1076 
OnDbStatus(wxCommandEvent & WXUNUSED (event))1077 void MyFrame::OnDbStatus(wxCommandEvent & WXUNUSED(event))
1078 {
1079 //
1080 // DB Status and internal statistics
1081 //
1082   DbStatusDialog *stats = new DbStatusDialog();
1083   stats->Create(this);
1084   stats->Show();
1085 }
1086 
OnCheckGeometries(wxCommandEvent & WXUNUSED (event))1087 void MyFrame::OnCheckGeometries(wxCommandEvent & WXUNUSED(event))
1088 {
1089 //
1090 // Checking all geometry columns
1091 //
1092   wxString msg =
1093     wxT("Do you really intend checking for validity all Geometries ?\n\n");
1094   msg +=
1095     wxT
1096     ("This will imply evaluating ST_IsValid() for each single Geometry stored\n");
1097   msg +=
1098     wxT
1099     ("within any \"layer\" defined in \"geometry_columns\", and could require\n");
1100   msg += wxT("a substantial time for a huge DB\n\n");
1101   msg += wxT("A HTML diagnostic report will be created.");
1102   int ret = wxMessageBox(msg, wxT("spatialite_gui"), wxYES_NO | wxICON_QUESTION,
1103                          this);
1104   if (ret != wxYES)
1105     return;
1106 
1107   char *err_msg = NULL;
1108   char output_dir[1024];
1109   wxDirDialog dirDialog(this, wxT("Directory for Diagnostic Report"));
1110   ret = dirDialog.ShowModal();
1111   if (ret == wxID_OK)
1112     {
1113       strcpy(output_dir, dirDialog.GetPath().ToUTF8());
1114       ::wxBeginBusyCursor();
1115       int invalids;
1116       ret =
1117         check_all_geometry_columns(GetSqlite(), output_dir, &invalids,
1118                                    &err_msg);
1119       ::wxEndBusyCursor();
1120       if (ret == 0)
1121         {
1122           // reporting some error condition
1123           msg = wxT("Some unexpected error occurred:\n\n");
1124           if (err_msg != NULL)
1125             {
1126               msg += wxString::FromUTF8(err_msg);
1127               free(err_msg);
1128           } else
1129             msg += wxT("Sorry, no further details are available");
1130           wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1131       } else
1132         {
1133           int mode;
1134           if (invalids > 0)
1135             {
1136               msg =
1137                 wxT
1138                 ("ATTENTION: some invalid Geometries have been detected !!!\n\n");
1139               mode = wxICON_WARNING;
1140           } else
1141             {
1142               msg =
1143                 wxT
1144                 ("No invalid Geometries have been detected; the whole DB is full valid\n\n");
1145               mode = wxICON_INFORMATION;
1146             }
1147           msg += wxT("A full diagnostic report has been created.\n");
1148           msg +=
1149             wxT
1150             ("Please point your WEB Browser at the following HTML document containing the report:\n\n");
1151 #if defined(_WIN32)
1152           const char *delim = "\\";
1153 #else
1154           const char *delim = "/";
1155 #endif
1156           msg +=
1157             dirDialog.GetPath() + wxString::FromUTF8(delim) + wxT("index.html");
1158           wxMessageBox(msg, wxT("spatialite_gui"), wxOK | mode, this);
1159         }
1160     }
1161 }
1162 
OnSanitizeGeometries(wxCommandEvent & WXUNUSED (event))1163 void MyFrame::OnSanitizeGeometries(wxCommandEvent & WXUNUSED(event))
1164 {
1165 //
1166 // Sanitizing all invalid geometries
1167 //
1168   int ret;
1169   SanitizeAllGeometriesDialog dlg;
1170   dlg.Create(this);
1171   ret = dlg.ShowModal();
1172   if (ret != wxYES)
1173     return;
1174 
1175   char tmp_prefix[1024];
1176   char *err_msg = NULL;
1177   char output_dir[1024];
1178   wxString msg;
1179   strcpy(tmp_prefix, dlg.GetTmpPrefix().ToUTF8());
1180 
1181   wxDirDialog dirDialog(this, wxT("Directory for Diagnostic Report"));
1182   ret = dirDialog.ShowModal();
1183   if (ret == wxID_OK)
1184     {
1185       strcpy(output_dir, dirDialog.GetPath().ToUTF8());
1186       ::wxBeginBusyCursor();
1187       int not_validated;
1188       ret =
1189         sanitize_all_geometry_columns(GetSqlite(), tmp_prefix, output_dir,
1190                                       &not_validated, &err_msg);
1191       ::wxEndBusyCursor();
1192       if (ret == 0)
1193         {
1194           // reporting some error condition
1195           msg = wxT("Some unexpected error occurred:\n\n");
1196           if (err_msg != NULL)
1197             {
1198               msg += wxString::FromUTF8(err_msg);
1199               free(err_msg);
1200           } else
1201             msg += wxT("Sorry, no further details are available");
1202           wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1203       } else
1204         {
1205           int mode;
1206           if (not_validated > 0)
1207             {
1208               msg =
1209                 wxT
1210                 ("ATTENTION: some invalid Geometries still remain invalid !!!\n\n");
1211               mode = wxICON_WARNING;
1212           } else
1213             {
1214               msg =
1215                 wxT
1216                 ("All invalid Geometries have been saned; the whole DB is now full valid\n\n");
1217               mode = wxICON_INFORMATION;
1218             }
1219           msg += wxT("A full diagnostic report has been created.\n");
1220           msg +=
1221             wxT
1222             ("Please point your WEB Browser at the following HTML document containing the report:\n\n");
1223 #if defined(_WIN32)
1224           const char *delim = "\\";
1225 #else
1226           const char *delim = "/";
1227 #endif
1228           msg +=
1229             dirDialog.GetPath() + wxString::FromUTF8(delim) + wxT("index.html");
1230           wxMessageBox(msg, wxT("spatialite_gui"), wxOK | mode, this);
1231         }
1232     }
1233 }
1234 
OnHelp(wxCommandEvent & WXUNUSED (event))1235 void MyFrame::OnHelp(wxCommandEvent & WXUNUSED(event))
1236 {
1237 //
1238 // HELP - event handler
1239 //
1240   if (HelpPane == true)
1241     return;
1242   HelpDialog *help = new HelpDialog(this);
1243   help->Show();
1244 }
1245 
OnAbout(wxCommandEvent & WXUNUSED (event))1246 void MyFrame::OnAbout(wxCommandEvent & WXUNUSED(event))
1247 {
1248 //
1249 // ABOUT dialog - event handler
1250 //
1251   bool has_libxml2 = false;
1252   char ver[128];
1253   wxAboutDialogInfo dlg;
1254   dlg.SetIcon(wxIcon(icon_info_xpm));
1255   dlg.SetName(wxT("spatialite_gui"));
1256   const char *version = VERSION;
1257   dlg.SetVersion(wxString::FromUTF8(version));
1258   wxString str = wxT("a GUI-tool for SQLite / SpatiaLite\n\n");
1259   sprintf(ver, "%d.%d.%d", wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER);
1260   str += wxT("wxWidgets version ") + wxString::FromUTF8(ver) + wxT("\n");
1261   strcpy(ver, spatialite_version());
1262   str += wxT("SpatiaLite version ") + wxString::FromUTF8(ver) + wxT("\n");
1263   strcpy(ver, sqlite3_libversion());
1264   str += wxT("SQLite version ") + wxString::FromUTF8(ver) + wxT("\n");
1265   strcpy(ver, GEOSversion());
1266   str += wxT("GEOS version ") + wxString::FromUTF8(ver) + wxT("\n");
1267   strcpy(ver, pj_get_release());
1268   str += wxT("PROJ.4 version ") + wxString::FromUTF8(ver) + wxT("\n");
1269   if (GetLwGeomVersion(ver))
1270     {
1271       // printing out the LWGEOM version if supported
1272       str += wxT("LWGEOM version ") + wxString::FromUTF8(ver) + wxT("\n");
1273     }
1274   if (GetLibXml2Version(ver))
1275     {
1276       // printing out the LIBXML2 version if supported
1277       str += wxT("LIBXML2 version ") + wxString::FromUTF8(ver) + wxT("\n");
1278       has_libxml2 = true;
1279     }
1280   str += wxT("\nSQLite's extension 'SpatiaLite' enabled\n");
1281   str += wxT("SQLite's extension 'VirtualShape' enabled\n");
1282   str += wxT("SQLite's extension 'VirtualDbf' enabled\n");
1283   str += wxT("SQLite's extension 'VirtualXL' enabled\n");
1284   str += wxT("SQLite's extension 'VirtualText' enabled\n");
1285   if (has_libxml2)
1286     str += wxT("SQLite's extension 'VirtualXPath' enabled\n");
1287   str += wxT("SQLite's extension 'VirtualNetwork' enabled\n");
1288   str += wxT("SQLite's extension 'RTree' enabled\n");
1289   str += wxT("SQLite's extension 'MbrCache' enabled\n");
1290   str += wxT("SQLite's extension 'VirtualFDO' enabled\n\n");
1291   dlg.SetDescription(str);
1292   dlg.SetCopyright(wxT("by Alessandro Furieri - 2008/2013"));
1293   dlg.SetWebSite(wxT("http://www.gaia-gis.it"));
1294   wxString license =
1295     wxT("This program is free software; you can redistribute it\n");
1296   license +=
1297     wxT("and/or modify it under the terms of the GNU General Public License\n");
1298   license += wxT("(GPL) as published by the Free Software Foundation\n\n");
1299   license +=
1300     wxT
1301     ("A copy of the GPL can be found at\nhttp://www.gnu.org/licenses/gpl.txt");
1302   dlg.SetLicense(license);
1303   ::wxAboutBox(dlg);
1304 }
1305 
OnMouseMove(wxMouseEvent & WXUNUSED (event))1306 void MyFrame::OnMouseMove(wxMouseEvent & WXUNUSED(event))
1307 {
1308 //
1309 // MOUSE motion - event handler
1310 //
1311   UpdateStatusBar();
1312 }
1313 
UpdateStatusBar()1314 void MyFrame::UpdateStatusBar()
1315 {
1316 //
1317 // updating the status bar
1318 //
1319   if (GetStatusBar() == NULL)
1320     return;
1321   if (MemoryDatabase == true)
1322     {
1323       GetStatusBar()->SetStatusText(wxT("Current SQLite DB: MEMORY-DB"), 0);
1324       QueryView->ShowControls();
1325   } else
1326     {
1327       if (SqlitePath.Len() < 1)
1328         GetStatusBar()->SetStatusText(wxT("not connected"), 0);
1329       else
1330         GetStatusBar()->SetStatusText(wxT("Current SQLite DB: ") + SqlitePath,
1331                                       0);
1332       if (SqlitePath.Len() < 1)
1333         {
1334           QueryView->HideControls();
1335           RsView->HideControls();
1336       } else
1337         QueryView->ShowControls();
1338     }
1339 }
1340 
OnConnect(wxCommandEvent & WXUNUSED (event))1341 void MyFrame::OnConnect(wxCommandEvent & WXUNUSED(event))
1342 {
1343 //
1344 // connecting to an existent SQLite DB
1345 //
1346   int ret;
1347   wxString lastDir;
1348   wxString suffixList =
1349     wxT("SpatiaLite DB (*.sqlite;*.atlas)|*.sqlite;*.atlas|");
1350   suffixList += wxT("SQLite DB (*.sqlite)|*.sqlite|");
1351   suffixList += wxT("LibreAtlas DB (*.atlas)|*.atlas|");
1352   suffixList += wxT("All files (*.*)|*.*");
1353   wxFileDialog fileDialog(this, wxT("DB connection"),
1354                           wxT(""), wxT("db.sqlite"), suffixList,
1355                           wxFD_OPEN | wxFD_FILE_MUST_EXIST, wxDefaultPosition,
1356                           wxDefaultSize, wxT("filedlg"));
1357   lastDir = GetLastDirectory();
1358   if (lastDir.Len() >= 1)
1359     fileDialog.SetDirectory(lastDir);
1360   ret = fileDialog.ShowModal();
1361   if (ret == wxID_OK)
1362     {
1363       SqlitePath = fileDialog.GetPath();
1364       if (OpenDB() == false)
1365         SqlitePath = wxT("");
1366       else
1367         {
1368           wxFileName file(fileDialog.GetPath());
1369           lastDir = file.GetPath();
1370           SetLastDirectory(lastDir);
1371           bool metadata = CheckMetadata();
1372           wxMenuBar *menuBar = GetMenuBar();
1373           menuBar->Enable(ID_Connect, false);
1374           menuBar->Enable(ID_CreateNew, false);
1375           menuBar->Enable(ID_Disconnect, true);
1376           menuBar->Enable(ID_MemoryDbLoad, false);
1377           menuBar->Enable(ID_MemoryDbNew, false);
1378           if (MemoryDatabase == true)
1379             {
1380               menuBar->Enable(ID_MemoryDbSave, true);
1381               menuBar->Enable(ID_MemoryDbClock, true);
1382           } else
1383             {
1384               menuBar->Enable(ID_MemoryDbSave, false);
1385               menuBar->Enable(ID_MemoryDbClock, false);
1386             }
1387           menuBar->Enable(ID_Vacuum, true);
1388           menuBar->Enable(ID_SqlScript, true);
1389           menuBar->Enable(ID_QueryViewComposer, HasViewsMetadata());
1390           menuBar->Enable(ID_LoadShp, true);
1391           menuBar->Enable(ID_VirtualShp, true);
1392           menuBar->Enable(ID_LoadTxt, true);
1393           menuBar->Enable(ID_VirtualTxt, true);
1394           menuBar->Enable(ID_LoadDbf, true);
1395           menuBar->Enable(ID_VirtualDbf, true);
1396           menuBar->Enable(ID_LoadXL, true);
1397           menuBar->Enable(ID_VirtualXL, true);
1398           menuBar->Enable(ID_Network, true);
1399           menuBar->Enable(ID_Exif, true);
1400           menuBar->Enable(ID_LoadXml, true);
1401           menuBar->Enable(ID_WFS, true);
1402           menuBar->Enable(ID_DXF, true);
1403           menuBar->Enable(ID_Srids, metadata);
1404           menuBar->Enable(ID_Attach, true);
1405           menuBar->Enable(ID_SqlLog, true);
1406           menuBar->Enable(ID_DbStatus, true);
1407           menuBar->Enable(ID_CheckGeom, true);
1408           menuBar->Enable(ID_SaneGeom, true);
1409           EnableSqlLog();
1410           menuBar->Check(ID_SqlLog, SqlLogEnabled);
1411           wxToolBar *toolBar = GetToolBar();
1412           toolBar->EnableTool(ID_Connect, false);
1413           toolBar->EnableTool(ID_CreateNew, false);
1414           toolBar->EnableTool(ID_Disconnect, true);
1415           toolBar->EnableTool(ID_MemoryDbLoad, false);
1416           toolBar->EnableTool(ID_MemoryDbNew, false);
1417           if (MemoryDatabase == true)
1418             {
1419               toolBar->EnableTool(ID_MemoryDbSave, true);
1420               toolBar->EnableTool(ID_MemoryDbClock, true);
1421           } else
1422             {
1423               toolBar->EnableTool(ID_MemoryDbSave, false);
1424               toolBar->EnableTool(ID_MemoryDbClock, false);
1425             }
1426           toolBar->EnableTool(ID_Vacuum, true);
1427           toolBar->EnableTool(ID_SqlScript, true);
1428           toolBar->EnableTool(ID_QueryViewComposer, HasViewsMetadata());
1429           toolBar->EnableTool(ID_LoadShp, true);
1430           toolBar->EnableTool(ID_VirtualShp, true);
1431           toolBar->EnableTool(ID_LoadTxt, true);
1432           toolBar->EnableTool(ID_VirtualTxt, true);
1433           toolBar->EnableTool(ID_LoadDbf, true);
1434           toolBar->EnableTool(ID_VirtualDbf, true);
1435           toolBar->EnableTool(ID_LoadXL, true);
1436           toolBar->EnableTool(ID_VirtualXL, true);
1437           toolBar->EnableTool(ID_Network, true);
1438           toolBar->EnableTool(ID_Exif, true);
1439           toolBar->EnableTool(ID_LoadXml, true);
1440           toolBar->EnableTool(ID_WFS, true);
1441           toolBar->EnableTool(ID_DXF, true);
1442           toolBar->EnableTool(ID_Srids, metadata);
1443           toolBar->EnableTool(ID_Attach, true);
1444           toolBar->EnableTool(ID_SqlLog, true);
1445           toolBar->EnableTool(ID_DbStatus, true);
1446           toolBar->EnableTool(ID_CheckGeom, true);
1447           toolBar->EnableTool(ID_SaneGeom, true);
1448           toolBar->ToggleTool(ID_SqlLog, SqlLogEnabled);
1449           UpdateStatusBar();
1450         }
1451     }
1452   if (AutoFDOmsg.Len() > 0)
1453     {
1454       wxMessageBox(AutoFDOmsg, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION,
1455                    this);
1456       AutoFDOmsg = wxT("");
1457     }
1458 }
1459 
OnDisconnect(wxCommandEvent & WXUNUSED (event))1460 void MyFrame::OnDisconnect(wxCommandEvent & WXUNUSED(event))
1461 {
1462 //
1463 // disconnecting current SQLite DB
1464 //
1465   if (TimerAutoSave)
1466     {
1467       TimerAutoSave->Stop();
1468       delete TimerAutoSave;
1469       TimerAutoSave = NULL;
1470     }
1471   CloseDB();
1472   ExternalSqlitePath = wxT("");
1473   wxMenuBar *menuBar = GetMenuBar();
1474   menuBar->Enable(ID_Connect, true);
1475   menuBar->Enable(ID_CreateNew, true);
1476   menuBar->Enable(ID_Disconnect, false);
1477   menuBar->Enable(ID_MemoryDbLoad, true);
1478   menuBar->Enable(ID_MemoryDbNew, true);
1479   menuBar->Enable(ID_MemoryDbSave, false);
1480   menuBar->Enable(ID_MemoryDbClock, false);
1481   menuBar->Enable(ID_Vacuum, false);
1482   menuBar->Enable(ID_SqlScript, false);
1483   menuBar->Enable(ID_QueryViewComposer, false);
1484   menuBar->Enable(ID_LoadShp, false);
1485   menuBar->Enable(ID_VirtualShp, false);
1486   menuBar->Enable(ID_LoadTxt, false);
1487   menuBar->Enable(ID_VirtualTxt, false);
1488   menuBar->Enable(ID_LoadDbf, false);
1489   menuBar->Enable(ID_VirtualDbf, false);
1490   menuBar->Enable(ID_LoadXL, false);
1491   menuBar->Enable(ID_VirtualXL, false);
1492   menuBar->Enable(ID_Network, false);
1493   menuBar->Enable(ID_Exif, false);
1494   menuBar->Enable(ID_LoadXml, false);
1495   menuBar->Enable(ID_WFS, false);
1496   menuBar->Enable(ID_DXF, false);
1497   menuBar->Enable(ID_Srids, false);
1498   menuBar->Enable(ID_Attach, false);
1499   menuBar->Enable(ID_SqlLog, false);
1500   menuBar->Enable(ID_DbStatus, false);
1501   menuBar->Enable(ID_CheckGeom, false);
1502   menuBar->Enable(ID_SaneGeom, false);
1503   SqlLogEnabled = false;
1504   wxToolBar *toolBar = GetToolBar();
1505   toolBar->EnableTool(ID_Connect, true);
1506   toolBar->EnableTool(ID_CreateNew, true);
1507   toolBar->EnableTool(ID_Disconnect, false);
1508   toolBar->EnableTool(ID_MemoryDbLoad, true);
1509   toolBar->EnableTool(ID_MemoryDbNew, true);
1510   toolBar->EnableTool(ID_MemoryDbSave, false);
1511   toolBar->EnableTool(ID_MemoryDbClock, false);
1512   toolBar->EnableTool(ID_Vacuum, false);
1513   toolBar->EnableTool(ID_SqlScript, false);
1514   toolBar->EnableTool(ID_QueryViewComposer, false);
1515   toolBar->EnableTool(ID_LoadShp, false);
1516   toolBar->EnableTool(ID_VirtualShp, false);
1517   toolBar->EnableTool(ID_LoadTxt, false);
1518   toolBar->EnableTool(ID_VirtualTxt, false);
1519   toolBar->EnableTool(ID_LoadDbf, false);
1520   toolBar->EnableTool(ID_VirtualDbf, false);
1521   toolBar->EnableTool(ID_LoadXL, false);
1522   toolBar->EnableTool(ID_VirtualXL, false);
1523   toolBar->EnableTool(ID_Network, false);
1524   toolBar->EnableTool(ID_Exif, false);
1525   toolBar->EnableTool(ID_LoadXml, false);
1526   toolBar->EnableTool(ID_WFS, false);
1527   toolBar->EnableTool(ID_DXF, false);
1528   toolBar->EnableTool(ID_Srids, false);
1529   toolBar->EnableTool(ID_Attach, false);
1530   toolBar->EnableTool(ID_SqlLog, false);
1531   toolBar->ToggleTool(ID_SqlLog, false);
1532   toolBar->EnableTool(ID_DbStatus, false);
1533   toolBar->ToggleTool(ID_DbStatus, false);
1534   toolBar->EnableTool(ID_CheckGeom, false);
1535   toolBar->ToggleTool(ID_CheckGeom, false);
1536   toolBar->EnableTool(ID_SaneGeom, false);
1537   toolBar->ToggleTool(ID_SaneGeom, false);
1538   UpdateStatusBar();
1539 }
1540 
OnCreateNew(wxCommandEvent & WXUNUSED (event))1541 void MyFrame::OnCreateNew(wxCommandEvent & WXUNUSED(event))
1542 {
1543 //
1544 // creating a new, empty SQLite DB
1545 //
1546   int retdlg;
1547   int ret;
1548   wxString lastDir;
1549   bool metadata;
1550   wxFileDialog fileDialog(this, wxT("Creating a new, empty DB"),
1551                           wxT(""), wxT("db.sqlite"),
1552                           wxT
1553                           ("SQLite DB (*.sqlite)|*.sqlite|All files (*.*)|*.*"),
1554                           wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
1555                           wxDefaultSize, wxT("filedlg"));
1556   lastDir = GetLastDirectory();
1557   if (lastDir.Len() >= 1)
1558     fileDialog.SetDirectory(lastDir);
1559   retdlg = fileDialog.ShowModal();
1560   if (retdlg == wxID_OK)
1561     {
1562       // creating the new DB
1563       SqlitePath = fileDialog.GetPath();
1564       ret = CreateDB();
1565       if (ret == false)
1566         goto error;
1567       metadata = CheckMetadata();
1568       wxFileName file(fileDialog.GetPath());
1569       lastDir = file.GetPath();
1570       SetLastDirectory(lastDir);
1571       wxMenuBar *menuBar = GetMenuBar();
1572       menuBar->Enable(ID_Connect, false);
1573       menuBar->Enable(ID_CreateNew, false);
1574       menuBar->Enable(ID_Disconnect, true);
1575       menuBar->Enable(ID_MemoryDbLoad, false);
1576       menuBar->Enable(ID_MemoryDbNew, false);
1577       menuBar->Enable(ID_MemoryDbSave, false);
1578       menuBar->Enable(ID_MemoryDbClock, false);
1579       menuBar->Enable(ID_Vacuum, true);
1580       menuBar->Enable(ID_SqlScript, true);
1581       menuBar->Enable(ID_QueryViewComposer, HasViewsMetadata());
1582       menuBar->Enable(ID_LoadShp, true);
1583       menuBar->Enable(ID_VirtualShp, true);
1584       menuBar->Enable(ID_LoadTxt, true);
1585       menuBar->Enable(ID_VirtualTxt, true);
1586       menuBar->Enable(ID_LoadDbf, true);
1587       menuBar->Enable(ID_VirtualDbf, true);
1588       menuBar->Enable(ID_LoadXL, true);
1589       menuBar->Enable(ID_VirtualXL, true);
1590       menuBar->Enable(ID_Network, true);
1591       menuBar->Enable(ID_Exif, true);
1592       menuBar->Enable(ID_LoadXml, true);
1593       menuBar->Enable(ID_WFS, true);
1594       menuBar->Enable(ID_DXF, true);
1595       menuBar->Enable(ID_Srids, metadata);
1596       menuBar->Enable(ID_Attach, true);
1597       menuBar->Enable(ID_SqlLog, true);
1598       menuBar->Enable(ID_DbStatus, true);
1599       menuBar->Enable(ID_CheckGeom, true);
1600       menuBar->Enable(ID_SaneGeom, true);
1601       EnableSqlLog();
1602       menuBar->Check(ID_SqlLog, SqlLogEnabled);
1603       wxToolBar *toolBar = GetToolBar();
1604       toolBar->EnableTool(ID_Connect, false);
1605       toolBar->EnableTool(ID_CreateNew, false);
1606       toolBar->EnableTool(ID_Disconnect, true);
1607       toolBar->EnableTool(ID_MemoryDbLoad, false);
1608       toolBar->EnableTool(ID_MemoryDbNew, false);
1609       toolBar->EnableTool(ID_MemoryDbSave, false);
1610       toolBar->EnableTool(ID_MemoryDbClock, false);
1611       toolBar->EnableTool(ID_Vacuum, true);
1612       toolBar->EnableTool(ID_SqlScript, true);
1613       toolBar->EnableTool(ID_QueryViewComposer, HasViewsMetadata());
1614       toolBar->EnableTool(ID_LoadShp, true);
1615       toolBar->EnableTool(ID_VirtualShp, true);
1616       toolBar->EnableTool(ID_LoadTxt, true);
1617       toolBar->EnableTool(ID_VirtualTxt, true);
1618       toolBar->EnableTool(ID_LoadDbf, true);
1619       toolBar->EnableTool(ID_VirtualDbf, true);
1620       toolBar->EnableTool(ID_LoadXL, true);
1621       toolBar->EnableTool(ID_VirtualXL, true);
1622       toolBar->EnableTool(ID_Network, true);
1623       toolBar->EnableTool(ID_Exif, true);
1624       toolBar->EnableTool(ID_LoadXml, true);
1625       toolBar->EnableTool(ID_WFS, true);
1626       toolBar->EnableTool(ID_DXF, true);
1627       toolBar->EnableTool(ID_Srids, metadata);
1628       toolBar->EnableTool(ID_Attach, true);
1629       toolBar->EnableTool(ID_SqlLog, true);
1630       toolBar->EnableTool(ID_DbStatus, true);
1631       toolBar->EnableTool(ID_CheckGeom, true);
1632       toolBar->EnableTool(ID_SaneGeom, true);
1633       toolBar->ToggleTool(ID_SqlLog, SqlLogEnabled);
1634       UpdateStatusBar();
1635       return;
1636   } else
1637     return;
1638 error:
1639   unlink(SqlitePath.ToUTF8());
1640   wxString msg = wxT("An error occurred\nno DB was created");
1641   wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1642   return;
1643 }
1644 
OnMemoryDbLoad(wxCommandEvent & WXUNUSED (event))1645 void MyFrame::OnMemoryDbLoad(wxCommandEvent & WXUNUSED(event))
1646 {
1647 //
1648 // loading an external DB into the MEMORY-DB
1649 //
1650   sqlite3 *extSqlite = NULL;
1651   sqlite3_backup *backup;
1652   int retdlg;
1653   int ret;
1654   wxString lastDir;
1655   char path[1024];
1656   wxString error;
1657   char *errMsg = NULL;
1658   wxFileDialog fileDialog(this,
1659                           wxT("Loading an existing DB into the MEMORY-DB"),
1660                           wxT(""), wxT("db.sqlite"),
1661                           wxT
1662                           ("SQLite DB (*.sqlite)|*.sqlite|All files (*.*)|*.*"),
1663                           wxFD_OPEN | wxFD_FILE_MUST_EXIST, wxDefaultPosition,
1664                           wxDefaultSize, wxT("filedlg"));
1665   lastDir = GetLastDirectory();
1666   if (lastDir.Len() >= 1)
1667     fileDialog.SetDirectory(lastDir);
1668   retdlg = fileDialog.ShowModal();
1669   if (retdlg == wxID_OK)
1670     {
1671       // opening the external DB
1672       ExternalSqlitePath = fileDialog.GetPath();
1673       strcpy(path, ExternalSqlitePath.ToUTF8());
1674       ret = sqlite3_open_v2(path, &extSqlite, SQLITE_OPEN_READWRITE, NULL);
1675       if (ret)
1676         {
1677           // an error occurred
1678           wxString errCause = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
1679           error = wxT("Failure while connecting to DB\n\n");
1680           error += errCause;
1681           error += wxT("\n");
1682           goto stop;
1683         }
1684       ret =
1685         sqlite3_open_v2(":memory:", &SqliteHandle,
1686                         SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
1687       if (ret)
1688         {
1689           // an error occurred
1690           wxString errCause = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
1691           error = wxT("MEMORY-DB: an error occurred \n\n");
1692           error += errCause;
1693           error += +wxT("\n");
1694           goto stop;
1695         }
1696       wxFileName file(fileDialog.GetPath());
1697       lastDir = file.GetPath();
1698       SetLastDirectory(lastDir);
1699       backup = sqlite3_backup_init(SqliteHandle, "main", extSqlite, "main");
1700       if (!backup)
1701         goto stop;
1702       while (1)
1703         {
1704           ret = sqlite3_backup_step(backup, 1024);
1705           if (ret == SQLITE_DONE)
1706             break;
1707         }
1708       ret = sqlite3_backup_finish(backup);
1709       sqlite3_close(extSqlite);
1710 // setting up the internal cache
1711       InternalCache = spatialite_alloc_connection();
1712       spatialite_init_ex(SqliteHandle, InternalCache, 0);
1713 // activating Foreign Key constraints
1714       ret =
1715         sqlite3_exec(SqliteHandle, "PRAGMA foreign_keys = 1", NULL, 0, &errMsg);
1716       if (ret != SQLITE_OK)
1717         {
1718           wxMessageBox(wxT("Unable to activate FOREIGN_KEY constraints"),
1719                        wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
1720           goto stop;
1721         }
1722       MemoryDatabase = true;
1723       AutoSaveInterval = 120;
1724       AutoFDOStart();
1725       InitTableTree();
1726       bool metadata = CheckMetadata();
1727       wxMenuBar *menuBar = GetMenuBar();
1728       menuBar->Enable(ID_Connect, false);
1729       menuBar->Enable(ID_CreateNew, false);
1730       menuBar->Enable(ID_Disconnect, true);
1731       menuBar->Enable(ID_MemoryDbLoad, false);
1732       menuBar->Enable(ID_MemoryDbNew, false);
1733       if (MemoryDatabase == true)
1734         {
1735           menuBar->Enable(ID_MemoryDbSave, true);
1736           menuBar->Enable(ID_MemoryDbClock, true);
1737       } else
1738         {
1739           menuBar->Enable(ID_MemoryDbSave, false);
1740           menuBar->Enable(ID_MemoryDbClock, false);
1741         }
1742       menuBar->Enable(ID_Vacuum, true);
1743       menuBar->Enable(ID_SqlScript, true);
1744       menuBar->Enable(ID_QueryViewComposer, HasViewsMetadata());
1745       menuBar->Enable(ID_LoadShp, true);
1746       menuBar->Enable(ID_VirtualShp, true);
1747       menuBar->Enable(ID_LoadTxt, true);
1748       menuBar->Enable(ID_VirtualTxt, true);
1749       menuBar->Enable(ID_LoadDbf, true);
1750       menuBar->Enable(ID_VirtualDbf, true);
1751       menuBar->Enable(ID_LoadXL, true);
1752       menuBar->Enable(ID_VirtualXL, true);
1753       menuBar->Enable(ID_Network, true);
1754       menuBar->Enable(ID_Exif, true);
1755       menuBar->Enable(ID_LoadXml, true);
1756       menuBar->Enable(ID_WFS, true);
1757       menuBar->Enable(ID_DXF, true);
1758       menuBar->Enable(ID_Srids, metadata);
1759       menuBar->Enable(ID_Attach, true);
1760       menuBar->Enable(ID_SqlLog, true);
1761       menuBar->Enable(ID_DbStatus, true);
1762       menuBar->Enable(ID_CheckGeom, true);
1763       menuBar->Enable(ID_SaneGeom, true);
1764       EnableSqlLog();
1765       menuBar->Check(ID_SqlLog, SqlLogEnabled);
1766       wxToolBar *toolBar = GetToolBar();
1767       toolBar->EnableTool(ID_Connect, false);
1768       toolBar->EnableTool(ID_CreateNew, false);
1769       toolBar->EnableTool(ID_Disconnect, true);
1770       toolBar->EnableTool(ID_MemoryDbLoad, false);
1771       toolBar->EnableTool(ID_MemoryDbNew, false);
1772       if (MemoryDatabase == true)
1773         {
1774           toolBar->EnableTool(ID_MemoryDbSave, true);
1775           toolBar->EnableTool(ID_MemoryDbClock, true);
1776       } else
1777         {
1778           toolBar->EnableTool(ID_MemoryDbSave, false);
1779           toolBar->EnableTool(ID_MemoryDbClock, false);
1780         }
1781       toolBar->EnableTool(ID_Vacuum, true);
1782       toolBar->EnableTool(ID_SqlScript, true);
1783       toolBar->EnableTool(ID_QueryViewComposer, HasViewsMetadata());
1784       toolBar->EnableTool(ID_LoadShp, true);
1785       toolBar->EnableTool(ID_VirtualShp, true);
1786       toolBar->EnableTool(ID_LoadTxt, true);
1787       toolBar->EnableTool(ID_VirtualTxt, true);
1788       toolBar->EnableTool(ID_LoadDbf, true);
1789       toolBar->EnableTool(ID_VirtualDbf, true);
1790       toolBar->EnableTool(ID_LoadXL, true);
1791       toolBar->EnableTool(ID_VirtualXL, true);
1792       toolBar->EnableTool(ID_Network, true);
1793       toolBar->EnableTool(ID_Exif, true);
1794       toolBar->EnableTool(ID_LoadXml, true);
1795       toolBar->EnableTool(ID_WFS, true);
1796       toolBar->EnableTool(ID_DXF, true);
1797       toolBar->EnableTool(ID_Srids, metadata);
1798       toolBar->EnableTool(ID_Attach, true);
1799       toolBar->EnableTool(ID_SqlLog, true);
1800       toolBar->EnableTool(ID_DbStatus, true);
1801       toolBar->EnableTool(ID_CheckGeom, true);
1802       toolBar->EnableTool(ID_SaneGeom, true);
1803       toolBar->ToggleTool(ID_SqlLog, SqlLogEnabled);
1804       UpdateStatusBar();
1805       if (AutoSaveInterval <= 0)
1806         {
1807           if (TimerAutoSave)
1808             {
1809               TimerAutoSave->Stop();
1810               delete TimerAutoSave;
1811               TimerAutoSave = NULL;
1812             }
1813       } else
1814         {
1815           //
1816           // starting the AutoSave timer
1817           //
1818           if (!TimerAutoSave)
1819             TimerAutoSave = new wxTimer(this, ID_AUTO_SAVE_TIMER);
1820           else
1821             TimerAutoSave->Stop();
1822           LastTotalChanges = 0;
1823           TimerAutoSave->Start(AutoSaveInterval * 1000, wxTIMER_ONE_SHOT);
1824         }
1825     }
1826   if (AutoFDOmsg.Len() > 0)
1827     {
1828       wxMessageBox(AutoFDOmsg, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION,
1829                    this);
1830       AutoFDOmsg = wxT("");
1831     }
1832   return;
1833 stop:
1834   MemoryDatabase = false;
1835   if (SqliteHandle)
1836     sqlite3_close(SqliteHandle);
1837   if (extSqlite)
1838     sqlite3_close(extSqlite);
1839   if (InternalCache)
1840     spatialite_cleanup_ex(InternalCache);
1841   wxString msg = wxT("MEMORY-DB wasn't loaded\n\n");
1842   msg += error;
1843   wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1844   SqliteHandle = NULL;
1845   InternalCache = NULL;
1846 }
1847 
OnMemoryDbNew(wxCommandEvent & WXUNUSED (event))1848 void MyFrame::OnMemoryDbNew(wxCommandEvent & WXUNUSED(event))
1849 {
1850 //
1851 //creating a new MEMORY-DB
1852 //
1853   int ret;
1854   wxToolBar *toolBar;
1855   wxMenuBar *menuBar;
1856   bool metadata;
1857   MemoryDatabase = true;
1858   AutoSaveInterval = 120;
1859   ExternalSqlitePath = wxT("");
1860 // creating the new MEMORY-DB
1861   ret = CreateDB();
1862   if (ret == false)
1863     goto error;
1864   metadata = CheckMetadata();
1865   menuBar = GetMenuBar();
1866   menuBar->Enable(ID_Connect, false);
1867   menuBar->Enable(ID_CreateNew, false);
1868   menuBar->Enable(ID_Disconnect, true);
1869   menuBar->Enable(ID_MemoryDbLoad, false);
1870   menuBar->Enable(ID_MemoryDbNew, false);
1871   menuBar->Enable(ID_MemoryDbSave, true);
1872   menuBar->Enable(ID_MemoryDbClock, true);
1873   menuBar->Enable(ID_Vacuum, true);
1874   menuBar->Enable(ID_SqlScript, true);
1875   menuBar->Enable(ID_QueryViewComposer, HasViewsMetadata());
1876   menuBar->Enable(ID_LoadShp, true);
1877   menuBar->Enable(ID_VirtualShp, true);
1878   menuBar->Enable(ID_LoadTxt, true);
1879   menuBar->Enable(ID_VirtualTxt, true);
1880   menuBar->Enable(ID_LoadDbf, true);
1881   menuBar->Enable(ID_VirtualDbf, true);
1882   menuBar->Enable(ID_LoadXL, true);
1883   menuBar->Enable(ID_VirtualXL, true);
1884   menuBar->Enable(ID_Network, true);
1885   menuBar->Enable(ID_Exif, true);
1886   menuBar->Enable(ID_LoadXml, true);
1887   menuBar->Enable(ID_WFS, true);
1888   menuBar->Enable(ID_DXF, true);
1889   menuBar->Enable(ID_Srids, metadata);
1890   menuBar->Enable(ID_Attach, true);
1891   menuBar->Enable(ID_SqlLog, true);
1892   menuBar->Enable(ID_DbStatus, true);
1893   menuBar->Enable(ID_CheckGeom, true);
1894   menuBar->Enable(ID_SaneGeom, true);
1895   EnableSqlLog();
1896   menuBar->Check(ID_SqlLog, SqlLogEnabled);
1897   toolBar = GetToolBar();
1898   toolBar->EnableTool(ID_Connect, false);
1899   toolBar->EnableTool(ID_CreateNew, false);
1900   toolBar->EnableTool(ID_Disconnect, true);
1901   toolBar->EnableTool(ID_MemoryDbLoad, false);
1902   toolBar->EnableTool(ID_MemoryDbNew, false);
1903   toolBar->EnableTool(ID_MemoryDbSave, true);
1904   toolBar->EnableTool(ID_MemoryDbClock, true);
1905   toolBar->EnableTool(ID_Vacuum, true);
1906   toolBar->EnableTool(ID_SqlScript, true);
1907   toolBar->EnableTool(ID_QueryViewComposer, HasViewsMetadata());
1908   toolBar->EnableTool(ID_LoadShp, true);
1909   toolBar->EnableTool(ID_VirtualShp, true);
1910   toolBar->EnableTool(ID_LoadTxt, true);
1911   toolBar->EnableTool(ID_VirtualTxt, true);
1912   toolBar->EnableTool(ID_LoadDbf, true);
1913   toolBar->EnableTool(ID_VirtualDbf, true);
1914   toolBar->EnableTool(ID_LoadXL, true);
1915   toolBar->EnableTool(ID_VirtualXL, true);
1916   toolBar->EnableTool(ID_Network, true);
1917   toolBar->EnableTool(ID_Exif, true);
1918   toolBar->EnableTool(ID_LoadXml, true);
1919   toolBar->EnableTool(ID_WFS, true);
1920   toolBar->EnableTool(ID_DXF, true);
1921   toolBar->EnableTool(ID_Srids, metadata);
1922   toolBar->EnableTool(ID_Attach, true);
1923   toolBar->EnableTool(ID_SqlLog, true);
1924   toolBar->EnableTool(ID_DbStatus, true);
1925   toolBar->EnableTool(ID_CheckGeom, true);
1926   toolBar->EnableTool(ID_SaneGeom, true);
1927   toolBar->ToggleTool(ID_SqlLog, SqlLogEnabled);
1928   UpdateStatusBar();
1929   if (AutoSaveInterval <= 0)
1930     {
1931       if (TimerAutoSave)
1932         {
1933           TimerAutoSave->Stop();
1934           delete TimerAutoSave;
1935           TimerAutoSave = NULL;
1936         }
1937   } else
1938     {
1939       //
1940       // starting the AutoSave timer
1941       //
1942       if (!TimerAutoSave)
1943         TimerAutoSave = new wxTimer(this, ID_AUTO_SAVE_TIMER);
1944       else
1945         TimerAutoSave->Stop();
1946       LastTotalChanges = 0;
1947       TimerAutoSave->Start(AutoSaveInterval * 1000, wxTIMER_ONE_SHOT);
1948     }
1949   return;
1950 error:
1951   wxString msg = wxT("An error occurred\nno MEMORY-DB was created");
1952   wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1953   return;
1954 }
1955 
MemoryDbSave()1956 bool MyFrame::MemoryDbSave()
1957 {
1958 //
1959 // trying to export the MEMORY-DB into an external DB
1960 //
1961   sqlite3 *extSqlite = NULL;
1962   sqlite3_backup *backup;
1963   char path[1024];
1964   char bak_path[1024];
1965   int ret;
1966   wxString error;
1967   if (ExternalSqlitePath.Len() == 0)
1968     return false;
1969   ::wxBeginBusyCursor();
1970   strcpy(path, ExternalSqlitePath.ToUTF8());
1971   strcpy(bak_path, path);
1972   strcat(bak_path, ".bak");
1973   unlink(bak_path);
1974   rename(path, bak_path);
1975   ret =
1976     sqlite3_open_v2(path, &extSqlite,
1977                     SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
1978   if (ret)
1979     {
1980       // an error occurred
1981       wxString errCause = wxString::FromUTF8(sqlite3_errmsg(extSqlite));
1982       error = wxT("An error occurred\n\n");
1983       error += errCause;
1984       error += +wxT("\n");
1985       error += ExternalSqlitePath;
1986       goto stop;
1987     }
1988   backup = sqlite3_backup_init(extSqlite, "main", SqliteHandle, "main");
1989   if (!backup)
1990     goto stop;
1991   while (1)
1992     {
1993       ret = sqlite3_backup_step(backup, 1024);
1994       if (ret == SQLITE_DONE)
1995         break;
1996     }
1997   ret = sqlite3_backup_finish(backup);
1998   sqlite3_close(extSqlite);
1999   unlink(bak_path);
2000   ::wxEndBusyCursor();
2001   LastTotalChanges = sqlite3_total_changes(SqliteHandle);
2002   return true;
2003 stop:
2004   if (extSqlite)
2005     sqlite3_close(extSqlite);
2006   wxString msg = wxT("Backup failure: MEMORY-DB wasn't saved\n\n");
2007   msg += error;
2008   wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2009   ExternalSqlitePath = wxT("");
2010   ::wxEndBusyCursor();
2011   return false;
2012 }
2013 
OnMemoryDbSave(wxCommandEvent & WXUNUSED (event))2014 void MyFrame::OnMemoryDbSave(wxCommandEvent & WXUNUSED(event))
2015 {
2016 //
2017 //  exporting the MEMORY-DB into an external DB
2018 //
2019   int retdlg;
2020   wxString lastDir;
2021   if (ExternalSqlitePath.Len() > 0)
2022     {
2023       if (MemoryDbSave() == true)
2024         {
2025           wxMessageBox(wxT("Ok, MEMORY-DB was succesfully saved"),
2026                        wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
2027           if (AutoSaveInterval <= 0)
2028             {
2029               if (TimerAutoSave)
2030                 {
2031                   TimerAutoSave->Stop();
2032                   delete TimerAutoSave;
2033                   TimerAutoSave = NULL;
2034                 }
2035           } else
2036             {
2037               //
2038               // restarting the AutoSave timer
2039               //
2040               if (!TimerAutoSave)
2041                 TimerAutoSave = new wxTimer(this, ID_AUTO_SAVE_TIMER);
2042               else
2043                 TimerAutoSave->Stop();
2044               TimerAutoSave->Start(AutoSaveInterval * 1000, wxTIMER_ONE_SHOT);
2045             }
2046           return;
2047         }
2048     }
2049   wxFileDialog fileDialog(this, wxT("Saving the MEMORY-DB"),
2050                           wxT(""), wxT("db.sqlite"),
2051                           wxT
2052                           ("SQLite DB (*.sqlite)|*.sqlite|All files (*.*)|*.*"),
2053                           wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
2054                           wxDefaultSize, wxT("filedlg"));
2055   lastDir = GetLastDirectory();
2056   if (lastDir.Len() >= 1)
2057     fileDialog.SetDirectory(lastDir);
2058   retdlg = fileDialog.ShowModal();
2059   if (retdlg == wxID_OK)
2060     {
2061       // exporting the external DB
2062       ExternalSqlitePath = fileDialog.GetPath();
2063       if (MemoryDbSave() == true)
2064         {
2065           wxMessageBox(wxT("Ok, MEMORY-DB was succesfully saved"),
2066                        wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
2067           wxFileName file(fileDialog.GetPath());
2068           lastDir = file.GetPath();
2069           SetLastDirectory(lastDir);
2070           if (AutoSaveInterval <= 0)
2071             {
2072               if (TimerAutoSave)
2073                 {
2074                   TimerAutoSave->Stop();
2075                   delete TimerAutoSave;
2076                   TimerAutoSave = NULL;
2077                 }
2078           } else
2079             {
2080               //
2081               // restarting the AutoSave timer
2082               //
2083               if (!TimerAutoSave)
2084                 TimerAutoSave = new wxTimer(this, ID_AUTO_SAVE_TIMER);
2085               else
2086                 TimerAutoSave->Stop();
2087               TimerAutoSave->Start(AutoSaveInterval * 1000, wxTIMER_ONE_SHOT);
2088             }
2089         }
2090     }
2091 }
2092 
OnMemoryDbClock(wxCommandEvent & WXUNUSED (event))2093 void MyFrame::OnMemoryDbClock(wxCommandEvent & WXUNUSED(event))
2094 {
2095 //
2096 //  setting up AutoSave for MEMORY-DB
2097 //
2098   AutoSaveDialog dlg;
2099   dlg.Create(this, ExternalSqlitePath, AutoSaveInterval);
2100   int ret = dlg.ShowModal();
2101   if (ret == wxID_OK)
2102     {
2103       AutoSaveInterval = dlg.GetSeconds();
2104       if (AutoSaveInterval <= 0)
2105         {
2106           //
2107           // stopping the AutoSave timer
2108           //
2109           if (TimerAutoSave)
2110             {
2111               TimerAutoSave->Stop();
2112               delete TimerAutoSave;
2113               TimerAutoSave = NULL;
2114             }
2115       } else
2116         {
2117           //
2118           // restarting the AutoSave timer
2119           //
2120           if (!TimerAutoSave)
2121             TimerAutoSave = new wxTimer(this, ID_AUTO_SAVE_TIMER);
2122           else
2123             TimerAutoSave->Stop();
2124           TimerAutoSave->Start(AutoSaveInterval * 1000, wxTIMER_ONE_SHOT);
2125         }
2126     }
2127 }
2128 
DbPagesCount(int * total,int * frees)2129 void MyFrame::DbPagesCount(int *total, int *frees)
2130 {
2131 //
2132 // computing the DB pages count
2133 //
2134   int ret;
2135   char **results;
2136   int rows;
2137   int columns;
2138   int i;
2139   char *errMsg = NULL;
2140   wxString sql;
2141   char *value;
2142   *total = 0;
2143   *frees = 0;
2144   sql = wxT("PRAGMA page_count");
2145   ret = sqlite3_get_table(GetSqlite(), sql.ToUTF8(), &results,
2146                           &rows, &columns, &errMsg);
2147   if (ret != SQLITE_OK)
2148     {
2149       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2150                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2151       sqlite3_free(errMsg);
2152       return;
2153     }
2154   if (rows < 1)
2155     ;
2156   else
2157     {
2158       for (i = 1; i <= rows; i++)
2159         {
2160           value = results[(i * columns) + 0];
2161           *total = atoi(value);
2162         }
2163     }
2164   sqlite3_free_table(results);
2165   sql = wxT("PRAGMA freelist_count");
2166   ret = sqlite3_get_table(GetSqlite(), sql.ToUTF8(), &results,
2167                           &rows, &columns, &errMsg);
2168   if (ret != SQLITE_OK)
2169     {
2170       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2171                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2172       sqlite3_free(errMsg);
2173       return;
2174     }
2175   if (rows < 1)
2176     ;
2177   else
2178     {
2179       for (i = 1; i <= rows; i++)
2180         {
2181           value = results[(i * columns) + 0];
2182           *frees = atoi(value);
2183         }
2184     }
2185   sqlite3_free_table(results);
2186 }
2187 
GetLwGeomVersion(char * buf)2188 bool MyFrame::GetLwGeomVersion(char *buf)
2189 {
2190 //
2191 // retieving the LWGEOM version (if enabled)
2192 //
2193   int ret;
2194   char **results;
2195   int rows;
2196   int columns;
2197   int i;
2198   bool ok = false;
2199 
2200   if (GetSqlite() == NULL)
2201     return false;
2202   ret = sqlite3_get_table(GetSqlite(), "SELECT lwgeom_version()", &results,
2203                           &rows, &columns, NULL);
2204   if (ret != SQLITE_OK)
2205     return false;
2206   if (rows < 1)
2207     ;
2208   else
2209     {
2210       for (i = 1; i <= rows; i++)
2211         {
2212           const char *version = results[(i * columns) + 0];
2213           if (version != NULL)
2214             {
2215               strcpy(buf, version);
2216               ok = true;
2217             }
2218         }
2219     }
2220   sqlite3_free_table(results);
2221   return ok;
2222 }
2223 
GetLibXml2Version(char * buf)2224 bool MyFrame::GetLibXml2Version(char *buf)
2225 {
2226 //
2227 // retieving the LIBXML2 version (if enabled)
2228 //
2229   int ret;
2230   char **results;
2231   int rows;
2232   int columns;
2233   int i;
2234   bool ok = false;
2235 
2236   if (GetSqlite() == NULL)
2237     return false;
2238   ret = sqlite3_get_table(GetSqlite(), "SELECT libxml2_version()", &results,
2239                           &rows, &columns, NULL);
2240   if (ret != SQLITE_OK)
2241     return false;
2242   if (rows < 1)
2243     ;
2244   else
2245     {
2246       for (i = 1; i <= rows; i++)
2247         {
2248           const char *version = results[(i * columns) + 0];
2249           if (version != NULL)
2250             {
2251               strcpy(buf, version);
2252               ok = true;
2253             }
2254         }
2255     }
2256   sqlite3_free_table(results);
2257   return ok;
2258 }
2259 
OnVacuum(wxCommandEvent & WXUNUSED (event))2260 void MyFrame::OnVacuum(wxCommandEvent & WXUNUSED(event))
2261 {
2262 //
2263 // performing a VACUUM in order to reorganize the current DB
2264 //
2265   char *errMsg = NULL;
2266   int totalPages;
2267   int freePages;
2268   int totalPages2;
2269   int freePages2;
2270   wxString msg;
2271   char dummy[128];
2272   DbPagesCount(&totalPages, &freePages);
2273   if (!freePages)
2274     {
2275       msg = wxT("The current DB doesn't requires to be VACUUMed\n\n");
2276       msg += wxT("Total Pages: ");
2277       sprintf(dummy, "%d\n", totalPages);
2278       msg += wxString::FromUTF8(dummy);
2279       msg += wxT("Free Pages: 0\n\n");
2280       msg += wxT("Free Ratio: 0.0%");
2281       wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
2282       return;
2283   } else
2284     {
2285       double ratio = 100.0 / ((double) totalPages / (double) freePages);
2286       if (ratio >= 33.33)
2287         msg = wxT("The current DB urgently requires to be VACUUMed\n\n");
2288       else if (ratio >= 10.0)
2289         msg = wxT("The current DB may usefully be VACUUMed\n\n");
2290       else
2291         msg =
2292           wxT("The current DB doesn't strictly requires to be VACUUMed\n\n");
2293       msg += wxT("Total Pages: ");
2294       sprintf(dummy, "%d\n", totalPages);
2295       msg += wxString::FromUTF8(dummy);
2296       msg += wxT("Free Pages: ");
2297       sprintf(dummy, "%d\n\n", freePages);
2298       msg += wxString::FromUTF8(dummy);
2299       msg += wxT("Free Ratio: ");
2300       sprintf(dummy, "%1.2f%%\n", ratio);
2301       msg += wxString::FromUTF8(dummy);
2302       msg += wxT("\n\nDo you confirm VACUUMing the current DB ?");
2303       int ret =
2304         wxMessageBox(msg, wxT("spatialite_gui"), wxYES_NO | wxICON_QUESTION,
2305                      this);
2306       if (ret != wxYES)
2307         return;
2308     }
2309   ::wxBeginBusyCursor();
2310   int ret = sqlite3_exec(SqliteHandle, "ANALYZE; VACUUM;", NULL, NULL, &errMsg);
2311   if (ret != SQLITE_OK)
2312     {
2313       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2314                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2315       sqlite3_free(errMsg);
2316   } else
2317     {
2318       DbPagesCount(&totalPages2, &freePages2);
2319       msg = wxT("Current DB was succesfully optimized");
2320       if (totalPages2 < totalPages)
2321         {
2322           sprintf(dummy, "\n\n%d unused pages where reclaimed",
2323                   totalPages - totalPages2);
2324           msg += wxString::FromUTF8(dummy);
2325         }
2326       wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
2327     }
2328   ::wxEndBusyCursor();
2329 }
2330 
ReadSqlLine(FILE * in,int * len,int * eof)2331 char *MyFrame::ReadSqlLine(FILE * in, int *len, int *eof)
2332 {
2333 //
2334 // reading an SQL script line
2335 //
2336   int c;
2337   *eof = 0;
2338   int size = 4096;
2339   char *line = (char *) malloc(size);
2340   int off = 0;
2341   while ((c = getc(in)) != EOF)
2342     {
2343       // consuming input one chat at each time
2344       if (off == size)
2345         {
2346           // buffer overflow; reallocating a bigger one
2347           // presumably this is because there is some BLOB, so we'll grow by 1MB at each time
2348           size += 1024 * 1024;
2349           line = (char *) realloc(line, size);
2350         }
2351       *(line + off) = c;
2352       off++;
2353       if (c == '\n')
2354         {
2355           // end of line marker
2356           *(line + off) = '\0';
2357           *len = off;
2358           return line;
2359         }
2360       if (c == ';')
2361         {
2362           // end of SQL statement marker
2363           *(line + off) = '\0';
2364           *len = off;
2365           return line;
2366         }
2367     }
2368 // EOF reached
2369   *len = off;
2370   *eof = 1;
2371   return line;
2372 }
2373 
OnQueryViewComposer(wxCommandEvent & WXUNUSED (event))2374 void MyFrame::OnQueryViewComposer(wxCommandEvent & WXUNUSED(event))
2375 {
2376 //
2377 // invoking the Query/View composer tool
2378 //
2379   QueryViewComposer();
2380 }
2381 
OnSqlScript(wxCommandEvent & WXUNUSED (event))2382 void MyFrame::OnSqlScript(wxCommandEvent & WXUNUSED(event))
2383 {
2384 //
2385 // executing an SQL Script
2386 //
2387   int ret;
2388   wxString lastDir;
2389   wxString path;
2390   wxString charset;
2391   FILE *sql;
2392   char *line = NULL;
2393   char *statement = NULL;
2394   int stmt_len = 0;
2395   char *prev_stmt;
2396   int prev_len;
2397   int eof;
2398   int rowNo = 1;
2399   int stmt = 0;
2400   int len;
2401   wxString msg;
2402   char dummy[128];
2403   void *cvtCS = NULL;
2404   char *utf8stmt = NULL;
2405   int cvtErr;
2406   char x_path[1024];
2407   char x_table[1024];
2408   char x_column[1024];
2409   char x_charset[1024];
2410   char x_type[1024];
2411   int rows;
2412   unsigned int urows;
2413   wxString extPath;
2414   wxString extTable;
2415   wxString extCharset;
2416   wxString extColumn;
2417   wxString extType;
2418   int extWorksheetIndex;
2419   int extFirstTitle;
2420   int srid;
2421   bool coerce2D;
2422   bool compressed;
2423   int command;
2424   bool stmtDone;
2425   wxString workingDir;
2426   wxFileDialog fileDialog(this, wxT("SQL Script"),
2427                           wxT(""),
2428                           wxT("init_spatialite.sql"),
2429                           wxT("SQL script (*.sql)|*.sql|All files (*.*)|*.*"),
2430                           wxFD_OPEN | wxFD_FILE_MUST_EXIST,
2431                           wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
2432   lastDir = GetLastDirectory();
2433   if (lastDir.Len() >= 1)
2434     fileDialog.SetDirectory(lastDir);
2435   ret = fileDialog.ShowModal();
2436   if (ret == wxID_OK)
2437     {
2438       path = fileDialog.GetPath();
2439       SqlScriptDialog dlg;
2440       dlg.Create(this, path, LocaleCharset);
2441       ret = dlg.ShowModal();
2442       if (ret == wxID_OK)
2443         charset = dlg.GetCharset();
2444       else
2445         return;
2446       // opening the SQL script
2447       sql = fopen(path.ToUTF8(), "r");
2448       if (sql == NULL)
2449         {
2450           wxMessageBox(wxT("can't open: ") + fileDialog.GetPath(),
2451                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2452       } else
2453         {
2454           wxFileName file(fileDialog.GetPath());
2455           lastDir = file.GetPath();
2456           SetLastDirectory(lastDir);
2457           cvtCS = gaiaCreateUTF8Converter(charset.ToUTF8());
2458           if (!cvtCS)
2459             {
2460               msg = charset + wxT(": unsupported CharacterSet");
2461               wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_WARNING,
2462                            this);
2463               goto stop;
2464             }
2465           ::wxBeginBusyCursor();
2466           workingDir = wxGetCwd();
2467           wxSetWorkingDirectory(lastDir);
2468           while (1)
2469             {
2470               // reading the SQL script lines
2471               line = ReadSqlLine(sql, &len, &eof);
2472               if (len > 0)
2473                 {
2474                   if (statement == NULL)
2475                     {
2476                       statement = line;
2477                       stmt_len = len;
2478                   } else
2479                     {
2480                       // appending line to SQL statement
2481                       prev_stmt = statement;
2482                       prev_len = stmt_len;
2483                       stmt_len = prev_len + len;
2484                       statement = (char *) malloc(stmt_len + 1);
2485                       memcpy(statement, prev_stmt, prev_len);
2486                       memcpy(statement + prev_len, line, len);
2487                       *(statement + stmt_len) = '\0';
2488                       free(prev_stmt);
2489                       free(line);
2490                       line = NULL;
2491                     }
2492               } else
2493                 {
2494                   free(line);
2495                   line = NULL;
2496                 }
2497               if (statement)
2498                 {
2499                   stmtDone = false;
2500                   command = TestDotCommand(statement);
2501                   if (command == CMD_SQLLOG)
2502                     {
2503                       // simply ignoring
2504                       free(statement);
2505                       statement = NULL;
2506                       stmt_len = 0;
2507                       stmt++;
2508                       stmtDone = true;
2509                     }
2510                   if (command == CMD_LOADSHP || command == CMD_LOADDBF
2511                       || command == CMD_LOADXL || command == CMD_DUMPSHP
2512                       || command == CMD_DUMPDBF)
2513                     {
2514                       utf8stmt =
2515                         gaiaConvertToUTF8(cvtCS, statement + 9, stmt_len,
2516                                           &cvtErr);
2517                       if (cvtErr || !utf8stmt)
2518                         {
2519                           Rollback();
2520                           msg =
2521                             wxT
2522                             ("SQL Script abnormal termination\nillegal character sequence");
2523                           msg +=
2524                             wxT("\n\nROLLBACK was automatically performed");
2525                           wxMessageBox(msg, wxT("spatialite_gui"),
2526                                        wxOK | wxICON_WARNING, this);
2527                           goto stop;
2528                         }
2529                       if (command == CMD_LOADSHP)
2530                         {
2531                           if (IsDotCommandLoadShp
2532                               (utf8stmt, x_path, x_table, x_charset,
2533                                x_column, &srid, &coerce2D, &compressed))
2534                             {
2535                               load_shapefile(SqliteHandle, x_path, x_table,
2536                                              x_charset, srid, x_column,
2537                                              coerce2D, compressed, 0, 0, &rows,
2538                                              NULL);
2539                               free(statement);
2540                               statement = NULL;
2541                               stmt_len = 0;
2542                               stmt++;
2543                               stmtDone = true;
2544                             }
2545                         }
2546                       if (command == CMD_LOADDBF)
2547                         {
2548                           if (IsDotCommandLoadDbf
2549                               (utf8stmt, x_path, x_table, x_charset) == true)
2550                             {
2551                               load_dbf(SqliteHandle, x_path, x_table, x_charset,
2552                                        0, &rows, NULL);
2553                               free(statement);
2554                               statement = NULL;
2555                               stmt_len = 0;
2556                               stmt++;
2557                               stmtDone = true;
2558                             }
2559                         }
2560                       if (command == CMD_LOADXL)
2561                         {
2562                           if (IsDotCommandLoadXL
2563                               (utf8stmt, x_path, x_table, &extWorksheetIndex,
2564                                &extFirstTitle) == true)
2565                             {
2566 #ifndef OMIT_FREEXL             /* only if FreeXL is enabled */
2567                               load_XL(SqliteHandle, x_path, x_table,
2568                                       extWorksheetIndex, extFirstTitle, &urows,
2569                                       NULL);
2570                               free(statement);
2571                               statement = NULL;
2572                               stmt_len = 0;
2573                               stmt++;
2574                               stmtDone = true;
2575 #else /* FreeXL isn't enabled */
2576                               stmtDone = false;
2577 #endif /* end FreeXL conditional support */
2578                             }
2579                         }
2580                       if (command == CMD_DUMPSHP)
2581                         {
2582                           if (IsDotCommandDumpShp
2583                               (utf8stmt, x_table, x_column, x_path,
2584                                x_charset, x_type) == true)
2585                             {
2586                               dump_shapefile(SqliteHandle, x_table, x_column,
2587                                              x_path, x_charset, x_type, 0,
2588                                              &rows, NULL);
2589                               free(statement);
2590                               statement = NULL;
2591                               stmt_len = 0;
2592                               stmt++;
2593                               stmtDone = true;
2594                             }
2595                         }
2596                       free(utf8stmt);
2597                       utf8stmt = NULL;
2598                     }
2599                   if (stmtDone)
2600                     ;
2601                   else if (sqlite3_complete(statement))
2602                     {
2603                       // executing the SQL statement
2604                       utf8stmt =
2605                         gaiaConvertToUTF8(cvtCS, statement, stmt_len, &cvtErr);
2606                       free(statement);
2607                       statement = NULL;
2608                       stmt_len = 0;
2609                       if (cvtErr || !utf8stmt)
2610                         {
2611                           Rollback();
2612                           msg =
2613                             wxT
2614                             ("SQL Script abnormal termination\nillegal character sequence");
2615                           msg +=
2616                             wxT("\n\nROLLBACK was automatically performed");
2617                           wxMessageBox(msg, wxT("spatialite_gui"),
2618                                        wxOK | wxICON_WARNING, this);
2619                           goto stop;
2620                         }
2621                       if (ExecuteSql(utf8stmt, rowNo) == false)
2622                         {
2623                           Rollback();
2624                           msg =
2625                             wxT
2626                             ("SQL Script abnormal termination\nan error occurred");
2627                           msg +=
2628                             wxT("\n\nROLLBACK was automatically performed");
2629                           wxMessageBox(msg, wxT("spatialite_gui"),
2630                                        wxOK | wxICON_WARNING, this);
2631                           goto stop;
2632                       } else
2633                         {
2634                           stmt++;
2635                           free(utf8stmt);
2636                           utf8stmt = NULL;
2637                         }
2638                     }
2639                 }
2640               rowNo++;
2641               if (eof)
2642                 break;
2643             }
2644           sprintf(dummy,
2645                   "SQL Script normal termination\n\n%d SQL statements where performed",
2646                   stmt);
2647           msg = wxString::FromUTF8(dummy);
2648           wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION,
2649                        this);
2650         stop:
2651           if (cvtCS)
2652             gaiaFreeUTF8Converter(cvtCS);
2653           if (utf8stmt)
2654             free(utf8stmt);
2655           if (statement)
2656             free(statement);
2657           if (line)
2658             free(line);
2659           fclose(sql);
2660           wxSetWorkingDirectory(workingDir);
2661           ::wxEndBusyCursor();
2662         }
2663     }
2664 }
2665 
OnLoadShp(wxCommandEvent & WXUNUSED (event))2666 void MyFrame::OnLoadShp(wxCommandEvent & WXUNUSED(event))
2667 {
2668 //
2669 // loading a shapefile
2670 //
2671   int ret;
2672   wxString table;
2673   wxString column = wxT("Geometry");
2674   wxString charset;
2675   int srid = 0;
2676   int coerce2D;
2677   int compressed;
2678   int spatial_index;
2679   wxString path;
2680   wxString lastDir;
2681   wxFileDialog fileDialog(this, wxT("Load Shapefile"),
2682                           wxT(""),
2683                           wxT("shapefile.shp"),
2684                           wxT("Shapefile (*.shp)|*.shp|All files (*.*)|*.*"),
2685                           wxFD_OPEN | wxFD_FILE_MUST_EXIST,
2686                           wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
2687   if (GetMetaDataType() != METADATA_CURRENT)
2688     srid = -1;                  // old default SRID
2689   lastDir = GetLastDirectory();
2690   if (lastDir.Len() >= 1)
2691     fileDialog.SetDirectory(lastDir);
2692   ret = fileDialog.ShowModal();
2693   if (ret == wxID_OK)
2694     {
2695       wxFileName file(fileDialog.GetPath());
2696       lastDir = file.GetPath();
2697       table = file.GetName();
2698       path = file.GetPath();
2699       path += file.GetPathSeparator();
2700       path += file.GetName();
2701       LoadShpDialog dlg;
2702       dlg.Create(this, path, table, srid, column, LocaleCharset);
2703       ret = dlg.ShowModal();
2704       if (ret == wxID_OK)
2705         {
2706           int rt;
2707           int rows;
2708           char x_path[1024];
2709           char x_table[1024];
2710           char x_column[1024];
2711           char x_gtype[1024];
2712           char *gtype;
2713           char x_pkey[1024];
2714           char *pkey;
2715           char x_charset[1024];
2716           char err_msg[1024];
2717           SetLastDirectory(lastDir);
2718           strcpy(x_path, path.ToUTF8());
2719           strcpy(x_table, dlg.GetTable().ToUTF8());
2720           srid = dlg.GetSrid();
2721           strcpy(x_column, dlg.GetColumn().ToUTF8());
2722           strcpy(x_charset, dlg.GetCharset().ToUTF8());
2723           if (dlg.ApplyCoertion2D() == true)
2724             coerce2D = 1;
2725           else
2726             coerce2D = 0;
2727           if (dlg.ApplyCompression() == true)
2728             compressed = 1;
2729           else
2730             compressed = 0;
2731           if (dlg.CreateSpatialIndex() == true)
2732             spatial_index = 1;
2733           else
2734             spatial_index = 0;
2735           if (dlg.IsUserDefinedGType() == false)
2736             gtype = NULL;
2737           else
2738             {
2739               strcpy(x_gtype, dlg.GetGeometryType().ToUTF8());
2740               gtype = x_gtype;
2741             }
2742           if (dlg.IsUserDefinedPKey() == false)
2743             pkey = NULL;
2744           else
2745             {
2746               strcpy(x_pkey, dlg.GetPKColumn().ToUTF8());
2747               pkey = x_pkey;
2748             }
2749           ::wxBeginBusyCursor();
2750           rt = load_shapefile_ex(SqliteHandle, x_path, x_table, x_charset, srid,
2751                                  x_column, gtype, pkey, coerce2D, compressed, 0,
2752                                  spatial_index, &rows, err_msg);
2753           ::wxEndBusyCursor();
2754           if (rt)
2755             {
2756               wxMessageBox(wxT("load shp OK:") +
2757                            wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
2758                            wxOK | wxICON_INFORMATION, this);
2759               InitTableTree();
2760           } else
2761             wxMessageBox(wxT("load shp error:") +
2762                          wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
2763                          wxOK | wxICON_ERROR, this);
2764         }
2765     }
2766 }
2767 
OnVirtualShp(wxCommandEvent & WXUNUSED (event))2768 void MyFrame::OnVirtualShp(wxCommandEvent & WXUNUSED(event))
2769 {
2770 //
2771 // creating a VirtualShape
2772 //
2773   int ret;
2774   wxString charset;
2775   int srid;
2776   char dummy[128];
2777   wxString sql;
2778   wxString path;
2779   wxString table;
2780   wxString lastDir;
2781   wxString geometryType;
2782   char *errMsg = NULL;
2783   char xname[1024];
2784   sqlite3 *sqlite = GetSqlite();
2785   wxFileDialog fileDialog(this, wxT("VirtualShape"),
2786                           wxT(""),
2787                           wxT("shapefile.shp"),
2788                           wxT("Shapefile (*.shp)|*.shp|All files (*.*)|*.*"),
2789                           wxFD_OPEN | wxFD_FILE_MUST_EXIST,
2790                           wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
2791   lastDir = GetLastDirectory();
2792   if (lastDir.Len() >= 1)
2793     fileDialog.SetDirectory(lastDir);
2794   ret = fileDialog.ShowModal();
2795   if (ret == wxID_OK)
2796     {
2797       path = fileDialog.GetPath();
2798       wxFileName file(path);
2799       table = file.GetName();
2800       VirtualShpDialog dlg;
2801       dlg.Create(this, path, table, LocaleCharset);
2802       ret = dlg.ShowModal();
2803       if (ret == wxID_OK)
2804         {
2805           table = dlg.GetTable();
2806           srid = dlg.GetSrid();
2807           charset = dlg.GetCharset();
2808       } else
2809         return;
2810       lastDir = file.GetPath();
2811       SetLastDirectory(lastDir);
2812       sql = wxT("CREATE VIRTUAL TABLE ");
2813       strcpy(xname, table.ToUTF8());
2814       DoubleQuotedSql(xname);
2815       sql += wxString::FromUTF8(xname);
2816       sql += wxT("\nUSING VirtualShape('");
2817       sql += file.GetPath();
2818       sql += file.GetPathSeparator();
2819       sql += file.GetName();
2820       sql += wxT("',\n'");
2821       sql += charset;
2822       sprintf(dummy, "', %d", srid);
2823       sql += wxString::FromUTF8(dummy);
2824       sql += wxT(")");
2825       ret = sqlite3_exec(sqlite, sql.ToUTF8(), NULL, NULL, &errMsg);
2826       if (ret != SQLITE_OK)
2827         {
2828           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2829                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2830           sqlite3_free(errMsg);
2831           return;
2832         }
2833       wxMessageBox(wxT("Virtual Table ") + table +
2834                    wxT(" was successfully created"), wxT("spatialite_gui"),
2835                    wxOK | wxICON_INFORMATION, this);
2836       InitTableTree();
2837     }
2838 }
2839 
OnLoadTxt(wxCommandEvent & WXUNUSED (event))2840 void MyFrame::OnLoadTxt(wxCommandEvent & WXUNUSED(event))
2841 {
2842 //
2843 // loading a CSV/TXT
2844 //
2845   int ret;
2846   wxString charset;
2847   wxString sql;
2848   wxString path;
2849   wxString table;
2850   wxString lastDir;
2851   bool first_titles;
2852   bool decimal_comma;
2853   char separator;
2854   char text_separator;
2855   wxString filelist = wxT("TXT and CSV files (*.txt;*.csv)|*.txt;*.csv");
2856   filelist +=
2857     wxT("|Text file (*.txt)|*.txt|CSV file (*.csv)|*.csv|All files (*.*)|*.*");
2858   wxFileDialog fileDialog(this, wxT("Load CSV/TXT"),
2859                           wxT(""),
2860                           wxT("textfile.txt"),
2861                           filelist,
2862                           wxFD_OPEN | wxFD_FILE_MUST_EXIST,
2863                           wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
2864   lastDir = GetLastDirectory();
2865   if (lastDir.Len() >= 1)
2866     fileDialog.SetDirectory(lastDir);
2867   ret = fileDialog.ShowModal();
2868   if (ret == wxID_OK)
2869     {
2870       path = fileDialog.GetPath();
2871       wxFileName file(path);
2872       table = file.GetName();
2873       LoadTxtDialog dlg;
2874       dlg.Create(this, path, table, LocaleCharset);
2875       ret = dlg.ShowModal();
2876       if (ret == wxID_OK)
2877         {
2878           SetLastDirectory(lastDir);
2879           table = dlg.GetTable();
2880           charset = dlg.GetCharset();
2881           first_titles = dlg.IsFirstLineTitles();
2882           decimal_comma = dlg.IsDecimalPointComma();
2883           separator = dlg.GetSeparator();
2884           text_separator = dlg.GetTextSeparator();
2885           char decimal_separator = '.';
2886           if (decimal_comma == true)
2887             decimal_separator = ',';
2888           LoadText(path, table, charset, first_titles, decimal_separator,
2889                    separator, text_separator);
2890         }
2891     }
2892 }
2893 
OnVirtualTxt(wxCommandEvent & WXUNUSED (event))2894 void MyFrame::OnVirtualTxt(wxCommandEvent & WXUNUSED(event))
2895 {
2896 //
2897 // creating a VirtualText
2898 //
2899   int ret;
2900   wxString charset;
2901   wxString sql;
2902   wxString path;
2903   wxString table;
2904   wxString lastDir;
2905   bool first_titles;
2906   bool decimal_comma;
2907   char separator;
2908   char text_separator;
2909   char dummy[16];
2910   char *errMsg = NULL;
2911   char xname[1024];
2912   sqlite3 *sqlite = GetSqlite();
2913   wxString filelist = wxT("TXT and CSV files (*.txt;*.csv)|*.txt;*.csv");
2914   filelist +=
2915     wxT("|Text file (*.txt)|*.txt|CSV file (*.csv)|*.csv|All files (*.*)|*.*");
2916   wxFileDialog fileDialog(this, wxT("VirtualText"),
2917                           wxT(""),
2918                           wxT("textfile.txt"),
2919                           filelist,
2920                           wxFD_OPEN | wxFD_FILE_MUST_EXIST,
2921                           wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
2922   lastDir = GetLastDirectory();
2923   if (lastDir.Len() >= 1)
2924     fileDialog.SetDirectory(lastDir);
2925   ret = fileDialog.ShowModal();
2926   if (ret == wxID_OK)
2927     {
2928       path = fileDialog.GetPath();
2929       wxFileName file(path);
2930       table = file.GetName();
2931       VirtualTxtDialog dlg;
2932       dlg.Create(this, path, table, LocaleCharset);
2933       ret = dlg.ShowModal();
2934       if (ret == wxID_OK)
2935         {
2936           table = dlg.GetTable();
2937           charset = dlg.GetCharset();
2938           first_titles = dlg.IsFirstLineTitles();
2939           decimal_comma = dlg.IsDecimalPointComma();
2940           separator = dlg.GetSeparator();
2941           text_separator = dlg.GetTextSeparator();
2942       } else
2943         return;
2944       lastDir = file.GetPath();
2945       SetLastDirectory(lastDir);
2946       sql = wxT("CREATE VIRTUAL TABLE ");
2947       strcpy(xname, table.ToUTF8());
2948       DoubleQuotedSql(xname);
2949       sql += wxString::FromUTF8(xname);
2950       sql += wxT("\nUSING VirtualText('");
2951       sql += path;
2952       sql += wxT("',\n'");
2953       sql += charset;
2954       if (first_titles == true)
2955         sql += wxT("', 1");
2956       else
2957         sql += wxT("', 0");
2958       if (decimal_comma == true)
2959         sql += wxT(", COMMA");
2960       else
2961         sql += wxT(", POINT");
2962       if (text_separator == '\'')
2963         sql += wxT(", SINGLEQUOTE");
2964       else if (text_separator == '"')
2965         sql += wxT(", DOUBLEQUOTE");
2966       else
2967         sql += wxT(", NONE");
2968       if (separator == '\t')
2969         sql += wxT(", TAB");
2970       else
2971         {
2972           sprintf(dummy, ", '%c'", separator);
2973           sql += wxString::FromUTF8(dummy);
2974         }
2975       sql += wxT(")");
2976       ::wxBeginBusyCursor();
2977       ret = sqlite3_exec(sqlite, sql.ToUTF8(), NULL, NULL, &errMsg);
2978       if (ret != SQLITE_OK)
2979         {
2980           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2981                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2982           sqlite3_free(errMsg);
2983           return;
2984         }
2985       ::wxEndBusyCursor();
2986       wxMessageBox(wxT("Virtual Table ") + table +
2987                    wxT(" was successfully created"), wxT("spatialite_gui"),
2988                    wxOK | wxICON_INFORMATION, this);
2989       InitTableTree();
2990     }
2991 }
2992 
OnLoadDbf(wxCommandEvent & WXUNUSED (event))2993 void MyFrame::OnLoadDbf(wxCommandEvent & WXUNUSED(event))
2994 {
2995 //
2996 // loading a DBF
2997 //
2998   int ret;
2999   wxString charset;
3000   wxString sql;
3001   wxString path;
3002   wxString table;
3003   wxString lastDir;
3004   wxString filelist = wxT("DBF files (*.dbf)|*.dbf|All files (*.*)|*.*");
3005   wxFileDialog fileDialog(this, wxT("Load DBF"),
3006                           wxT(""),
3007                           wxT("dbfile.dbf"),
3008                           filelist,
3009                           wxFD_OPEN | wxFD_FILE_MUST_EXIST,
3010                           wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
3011   lastDir = GetLastDirectory();
3012   if (lastDir.Len() >= 1)
3013     fileDialog.SetDirectory(lastDir);
3014   ret = fileDialog.ShowModal();
3015   if (ret == wxID_OK)
3016     {
3017       path = fileDialog.GetPath();
3018       wxFileName file(path);
3019       table = file.GetName();
3020       LoadDbfDialog dlg;
3021       dlg.Create(this, path, table, LocaleCharset);
3022       ret = dlg.ShowModal();
3023       if (ret == wxID_OK)
3024         {
3025           int rt;
3026           int rows;
3027           char x_path[1024];
3028           char x_table[1024];
3029           char x_charset[1024];
3030           char x_pkey[1024];
3031           char *pkey;
3032           char err_msg[1024];
3033           SetLastDirectory(lastDir);
3034           strcpy(x_path, path.ToUTF8());
3035           strcpy(x_table, dlg.GetTable().ToUTF8());
3036           strcpy(x_charset, dlg.GetCharset().ToUTF8());
3037           if (dlg.IsUserDefinedPKey() == false)
3038             pkey = NULL;
3039           else
3040             {
3041               strcpy(x_pkey, dlg.GetPKColumn().ToUTF8());
3042               pkey = x_pkey;
3043             }
3044           rt =
3045             load_dbf_ex(SqliteHandle, x_path, x_table, pkey, x_charset, 0,
3046                         &rows, err_msg);
3047           if (rt)
3048             wxMessageBox(wxT("load dbf OK:") +
3049                          wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
3050                          wxOK | wxICON_INFORMATION, this);
3051           else
3052             wxMessageBox(wxT("load dbf error:") +
3053                          wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
3054                          wxOK | wxICON_ERROR, this);
3055         }
3056     }
3057 }
3058 
OnVirtualDbf(wxCommandEvent & WXUNUSED (event))3059 void MyFrame::OnVirtualDbf(wxCommandEvent & WXUNUSED(event))
3060 {
3061 //
3062 // creating a VirtualDbf
3063 //
3064   int ret;
3065   wxString charset;
3066   wxString sql;
3067   wxString path;
3068   wxString table;
3069   wxString lastDir;
3070   char *errMsg = NULL;
3071   char xname[1024];
3072   sqlite3 *sqlite = GetSqlite();
3073   wxString filelist = wxT("DBF files (*.dbf)|*.dbf|All files (*.*)|*.*");
3074   wxFileDialog fileDialog(this, wxT("VirtualDbf"),
3075                           wxT(""),
3076                           wxT("dbfile.dbf"),
3077                           filelist,
3078                           wxFD_OPEN | wxFD_FILE_MUST_EXIST,
3079                           wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
3080   lastDir = GetLastDirectory();
3081   if (lastDir.Len() >= 1)
3082     fileDialog.SetDirectory(lastDir);
3083   ret = fileDialog.ShowModal();
3084   if (ret == wxID_OK)
3085     {
3086       path = fileDialog.GetPath();
3087       wxFileName file(path);
3088       table = file.GetName();
3089       VirtualDbfDialog dlg;
3090       dlg.Create(this, path, table, LocaleCharset);
3091       ret = dlg.ShowModal();
3092       if (ret == wxID_OK)
3093         {
3094           table = dlg.GetTable();
3095           charset = dlg.GetCharset();
3096       } else
3097         return;
3098       lastDir = file.GetPath();
3099       SetLastDirectory(lastDir);
3100       sql = wxT("CREATE VIRTUAL TABLE ");
3101       strcpy(xname, table.ToUTF8());
3102       DoubleQuotedSql(xname);
3103       sql += wxString::FromUTF8(xname);
3104       sql += wxT("\nUSING VirtualDbf('");
3105       sql += path;
3106       sql += wxT("', '");
3107       sql += charset;
3108       sql += wxT("')");
3109       ret = sqlite3_exec(sqlite, sql.ToUTF8(), NULL, NULL, &errMsg);
3110       if (ret != SQLITE_OK)
3111         {
3112           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
3113                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
3114           sqlite3_free(errMsg);
3115           return;
3116         }
3117       wxMessageBox(wxT("Virtual Table ") + table +
3118                    wxT(" was successfully created"), wxT("spatialite_gui"),
3119                    wxOK | wxICON_INFORMATION, this);
3120       InitTableTree();
3121     }
3122 }
3123 
OnLoadXL(wxCommandEvent & WXUNUSED (event))3124 void MyFrame::OnLoadXL(wxCommandEvent & WXUNUSED(event))
3125 {
3126 //
3127 // loading an XLS
3128 //
3129 #ifndef OMIT_FREEXL             /* FreeXL is enabled */
3130   int ret;
3131   wxString charset;
3132   wxString sql;
3133   wxString path;
3134   wxString table;
3135   int sheetIndex;
3136   int firstLineTitles;
3137   char err_msg[1024];
3138   unsigned int rows;
3139   wxString lastDir;
3140   wxString filelist =
3141     wxT("Microsoft Excel spreadsheets (*.xls)|*.xls|All files (*.*)|*.*");
3142   wxFileDialog fileDialog(this, wxT("Load XLS"), wxT(""),
3143                           wxT("spreadsheet.xls"), filelist,
3144                           wxFD_OPEN | wxFD_FILE_MUST_EXIST, wxDefaultPosition,
3145                           wxDefaultSize, wxT("filedlg"));
3146   lastDir = GetLastDirectory();
3147   if (lastDir.Len() >= 1)
3148     fileDialog.SetDirectory(lastDir);
3149   ret = fileDialog.ShowModal();
3150   if (ret == wxID_OK)
3151     {
3152       path = fileDialog.GetPath();
3153       wxFileName file(path);
3154       table = file.GetName();
3155       LoadXLDialog dlg;
3156       dlg.Create(this, path, table);
3157       ret = dlg.ShowModal();
3158       if (ret == wxID_OK)
3159         {
3160           char x_path[1024];
3161           char x_table[1024];
3162           table = dlg.GetTable();
3163           sheetIndex = dlg.GetWorksheetIndex();
3164           if (dlg.IsFirstLineTitles() == true)
3165             firstLineTitles = 1;
3166           else
3167             firstLineTitles = 0;
3168           strcpy(x_path, path.ToUTF8());
3169           strcpy(x_table, table.ToUTF8());
3170           if (!load_XL
3171               (SqliteHandle, x_path, x_table, sheetIndex, firstLineTitles,
3172                &rows, err_msg))
3173             {
3174               wxMessageBox(wxT("load XL error:") +
3175                            wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
3176                            wxOK | wxICON_ERROR, this);
3177             }
3178         }
3179     }
3180 #else /* FreeXL disabled */
3181   wxString msg = wxT("This copy of spatialite_gui was built explictly\n");
3182   msg += wxT("disabling the FreeXL support.\n");
3183   msg += wxT("Sorry ...");
3184   wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_EXCLAMATION, this);
3185 #endif /* end FreeXL conditional */
3186 }
3187 
OnVirtualXL(wxCommandEvent & WXUNUSED (event))3188 void MyFrame::OnVirtualXL(wxCommandEvent & WXUNUSED(event))
3189 {
3190 //
3191 // creating a VirtualXL
3192 //
3193 #ifndef OMIT_FREEXL             /* FreeXL is enabled */
3194   int ret;
3195   wxString charset;
3196   wxString sql;
3197   wxString path;
3198   wxString table;
3199   int sheetIndex;
3200   bool firstLineTitles;
3201   wxString lastDir;
3202   char *errMsg = NULL;
3203   char xname[1024];
3204   sqlite3 *sqlite = GetSqlite();
3205   wxString filelist =
3206     wxT("Microsoft Excel spreadsheets (*.xls)|*.xls|All files (*.*)|*.*");
3207   wxFileDialog fileDialog(this, wxT("VirtualXL"), wxT(""),
3208                           wxT("spreadsheet.xls"), filelist,
3209                           wxFD_OPEN | wxFD_FILE_MUST_EXIST, wxDefaultPosition,
3210                           wxDefaultSize, wxT("filedlg"));
3211   lastDir = GetLastDirectory();
3212   if (lastDir.Len() >= 1)
3213     fileDialog.SetDirectory(lastDir);
3214   ret = fileDialog.ShowModal();
3215   if (ret == wxID_OK)
3216     {
3217       path = fileDialog.GetPath();
3218       wxFileName file(path);
3219       table = file.GetName();
3220       VirtualXLDialog dlg;
3221       dlg.Create(this, path, table);
3222       ret = dlg.ShowModal();
3223       if (ret == wxID_OK)
3224         {
3225           table = dlg.GetTable();
3226           sheetIndex = dlg.GetWorksheetIndex();
3227           firstLineTitles = dlg.IsFirstLineTitles();
3228       } else
3229         return;
3230       lastDir = file.GetPath();
3231       SetLastDirectory(lastDir);
3232       sql = wxT("CREATE VIRTUAL TABLE ");
3233       strcpy(xname, table.ToUTF8());
3234       DoubleQuotedSql(xname);
3235       sql += wxString::FromUTF8(xname);
3236       sql += wxT("\nUSING VirtualXL('");
3237       sql += path;
3238       sprintf(xname, "', %d, %d)", sheetIndex,
3239               (firstLineTitles == true) ? 1 : 0);
3240       sql += wxString::FromUTF8(xname);
3241       ret = sqlite3_exec(sqlite, sql.ToUTF8(), NULL, NULL, &errMsg);
3242       if (ret != SQLITE_OK)
3243         {
3244           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
3245                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
3246           sqlite3_free(errMsg);
3247           return;
3248         }
3249       wxMessageBox(wxT("Virtual Table ") + table +
3250                    wxT(" was successfully created"), wxT("spatialite_gui"),
3251                    wxOK | wxICON_INFORMATION, this);
3252       InitTableTree();
3253     }
3254 #else /* FreeXL disabled */
3255   wxString msg = wxT("This copy of spatialite_gui was built explictly\n");
3256   msg += wxT("disabling the FreeXL support.\n");
3257   msg += wxT("Sorry ...");
3258   wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_EXCLAMATION, this);
3259 #endif /* end FreeXL conditional */
3260 }
3261 
OnNetwork(wxCommandEvent & WXUNUSED (event))3262 void MyFrame::OnNetwork(wxCommandEvent & WXUNUSED(event))
3263 {
3264 //
3265 // building a Network
3266 //
3267   NetworkDialog dlg;
3268   int ret;
3269   wxString table;
3270   wxString from;
3271   wxString to;
3272   wxString geom;
3273   wxString name;
3274   bool isGeomLength;
3275   wxString cost;
3276   bool isBidirectional;
3277   bool isOneWays;
3278   wxString oneWayToFrom;
3279   wxString oneWayFromTo;
3280   bool aStarSupported;
3281   dlg.Create(this);
3282   ret = dlg.ShowModal();
3283   if (ret == wxID_OK)
3284     {
3285       table = dlg.GetTableName();
3286       from = dlg.GetFromColumn();
3287       to = dlg.GetToColumn();
3288       geom = dlg.GetGeomColumn();
3289       name = dlg.GetNameColumn();
3290       isGeomLength = dlg.IsGeomLength();
3291       cost = dlg.GetCostColumn();
3292       isBidirectional = dlg.IsBidirectional();
3293       isOneWays = dlg.IsOneWays();
3294       oneWayToFrom = dlg.GetOneWayToFrom();
3295       oneWayFromTo = dlg.GetOneWayFromTo();
3296       aStarSupported = dlg.IsAStarSupported();
3297       BuildNetwork(table, from, to, geom, name, isGeomLength, cost,
3298                    isBidirectional, isOneWays, oneWayFromTo, oneWayToFrom,
3299                    aStarSupported);
3300     }
3301 }
3302 
OnImportXmlDocuments(wxCommandEvent & WXUNUSED (event))3303 void MyFrame::OnImportXmlDocuments(wxCommandEvent & WXUNUSED(event))
3304 {
3305 //
3306 // importing XML Documents
3307 //
3308 #ifdef ENABLE_LIBXML2           /* only if LIBXML2 is enabled */
3309   XmlDocumentsDialog dlg;
3310   int ret;
3311   wxString path;
3312   bool isFolder;
3313   int compressed;
3314   bool isInternalSchema;
3315   char *schemaURI;
3316   char xschema[8192];
3317   wxString lastDir;
3318   wxString dir_path;
3319   wxString xml_path;
3320   wxString suffix;
3321   wxString table;
3322   wxString pkName;
3323   wxString xmlColumn;
3324   wxString inPathColumn;
3325   wxString parseErrColumn;
3326   wxString validateErrColumn;
3327   wxString schemaUriColumn;
3328   wxString filelist = wxT("XML Documents (*.xml)|*.xml|All files (*.*)|*.*");
3329   wxFileDialog fileDialog(this, wxT("XML File/Folder selection"),
3330                           wxT(""),
3331                           wxT(""),
3332                           filelist,
3333                           wxFD_OPEN | wxFD_FILE_MUST_EXIST,
3334                           wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
3335   lastDir = GetLastDirectory();
3336   if (lastDir.Len() >= 1)
3337     fileDialog.SetDirectory(lastDir);
3338   ret = fileDialog.ShowModal();
3339   if (ret == wxID_OK)
3340     {
3341       xml_path = fileDialog.GetPath();
3342       wxFileName file(xml_path);
3343       dir_path = file.GetPath();
3344   } else
3345     return;
3346   dlg.Create(this, dir_path, xml_path);
3347   ret = dlg.ShowModal();
3348   if (ret == wxID_OK)
3349     {
3350       ::wxBeginBusyCursor();
3351       SetLastDirectory(dir_path);
3352       isFolder = dlg.IsFolder();
3353       if (isFolder == true)
3354         path = dlg.GetDirPath();
3355       else
3356         path = dlg.GetXmlPath();
3357       suffix = dlg.GetSuffix();
3358       table = dlg.GetTargetTable();
3359       pkName = dlg.GetPkName();
3360       xmlColumn = dlg.GetXmlColumn();
3361       compressed = dlg.IsCompressed();
3362       wxString schema = dlg.GetSchemaURI();
3363       isInternalSchema = dlg.IsInternalSchemaURI();
3364       if (schema.Len() == 0)
3365         schemaURI = NULL;
3366       else
3367         {
3368           strcpy((char *) xschema, schema.ToUTF8());
3369           schemaURI = xschema;
3370         }
3371       inPathColumn = dlg.GetInPathColumn();
3372       schemaUriColumn = dlg.GetSchemaUriColumn();
3373       parseErrColumn = dlg.GetParseErrorColumn();
3374       validateErrColumn = dlg.GetValidateErrorColumn();
3375       wxString currDir =::wxGetCwd();
3376       ::wxSetWorkingDirectory(dir_path);
3377       ImportXmlDocuments(path, isFolder, suffix, table, pkName, xmlColumn,
3378                          inPathColumn, schemaUriColumn, parseErrColumn,
3379                          validateErrColumn, compressed, schemaURI,
3380                          isInternalSchema);
3381       ::wxSetWorkingDirectory(currDir);
3382       ::wxEndBusyCursor();
3383       InitTableTree();
3384     }
3385 #else
3386 
3387   wxMessageBox(wxT
3388                ("Sorry, spatialite_gui was built disabling LIBXML2\n\nUnsupported operation"),
3389                wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
3390 
3391 #endif /* end LIBXML2 conditionals */
3392 }
3393 
OnImportWFS(wxCommandEvent & WXUNUSED (event))3394 void MyFrame::OnImportWFS(wxCommandEvent & WXUNUSED(event))
3395 {
3396 //
3397 // importing data from WFS datasource
3398 //
3399 #ifdef ENABLE_LIBXML2           /* only if LIBXML2 is enabled */
3400   WfsDialog dlg;
3401   dlg.Create(this);
3402   dlg.ShowModal();
3403 
3404 #else
3405 
3406   wxMessageBox(wxT
3407                ("Sorry, spatialite_gui was built disabling LIBXML2\n\nUnsupported operation"),
3408                wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
3409 
3410 #endif /* end LIBXML2 conditionals */
3411 }
3412 
OnImportDXF(wxCommandEvent & WXUNUSED (event))3413 void MyFrame::OnImportDXF(wxCommandEvent & WXUNUSED(event))
3414 {
3415 //
3416 // importing DXF file(s)
3417 //
3418   DxfDialog dlg;
3419   int ret;
3420   wxString path;
3421   bool isFolder;
3422   wxString lastDir;
3423   wxString dir_path;
3424   wxString dxf_path;
3425   wxString prefix;
3426   wxString layer;
3427   int srid;
3428   bool force2d;
3429   bool force3d;
3430   bool mixed;
3431   bool linked;
3432   bool unlinked;
3433   bool append;
3434   wxString filelist = wxT("DXF drawing file (*.dxf)|*.dxf|All files (*.*)|*.*");
3435   wxFileDialog fileDialog(this, wxT("DXF File/Folder selection"),
3436                           wxT(""),
3437                           wxT(""),
3438                           filelist,
3439                           wxFD_OPEN | wxFD_FILE_MUST_EXIST,
3440                           wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
3441   lastDir = GetLastDirectory();
3442   if (lastDir.Len() >= 1)
3443     fileDialog.SetDirectory(lastDir);
3444   ret = fileDialog.ShowModal();
3445   if (ret == wxID_OK)
3446     {
3447       dxf_path = fileDialog.GetPath();
3448       wxFileName file(dxf_path);
3449       dir_path = file.GetPath();
3450   } else
3451     return;
3452   dlg.Create(this, dir_path, dxf_path);
3453   ret = dlg.ShowModal();
3454   if (ret == wxID_OK)
3455     {
3456       ::wxBeginBusyCursor();
3457       SetLastDirectory(dir_path);
3458       isFolder = dlg.IsFolder();
3459       if (isFolder == true)
3460         path = dlg.GetDirPath();
3461       else
3462         path = dlg.GetDxfPath();
3463       prefix = dlg.GetPrefix();
3464       layer = dlg.GetSingleLayer();
3465       srid = dlg.GetSrid();
3466       force2d = dlg.IsForce2D();
3467       force3d = dlg.IsForce3D();
3468       mixed = dlg.IsImportMixed();
3469       linked = dlg.IsLinkedRings();
3470       unlinked = dlg.IsUnlinkedRings();
3471       append = dlg.IsAppendMode();
3472       wxString currDir =::wxGetCwd();
3473       ::wxSetWorkingDirectory(dir_path);
3474       ImportDXFfiles(path, isFolder, prefix, layer, srid, force2d, force3d,
3475                      mixed, linked, unlinked, append);
3476       ::wxSetWorkingDirectory(currDir);
3477       ::wxEndBusyCursor();
3478       InitTableTree();
3479     }
3480 }
3481 
OnImportExifPhotos(wxCommandEvent & WXUNUSED (event))3482 void MyFrame::OnImportExifPhotos(wxCommandEvent & WXUNUSED(event))
3483 {
3484 //
3485 // importing EXIF Photos
3486 //
3487   ExifDialog dlg;
3488   int ret;
3489   wxString path;
3490   bool isFolder;
3491   bool isMetadata;
3492   bool isGpsOnly;
3493   wxString lastDir;
3494   wxString dir_path;
3495   wxString img_path;
3496   wxString filelist = wxT("JPEG files (*.jpg;*.jpeg)|*.jpg;*.jpeg|");
3497   filelist += wxT("All files (*.*)|*.*");
3498   wxFileDialog fileDialog(this, wxT("EXIF File/Folder selection"),
3499                           wxT(""),
3500                           wxT(""),
3501                           filelist,
3502                           wxFD_OPEN | wxFD_FILE_MUST_EXIST,
3503                           wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
3504   lastDir = GetLastDirectory();
3505   if (lastDir.Len() >= 1)
3506     fileDialog.SetDirectory(lastDir);
3507   ret = fileDialog.ShowModal();
3508   if (ret == wxID_OK)
3509     {
3510       img_path = fileDialog.GetPath();
3511       wxFileName file(img_path);
3512       dir_path = file.GetPath();
3513   } else
3514     return;
3515   dlg.Create(this, dir_path, img_path);
3516   ret = dlg.ShowModal();
3517   if (ret == wxID_OK)
3518     {
3519       SetLastDirectory(dir_path);
3520       isFolder = dlg.IsFolder();
3521       if (isFolder == true)
3522         path = dlg.GetDirPath();
3523       else
3524         path = dlg.GetImgPath();
3525       isMetadata = dlg.IsMetadata();
3526       isGpsOnly = dlg.IsGpsOnly();
3527       ImportExifPhotos(path, isFolder, isMetadata, isGpsOnly);
3528     }
3529 }
3530 
OnSrids(wxCommandEvent & WXUNUSED (event))3531 void MyFrame::OnSrids(wxCommandEvent & WXUNUSED(event))
3532 {
3533 //
3534 // searching a SRID by name
3535 //
3536   SearchSridDialog dlg;
3537   int ret;
3538   wxString string;
3539   wxString sql;
3540   dlg.Create(this);
3541   ret = dlg.ShowModal();
3542   if (ret == wxID_OK)
3543     {
3544       sql = wxT("SELECT * FROM spatial_ref_sys\n");
3545       if (dlg.IsSearchBySrid() == true)
3546         {
3547           // searching by SRID
3548           char txt[128];
3549           sprintf(txt, "WHERE srid = %d", dlg.GetSrid());
3550           sql += wxString::FromUTF8(txt);
3551       } else
3552         {
3553           // searching by NAME
3554           string = dlg.GetString();
3555           sql += wxT("WHERE ref_sys_name LIKE '%");
3556           sql += string;
3557           sql += wxT("%'\nORDER BY srid");
3558         }
3559       QueryView->SetSql(sql, true);
3560     }
3561 }
3562 
OnCharset(wxCommandEvent & WXUNUSED (event))3563 void MyFrame::OnCharset(wxCommandEvent & WXUNUSED(event))
3564 {
3565 //
3566 // setting the default CHARSET
3567 //
3568   DefaultCharsetDialog dlg;
3569   int ret;
3570   dlg.Create(this, DefaultCharset, AskCharset);
3571   ret = dlg.ShowModal();
3572   if (ret == wxID_OK)
3573     {
3574       DefaultCharset = dlg.GetCharset();
3575       AskCharset = dlg.IsSetAskCharset();
3576     }
3577 }
3578 
OnTimerAutoSave(wxTimerEvent & WXUNUSED (event))3579 void MyFrame::OnTimerAutoSave(wxTimerEvent & WXUNUSED(event))
3580 {
3581 //
3582 // AutoSave - Timer event handler
3583 //
3584   int tc = sqlite3_total_changes(SqliteHandle);
3585   if (tc != LastTotalChanges)
3586     MemoryDbSave();
3587   if (AutoSaveInterval <= 0)
3588     {
3589       delete TimerAutoSave;
3590       TimerAutoSave = NULL;
3591   } else
3592     TimerAutoSave->Start(AutoSaveInterval * 1000, wxTIMER_ONE_SHOT);
3593 }
3594 
ExecuteSql(const char * sql,int rowNo)3595 bool MyFrame::ExecuteSql(const char *sql, int rowNo)
3596 {
3597 //
3598 // executes an SQL statement from the SQL script
3599 //
3600   int ret;
3601   char *errMsg = NULL;
3602   wxString msg;
3603   char dummy[128];
3604   ret = sqlite3_exec(SqliteHandle, sql, NULL, NULL, &errMsg);
3605   if (ret != SQLITE_OK)
3606     {
3607       sprintf(dummy, "row %d\n\nSQLite SQL error: ", rowNo);
3608       msg = wxString::FromUTF8(dummy);
3609       wxMessageBox(msg + wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
3610                    wxOK | wxICON_ERROR, this);
3611       sqlite3_free(errMsg);
3612       return false;
3613     }
3614   return true;
3615 }
3616 
Rollback()3617 void MyFrame::Rollback()
3618 {
3619 //
3620 // performing a ROLLBACK
3621 //
3622   sqlite3_exec(SqliteHandle, "ROLLBACK", NULL, NULL, NULL);
3623 }
3624 
OpenDB()3625 bool MyFrame::OpenDB()
3626 {
3627 //
3628 // establishing a physical connetion to some DB SQLite
3629 //
3630   int ret;
3631   char *errMsg = NULL;
3632   ret =
3633     sqlite3_open_v2(SqlitePath.ToUTF8(), &SqliteHandle, SQLITE_OPEN_READWRITE,
3634                     NULL);
3635   if (ret)
3636     {
3637       // an error occurred
3638       wxString errCause;
3639       errCause = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
3640       sqlite3_close(SqliteHandle);
3641       wxMessageBox(wxT("Failure while connecting to DB\n\n") + errCause +
3642                    wxT("\n") + SqlitePath, wxT("spatialite_gui"),
3643                    wxOK | wxICON_ERROR, this);
3644       SqliteHandle = NULL;
3645       InternalCache = NULL;
3646       ClearTableTree();
3647       MemoryDatabase = false;
3648       return false;
3649     }
3650 // setting up the internal cache
3651   InternalCache = spatialite_alloc_connection();
3652   spatialite_init_ex(SqliteHandle, InternalCache, 0);
3653 // enabling LOAD_EXTENSION
3654   ret = sqlite3_enable_load_extension(SqliteHandle, 1);
3655   if (ret != SQLITE_OK)
3656     {
3657       wxMessageBox(wxT("Unable to enable LOAD_EXTENSION"),
3658                    wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
3659       sqlite3_free(errMsg);
3660     }
3661 // activating Foreign Key constraints
3662   ret = sqlite3_exec(SqliteHandle, "PRAGMA foreign_keys = 1", NULL, 0, &errMsg);
3663   if (ret != SQLITE_OK)
3664     {
3665       wxMessageBox(wxT("Unable to activate FOREIGN_KEY constraints"),
3666                    wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
3667       sqlite3_free(errMsg);
3668     }
3669   AutoFDOStart();
3670   InitTableTree();
3671   LoadHistory();
3672   return true;
3673 }
3674 
LastDitchMemoryDbSave()3675 void MyFrame::LastDitchMemoryDbSave()
3676 {
3677 //
3678 // performing the last desperate attempt to save a MEMORY-DB
3679 //
3680   int tc;
3681   int ret;
3682   wxString lastDir;
3683   if (MemoryDatabase == false)
3684     return;
3685   if (!SqliteHandle)
3686     return;
3687   tc = sqlite3_total_changes(SqliteHandle);
3688   if (tc == LastTotalChanges)
3689     return;
3690   while (1)
3691     {
3692       // OK, this MEMORY-DB needs to be saved
3693       if (MemoryDbSave() == true)
3694         break;
3695       // we must ask the user
3696       wxString msg =
3697         wxT("WARNING: the MEMORY-DB contains uncommitted changes\n\n");
3698       msg += wxT("The MEMORY_DB is intrinsecally volatile, so these changes\n");
3699       msg +=
3700         wxT("will be irremediably lost if you don't export them to some\n");
3701       msg += wxT("persistent storage [i.e. on the file-system]\n\n");
3702       msg +=
3703         wxT
3704         ("Do you want to export [SAVE] the MEMORY-DB to some external database ?");
3705       ret =
3706         wxMessageBox(msg, wxT("spatialite_gui"), wxYES_NO | wxICON_QUESTION,
3707                      this);
3708       if (ret != wxYES)
3709         break;
3710       // asking a PATHNAME to the user
3711       wxFileDialog fileDialog(this, wxT("Saving the MEMORY-DB"),
3712                               wxT(""), wxT("db.sqlite"),
3713                               wxT
3714                               ("SQLite DB (*.sqlite)|*.sqlite|All files (*.*)|*.*"),
3715                               wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
3716                               wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
3717       lastDir = GetLastDirectory();
3718       if (lastDir.Len() >= 1)
3719         fileDialog.SetDirectory(lastDir);
3720       ret = fileDialog.ShowModal();
3721       if (ret == wxID_OK)
3722         {
3723           // exporting the external DB
3724           ExternalSqlitePath = fileDialog.GetPath();
3725           if (MemoryDbSave() == true)
3726             {
3727               wxMessageBox(wxT("Ok, MEMORY-DB was succesfully saved"),
3728                            wxT("spatialite_gui"), wxOK | wxICON_INFORMATION,
3729                            this);
3730               break;
3731             }
3732         }
3733     }
3734 }
3735 
CloseDB()3736 void MyFrame::CloseDB()
3737 {
3738 //
3739 // disconnecting current SQLite DB
3740 //
3741   if (!SqliteHandle)
3742     return;
3743   AutoFDOStop();
3744   if (AutoFDOmsg.Len() > 0)
3745     wxMessageBox(AutoFDOmsg, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION,
3746                  this);
3747   LastDitchMemoryDbSave();
3748   sqlite3_close(SqliteHandle);
3749   SqliteHandle = NULL;
3750   spatialite_cleanup_ex(InternalCache);
3751   InternalCache = NULL;
3752   SqlitePath = wxT("");
3753   MemoryDatabase = false;
3754   ClearTableTree();
3755 }
3756 
CreateDB()3757 bool MyFrame::CreateDB()
3758 {
3759 // creating a new, empty SQLite DB
3760   int ret;
3761   char path[1024];
3762   char *errMsg = NULL;
3763   if (MemoryDatabase == true)
3764     strcpy(path, ":memory:");
3765   else
3766     {
3767       strcpy(path, SqlitePath.ToUTF8());
3768       unlink(path);
3769     }
3770   ret =
3771     sqlite3_open_v2(path, &SqliteHandle,
3772                     SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
3773   if (ret)
3774     {
3775       // an error occurred
3776       wxString errCause;
3777       errCause = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
3778       sqlite3_close(SqliteHandle);
3779       wxMessageBox(wxT("An error occurred\n\n") + errCause + wxT("\n") +
3780                    SqlitePath, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
3781                    this);
3782       SqliteHandle = NULL;
3783       InternalCache = NULL;
3784       ClearTableTree();
3785       MemoryDatabase = false;
3786       return false;
3787     }
3788 // setting up the internal cache
3789   InternalCache = spatialite_alloc_connection();
3790   spatialite_init_ex(SqliteHandle, InternalCache, 0);
3791 // activating Foreign Key constraints
3792   ret = sqlite3_exec(SqliteHandle, "PRAGMA foreign_keys = 1", NULL, 0, &errMsg);
3793   if (ret != SQLITE_OK)
3794     {
3795       wxMessageBox(wxT("Unable to activate FOREIGN_KEY constraints"),
3796                    wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
3797       sqlite3_free(errMsg);
3798       SqliteHandle = NULL;
3799       ClearTableTree();
3800       MemoryDatabase = false;
3801       return false;
3802     }
3803   InitializeSpatialMetadata();
3804   AutoFDOStart();
3805   InitTableTree();
3806   return true;
3807 }
3808 
InitializeSpatialMetadata()3809 void MyFrame::InitializeSpatialMetadata()
3810 {
3811 // attempting to perform self-initialization for a newly created DB
3812   int ret;
3813   char sql[1024];
3814   char *errMsg = NULL;
3815   int count;
3816   int i;
3817   char **results;
3818   int rows;
3819   int columns;
3820 
3821   if (SqliteHandle == NULL)
3822     return;
3823 // checking if this DB is really empty
3824   strcpy(sql, "SELECT Count(*) from sqlite_master");
3825   ret = sqlite3_get_table(SqliteHandle, sql, &results, &rows, &columns, NULL);
3826   if (ret != SQLITE_OK)
3827     return;
3828   if (rows < 1)
3829     ;
3830   else
3831     {
3832       for (i = 1; i <= rows; i++)
3833         count = atoi(results[(i * columns) + 0]);
3834     }
3835   sqlite3_free_table(results);
3836 
3837   if (count > 0)
3838     return;
3839 
3840 // all right, it's empty: proceding to initialize
3841   strcpy(sql, "SELECT InitSpatialMetadata(1)");
3842   ret = sqlite3_exec(SqliteHandle, sql, NULL, NULL, &errMsg);
3843   if (ret != SQLITE_OK)
3844     {
3845       wxMessageBox(wxT("Unable to initialite SpatialMetadata: ") +
3846                    wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
3847                    wxOK | wxICON_ERROR, this);
3848       sqlite3_free(errMsg);
3849       return;
3850     }
3851 }
3852 
HasHistory(void)3853 bool MyFrame::HasHistory(void)
3854 {
3855 // checks if the "sql_statement" table exists
3856   int ret;
3857   int i;
3858   char **results;
3859   int rows;
3860   int columns;
3861   wxString sql;
3862   bool ok_sql = false;
3863   bool ok_cause = false;
3864   bool ok_time = false;
3865   char *errMsg = NULL;
3866 
3867   sql = wxT("PRAGMA table_info(sql_statements_log)");
3868   ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
3869                           &rows, &columns, &errMsg);
3870   if (ret != SQLITE_OK)
3871     {
3872       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
3873                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
3874       sqlite3_free(errMsg);
3875       return false;
3876     }
3877   if (rows < 1)
3878     ;
3879   else
3880     {
3881       for (i = 1; i <= rows; i++)
3882         {
3883           const char *name = results[(i * columns) + 1];
3884           wxString x = wxString::FromUTF8(name);
3885           if (x.CmpNoCase(wxT("sql_statement")) == 0)
3886             ok_sql = true;
3887           if (x.CmpNoCase(wxT("error_cause")) == 0)
3888             ok_cause = true;
3889           if (x.CmpNoCase(wxT("sql_statement")) == 0)
3890             ok_time = true;
3891         }
3892     }
3893   sqlite3_free_table(results);
3894   if (ok_sql && ok_cause && ok_time)
3895     return true;
3896   return false;
3897 }
3898 
LoadHistory(void)3899 void MyFrame::LoadHistory(void)
3900 {
3901 // attempting to load the most recent SQL history
3902   int ret;
3903   int i;
3904   char **results;
3905   int rows;
3906   int columns;
3907   wxString sql;
3908   char *errMsg = NULL;
3909   if (!HasHistory())
3910     return;
3911 
3912   sql = wxT("SELECT sql_statement FROM sql_statements_log ");
3913   sql += wxT("WHERE error_cause = 'success' ORDER BY time_end DESC ");
3914   sql += wxT("LIMIT 25");
3915   ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
3916                           &rows, &columns, &errMsg);
3917   if (ret != SQLITE_OK)
3918     {
3919       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
3920                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
3921       sqlite3_free(errMsg);
3922       return;
3923     }
3924   if (rows < 1)
3925     ;
3926   else
3927     {
3928       for (i = 1; i < rows; i++)
3929         {
3930           const char *name = results[(i * columns) + 1];
3931           wxString x = wxString::FromUTF8(name);
3932           QueryView->GetHistory()->Prepend(x);
3933         }
3934     }
3935   sqlite3_free_table(results);
3936   QueryView->SetHistoryStates();
3937 }
3938 
DoubleQuotedSql(char * buf)3939 void MyFrame::DoubleQuotedSql(char *buf)
3940 {
3941 // well-formatting a string to be used as an SQL name
3942   char tmp[1024];
3943   char *in = tmp;
3944   char *out = buf;
3945   strcpy(tmp, buf);
3946   *out++ = '"';
3947   while (*in != '\0')
3948     {
3949       if (*in == '"')
3950         *out++ = '"';
3951       *out++ = *in++;
3952     }
3953   *out++ = '"';
3954   *out = '\0';
3955 }
3956 
IsSpatialIndex(wxString & tableName)3957 bool MyFrame::IsSpatialIndex(wxString & tableName)
3958 {
3959 // testing if this table belongs to some R*Tree Spatial Index
3960   int i;
3961   char **results;
3962   int rows;
3963   int columns;
3964   char *errMsg = NULL;
3965   char *name;
3966   char *geom;
3967   char dummy[2048];
3968   wxString tblName;
3969   wxString sql;
3970 // fetching any defined Spatial Index
3971   sql =
3972     wxT
3973     ("SELECT f_table_name, f_geometry_column FROM geometry_columns WHERE spatial_index_enabled = 1");
3974   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
3975                               &rows, &columns, &errMsg);
3976   if (ret != SQLITE_OK)
3977     return false;
3978   if (rows < 1)
3979     ;
3980   else
3981     {
3982       for (i = 1; i <= rows; i++)
3983         {
3984           name = results[(i * columns) + 0];
3985           geom = results[(i * columns) + 1];
3986           sprintf(dummy, "idx_%s_%s", name, geom);
3987           tblName = wxString::FromUTF8(dummy);
3988           if (tableName.CmpNoCase(tblName) == 0)
3989             return true;
3990           sprintf(dummy, "idx_%s_%s_node", name, geom);
3991           tblName = wxString::FromUTF8(dummy);
3992           if (tableName.CmpNoCase(tblName) == 0)
3993             return true;
3994           sprintf(dummy, "idx_%s_%s_parent", name, geom);
3995           tblName = wxString::FromUTF8(dummy);
3996           if (tableName.CmpNoCase(tblName) == 0)
3997             return true;
3998           sprintf(dummy, "idx_%s_%s_rowid", name, geom);
3999           tblName = wxString::FromUTF8(dummy);
4000           if (tableName.CmpNoCase(tblName) == 0)
4001             return true;
4002         }
4003     }
4004   sqlite3_free_table(results);
4005   return false;
4006 }
4007 
IsSpatialIndex(wxString & dbAlias,wxString & tableName)4008 bool MyFrame::IsSpatialIndex(wxString & dbAlias, wxString & tableName)
4009 {
4010 // testing if this table belongs to some R*Tree Spatial Index
4011   int i;
4012   char **results;
4013   int rows;
4014   int columns;
4015   char *errMsg = NULL;
4016   char *name;
4017   char *geom;
4018   char dummy[2048];
4019   wxString tblName;
4020   wxString sql;
4021 // fetching any defined Spatial Index
4022   sql = wxT("SELECT f_table_name, f_geometry_column FROM ");
4023   sql += dbAlias + wxT(".geometry_columns WHERE spatial_index_enabled = 1");
4024   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
4025                               &rows, &columns, &errMsg);
4026   if (ret != SQLITE_OK)
4027     return false;
4028   if (rows < 1)
4029     ;
4030   else
4031     {
4032       for (i = 1; i <= rows; i++)
4033         {
4034           name = results[(i * columns) + 0];
4035           geom = results[(i * columns) + 1];
4036           sprintf(dummy, "idx_%s_%s", name, geom);
4037           tblName = wxString::FromUTF8(dummy);
4038           if (tableName.CmpNoCase(tblName) == 0)
4039             return true;
4040           sprintf(dummy, "idx_%s_%s_node", name, geom);
4041           tblName = wxString::FromUTF8(dummy);
4042           if (tableName.CmpNoCase(tblName) == 0)
4043             return true;
4044           sprintf(dummy, "idx_%s_%s_parent", name, geom);
4045           tblName = wxString::FromUTF8(dummy);
4046           if (tableName.CmpNoCase(tblName) == 0)
4047             return true;
4048           sprintf(dummy, "idx_%s_%s_rowid", name, geom);
4049           tblName = wxString::FromUTF8(dummy);
4050           if (tableName.CmpNoCase(tblName) == 0)
4051             return true;
4052         }
4053     }
4054   sqlite3_free_table(results);
4055   return false;
4056 }
4057 
ElementaryGeoms(wxString & inTable,wxString & geometry,wxString & outTable,wxString & pKey,wxString & multiID,wxString & type,int * srid,wxString & coordDims,bool * spIdx)4058 void MyFrame::ElementaryGeoms(wxString & inTable, wxString & geometry,
4059                               wxString & outTable, wxString & pKey,
4060                               wxString & multiID, wxString & type, int *srid,
4061                               wxString & coordDims, bool * spIdx)
4062 {
4063 // ancillary SQL for ElementaryGeoms
4064   int i;
4065   char **results;
4066   int rows;
4067   int columns;
4068   char *errMsg = NULL;
4069   char *name;
4070   char *gtp;
4071   char *dims;
4072   char dummy[2048];
4073   wxString sql;
4074   bool ok;
4075   int metadata_type;
4076 
4077   outTable = inTable + wxT("_elem");
4078   pKey = wxT("pk_elem");
4079   multiID = wxT("multi_id");
4080   type = wxT("*** Error ***");
4081   *srid = 0;
4082   coordDims = wxT("*** Error ***");
4083   *spIdx = false;
4084 
4085 // fetching metadata
4086   metadata_type = GetMetaDataType();
4087   if (metadata_type == METADATA_LEGACY)
4088     sql =
4089       wxT
4090       ("SELECT type, coord_dimension, srid, spatial_index_enabled FROM geometry_columns ");
4091   else if (metadata_type == METADATA_CURRENT)
4092     sql =
4093       wxT
4094       ("SELECT geometry_type, srid, spatial_index_enabled FROM geometry_columns ");
4095   else
4096     return;
4097   sql += wxT("WHERE Lower(f_table_name) = Lower('");
4098   strcpy(dummy, inTable.ToUTF8());
4099   CleanSqlString(dummy);
4100   sql += wxString::FromUTF8(dummy);
4101   sql += wxT("') AND Lower(f_geometry_column) = Lower('");
4102   strcpy(dummy, geometry.ToUTF8());
4103   CleanSqlString(dummy);
4104   sql += wxString::FromUTF8(dummy);
4105   sql += wxT("')");
4106   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
4107                               &rows, &columns, &errMsg);
4108   if (ret != SQLITE_OK)
4109     {
4110       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
4111                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4112       sqlite3_free(errMsg);
4113       return;
4114     }
4115   if (rows < 1)
4116     ;
4117   else
4118     {
4119       for (i = 1; i <= rows; i++)
4120         {
4121           if (metadata_type == METADATA_LEGACY)
4122             {
4123               /* legacy Spatial MetaData layout */
4124               gtp = results[(i * columns) + 0];
4125               dims = results[(i * columns) + 1];
4126               *srid = atoi(results[(i * columns) + 2]);
4127               if (atoi(results[(i * columns) + 3]) == 0)
4128                 *spIdx = false;
4129               else
4130                 *spIdx = true;
4131               if (strcasecmp(gtp, "POINT") == 0
4132                   || strcasecmp(gtp, "MULTIPOINT") == 0)
4133                 type = wxString::FromUTF8("POINT");
4134               else if (strcasecmp(gtp, "LINESTRING") == 0
4135                        || strcasecmp(gtp, "MULTILINESTRING") == 0)
4136                 type = wxString::FromUTF8("LINESTRING");
4137               else if (strcasecmp(gtp, "POLYGON") == 0
4138                        || strcasecmp(gtp, "MULTIPOLYGON") == 0)
4139                 type = wxString::FromUTF8("POLYGON");
4140               else
4141                 type = wxString::FromUTF8("GEOMETRY");
4142               coordDims = wxString::FromUTF8(dims);
4143           } else
4144             {
4145               /* current Spatial MetaData layout */
4146               switch (atoi(results[(i * columns) + 0]))
4147                 {
4148                   case 0:
4149                   case 1:
4150                   case 2:
4151                   case 3:
4152                   case 7:
4153                     type = wxT("GEOMETRY");
4154                     coordDims = wxT("XY");
4155                     break;
4156                   case 1000:
4157                   case 1001:
4158                   case 1002:
4159                   case 1003:
4160                   case 1007:
4161                     type = wxT("GEOMETRY");
4162                     coordDims = wxT("XYZ");
4163                     break;
4164                   case 2000:
4165                   case 2001:
4166                   case 2002:
4167                   case 2003:
4168                   case 2007:
4169                     type = wxT("GEOMETRY");
4170                     coordDims = wxT("XYM");
4171                     break;
4172                   case 3000:
4173                   case 3001:
4174                   case 3002:
4175                   case 3003:
4176                   case 3007:
4177                     type = wxT("GEOMETRY");
4178                     coordDims = wxT("XYZM");
4179                     break;
4180                   case 4:
4181                     type = wxT("POINT");
4182                     coordDims = wxT("XY");
4183                     break;
4184                   case 1004:
4185                     type = wxT("POINT");
4186                     coordDims = wxT("XYZ");
4187                     break;
4188                   case 2004:
4189                     type = wxT("POINT");
4190                     coordDims = wxT("XYM");
4191                     break;
4192                   case 3004:
4193                     type = wxT("POINT");
4194                     coordDims = wxT("XYZM");
4195                     break;
4196                   case 5:
4197                     type = wxT("LINESTRING");
4198                     coordDims = wxT("XY");
4199                     break;
4200                   case 1005:
4201                     type = wxT("LINESTRING");
4202                     coordDims = wxT("XYZ");
4203                     break;
4204                   case 2005:
4205                     type = wxT("LINESTRING");
4206                     coordDims = wxT("XYM");
4207                     break;
4208                   case 3005:
4209                     type = wxT("LINESTRING");
4210                     coordDims = wxT("XYZM");
4211                     break;
4212                   case 6:
4213                     type = wxT("POLYGON");
4214                     coordDims = wxT("XY");
4215                     break;
4216                   case 1006:
4217                     type = wxT("POLYGON");
4218                     coordDims = wxT("XYZ");
4219                     break;
4220                   case 2006:
4221                     type = wxT("POLYGON");
4222                     coordDims = wxT("XYM");
4223                     break;
4224                   case 3006:
4225                     type = wxT("POLYGON");
4226                     coordDims = wxT("XYZM");
4227                     break;
4228                 };
4229               *srid = atoi(results[(i * columns) + 1]);
4230               if (atoi(results[(i * columns) + 2]) == 0)
4231                 *spIdx = false;
4232               else
4233                 *spIdx = true;
4234             }
4235         }
4236     }
4237   sqlite3_free_table(results);
4238 
4239   ok = true;
4240   while (ok)
4241     {
4242       // creating an unique PrimaryKey name
4243       ok = false;
4244       sql = wxT("PRAGMA table_info(");
4245       strcpy(dummy, inTable.ToUTF8());
4246       DoubleQuotedSql(dummy);
4247       sql += wxString::FromUTF8(dummy);
4248       sql += wxT(")");
4249       ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
4250                               &rows, &columns, &errMsg);
4251       if (ret != SQLITE_OK)
4252         {
4253           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
4254                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4255           sqlite3_free(errMsg);
4256           return;
4257         }
4258       if (rows < 1)
4259         ;
4260       else
4261         {
4262           for (i = 1; i <= rows; i++)
4263             {
4264               name = results[(i * columns) + 1];
4265               wxString x = wxString::FromUTF8(name);
4266               if (x.CmpNoCase(pKey) == 0)
4267                 {
4268                   pKey += wxT("_1");
4269                   ok = true;
4270                   break;
4271                 }
4272             }
4273         }
4274       sqlite3_free_table(results);
4275     }
4276 
4277   ok = true;
4278   while (ok)
4279     {
4280       // creating an unique MultiID name
4281       ok = false;
4282       sql = wxT("PRAGMA table_info(");
4283       strcpy(dummy, inTable.ToUTF8());
4284       DoubleQuotedSql(dummy);
4285       sql += wxString::FromUTF8(dummy);
4286       sql += wxT(")");
4287       ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
4288                               &rows, &columns, &errMsg);
4289       if (ret != SQLITE_OK)
4290         {
4291           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
4292                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4293           sqlite3_free(errMsg);
4294           return;
4295         }
4296       if (rows < 1)
4297         ;
4298       else
4299         {
4300           for (i = 1; i <= rows; i++)
4301             {
4302               name = results[(i * columns) + 1];
4303               wxString x = wxString::FromUTF8(name);
4304               if (x.CmpNoCase(multiID) == 0)
4305                 {
4306                   multiID += wxT("_1");
4307                   ok = true;
4308                   break;
4309                 }
4310             }
4311         }
4312       sqlite3_free_table(results);
4313     }
4314 
4315   ok = true;
4316   while (ok)
4317     {
4318       // creating an unique Table name
4319       ok = false;
4320       sql =
4321         wxT
4322         ("SELECT Count(*) FROM sqlite_master WHERE type = 'table' AND Lower(tbl_name) = Lower('");
4323       strcpy(dummy, outTable.ToUTF8());
4324       CleanSqlString(dummy);
4325       sql += wxString::FromUTF8(dummy);
4326       sql += wxT("')");
4327       ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
4328                               &rows, &columns, &errMsg);
4329       if (ret != SQLITE_OK)
4330         {
4331           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
4332                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4333           sqlite3_free(errMsg);
4334           return;
4335         }
4336       if (rows < 1)
4337         ;
4338       else
4339         {
4340           for (i = 1; i <= rows; i++)
4341             {
4342               if (atoi(results[(i * columns) + 0]) != 0)
4343                 {
4344                   outTable += wxT("_1");
4345                   ok = true;
4346                   break;
4347                 }
4348             }
4349         }
4350       sqlite3_free_table(results);
4351     }
4352 }
4353 
DoElementaryGeometries(wxString & inTable,wxString & geometry,wxString & outTable,wxString & pKey,wxString & multiID,wxString & type,int srid,wxString & coordDims,bool spIdx)4354 bool MyFrame::DoElementaryGeometries(wxString & inTable, wxString & geometry,
4355                                      wxString & outTable, wxString & pKey,
4356                                      wxString & multiID, wxString & type,
4357                                      int srid, wxString & coordDims, bool spIdx)
4358 {
4359 // testing if this table belongs to some R*Tree Spatial Index
4360   int ret;
4361   int i;
4362   char **results;
4363   int rows;
4364   int columns;
4365   wxString sql;
4366   wxString sql2;
4367   wxString sql3;
4368   wxString sql4;
4369   wxString sql_geom;
4370   wxString sql_spidx;
4371   wxString sqlx;
4372   char dummy[8192];
4373   char *errMsg = NULL;
4374   bool comma = false;
4375   sqlite3_stmt *stmt_in = NULL;
4376   sqlite3_stmt *stmt_out = NULL;
4377   int n_columns;
4378   sqlite3_int64 id = 0;
4379   int geom_idx = -1;
4380 
4381 // starts a transaction
4382   ret = sqlite3_exec(SqliteHandle, "BEGIN", NULL, NULL, &errMsg);
4383   if (ret != SQLITE_OK)
4384     {
4385       wxMessageBox(wxT("BEGIN error: ") + wxString::FromUTF8(errMsg),
4386                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4387       sqlite3_free(errMsg);
4388       goto abort;
4389     }
4390 
4391   sql = wxT("SELECT ");
4392   sql2 = wxT("INSERT INTO ");
4393   sql3 = wxT(") VALUES (NULL, ?");
4394   sql4 = wxT("CREATE TABLE ");
4395   strcpy(dummy, outTable.ToUTF8());
4396   DoubleQuotedSql(dummy);
4397   sql2 += wxString::FromUTF8(dummy);
4398   sql2 += wxT(" (");
4399   sql4 += wxString::FromUTF8(dummy);
4400   strcpy(dummy, pKey.ToUTF8());
4401   DoubleQuotedSql(dummy);
4402   sql2 += wxString::FromUTF8(dummy);
4403   sql2 += wxT(", ");
4404   strcpy(dummy, multiID.ToUTF8());
4405   DoubleQuotedSql(dummy);
4406   sql2 += wxString::FromUTF8(dummy);
4407   sql4 += wxT(" (\n\t");
4408   strcpy(dummy, pKey.ToUTF8());
4409   DoubleQuotedSql(dummy);
4410   sql4 += wxString::FromUTF8(dummy);
4411   sql4 += wxT(" INTEGER PRIMARY KEY AUTOINCREMENT");
4412   sql4 += wxT(",\n\t");
4413   strcpy(dummy, multiID.ToUTF8());
4414   DoubleQuotedSql(dummy);
4415   sql4 += wxString::FromUTF8(dummy);
4416   sql4 += wxT(" INTEGER NOT NULL");
4417 
4418   sqlx = wxT("PRAGMA table_info(");
4419   strcpy(dummy, inTable.ToUTF8());
4420   DoubleQuotedSql(dummy);
4421   sqlx += wxString::FromUTF8(dummy);
4422   sqlx += wxT(")");
4423   ret = sqlite3_get_table(SqliteHandle, sqlx.ToUTF8(), &results,
4424                           &rows, &columns, &errMsg);
4425   if (ret != SQLITE_OK)
4426     {
4427       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
4428                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4429       sqlite3_free(errMsg);
4430       goto abort;
4431     }
4432   if (rows < 1)
4433     ;
4434   else
4435     {
4436       for (i = 1; i <= rows; i++)
4437         {
4438           strcpy(dummy, results[(i * columns) + 1]);
4439           DoubleQuotedSql(dummy);
4440           if (comma)
4441             sql += wxT(", ");
4442           else
4443             comma = true;
4444           sql += wxString::FromUTF8(dummy);
4445           sql2 += wxT(", ");
4446           sql2 += wxString::FromUTF8(dummy);
4447           sql3 += wxT(", ?");
4448 
4449           wxString x = wxString::FromUTF8(results[(i * columns) + 1]);
4450           if (x.CmpNoCase(geometry) == 0)
4451             geom_idx = i - 1;
4452           else
4453             {
4454               sql4 += wxT(",\n\t");
4455               sql4 += wxString::FromUTF8(dummy);
4456               sql4 += wxT(" ") + wxString::FromUTF8(results[(i * columns) + 2]);
4457               if (atoi(results[(i * columns) + 3]) != 0)
4458                 sql4 += wxT(" NOT NULL");
4459             }
4460         }
4461     }
4462   sqlite3_free_table(results);
4463   if (geom_idx < 0)
4464     goto abort;
4465 
4466   sql += wxT(" FROM ");
4467   strcpy(dummy, inTable.ToUTF8());
4468   DoubleQuotedSql(dummy);
4469   sql += wxString::FromUTF8(dummy);
4470   sql2 += sql3;
4471   sql2 += wxT(")");
4472   sql4 += wxT(")");
4473 
4474   sql_geom = wxT("SELECT AddGeometryColumn('");
4475   strcpy(dummy, outTable.ToUTF8());
4476   CleanSqlString(dummy);
4477   sql_geom += wxString::FromUTF8(dummy);
4478   sql_geom += wxT("', '");
4479   strcpy(dummy, geometry.ToUTF8());
4480   CleanSqlString(dummy);
4481   sql_geom += wxString::FromUTF8(dummy);
4482   sql_geom += wxT("', ");
4483   sprintf(dummy, "%d, '", srid);
4484   sql_geom += wxString::FromUTF8(dummy);
4485   strcpy(dummy, type.ToUTF8());
4486   CleanSqlString(dummy);
4487   sql_geom += wxString::FromUTF8(dummy);
4488   sql_geom += wxT("', '");
4489   strcpy(dummy, coordDims.ToUTF8());
4490   CleanSqlString(dummy);
4491   sql_geom += wxString::FromUTF8(dummy);
4492   sql_geom += wxT("')");
4493   if (spIdx == true)
4494     {
4495       sql_spidx = wxT("SELECT CreateSpatialIndex('");
4496       strcpy(dummy, outTable.ToUTF8());
4497       CleanSqlString(dummy);
4498       sql_spidx += wxString::FromUTF8(dummy);
4499       sql_spidx += wxT("', '");
4500       strcpy(dummy, geometry.ToUTF8());
4501       CleanSqlString(dummy);
4502       sql_spidx += wxString::FromUTF8(dummy);
4503       sql_spidx += wxT("')");
4504     }
4505 // creating the output table
4506   strcpy(dummy, sql4.ToUTF8());
4507   ret = sqlite3_exec(SqliteHandle, dummy, NULL, NULL, &errMsg);
4508   if (ret != SQLITE_OK)
4509     {
4510       wxMessageBox(wxT("CREATE TABLE error: ") + wxString::FromUTF8(errMsg),
4511                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4512       sqlite3_free(errMsg);
4513       goto abort;
4514     }
4515 // creating the output Geometry
4516   strcpy(dummy, sql_geom.ToUTF8());
4517   ret = sqlite3_exec(SqliteHandle, dummy, NULL, NULL, &errMsg);
4518   if (ret != SQLITE_OK)
4519     {
4520       wxMessageBox(wxT("AddGeometryColumn error: ") +
4521                    wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
4522                    wxOK | wxICON_ERROR, this);
4523       sqlite3_free(errMsg);
4524       goto abort;
4525     }
4526   if (spIdx == true)
4527     {
4528       // creating the R*Tree Spatial Index
4529       strcpy(dummy, sql_spidx.ToUTF8());
4530       ret = sqlite3_exec(SqliteHandle, dummy, NULL, NULL, &errMsg);
4531       if (ret != SQLITE_OK)
4532         {
4533           wxMessageBox(wxT("CreateSpatialIndex error: ") +
4534                        wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
4535                        wxOK | wxICON_ERROR, this);
4536           sqlite3_free(errMsg);
4537           goto abort;
4538         }
4539     }
4540 // preparing the INPUT statement
4541   strcpy(dummy, sql.ToUTF8());
4542   ret = sqlite3_prepare_v2(SqliteHandle, dummy, strlen(dummy), &stmt_in, NULL);
4543   if (ret != SQLITE_OK)
4544     {
4545       wxString err = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
4546       wxMessageBox(wxT("[IN]SQL error: ") + err, wxT("spatialite_gui"),
4547                    wxOK | wxICON_ERROR, this);
4548       goto abort;
4549     }
4550 // preparing the OUTPUT statement
4551   strcpy(dummy, sql2.ToUTF8());
4552   ret = sqlite3_prepare_v2(SqliteHandle, dummy, strlen(dummy), &stmt_out, NULL);
4553   if (ret != SQLITE_OK)
4554     {
4555       wxString err = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
4556       wxMessageBox(wxT("[OUT]SQL error: ") + err, wxT("spatialite_gui"),
4557                    wxOK | wxICON_ERROR, this);
4558       goto abort;
4559     }
4560 // data transfer
4561   n_columns = sqlite3_column_count(stmt_in);
4562   while (1)
4563     {
4564       ret = sqlite3_step(stmt_in);
4565       if (ret == SQLITE_DONE)
4566         break;
4567       if (ret == SQLITE_ROW)
4568         {
4569           gaiaGeomCollPtr g =
4570             gaiaFromSpatiaLiteBlobWkb((const unsigned char *)
4571                                       sqlite3_column_blob(stmt_in, geom_idx),
4572                                       sqlite3_column_bytes(stmt_in, geom_idx));
4573           if (!g)
4574             {
4575               // NULL input geometry
4576               sqlite3_reset(stmt_out);
4577               sqlite3_clear_bindings(stmt_out);
4578               sqlite3_bind_int64(stmt_out, 1, id);
4579               sqlite3_bind_null(stmt_out, geom_idx + 2);
4580 
4581               for (i = 0; i < n_columns; i++)
4582                 {
4583                   int type = sqlite3_column_type(stmt_in, i);
4584                   if (i == geom_idx)
4585                     continue;
4586                   switch (type)
4587                     {
4588                       case SQLITE_INTEGER:
4589                         sqlite3_bind_int64(stmt_out, i + 2,
4590                                            sqlite3_column_int(stmt_in, i));
4591                         break;
4592                       case SQLITE_FLOAT:
4593                         sqlite3_bind_double(stmt_out, i + 2,
4594                                             sqlite3_column_double(stmt_in, i));
4595                         break;
4596                       case SQLITE_TEXT:
4597                         sqlite3_bind_text(stmt_out, i + 2,
4598                                           (const char *)
4599                                           sqlite3_column_text(stmt_in, i),
4600                                           sqlite3_column_bytes(stmt_in, i),
4601                                           SQLITE_STATIC);
4602                         break;
4603                       case SQLITE_BLOB:
4604                         sqlite3_bind_blob(stmt_out, i + 2,
4605                                           sqlite3_column_blob(stmt_in, i),
4606                                           sqlite3_column_bytes(stmt_in, i),
4607                                           SQLITE_STATIC);
4608                         break;
4609                       case SQLITE_NULL:
4610                       default:
4611                         sqlite3_bind_null(stmt_out, i + 2);
4612                         break;
4613                     };
4614                 }
4615 
4616               ret = sqlite3_step(stmt_out);
4617               if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4618                 ;
4619               else
4620                 {
4621                   wxString err =
4622                     wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
4623                   wxMessageBox(wxT("[OUT]step error: ") + err,
4624                                wxT("spatialite_gui"), wxOK | wxICON_ERROR,
4625                                this);
4626                   goto abort;
4627                 }
4628           } else
4629             {
4630               // separating Elementary Geoms
4631               gaiaPointPtr pt;
4632               gaiaLinestringPtr ln;
4633               gaiaPolygonPtr pg;
4634               gaiaGeomCollPtr outGeom;
4635               pt = g->FirstPoint;
4636               while (pt)
4637                 {
4638                   // separating Points
4639                   outGeom = GeomFromPoint(pt, g->Srid);
4640                   sqlite3_reset(stmt_out);
4641                   sqlite3_clear_bindings(stmt_out);
4642                   sqlite3_bind_int64(stmt_out, 1, id);
4643                   if (!outGeom)
4644                     sqlite3_bind_null(stmt_out, geom_idx + 2);
4645                   else
4646                     {
4647                       unsigned char *blob;
4648                       int size;
4649                       gaiaToSpatiaLiteBlobWkb(outGeom, &blob, &size);
4650                       sqlite3_bind_blob(stmt_out, geom_idx + 2, blob, size,
4651                                         free);
4652                       gaiaFreeGeomColl(outGeom);
4653                     }
4654 
4655                   for (i = 0; i < n_columns; i++)
4656                     {
4657                       int type = sqlite3_column_type(stmt_in, i);
4658                       if (i == geom_idx)
4659                         continue;
4660                       switch (type)
4661                         {
4662                           case SQLITE_INTEGER:
4663                             sqlite3_bind_int64(stmt_out, i + 2,
4664                                                sqlite3_column_int(stmt_in, i));
4665                             break;
4666                           case SQLITE_FLOAT:
4667                             sqlite3_bind_double(stmt_out, i + 2,
4668                                                 sqlite3_column_double(stmt_in,
4669                                                                       i));
4670                             break;
4671                           case SQLITE_TEXT:
4672                             sqlite3_bind_text(stmt_out, i + 2,
4673                                               (const char *)
4674                                               sqlite3_column_text(stmt_in, i),
4675                                               sqlite3_column_bytes(stmt_in, i),
4676                                               SQLITE_STATIC);
4677                             break;
4678                           case SQLITE_BLOB:
4679                             sqlite3_bind_blob(stmt_out, i + 2,
4680                                               sqlite3_column_blob(stmt_in, i),
4681                                               sqlite3_column_bytes(stmt_in, i),
4682                                               SQLITE_STATIC);
4683                             break;
4684                           case SQLITE_NULL:
4685                           default:
4686                             sqlite3_bind_null(stmt_out, i + 2);
4687                             break;
4688                         };
4689                     }
4690 
4691                   ret = sqlite3_step(stmt_out);
4692                   if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4693                     ;
4694                   else
4695                     {
4696                       wxString err =
4697                         wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
4698                       wxMessageBox(wxT("[OUT]step error: ") + err,
4699                                    wxT("spatialite_gui"), wxOK | wxICON_ERROR,
4700                                    this);
4701                       goto abort;
4702                     }
4703                   pt = pt->Next;
4704                 }
4705               ln = g->FirstLinestring;
4706               while (ln)
4707                 {
4708                   // separating Linestrings
4709                   outGeom = GeomFromLinestring(ln, g->Srid);
4710                   sqlite3_reset(stmt_out);
4711                   sqlite3_clear_bindings(stmt_out);
4712                   sqlite3_bind_int64(stmt_out, 1, id);
4713                   if (!outGeom)
4714                     sqlite3_bind_null(stmt_out, geom_idx + 2);
4715                   else
4716                     {
4717                       unsigned char *blob;
4718                       int size;
4719                       gaiaToSpatiaLiteBlobWkb(outGeom, &blob, &size);
4720                       sqlite3_bind_blob(stmt_out, geom_idx + 2, blob, size,
4721                                         free);
4722                       gaiaFreeGeomColl(outGeom);
4723                     }
4724 
4725                   for (i = 0; i < n_columns; i++)
4726                     {
4727                       int type = sqlite3_column_type(stmt_in, i);
4728                       if (i == geom_idx)
4729                         continue;
4730                       switch (type)
4731                         {
4732                           case SQLITE_INTEGER:
4733                             sqlite3_bind_int64(stmt_out, i + 2,
4734                                                sqlite3_column_int(stmt_in, i));
4735                             break;
4736                           case SQLITE_FLOAT:
4737                             sqlite3_bind_double(stmt_out, i + 2,
4738                                                 sqlite3_column_double(stmt_in,
4739                                                                       i));
4740                             break;
4741                           case SQLITE_TEXT:
4742                             sqlite3_bind_text(stmt_out, i + 2,
4743                                               (const char *)
4744                                               sqlite3_column_text(stmt_in, i),
4745                                               sqlite3_column_bytes(stmt_in, i),
4746                                               SQLITE_STATIC);
4747                             break;
4748                           case SQLITE_BLOB:
4749                             sqlite3_bind_blob(stmt_out, i + 2,
4750                                               sqlite3_column_blob(stmt_in, i),
4751                                               sqlite3_column_bytes(stmt_in, i),
4752                                               SQLITE_STATIC);
4753                             break;
4754                           case SQLITE_NULL:
4755                           default:
4756                             sqlite3_bind_null(stmt_out, i + 2);
4757                             break;
4758                         };
4759                     }
4760 
4761                   ret = sqlite3_step(stmt_out);
4762                   if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4763                     ;
4764                   else
4765                     {
4766                       wxString err =
4767                         wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
4768                       wxMessageBox(wxT("[OUT]step error: ") + err,
4769                                    wxT("spatialite_gui"), wxOK | wxICON_ERROR,
4770                                    this);
4771                       goto abort;
4772                     }
4773                   ln = ln->Next;
4774                 }
4775               pg = g->FirstPolygon;
4776               while (pg)
4777                 {
4778                   // separating Polygons
4779                   outGeom = GeomFromPolygon(pg, g->Srid);
4780                   sqlite3_reset(stmt_out);
4781                   sqlite3_clear_bindings(stmt_out);
4782                   sqlite3_bind_int64(stmt_out, 1, id);
4783                   if (!outGeom)
4784                     sqlite3_bind_null(stmt_out, geom_idx + 2);
4785                   else
4786                     {
4787                       unsigned char *blob;
4788                       int size;
4789                       gaiaToSpatiaLiteBlobWkb(outGeom, &blob, &size);
4790                       sqlite3_bind_blob(stmt_out, geom_idx + 2, blob, size,
4791                                         free);
4792                       gaiaFreeGeomColl(outGeom);
4793                     }
4794 
4795                   for (i = 0; i < n_columns; i++)
4796                     {
4797                       int type = sqlite3_column_type(stmt_in, i);
4798                       if (i == geom_idx)
4799                         continue;
4800                       switch (type)
4801                         {
4802                           case SQLITE_INTEGER:
4803                             sqlite3_bind_int64(stmt_out, i + 2,
4804                                                sqlite3_column_int(stmt_in, i));
4805                             break;
4806                           case SQLITE_FLOAT:
4807                             sqlite3_bind_double(stmt_out, i + 2,
4808                                                 sqlite3_column_double(stmt_in,
4809                                                                       i));
4810                             break;
4811                           case SQLITE_TEXT:
4812                             sqlite3_bind_text(stmt_out, i + 2,
4813                                               (const char *)
4814                                               sqlite3_column_text(stmt_in, i),
4815                                               sqlite3_column_bytes(stmt_in, i),
4816                                               SQLITE_STATIC);
4817                             break;
4818                           case SQLITE_BLOB:
4819                             sqlite3_bind_blob(stmt_out, i + 2,
4820                                               sqlite3_column_blob(stmt_in, i),
4821                                               sqlite3_column_bytes(stmt_in, i),
4822                                               SQLITE_STATIC);
4823                             break;
4824                           case SQLITE_NULL:
4825                           default:
4826                             sqlite3_bind_null(stmt_out, i + 2);
4827                             break;
4828                         };
4829                     }
4830 
4831                   ret = sqlite3_step(stmt_out);
4832                   if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4833                     ;
4834                   else
4835                     {
4836                       wxString err =
4837                         wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
4838                       wxMessageBox(wxT("[OUT]step error: ") + err,
4839                                    wxT("spatialite_gui"), wxOK | wxICON_ERROR,
4840                                    this);
4841                       goto abort;
4842                     }
4843                   pg = pg->Next;
4844                 }
4845               gaiaFreeGeomColl(g);
4846             }
4847           id++;
4848       } else
4849         {
4850           wxString err = wxString::FromUTF8(sqlite3_errmsg(SqliteHandle));
4851           wxMessageBox(wxT("[IN]step error: ") + err, wxT("spatialite_gui"),
4852                        wxOK | wxICON_ERROR, this);
4853           goto abort;
4854         }
4855     }
4856   sqlite3_finalize(stmt_in);
4857   sqlite3_finalize(stmt_out);
4858 
4859 // commits the transaction
4860   ret = sqlite3_exec(SqliteHandle, "COMMIT", NULL, NULL, &errMsg);
4861   if (ret != SQLITE_OK)
4862     {
4863       wxMessageBox(wxT("COMMIT error: ") + wxString::FromUTF8(errMsg),
4864                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4865       sqlite3_free(errMsg);
4866       goto abort;
4867     }
4868   return true;
4869 
4870 abort:
4871   if (stmt_in)
4872     sqlite3_finalize(stmt_in);
4873   if (stmt_out)
4874     sqlite3_finalize(stmt_out);
4875   return false;
4876 }
4877 
GeomFromPoint(gaiaPointPtr pt,int srid)4878 gaiaGeomCollPtr MyFrame::GeomFromPoint(gaiaPointPtr pt, int srid)
4879 {
4880 // creating a Geometry containing a single Point
4881   gaiaGeomCollPtr g = NULL;
4882   switch (pt->DimensionModel)
4883     {
4884       case GAIA_XY_Z_M:
4885         g = gaiaAllocGeomCollXYZM();
4886         break;
4887       case GAIA_XY_Z:
4888         g = gaiaAllocGeomCollXYZ();
4889         break;
4890       case GAIA_XY_M:
4891         g = gaiaAllocGeomCollXYM();
4892         break;
4893       default:
4894         g = gaiaAllocGeomColl();
4895         break;
4896     };
4897   if (!g)
4898     return NULL;
4899   g->Srid = srid;
4900   g->DeclaredType = GAIA_POINT;
4901   switch (pt->DimensionModel)
4902     {
4903       case GAIA_XY_Z_M:
4904         gaiaAddPointToGeomCollXYZM(g, pt->X, pt->Y, pt->Z, pt->M);
4905         break;
4906       case GAIA_XY_Z:
4907         gaiaAddPointToGeomCollXYZ(g, pt->X, pt->Y, pt->Z);
4908         break;
4909       case GAIA_XY_M:
4910         gaiaAddPointToGeomCollXYM(g, pt->X, pt->Y, pt->M);
4911         break;
4912       default:
4913         gaiaAddPointToGeomColl(g, pt->X, pt->Y);
4914         break;
4915     };
4916   return g;
4917 }
4918 
GeomFromLinestring(gaiaLinestringPtr ln,int srid)4919 gaiaGeomCollPtr MyFrame::GeomFromLinestring(gaiaLinestringPtr ln, int srid)
4920 {
4921 // creating a Geometry containing a single Linestring
4922   gaiaGeomCollPtr g = NULL;
4923   gaiaLinestringPtr ln2;
4924   int iv;
4925   double x;
4926   double y;
4927   double z;
4928   double m;
4929   switch (ln->DimensionModel)
4930     {
4931       case GAIA_XY_Z_M:
4932         g = gaiaAllocGeomCollXYZM();
4933         break;
4934       case GAIA_XY_Z:
4935         g = gaiaAllocGeomCollXYZ();
4936         break;
4937       case GAIA_XY_M:
4938         g = gaiaAllocGeomCollXYM();
4939         break;
4940       default:
4941         g = gaiaAllocGeomColl();
4942         break;
4943     };
4944   if (!g)
4945     return NULL;
4946   g->Srid = srid;
4947   g->DeclaredType = GAIA_LINESTRING;
4948   ln2 = gaiaAddLinestringToGeomColl(g, ln->Points);
4949   switch (ln->DimensionModel)
4950     {
4951       case GAIA_XY_Z_M:
4952         for (iv = 0; iv < ln->Points; iv++)
4953           {
4954             gaiaGetPointXYZM(ln->Coords, iv, &x, &y, &z, &m);
4955             gaiaSetPointXYZM(ln2->Coords, iv, x, y, z, m);
4956           }
4957         break;
4958       case GAIA_XY_Z:
4959         for (iv = 0; iv < ln->Points; iv++)
4960           {
4961             gaiaGetPointXYZ(ln->Coords, iv, &x, &y, &z);
4962             gaiaSetPointXYZ(ln2->Coords, iv, x, y, z);
4963           }
4964         break;
4965       case GAIA_XY_M:
4966         for (iv = 0; iv < ln->Points; iv++)
4967           {
4968             gaiaGetPointXYM(ln->Coords, iv, &x, &y, &m);
4969             gaiaSetPointXYM(ln2->Coords, iv, x, y, m);
4970           }
4971         break;
4972       default:
4973         for (iv = 0; iv < ln->Points; iv++)
4974           {
4975             gaiaGetPoint(ln->Coords, iv, &x, &y);
4976             gaiaSetPoint(ln2->Coords, iv, x, y);
4977           }
4978         break;
4979     };
4980   return g;
4981 }
4982 
GeomFromPolygon(gaiaPolygonPtr pg,int srid)4983 gaiaGeomCollPtr MyFrame::GeomFromPolygon(gaiaPolygonPtr pg, int srid)
4984 {
4985 // creating a Geometry containing a single Polygon
4986   gaiaGeomCollPtr g = NULL;
4987   gaiaPolygonPtr pg2;
4988   gaiaRingPtr rng;
4989   gaiaRingPtr rng2;
4990   int ib;
4991   int iv;
4992   double x;
4993   double y;
4994   double z;
4995   double m;
4996   switch (pg->DimensionModel)
4997     {
4998       case GAIA_XY_Z_M:
4999         g = gaiaAllocGeomCollXYZM();
5000         break;
5001       case GAIA_XY_Z:
5002         g = gaiaAllocGeomCollXYZ();
5003         break;
5004       case GAIA_XY_M:
5005         g = gaiaAllocGeomCollXYM();
5006         break;
5007       default:
5008         g = gaiaAllocGeomColl();
5009         break;
5010     };
5011   if (!g)
5012     return NULL;
5013   g->Srid = srid;
5014   g->DeclaredType = GAIA_POLYGON;
5015   rng = pg->Exterior;
5016   pg2 = gaiaAddPolygonToGeomColl(g, rng->Points, pg->NumInteriors);
5017   rng2 = pg2->Exterior;
5018   switch (pg->DimensionModel)
5019     {
5020       case GAIA_XY_Z_M:
5021         for (iv = 0; iv < rng->Points; iv++)
5022           {
5023             gaiaGetPointXYZM(rng->Coords, iv, &x, &y, &z, &m);
5024             gaiaSetPointXYZM(rng2->Coords, iv, x, y, z, m);
5025           }
5026         for (ib = 0; ib < pg->NumInteriors; ib++)
5027           {
5028             rng = pg->Interiors + ib;
5029             rng2 = gaiaAddInteriorRing(pg2, ib, rng->Points);
5030             for (iv = 0; iv < rng->Points; iv++)
5031               {
5032                 gaiaGetPointXYZM(rng->Coords, iv, &x, &y, &z, &m);
5033                 gaiaSetPointXYZM(rng2->Coords, iv, x, y, z, m);
5034               }
5035           }
5036         break;
5037       case GAIA_XY_Z:
5038         for (iv = 0; iv < rng->Points; iv++)
5039           {
5040             gaiaGetPointXYZ(rng->Coords, iv, &x, &y, &z);
5041             gaiaSetPointXYZ(rng2->Coords, iv, x, y, z);
5042           }
5043         for (ib = 0; ib < pg->NumInteriors; ib++)
5044           {
5045             rng = pg->Interiors + ib;
5046             rng2 = gaiaAddInteriorRing(pg2, ib, rng->Points);
5047             for (iv = 0; iv < rng->Points; iv++)
5048               {
5049                 gaiaGetPointXYZ(rng->Coords, iv, &x, &y, &z);
5050                 gaiaSetPointXYZ(rng2->Coords, iv, x, y, z);
5051               }
5052           }
5053         break;
5054       case GAIA_XY_M:
5055         for (iv = 0; iv < rng->Points; iv++)
5056           {
5057             gaiaGetPointXYM(rng->Coords, iv, &x, &y, &m);
5058             gaiaSetPointXYM(rng2->Coords, iv, x, y, m);
5059           }
5060         for (ib = 0; ib < pg->NumInteriors; ib++)
5061           {
5062             rng = pg->Interiors + ib;
5063             rng2 = gaiaAddInteriorRing(pg2, ib, rng->Points);
5064             for (iv = 0; iv < rng->Points; iv++)
5065               {
5066                 gaiaGetPointXYM(rng->Coords, iv, &x, &y, &m);
5067                 gaiaSetPointXYM(rng2->Coords, iv, x, y, m);
5068               }
5069           }
5070         break;
5071       default:
5072         for (iv = 0; iv < rng->Points; iv++)
5073           {
5074             gaiaGetPoint(rng->Coords, iv, &x, &y);
5075             gaiaSetPoint(rng2->Coords, iv, x, y);
5076           }
5077         for (ib = 0; ib < pg->NumInteriors; ib++)
5078           {
5079             rng = pg->Interiors + ib;
5080             rng2 = gaiaAddInteriorRing(pg2, ib, rng->Points);
5081             for (iv = 0; iv < rng->Points; iv++)
5082               {
5083                 gaiaGetPoint(rng->Coords, iv, &x, &y);
5084                 gaiaSetPoint(rng2->Coords, iv, x, y);
5085               }
5086           }
5087         break;
5088     };
5089   return g;
5090 }
5091 
InitTableTree()5092 void MyFrame::InitTableTree()
5093 {
5094 // loads the table TREE list
5095   int i;
5096   char **results;
5097   int rows;
5098   int columns;
5099   char *errMsg = NULL;
5100   char *name;
5101   char *createSql;
5102   char *type;
5103   wxString tblName;
5104   wxString sql;
5105   bool virtualTable = false;
5106   TableTree->Show(false);
5107   if (MemoryDatabase == true)
5108     {
5109       wxString memory = wxT("MEMORY-DB");
5110       TableTree->SetPath(memory);
5111   } else
5112     TableTree->SetPath(SqlitePath);
5113   TableTree->FlushAll();
5114   if (ExistsTopologyMaster())
5115     {
5116       //
5117       wxString column_list;
5118       GetTopologyColumns(&column_list);
5119       // fetching topologies
5120       sql = wxT("SELECT ");
5121       sql += column_list;
5122       sql += wxT(" FROM topology_master");
5123       int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
5124                                   &rows, &columns, &errMsg);
5125       if (ret != SQLITE_OK)
5126         {
5127           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5128                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5129           sqlite3_free(errMsg);
5130           return;
5131         }
5132       if (rows < 1)
5133         ;
5134       else
5135         {
5136           int srid_column = -1;
5137           int dims_column = -1;
5138           for (int c = 0; c < columns; c++)
5139             {
5140               const char *name = results[c];
5141               if (strcasecmp(name, "srid") == 0)
5142                 srid_column = c;
5143               if (strcasecmp(name, "coord_dimension") == 0)
5144                 dims_column = c;
5145             }
5146           for (i = 1; i <= rows; i++)
5147             {
5148               // adding some Topology
5149               TopologySet topology;
5150               for (int c = 0; c < columns; c++)
5151                 {
5152                   const char *name = results[(i * columns) + c];
5153                   if (name != NULL)
5154                     {
5155                       if (c == srid_column)
5156                         topology.SetSrid(atoi(name));
5157                       else if (c == dims_column)
5158                         topology.SetCoordDims(name);
5159                       else
5160                         {
5161                           bool table;
5162                           bool view;
5163                           CheckIfExists(name, &table, &view);
5164                           if (table == true || view == true)
5165                             topology.Add(name, table, view);
5166                         }
5167                     }
5168                 }
5169               if (topology.CheckPrefix() == true)
5170                 TableTree->AddTopology(&topology);
5171             }
5172         }
5173       sqlite3_free_table(results);
5174     }
5175 // fetching persistent tables and views
5176   sql =
5177     wxT
5178     ("SELECT name, sql, type FROM sqlite_master WHERE (type = 'table' OR type = 'view') ORDER BY name");
5179   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
5180                               &rows, &columns, &errMsg);
5181   if (ret != SQLITE_OK)
5182     {
5183       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5184                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5185       sqlite3_free(errMsg);
5186       return;
5187     }
5188   if (rows < 1)
5189     ;
5190   else
5191     {
5192       for (i = 1; i <= rows; i++)
5193         {
5194           name = results[(i * columns) + 0];
5195           createSql = results[(i * columns) + 1];
5196           type = results[(i * columns) + 2];
5197           if (strstr(createSql, " VIRTUAL ") || strstr(createSql, " virtual "))
5198             virtualTable = true;
5199           else
5200             virtualTable = false;
5201           tblName = wxString::FromUTF8(name);
5202           if (strcmp(type, "view") == 0)
5203             TableTree->AddView(tblName, false);
5204           else
5205             TableTree->AddTable(tblName, virtualTable, false);
5206         }
5207     }
5208   sqlite3_free_table(results);
5209 // fetching temporary tables and views
5210   sql =
5211     wxT
5212     ("SELECT name, sql, type FROM sqlite_temp_master WHERE (type = 'table' OR type = 'view') ORDER BY name");
5213   ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
5214                           &rows, &columns, &errMsg);
5215   if (ret != SQLITE_OK)
5216     {
5217       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5218                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5219       sqlite3_free(errMsg);
5220       return;
5221     }
5222   if (rows < 1)
5223     ;
5224   else
5225     {
5226       for (i = 1; i <= rows; i++)
5227         {
5228           name = results[(i * columns) + 0];
5229           createSql = results[(i * columns) + 1];
5230           type = results[(i * columns) + 2];
5231           if (strstr(createSql, " VIRTUAL ") || strstr(createSql, " virtual "))
5232             virtualTable = true;
5233           else
5234             virtualTable = false;
5235           tblName = wxString::FromUTF8(name);
5236           if (strcmp(type, "view") == 0)
5237             TableTree->AddView(tblName, true);
5238           else
5239             TableTree->AddTable(tblName, virtualTable, true);
5240         }
5241     }
5242   sqlite3_free_table(results);
5243   ListAttached();
5244   TableTree->ExpandRoot();
5245   TableTree->Show(true);
5246 }
5247 
InitTableTree(wxString & dbAlias,wxString & path)5248 void MyFrame::InitTableTree(wxString & dbAlias, wxString & path)
5249 {
5250 // loads the table TREE list [ATTACHED DB]
5251   int i;
5252   char **results;
5253   int rows;
5254   int columns;
5255   char *errMsg = NULL;
5256   char *name;
5257   char *createSql;
5258   char *type;
5259   wxString tblName;
5260   wxString sql;
5261   bool virtualTable = false;
5262   wxString dbInfos = dbAlias + wxT(": ") + path;
5263   wxTreeItemId db = TableTree->AppendItem(TableTree->GetRootItem(), dbInfos);
5264   TableTree->SetItemData(db,
5265                          (wxTreeItemData *) (new
5266                                              MyObject(MY_ATTACHED, true,
5267                                                       dbAlias, path)));
5268   TableTree->SetItemImage(db, 21);
5269   wxTreeItemId rootUserData = TableTree->AppendItem(db, wxT("User Data"));
5270   wxTreeItemId rootIsoMetadata = TableTree->AppendItem(db, wxT("ISO Metadata"));
5271   wxTreeItemId rootStyling = TableTree->AppendItem(db, wxT("Styling"));
5272   wxTreeItemId rootTopologies = TableTree->AppendItem(db, wxT("Topologies"));
5273   wxTreeItemId rootMetadata = TableTree->AppendItem(db, wxT("Metadata"));
5274   wxTreeItemId rootInternal = TableTree->AppendItem(db, wxT("Internal Data"));
5275   wxTreeItemId rootSpatialIndex =
5276     TableTree->AppendItem(db, wxT("Spatial Index"));
5277   TableTree->SetItemImage(rootUserData, 17);
5278   TableTree->SetItemImage(rootTopologies, 17);
5279   TableTree->SetItemImage(rootStyling, 17);
5280   TableTree->SetItemImage(rootIsoMetadata, 17);
5281   TableTree->SetItemImage(rootMetadata, 17);
5282   TableTree->SetItemImage(rootInternal, 17);
5283   TableTree->SetItemImage(rootSpatialIndex, 17);
5284   RootNodes nodes =
5285     RootNodes(dbAlias, rootUserData, rootTopologies, rootStyling,
5286               rootIsoMetadata, rootMetadata,
5287               rootInternal,
5288               rootSpatialIndex);
5289   if (ExistsTopologyMaster(dbAlias))
5290     {
5291       //
5292       wxString column_list;
5293       GetTopologyColumns(dbAlias, &column_list);
5294       // fetching topologies
5295       sql = wxT("SELECT ");
5296       sql += column_list;
5297       sql += wxT(" FROM ") + dbAlias + wxT(".topology_master");
5298       int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
5299                                   &rows, &columns, &errMsg);
5300       if (ret != SQLITE_OK)
5301         {
5302           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5303                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5304           sqlite3_free(errMsg);
5305           return;
5306         }
5307       if (rows < 1)
5308         ;
5309       else
5310         {
5311           int srid_column = -1;
5312           int dims_column = -1;
5313           for (int c = 0; c < columns; c++)
5314             {
5315               const char *name = results[c];
5316               if (strcasecmp(name, "srid") == 0)
5317                 srid_column = c;
5318               if (strcasecmp(name, "coord_dimension") == 0)
5319                 dims_column = c;
5320             }
5321           for (i = 1; i <= rows; i++)
5322             {
5323               // adding some Topology
5324               TopologySet topology;
5325               for (int c = 0; c < columns; c++)
5326                 {
5327                   const char *name = results[(i * columns) + c];
5328                   if (name != NULL)
5329                     {
5330                       if (c == srid_column)
5331                         topology.SetSrid(atoi(name));
5332                       else if (c == dims_column)
5333                         topology.SetCoordDims(name);
5334                       else
5335                         {
5336                           bool table;
5337                           bool view;
5338                           CheckIfExists(dbAlias, name, &table, &view);
5339                           if (table == true || view == true)
5340                             topology.Add(name, table, view);
5341                         }
5342                     }
5343                 }
5344               if (topology.CheckPrefix() == true)
5345                 TableTree->AddTopology(rootTopologies, &topology);
5346             }
5347         }
5348       sqlite3_free_table(results);
5349     }
5350 // fetching tables and views
5351   sql = wxT("SELECT name, sql, type FROM ");
5352   sql += dbAlias;
5353   sql +=
5354     wxT(".sqlite_master WHERE (type = 'table' OR type = 'view') ORDER BY name");
5355   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
5356                               &rows, &columns, &errMsg);
5357   if (ret != SQLITE_OK)
5358     {
5359       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5360                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5361       sqlite3_free(errMsg);
5362       return;
5363     }
5364   if (rows < 1)
5365     ;
5366   else
5367     {
5368       for (i = 1; i <= rows; i++)
5369         {
5370           name = results[(i * columns) + 0];
5371           createSql = results[(i * columns) + 1];
5372           type = results[(i * columns) + 2];
5373           if (strstr(createSql, " VIRTUAL ") || strstr(createSql, " virtual "))
5374             virtualTable = true;
5375           else
5376             virtualTable = false;
5377           tblName = wxString::FromUTF8(name);
5378           if (strcmp(type, "view") == 0)
5379             TableTree->AddView(dbAlias, tblName, &nodes);
5380           else
5381             TableTree->AddTable(dbAlias, tblName, virtualTable, &nodes);
5382         }
5383     }
5384   sqlite3_free_table(results);
5385 }
5386 
ListAttached()5387 void MyFrame::ListAttached()
5388 {
5389 //
5390 // listing all Attached DBs
5391 //
5392   int ret;
5393   char **results;
5394   int rows;
5395   int columns;
5396   int i;
5397   char *errMsg = NULL;
5398   ret = sqlite3_get_table(GetSqlite(), "PRAGMA database_list", &results,
5399                           &rows, &columns, &errMsg);
5400   if (ret != SQLITE_OK)
5401     {
5402       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5403                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5404       sqlite3_free(errMsg);
5405       return;
5406     }
5407   if (rows < 1)
5408     ;
5409   else
5410     {
5411       for (i = 1; i <= rows; i++)
5412         {
5413           if (strcasecmp("main", results[(i * columns) + 1]) == 0)
5414             continue;
5415           if (strcasecmp("temp", results[(i * columns) + 1]) == 0)
5416             continue;
5417           wxString dbAlias = wxString::FromUTF8(results[(i * columns) + 1]);
5418           wxString dbPath = wxString::FromUTF8(results[(i * columns) + 2]);
5419           InitTableTree(dbAlias, dbPath);
5420         }
5421     }
5422   sqlite3_free_table(results);
5423 }
5424 
GetTables(int * n)5425 wxString *MyFrame::GetTables(int *n)
5426 {
5427 // loads the table list
5428   int i;
5429   char **results;
5430   int rows;
5431   int columns;
5432   char *errMsg = NULL;
5433   char *name;
5434   wxString *tables = NULL;
5435   wxString sql;
5436   *n = 0;
5437   sql =
5438     wxT("SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name");
5439   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
5440                               &rows, &columns, &errMsg);
5441   if (ret != SQLITE_OK)
5442     {
5443       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5444                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5445       sqlite3_free(errMsg);
5446       return tables;
5447     }
5448   if (rows < 1)
5449     ;
5450   else
5451     {
5452       tables = new wxString[rows];
5453       *n = rows;
5454       for (i = 1; i <= rows; i++)
5455         {
5456           name = results[(i * columns) + 0];
5457           tables[i - 1] = wxString::FromUTF8(name);
5458         }
5459     }
5460   sqlite3_free_table(results);
5461   return tables;
5462 }
5463 
GetTableColumns(wxString & tableName,MyTableInfo * list)5464 void MyFrame::GetTableColumns(wxString & tableName, MyTableInfo * list)
5465 {
5466 // loads the table's column list
5467   int i;
5468   char **results;
5469   int rows;
5470   int columns;
5471   char *errMsg = NULL;
5472   char *name;
5473   char *column;
5474   wxString Name;
5475   wxString Column;
5476   bool pKey;
5477   bool index;
5478   bool cached;
5479   wxString sql;
5480   char xname[1024];
5481   sql = wxT("PRAGMA table_info(");
5482   strcpy(xname, tableName.ToUTF8());
5483   DoubleQuotedSql(xname);
5484   sql += wxString::FromUTF8(xname);
5485   sql += wxT(")");
5486   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
5487                               &rows, &columns, &errMsg);
5488   if (ret != SQLITE_OK)
5489     {
5490       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5491                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5492       sqlite3_free(errMsg);
5493       return;
5494     }
5495   if (rows < 1)
5496     ;
5497   else
5498     {
5499       for (i = 1; i <= rows; i++)
5500         {
5501           name = results[(i * columns) + 1];
5502           if (atoi(results[(i * columns) + 5]) == 0)
5503             pKey = false;
5504           else
5505             pKey = true;
5506           Name = wxString::FromUTF8(name);
5507           list->AddColumn(Name, pKey);
5508         }
5509     }
5510   sqlite3_free_table(results);
5511   if (CheckMetadata() == true)
5512     {
5513       // ok, Spatial MetaData exists; retrieving Geometries and Spatial Indices
5514       sql =
5515         wxT
5516         ("SELECT f_geometry_column, spatial_index_enabled FROM geometry_columns ");
5517       sql += wxT("WHERE Lower(f_table_name) = Lower('");
5518       strcpy(xname, tableName.ToUTF8());
5519       CleanSqlString(xname);
5520       sql += wxString::FromUTF8(xname);
5521       sql += wxT("')");
5522       ret =
5523         sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results, &rows, &columns,
5524                           &errMsg);
5525       if (ret != SQLITE_OK)
5526         {
5527           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5528                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5529           sqlite3_free(errMsg);
5530           return;
5531         }
5532       if (rows < 1)
5533         ;
5534       else
5535         {
5536           for (i = 1; i <= rows; i++)
5537             {
5538               column = results[(i * columns) + 0];
5539               if (atoi(results[(i * columns) + 1]) == 1)
5540                 index = true;
5541               else
5542                 index = false;
5543               if (atoi(results[(i * columns) + 1]) == 2)
5544                 cached = true;
5545               else
5546                 cached = false;
5547               Column = wxString::FromUTF8(column);
5548               list->SetGeometry(Column, index, cached);
5549             }
5550         }
5551       sqlite3_free_table(results);
5552 
5553       if (HasVirtsMetadata() == true)
5554         {
5555           // may also be some VirtualShape
5556           sql = wxT("SELECT virt_geometry FROM virts_geometry_columns ");
5557           sql += wxT("WHERE Lower(virt_name) = Lower('");
5558           strcpy(xname, tableName.ToUTF8());
5559           CleanSqlString(xname);
5560           sql += wxString::FromUTF8(xname);
5561           sql += wxT("')");
5562           ret =
5563             sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results, &rows,
5564                               &columns, &errMsg);
5565           if (ret != SQLITE_OK)
5566             {
5567               wxMessageBox(wxT("SQLite SQL error: ") +
5568                            wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
5569                            wxOK | wxICON_ERROR, this);
5570               sqlite3_free(errMsg);
5571               return;
5572             }
5573           if (rows < 1)
5574             ;
5575           else
5576             {
5577               for (i = 1; i <= rows; i++)
5578                 {
5579                   column = results[(i * columns) + 0];
5580                   Column = wxString::FromUTF8(column);
5581                   list->SetGeometry(Column, false, false);
5582                 }
5583             }
5584           sqlite3_free_table(results);
5585         }
5586     }
5587 }
5588 
GetTableColumns(wxString & dbAlias,wxString & tableName,MyTableInfo * list)5589 void MyFrame::GetTableColumns(wxString & dbAlias, wxString & tableName,
5590                               MyTableInfo * list)
5591 {
5592 // loads the table's column list [Attached DB]
5593   int i;
5594   char **results;
5595   int rows;
5596   int columns;
5597   char *errMsg = NULL;
5598   char *name;
5599   char *column;
5600   wxString Name;
5601   wxString Column;
5602   bool pKey;
5603   bool index;
5604   bool cached;
5605   wxString sql;
5606   char xname[1024];
5607   sql = wxT("PRAGMA ") + dbAlias + wxT(".table_info(");
5608   strcpy(xname, tableName.ToUTF8());
5609   DoubleQuotedSql(xname);
5610   sql += wxString::FromUTF8(xname);
5611   sql += wxT(")");
5612   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
5613                               &rows, &columns, &errMsg);
5614   if (ret != SQLITE_OK)
5615     {
5616       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5617                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5618       sqlite3_free(errMsg);
5619       return;
5620     }
5621   if (rows < 1)
5622     ;
5623   else
5624     {
5625       for (i = 1; i <= rows; i++)
5626         {
5627           name = results[(i * columns) + 1];
5628           if (atoi(results[(i * columns) + 5]) == 0)
5629             pKey = false;
5630           else
5631             pKey = true;
5632           Name = wxString::FromUTF8(name);
5633           list->AddColumn(Name, pKey);
5634         }
5635     }
5636   sqlite3_free_table(results);
5637   if (CheckMetadata(dbAlias) == true)
5638     {
5639       // ok, Spatial MetaData exists; retrieving Geometries and Spatial Indices
5640       sql = wxT("SELECT f_geometry_column, spatial_index_enabled FROM ");
5641       sql += dbAlias + wxT(".geometry_columns ");
5642       sql += wxT("WHERE Lower(f_table_name) = Lower('");
5643       strcpy(xname, tableName.ToUTF8());
5644       CleanSqlString(xname);
5645       sql += wxString::FromUTF8(xname);
5646       sql += wxT("')");
5647       ret =
5648         sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results, &rows, &columns,
5649                           &errMsg);
5650       if (ret != SQLITE_OK)
5651         {
5652           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5653                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5654           sqlite3_free(errMsg);
5655           return;
5656         }
5657       if (rows < 1)
5658         ;
5659       else
5660         {
5661           for (i = 1; i <= rows; i++)
5662             {
5663               column = results[(i * columns) + 0];
5664               if (atoi(results[(i * columns) + 1]) == 1)
5665                 index = true;
5666               else
5667                 index = false;
5668               if (atoi(results[(i * columns) + 1]) == 2)
5669                 cached = true;
5670               else
5671                 cached = false;
5672               Column = wxString::FromUTF8(column);
5673               list->SetGeometry(Column, index, cached);
5674             }
5675         }
5676       sqlite3_free_table(results);
5677 
5678       if (HasVirtsMetadata(dbAlias) == true)
5679         {
5680           // may also be some VirtualShape
5681           sql = wxT("SELECT virt_geometry FROM ");
5682           sql += dbAlias + wxT(".virts_geometry_columns ");
5683           sql += wxT("WHERE Lower(virt_name) = Lower('");
5684           strcpy(xname, tableName.ToUTF8());
5685           CleanSqlString(xname);
5686           sql += wxString::FromUTF8(xname);
5687           sql += wxT("')");
5688           ret =
5689             sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results, &rows,
5690                               &columns, &errMsg);
5691           if (ret != SQLITE_OK)
5692             {
5693               wxMessageBox(wxT("SQLite SQL error: ") +
5694                            wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
5695                            wxOK | wxICON_ERROR, this);
5696               sqlite3_free(errMsg);
5697               return;
5698             }
5699           if (rows < 1)
5700             ;
5701           else
5702             {
5703               for (i = 1; i <= rows; i++)
5704                 {
5705                   column = results[(i * columns) + 0];
5706                   Column = wxString::FromUTF8(column);
5707                   list->SetGeometry(Column, false, false);
5708                 }
5709             }
5710           sqlite3_free_table(results);
5711         }
5712     }
5713 }
5714 
IsPrimaryKey(wxString & tableName,wxString & columnName)5715 bool MyFrame::IsPrimaryKey(wxString & tableName, wxString & columnName)
5716 {
5717 // checking if some column is a PRIMARY KEY
5718   int i;
5719   char **results;
5720   int rows;
5721   int columns;
5722   char *errMsg = NULL;
5723   char *name;
5724   bool pk = false;
5725   wxString sql;
5726   char column[1024];
5727   char xname[1024];
5728   strcpy(column, columnName.ToUTF8());
5729   sql = wxT("PRAGMA table_info(");
5730   strcpy(xname, tableName.ToUTF8());
5731   DoubleQuotedSql(xname);
5732   sql += wxString::FromUTF8(xname);
5733   sql += wxT(")");
5734   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
5735                               &rows, &columns, &errMsg);
5736   if (ret != SQLITE_OK)
5737     {
5738       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5739                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5740       sqlite3_free(errMsg);
5741       return false;
5742     }
5743   if (rows < 1)
5744     ;
5745   else
5746     {
5747       for (i = 1; i <= rows; i++)
5748         {
5749           name = results[(i * columns) + 1];
5750           if (strcasecmp(name, column) == 0)
5751             {
5752               if (atoi(results[(i * columns) + 5]) != 0)
5753                 pk = true;
5754             }
5755         }
5756     }
5757   sqlite3_free_table(results);
5758   return pk;
5759 }
5760 
GetViewColumns(wxString & tableName,MyViewInfo * list)5761 void MyFrame::GetViewColumns(wxString & tableName, MyViewInfo * list)
5762 {
5763 // loads the view's column list
5764   int i;
5765   char **results;
5766   int rows;
5767   int columns;
5768   char *errMsg = NULL;
5769   char *name;
5770   char *column;
5771   wxString Name;
5772   wxString Column;
5773   bool index;
5774   bool cached;
5775   wxString sql;
5776   char xname[1024];
5777   char xsql[4192];
5778   sql = wxT("PRAGMA table_info(");
5779   strcpy(xname, tableName.ToUTF8());
5780   DoubleQuotedSql(xname);
5781   sql += wxString::FromUTF8(xname);
5782   sql += wxT(")");
5783   strcpy(xsql, sql.ToUTF8());
5784   int ret = sqlite3_get_table(SqliteHandle, xsql, &results,
5785                               &rows, &columns, &errMsg);
5786   if (ret != SQLITE_OK)
5787     {
5788       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5789                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5790       sqlite3_free(errMsg);
5791       return;
5792     }
5793   if (rows < 1)
5794     ;
5795   else
5796     {
5797       for (i = 1; i <= rows; i++)
5798         {
5799           name = results[(i * columns) + 1];
5800           Name = wxString::FromUTF8(name);
5801           list->AddColumn(Name);
5802         }
5803     }
5804   sqlite3_free_table(results);
5805   if (HasViewsMetadata() == true)
5806     {
5807       // ok, Spatial MetaData exists; retrieving Geometries and Spatial Indices
5808       sql = wxT("SELECT a.view_geometry, b.spatial_index_enabled ");
5809       sql += wxT("FROM views_geometry_columns AS a ");
5810       sql += wxT("JOIN geometry_columns AS b ON (");
5811       sql += wxT("Lower(a.f_table_name) = Lower(b.f_table_name) AND ");
5812       sql += wxT("Lower(a.f_geometry_column) = Lower(b.f_geometry_column)) ");
5813       sql += wxT("WHERE Lower(view_name) = Lower('");
5814       strcpy(xname, tableName.ToUTF8());
5815       CleanSqlString(xname);
5816       sql += wxString::FromUTF8(xname);
5817       sql += wxT("')");
5818       strcpy(xsql, sql.ToUTF8());
5819       ret =
5820         sqlite3_get_table(SqliteHandle, xsql, &results, &rows, &columns,
5821                           &errMsg);
5822       if (ret != SQLITE_OK)
5823         {
5824           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5825                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5826           sqlite3_free(errMsg);
5827           return;
5828         }
5829       if (rows < 1)
5830         ;
5831       else
5832         {
5833           for (i = 1; i <= rows; i++)
5834             {
5835               column = results[(i * columns) + 0];
5836               if (atoi(results[(i * columns) + 1]) == 1)
5837                 index = true;
5838               else
5839                 index = false;
5840               if (atoi(results[(i * columns) + 1]) == 2)
5841                 cached = true;
5842               else
5843                 cached = false;
5844               Column = wxString::FromUTF8(column);
5845               list->SetGeometry(Column, index, cached);
5846             }
5847         }
5848       sqlite3_free_table(results);
5849     }
5850 }
5851 
GetViewColumns(wxString & dbAlias,wxString & tableName,MyViewInfo * list)5852 void MyFrame::GetViewColumns(wxString & dbAlias, wxString & tableName,
5853                              MyViewInfo * list)
5854 {
5855 // loads the view's column list [Attached DB]
5856   int i;
5857   char **results;
5858   int rows;
5859   int columns;
5860   char *errMsg = NULL;
5861   char *name;
5862   char *column;
5863   wxString Name;
5864   wxString Column;
5865   bool index;
5866   bool cached;
5867   wxString sql;
5868   char xname[1024];
5869   char xsql[4192];
5870   sql = wxT("PRAGMA ") + dbAlias + wxT(".table_info(");
5871   strcpy(xname, tableName.ToUTF8());
5872   DoubleQuotedSql(xname);
5873   sql += wxString::FromUTF8(xname);
5874   sql += wxT(")");
5875   strcpy(xsql, sql.ToUTF8());
5876   int ret = sqlite3_get_table(SqliteHandle, xsql, &results,
5877                               &rows, &columns, &errMsg);
5878   if (ret != SQLITE_OK)
5879     {
5880       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5881                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5882       sqlite3_free(errMsg);
5883       return;
5884     }
5885   if (rows < 1)
5886     ;
5887   else
5888     {
5889       for (i = 1; i <= rows; i++)
5890         {
5891           name = results[(i * columns) + 1];
5892           Name = wxString::FromUTF8(name);
5893           list->AddColumn(Name);
5894         }
5895     }
5896   sqlite3_free_table(results);
5897   if (HasViewsMetadata(dbAlias) == true)
5898     {
5899       // ok, Spatial MetaData exists; retrieving Geometries and Spatial Indices
5900       sql = wxT("SELECT a.view_geometry, b.spatial_index_enabled ");
5901       sql += wxT("FROM ") + dbAlias + wxT(".views_geometry_columns AS a ");
5902       sql += wxT("JOIN ") + dbAlias + wxT(".geometry_columns AS b ON (");
5903       sql += wxT("Lower(a.f_table_name) = Lower(b.f_table_name) AND ");
5904       sql += wxT("Lower(a.f_geometry_column) = Lower(b.f_geometry_column)) ");
5905       sql += wxT("WHERE Lower(view_name) = Lower('");
5906       strcpy(xname, tableName.ToUTF8());
5907       CleanSqlString(xname);
5908       sql += wxString::FromUTF8(xname);
5909       sql += wxT("')");
5910       strcpy(xsql, sql.ToUTF8());
5911       ret =
5912         sqlite3_get_table(SqliteHandle, xsql, &results, &rows, &columns,
5913                           &errMsg);
5914       if (ret != SQLITE_OK)
5915         {
5916           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5917                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5918           sqlite3_free(errMsg);
5919           return;
5920         }
5921       if (rows < 1)
5922         ;
5923       else
5924         {
5925           for (i = 1; i <= rows; i++)
5926             {
5927               column = results[(i * columns) + 0];
5928               if (atoi(results[(i * columns) + 1]) == 1)
5929                 index = true;
5930               else
5931                 index = false;
5932               if (atoi(results[(i * columns) + 1]) == 2)
5933                 cached = true;
5934               else
5935                 cached = false;
5936               Column = wxString::FromUTF8(column);
5937               list->SetGeometry(Column, index, cached);
5938             }
5939         }
5940       sqlite3_free_table(results);
5941     }
5942 }
5943 
GetViewTriggers(wxString & tableName,MyViewInfo * list)5944 void MyFrame::GetViewTriggers(wxString & tableName, MyViewInfo * list)
5945 {
5946 // loads the view's indices list
5947   int i;
5948   char **results;
5949   int rows;
5950   int columns;
5951   char *errMsg = NULL;
5952   char *name;
5953   wxString Name;
5954   wxString sql;
5955   char xname[1024];
5956   sql =
5957     wxT
5958     ("SELECT name FROM sqlite_master WHERE type = 'trigger' AND tbl_name = '");
5959   strcpy(xname, tableName.ToUTF8());
5960   CleanSqlString(xname);
5961   sql += wxString::FromUTF8(xname);
5962   sql += wxT("' ORDER BY name");
5963   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
5964                               &rows, &columns, &errMsg);
5965   if (ret != SQLITE_OK)
5966     {
5967       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5968                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5969       sqlite3_free(errMsg);
5970       return;
5971     }
5972   if (rows < 1)
5973     ;
5974   else
5975     {
5976       for (i = 1; i <= rows; i++)
5977         {
5978           name = results[(i * columns) + 0];
5979           Name = wxString::FromUTF8(name);
5980           list->AddTrigger(Name);
5981         }
5982     }
5983   sqlite3_free_table(results);
5984   TableTree->ExpandRoot();
5985 }
5986 
GetViewTriggers(wxString & dbAlias,wxString & tableName,MyViewInfo * list)5987 void MyFrame::GetViewTriggers(wxString & dbAlias, wxString & tableName,
5988                               MyViewInfo * list)
5989 {
5990 // loads the view's indices list [Attached DB]
5991   int i;
5992   char **results;
5993   int rows;
5994   int columns;
5995   char *errMsg = NULL;
5996   char *name;
5997   wxString Name;
5998   wxString sql;
5999   char xname[1024];
6000   sql =
6001     wxT("SELECT name FROM ") + dbAlias +
6002     wxT(".sqlite_master WHERE type = 'trigger' AND tbl_name = '");
6003   strcpy(xname, tableName.ToUTF8());
6004   CleanSqlString(xname);
6005   sql += wxString::FromUTF8(xname);
6006   sql += wxT("' ORDER BY name");
6007   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6008                               &rows, &columns, &errMsg);
6009   if (ret != SQLITE_OK)
6010     {
6011       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6012                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6013       sqlite3_free(errMsg);
6014       return;
6015     }
6016   if (rows < 1)
6017     ;
6018   else
6019     {
6020       for (i = 1; i <= rows; i++)
6021         {
6022           name = results[(i * columns) + 0];
6023           Name = wxString::FromUTF8(name);
6024           list->AddTrigger(Name);
6025         }
6026     }
6027   sqlite3_free_table(results);
6028   TableTree->ExpandRoot();
6029 }
6030 
GetTableIndices(wxString & tableName,MyTableInfo * list)6031 void MyFrame::GetTableIndices(wxString & tableName, MyTableInfo * list)
6032 {
6033 // loads the table's indices list
6034   int i;
6035   char **results;
6036   int rows;
6037   int columns;
6038   char *errMsg = NULL;
6039   char *name;
6040   wxString Name;
6041   wxString sql;
6042   char xname[1024];
6043   sql = wxT("PRAGMA index_list(");
6044   strcpy(xname, tableName.ToUTF8());
6045   DoubleQuotedSql(xname);
6046   sql += wxString::FromUTF8(xname);
6047   sql += wxT(")");
6048   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6049                               &rows, &columns, &errMsg);
6050   if (ret != SQLITE_OK)
6051     {
6052       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6053                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6054       sqlite3_free(errMsg);
6055       return;
6056     }
6057   if (rows < 1)
6058     ;
6059   else
6060     {
6061       for (i = 1; i <= rows; i++)
6062         {
6063           name = results[(i * columns) + 1];
6064           Name = wxString::FromUTF8(name);
6065           list->AddIndex(Name);
6066         }
6067     }
6068   sqlite3_free_table(results);
6069 }
6070 
GetTableIndices(wxString & dbAlias,wxString & tableName,MyTableInfo * list)6071 void MyFrame::GetTableIndices(wxString & dbAlias, wxString & tableName,
6072                               MyTableInfo * list)
6073 {
6074 // loads the table's indices list [Attached DB]
6075   int i;
6076   char **results;
6077   int rows;
6078   int columns;
6079   char *errMsg = NULL;
6080   char *name;
6081   wxString Name;
6082   wxString sql;
6083   char xname[1024];
6084   sql = wxT("PRAGMA ") + dbAlias + wxT(".index_list(");
6085   strcpy(xname, tableName.ToUTF8());
6086   DoubleQuotedSql(xname);
6087   sql += wxString::FromUTF8(xname);
6088   sql += wxT(")");
6089   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6090                               &rows, &columns, &errMsg);
6091   if (ret != SQLITE_OK)
6092     {
6093       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6094                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6095       sqlite3_free(errMsg);
6096       return;
6097     }
6098   if (rows < 1)
6099     ;
6100   else
6101     {
6102       for (i = 1; i <= rows; i++)
6103         {
6104           name = results[(i * columns) + 1];
6105           Name = wxString::FromUTF8(name);
6106           list->AddIndex(Name);
6107         }
6108     }
6109   sqlite3_free_table(results);
6110 }
6111 
GetIndexFields(wxString & indexName,wxTreeItemId & node)6112 void MyFrame::GetIndexFields(wxString & indexName, wxTreeItemId & node)
6113 {
6114 // loads the index fields list
6115   int i;
6116   char **results;
6117   int rows;
6118   int columns;
6119   char *errMsg = NULL;
6120   char *name;
6121   wxString Name;
6122   wxString sql;
6123   char xname[1024];
6124   sql = wxT("PRAGMA index_info(");
6125   strcpy(xname, indexName.ToUTF8());
6126   DoubleQuotedSql(xname);
6127   sql += wxString::FromUTF8(xname);
6128   sql += wxT(")");
6129   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6130                               &rows, &columns, &errMsg);
6131   if (ret != SQLITE_OK)
6132     {
6133       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6134                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6135       sqlite3_free(errMsg);
6136       return;
6137     }
6138   if (rows < 1)
6139     ;
6140   else
6141     {
6142       for (i = 1; i <= rows; i++)
6143         {
6144           name = results[(i * columns) + 2];
6145           Name = wxString::FromUTF8(name);
6146           TableTree->AppendItem(node, Name, 3);
6147         }
6148     }
6149   sqlite3_free_table(results);
6150 }
6151 
GetIndexFields(wxString & dbAlias,wxString & indexName,wxTreeItemId & node)6152 void MyFrame::GetIndexFields(wxString & dbAlias, wxString & indexName,
6153                              wxTreeItemId & node)
6154 {
6155 // loads the index fields list [Attached DB]
6156   int i;
6157   char **results;
6158   int rows;
6159   int columns;
6160   char *errMsg = NULL;
6161   char *name;
6162   wxString Name;
6163   wxString sql;
6164   char xname[1024];
6165   sql = wxT("PRAGMA ") + dbAlias + wxT(".index_info(");
6166   strcpy(xname, indexName.ToUTF8());
6167   DoubleQuotedSql(xname);
6168   sql += wxString::FromUTF8(xname);
6169   sql += wxT(")");
6170   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6171                               &rows, &columns, &errMsg);
6172   if (ret != SQLITE_OK)
6173     {
6174       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6175                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6176       sqlite3_free(errMsg);
6177       return;
6178     }
6179   if (rows < 1)
6180     ;
6181   else
6182     {
6183       for (i = 1; i <= rows; i++)
6184         {
6185           name = results[(i * columns) + 2];
6186           Name = wxString::FromUTF8(name);
6187           TableTree->AppendItem(node, Name, 3);
6188         }
6189     }
6190   sqlite3_free_table(results);
6191 }
6192 
GetPrimaryKeyFields(wxString & indexName,wxTreeItemId & node)6193 void MyFrame::GetPrimaryKeyFields(wxString & indexName, wxTreeItemId & node)
6194 {
6195 // loads the Primary Key fields list
6196   int i;
6197   char **results;
6198   int rows;
6199   int columns;
6200   char *errMsg = NULL;
6201   char *name;
6202   wxString Name;
6203   wxString sql;
6204   char xname[1024];
6205   sql = wxT("PRAGMA index_info(");
6206   strcpy(xname, indexName.ToUTF8());
6207   DoubleQuotedSql(xname);
6208   sql += wxString::FromUTF8(xname);
6209   sql += wxT(")");
6210   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6211                               &rows, &columns, &errMsg);
6212   if (ret != SQLITE_OK)
6213     {
6214       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6215                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6216       sqlite3_free(errMsg);
6217       return;
6218     }
6219   if (rows < 1)
6220     ;
6221   else
6222     {
6223       for (i = 1; i <= rows; i++)
6224         {
6225           name = results[(i * columns) + 2];
6226           Name = wxString::FromUTF8(name);
6227           TableTree->AppendItem(node, Name, 2);
6228         }
6229     }
6230   sqlite3_free_table(results);
6231 }
6232 
GetPrimaryKeyFields(wxString & dbAlias,wxString & indexName,wxTreeItemId & node)6233 void MyFrame::GetPrimaryKeyFields(wxString & dbAlias, wxString & indexName,
6234                                   wxTreeItemId & node)
6235 {
6236 // loads the Primary Key fields list [Attached DB]
6237   int i;
6238   char **results;
6239   int rows;
6240   int columns;
6241   char *errMsg = NULL;
6242   char *name;
6243   wxString Name;
6244   wxString sql;
6245   char xname[1024];
6246   sql = wxT("PRAGMA ") + dbAlias + wxT(".index_info(");
6247   strcpy(xname, indexName.ToUTF8());
6248   DoubleQuotedSql(xname);
6249   sql += wxString::FromUTF8(xname);
6250   sql += wxT(")");
6251   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6252                               &rows, &columns, &errMsg);
6253   if (ret != SQLITE_OK)
6254     {
6255       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6256                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6257       sqlite3_free(errMsg);
6258       return;
6259     }
6260   if (rows < 1)
6261     ;
6262   else
6263     {
6264       for (i = 1; i <= rows; i++)
6265         {
6266           name = results[(i * columns) + 2];
6267           Name = wxString::FromUTF8(name);
6268           TableTree->AppendItem(node, Name, 2);
6269         }
6270     }
6271   sqlite3_free_table(results);
6272 }
6273 
GetForeignKeys(wxString & tableName,wxTreeItemId & node)6274 void MyFrame::GetForeignKeys(wxString & tableName, wxTreeItemId & node)
6275 {
6276 // loads the Foreign Keys list
6277   int i;
6278   char **results;
6279   int rows;
6280   int columns;
6281   char *errMsg = NULL;
6282   char *ref_table;
6283   char *column;
6284   int id;
6285   int uid = INT_MIN;
6286   wxString refTable;
6287   wxString Column;
6288   wxString sql;
6289   char xname[1024];
6290   wxTreeItemId item;
6291   sql = wxT("PRAGMA foreign_key_list(");
6292   strcpy(xname, tableName.ToUTF8());
6293   DoubleQuotedSql(xname);
6294   sql += wxString::FromUTF8(xname);
6295   sql += wxT(")");
6296   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6297                               &rows, &columns, &errMsg);
6298   if (ret != SQLITE_OK)
6299     {
6300       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6301                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6302       sqlite3_free(errMsg);
6303       return;
6304     }
6305   if (rows < 1)
6306     ;
6307   else
6308     {
6309       for (i = 1; i <= rows; i++)
6310         {
6311           id = atoi(results[(i * columns) + 0]);
6312           ref_table = results[(i * columns) + 2];
6313           column = results[(i * columns) + 3];
6314           refTable = wxString::FromUTF8(ref_table);
6315           Column = wxString::FromUTF8(column);
6316           if (i == 1)
6317             {
6318               wxString fkName = wxT("FK#");
6319               sprintf(xname, "%d", id);
6320               fkName += wxString::FromUTF8(xname);
6321               fkName += wxT(" ref: ") + refTable;
6322               item = TableTree->AppendItem(node, fkName, 18);
6323               uid = id;
6324           } else if (id != uid)
6325             {
6326               wxString fkName = wxT("FK#");
6327               sprintf(xname, "%d", id);
6328               fkName += wxString::FromUTF8(xname);
6329               fkName += wxT(" ref: ") + refTable;
6330               item = TableTree->AppendItem(node, fkName, 18);
6331               uid = id;
6332             }
6333           TableTree->AppendItem(item, Column, 3);
6334         }
6335     }
6336   sqlite3_free_table(results);
6337 }
6338 
GetForeignKeys(wxString & dbAlias,wxString & tableName,wxTreeItemId & node)6339 void MyFrame::GetForeignKeys(wxString & dbAlias, wxString & tableName,
6340                              wxTreeItemId & node)
6341 {
6342 // loads the Foreign Keys list [Attached DB]
6343   int i;
6344   char **results;
6345   int rows;
6346   int columns;
6347   char *errMsg = NULL;
6348   char *ref_table;
6349   char *column;
6350   int id;
6351   int uid = INT_MIN;
6352   wxString refTable;
6353   wxString Column;
6354   wxString sql;
6355   char xname[1024];
6356   wxTreeItemId item;
6357   sql = wxT("PRAGMA ") + dbAlias + wxT(".foreign_key_list(");
6358   strcpy(xname, tableName.ToUTF8());
6359   DoubleQuotedSql(xname);
6360   sql += wxString::FromUTF8(xname);
6361   sql += wxT(")");
6362   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6363                               &rows, &columns, &errMsg);
6364   if (ret != SQLITE_OK)
6365     {
6366       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6367                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6368       sqlite3_free(errMsg);
6369       return;
6370     }
6371   if (rows < 1)
6372     ;
6373   else
6374     {
6375       for (i = 1; i <= rows; i++)
6376         {
6377           id = atoi(results[(i * columns) + 0]);
6378           ref_table = results[(i * columns) + 2];
6379           column = results[(i * columns) + 3];
6380           refTable = wxString::FromUTF8(ref_table);
6381           Column = wxString::FromUTF8(column);
6382           if (i == 1)
6383             {
6384               wxString fkName = wxT("FK#");
6385               sprintf(xname, "%d", id);
6386               fkName += wxString::FromUTF8(xname);
6387               fkName += wxT(" ref: ") + refTable;
6388               item = TableTree->AppendItem(node, fkName, 18);
6389               uid = id;
6390           } else if (id != uid)
6391             {
6392               wxString fkName = wxT("FK#");
6393               sprintf(xname, "%d", id);
6394               fkName += wxString::FromUTF8(xname);
6395               fkName += wxT(" ref: ") + refTable;
6396               item = TableTree->AppendItem(node, fkName, 18);
6397               uid = id;
6398             }
6399           TableTree->AppendItem(item, Column, 3);
6400         }
6401     }
6402   sqlite3_free_table(results);
6403 }
6404 
GetTableTriggers(wxString & tableName,MyTableInfo * list)6405 void MyFrame::GetTableTriggers(wxString & tableName, MyTableInfo * list)
6406 {
6407 // loads the table's indices list
6408   int i;
6409   char **results;
6410   int rows;
6411   int columns;
6412   char *errMsg = NULL;
6413   char *name;
6414   wxString Name;
6415   wxString sql;
6416   char xname[1024];
6417   sql =
6418     wxT
6419     ("SELECT name FROM sqlite_master WHERE type = 'trigger' AND tbl_name = '");
6420   strcpy(xname, tableName.ToUTF8());
6421   CleanSqlString(xname);
6422   sql += wxString::FromUTF8(xname);
6423   sql += wxT("' ORDER BY name");
6424   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6425                               &rows, &columns, &errMsg);
6426   if (ret != SQLITE_OK)
6427     {
6428       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6429                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6430       sqlite3_free(errMsg);
6431       return;
6432     }
6433   if (rows < 1)
6434     ;
6435   else
6436     {
6437       for (i = 1; i <= rows; i++)
6438         {
6439           name = results[(i * columns) + 0];
6440           Name = wxString::FromUTF8(name);
6441           list->AddTrigger(Name);
6442         }
6443     }
6444   sqlite3_free_table(results);
6445   TableTree->ExpandRoot();
6446 }
6447 
GetTableTriggers(wxString & dbAlias,wxString & tableName,MyTableInfo * list)6448 void MyFrame::GetTableTriggers(wxString & dbAlias, wxString & tableName,
6449                                MyTableInfo * list)
6450 {
6451 // loads the table's indices list [Attached DB]
6452   int i;
6453   char **results;
6454   int rows;
6455   int columns;
6456   char *errMsg = NULL;
6457   char *name;
6458   wxString Name;
6459   wxString sql;
6460   char xname[1024];
6461   sql = wxT("SELECT name FROM ") + dbAlias;
6462   sql += wxT(".sqlite_master WHERE type = 'trigger' AND tbl_name = '");
6463   strcpy(xname, tableName.ToUTF8());
6464   CleanSqlString(xname);
6465   sql += wxString::FromUTF8(xname);
6466   sql += wxT("' ORDER BY name");
6467   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6468                               &rows, &columns, &errMsg);
6469   if (ret != SQLITE_OK)
6470     {
6471       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6472                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6473       sqlite3_free(errMsg);
6474       return;
6475     }
6476   if (rows < 1)
6477     ;
6478   else
6479     {
6480       for (i = 1; i <= rows; i++)
6481         {
6482           name = results[(i * columns) + 0];
6483           Name = wxString::FromUTF8(name);
6484           list->AddTrigger(Name);
6485         }
6486     }
6487   sqlite3_free_table(results);
6488   TableTree->ExpandRoot();
6489 }
6490 
GetColumnNames(wxString & tableName,int * n_cols)6491 wxString *MyFrame::GetColumnNames(wxString & tableName, int *n_cols)
6492 {
6493 // loads the table's column names list
6494   wxString *cols = NULL;
6495   int nCols = 0;
6496   char **results;
6497   int rows;
6498   int columns;
6499   int i;
6500   char *errMsg = NULL;
6501   wxString sql;
6502   char *column;
6503   char xname[1024];
6504   sql = wxT("PRAGMA table_info(");
6505   strcpy(xname, tableName.ToUTF8());
6506   DoubleQuotedSql(xname);
6507   sql += wxString::FromUTF8(xname);
6508   sql += wxT(")");
6509   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6510                               &rows, &columns, &errMsg);
6511   if (ret != SQLITE_OK)
6512     {
6513       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6514                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6515       sqlite3_free(errMsg);
6516       return NULL;
6517     }
6518   sql = wxT("");
6519   if (rows < 1)
6520     ;
6521   else
6522     {
6523       nCols = rows;
6524       cols = new wxString[rows];
6525       for (i = 1; i <= rows; i++)
6526         {
6527           column = results[(i * columns) + 1];
6528           *(cols + i - 1) += wxString::FromUTF8(column);
6529         }
6530     }
6531   sqlite3_free_table(results);
6532   *n_cols = nCols;
6533   return cols;
6534 }
6535 
GetCharsetIndex(wxString & charset)6536 int MyFrame::GetCharsetIndex(wxString & charset)
6537 {
6538 // identifies the INDEX for a given charset
6539   int i;
6540   for (i = 0; i < CharsetsLen; i++)
6541     {
6542       if (*(Charsets + i) == charset)
6543         return i;
6544     }
6545   return wxNOT_FOUND;
6546 }
6547 
GetCharsetName(wxString & charset)6548 wxString & MyFrame::GetCharsetName(wxString & charset)
6549 {
6550 // identifies the full name for a given charset code
6551   int i;
6552   for (i = 0; i < CharsetsLen; i++)
6553     {
6554       if (*(Charsets + i) == charset)
6555         return *(CharsetsNames + i);
6556     }
6557   return charset;
6558 }
6559 
ClearTableTree()6560 void MyFrame::ClearTableTree()
6561 {
6562 // resets the table TREE list to the empty state
6563   wxString path = wxT("no current DB");
6564   TableTree->SetPath(path);
6565   TableTree->FlushAll();
6566 }
6567 
AutoFDOStart()6568 void MyFrame::AutoFDOStart()
6569 {
6570 //
6571 // trying to start the FDO-OGR auto-wrapper
6572 //
6573   int ret;
6574   const char *name;
6575   int i;
6576   char **results;
6577   int rows;
6578   int columns;
6579   char sql[1024];
6580   int count = 0;
6581   int len;
6582   int spatial_type = 0;
6583   AutoFDOTables tables;
6584   AutoFDOTable *p;
6585   wxString fdoNames[5];
6586   char xname[1024];
6587   char xname2[1024];
6588   SpatiaLiteMetadata = false;
6589   AutoFDOmsg = wxT("");
6590   strcpy(sql, "SELECT CheckSpatialMetadata()");
6591   ret = sqlite3_get_table(SqliteHandle, sql, &results, &rows, &columns, NULL);
6592   if (ret != SQLITE_OK)
6593     goto error1;
6594   if (rows < 1)
6595     ;
6596   else
6597     {
6598       for (i = 1; i <= rows; i++)
6599         spatial_type = atoi(results[(i * columns) + 0]);
6600     }
6601   sqlite3_free_table(results);
6602 error1:
6603   if (spatial_type == 1 || spatial_type == 3)
6604     SpatiaLiteMetadata = true;
6605   if (spatial_type == 2)
6606     {
6607       //
6608       // ok, creating VirtualFDO tables
6609       //
6610       strcpy(sql, "SELECT DISTINCT f_table_name FROM geometry_columns");
6611       ret =
6612         sqlite3_get_table(SqliteHandle, sql, &results, &rows, &columns, NULL);
6613       if (ret != SQLITE_OK)
6614         goto error;
6615       if (rows < 1)
6616         ;
6617       else
6618         {
6619           for (i = 1; i <= rows; i++)
6620             {
6621               name = results[(i * columns) + 0];
6622               if (name)
6623                 {
6624                   len = strlen(name);
6625                   tables.Add(name, len);
6626                 }
6627             }
6628         }
6629       sqlite3_free_table(results);
6630       p = tables.GetFirst();
6631       while (p)
6632         {
6633           //
6634           // destroying the VirtualFDO table [if existing]
6635           //
6636           sprintf(xname, "fdo_%s", p->GetName());
6637           DoubleQuotedSql(xname);
6638           sprintf(sql, "DROP TABLE IF EXISTS %s", xname);
6639           ret = sqlite3_exec(SqliteHandle, sql, NULL, 0, NULL);
6640           if (ret != SQLITE_OK)
6641             goto error;
6642           //
6643           // creating the VirtualFDO table
6644           //
6645           sprintf(xname, "fdo_%s", p->GetName());
6646           DoubleQuotedSql(xname);
6647           strcpy(xname2, p->GetName());
6648           DoubleQuotedSql(xname2);
6649           sprintf(sql, "CREATE VIRTUAL TABLE %s USING VirtualFDO(%s)",
6650                   xname, xname2);
6651           ret = sqlite3_exec(SqliteHandle, sql, NULL, 0, NULL);
6652           if (ret != SQLITE_OK)
6653             goto error;
6654           if (count < 5)
6655             fdoNames[count] =
6656               wxT("- VirtualTable: fdo_") + wxString::FromUTF8(p->GetName());
6657           else
6658             fdoNames[4] = wxT("- ... and others ...");
6659           count++;
6660           p = p->GetNext();
6661         }
6662     error:
6663       if (count++)
6664         {
6665           AutoFDOmsg =
6666             wxT("FDO-OGR detected; activating FDO-OGR auto-wrapping ...\n\n");
6667           if (fdoNames[0].Len() > 0)
6668             AutoFDOmsg += fdoNames[0] + wxT("\n");
6669           if (fdoNames[1].Len() > 0)
6670             AutoFDOmsg += fdoNames[1] + wxT("\n");
6671           if (fdoNames[2].Len() > 0)
6672             AutoFDOmsg += fdoNames[2] + wxT("\n");
6673           if (fdoNames[3].Len() > 0)
6674             AutoFDOmsg += fdoNames[3] + wxT("\n");
6675           if (fdoNames[4].Len() > 0)
6676             AutoFDOmsg += fdoNames[4] + wxT("\n");
6677           AutoFDOmsg +=
6678             wxT
6679             ("\nAccessing these fdo_XX tables you can take full advantage of\n");
6680           AutoFDOmsg += wxT("FDO-OGR auto-wrapping facility\n");
6681           AutoFDOmsg +=
6682             wxT
6683             ("This allows you to access any specific FDO-OGR Geometry as if it\n");
6684           AutoFDOmsg +=
6685             wxT
6686             ("where native SpatiaLite ones in a completely transparent way.\n");
6687         }
6688       return;
6689     }
6690 }
6691 
AutoFDOStop()6692 void MyFrame::AutoFDOStop()
6693 {
6694 //
6695 // trying to stop the FDO-OGR auto-wrapper
6696 //
6697   int ret;
6698   const char *name;
6699   int i;
6700   char **results;
6701   int rows;
6702   int columns;
6703   char sql[1024];
6704   int count = 0;
6705   int len;
6706   int spatial_type = 0;
6707   char xname[1024];
6708   AutoFDOTables tables;
6709   AutoFDOTable *p;
6710   AutoFDOmsg = wxT("");
6711   strcpy(sql, "SELECT CheckSpatialMetadata()");
6712   ret = sqlite3_get_table(SqliteHandle, sql, &results, &rows, &columns, NULL);
6713   if (ret != SQLITE_OK)
6714     goto error1;
6715   if (rows < 1)
6716     ;
6717   else
6718     {
6719       for (i = 1; i <= rows; i++)
6720         spatial_type = atoi(results[(i * columns) + 0]);
6721     }
6722   sqlite3_free_table(results);
6723 error1:
6724   if (spatial_type == 2)
6725     {
6726       //
6727       // ok, destroying VirtualFDO tables
6728       //
6729       strcpy(sql, "SELECT DISTINCT f_table_name FROM geometry_columns");
6730       ret =
6731         sqlite3_get_table(SqliteHandle, sql, &results, &rows, &columns, NULL);
6732       if (ret != SQLITE_OK)
6733         goto error;
6734       if (rows < 1)
6735         ;
6736       else
6737         {
6738           for (i = 1; i <= rows; i++)
6739             {
6740               name = results[(i * columns) + 0];
6741               if (name)
6742                 {
6743                   len = strlen(name);
6744                   tables.Add(name, len);
6745                 }
6746             }
6747         }
6748       sqlite3_free_table(results);
6749       p = tables.GetFirst();
6750       while (p)
6751         {
6752           //
6753           // destroying the VirtualFDO table [if existing]
6754           //
6755           sprintf(xname, "fdo_%s", p->GetName());
6756           DoubleQuotedSql(xname);
6757           sprintf(sql, "DROP TABLE IF EXISTS %s", xname);
6758           ret = sqlite3_exec(SqliteHandle, sql, NULL, 0, NULL);
6759           if (ret != SQLITE_OK)
6760             goto error;
6761           count++;
6762           p = p->GetNext();
6763         }
6764     error:
6765       if (count++)
6766         AutoFDOmsg = wxT("FDO-OGR auto-wrapping shutdown done");
6767       return;
6768     }
6769 }
6770 
HasVirtsMetadata()6771 bool MyFrame::HasVirtsMetadata()
6772 {
6773 //
6774 // testing if the VIRTS_GEOMETRY_COLUMNS table exists
6775 //
6776   int i;
6777   char **results;
6778   int rows;
6779   int columns;
6780   char *errMsg = NULL;
6781   wxString sql;
6782   bool defined = false;
6783   sql = wxT("PRAGMA table_info(virts_geometry_columns)");
6784   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6785                               &rows, &columns, &errMsg);
6786   if (ret != SQLITE_OK)
6787     {
6788       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6789                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6790       sqlite3_free(errMsg);
6791       return false;
6792     }
6793   if (rows < 1)
6794     ;
6795   else
6796     {
6797       for (i = 1; i <= rows; i++)
6798         defined = true;
6799     }
6800   sqlite3_free_table(results);
6801   return defined;
6802 }
6803 
HasVirtsMetadata(wxString & dbAlias)6804 bool MyFrame::HasVirtsMetadata(wxString & dbAlias)
6805 {
6806 //
6807 // testing if the VIRTS_GEOMETRY_COLUMNS table exists [Attached DB]
6808 //
6809   int i;
6810   char **results;
6811   int rows;
6812   int columns;
6813   char *errMsg = NULL;
6814   wxString sql;
6815   bool defined = false;
6816   sql = wxT("PRAGMA ") + dbAlias + wxT(".table_info(virts_geometry_columns)");
6817   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6818                               &rows, &columns, &errMsg);
6819   if (ret != SQLITE_OK)
6820     {
6821       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6822                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6823       sqlite3_free(errMsg);
6824       return false;
6825     }
6826   if (rows < 1)
6827     ;
6828   else
6829     {
6830       for (i = 1; i <= rows; i++)
6831         defined = true;
6832     }
6833   sqlite3_free_table(results);
6834   return defined;
6835 }
6836 
HasViewsMetadata()6837 bool MyFrame::HasViewsMetadata()
6838 {
6839 //
6840 // testing if the VIEWS_GEOMETRY_COLUMNS table exists
6841 //
6842   int i;
6843   char **results;
6844   int rows;
6845   int columns;
6846   char *errMsg = NULL;
6847   wxString sql;
6848   bool defined = false;
6849   sql = wxT("PRAGMA table_info(views_geometry_columns)");
6850   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6851                               &rows, &columns, &errMsg);
6852   if (ret != SQLITE_OK)
6853     {
6854       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6855                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6856       sqlite3_free(errMsg);
6857       return false;
6858     }
6859   if (rows < 1)
6860     ;
6861   else
6862     {
6863       for (i = 1; i <= rows; i++)
6864         defined = true;
6865     }
6866   sqlite3_free_table(results);
6867   return defined;
6868 }
6869 
HasViewsMetadata(wxString & dbAlias)6870 bool MyFrame::HasViewsMetadata(wxString & dbAlias)
6871 {
6872 //
6873 // testing if the VIEWS_GEOMETRY_COLUMNS table exists [Attached DB]
6874 //
6875   int i;
6876   char **results;
6877   int rows;
6878   int columns;
6879   char *errMsg = NULL;
6880   wxString sql;
6881   bool defined = false;
6882   sql = wxT("PRAGMA ") + dbAlias + wxT(".table_info(views_geometry_columns)");
6883   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
6884                               &rows, &columns, &errMsg);
6885   if (ret != SQLITE_OK)
6886     {
6887       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
6888                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6889       sqlite3_free(errMsg);
6890       return false;
6891     }
6892   if (rows < 1)
6893     ;
6894   else
6895     {
6896       for (i = 1; i <= rows; i++)
6897         defined = true;
6898     }
6899   sqlite3_free_table(results);
6900   return defined;
6901 }
6902 
TestDotCommand(const char * p_stmt)6903 int MyFrame::TestDotCommand(const char *p_stmt)
6904 {
6905 //
6906 // identifying DOT-COMMANDS [SQL script]
6907 //
6908   const char *stmt = p_stmt;
6909   int len;
6910 
6911   if (*p_stmt == '\n')
6912     stmt = p_stmt + 1;
6913   len = strlen(stmt);
6914   if (strncasecmp(stmt, ".loadxl ", 8) == 0)
6915     return CMD_LOADXL;
6916   if (len <= 9)
6917     return CMD_NONE;
6918   if (strncasecmp(stmt, ".loadshp ", 9) == 0)
6919     return CMD_LOADSHP;
6920   if (strncasecmp(stmt, ".loaddbf ", 9) == 0)
6921     return CMD_LOADDBF;
6922   if (strncasecmp(stmt, ".dumpshp ", 9) == 0)
6923     return CMD_DUMPSHP;
6924   if (strncasecmp(stmt, ".dumpdbf ", 9) == 0)
6925     return CMD_DUMPDBF;
6926   if (strncasecmp(stmt, ".sqllog ", 8) == 0)
6927     return CMD_SQLLOG;
6928   return CMD_NONE;
6929 }
6930 
IsDotCommandLoadShp(const char * stmt,char * path,char * table,char * charset,char * column,int * srid,bool * coerce2D,bool * compressed)6931 bool MyFrame::IsDotCommandLoadShp(const char *stmt, char *path,
6932                                   char *table, char *charset,
6933                                   char *column, int *srid, bool * coerce2D,
6934                                   bool * compressed)
6935 {
6936 //
6937 // attempting to parse a .loadshp command [SQL script]
6938 //
6939   wxString cmd = wxString::FromUTF8(stmt);
6940   wxString extPath;
6941   wxString extTable;
6942   wxString extCharset;
6943   wxString extColumn = wxT("Geometry");
6944   long extSrid = 0;
6945   bool extCoerce2D = false;
6946   bool extCompressed = false;
6947   int count = 0;
6948   wxStringTokenizer tok(cmd);
6949   while (tok.HasMoreTokens())
6950     {
6951       wxString token = tok.GetNextToken();
6952       switch (count)
6953         {
6954           case 0:
6955             extPath = token;
6956             break;
6957           case 1:
6958             extTable = token;
6959             break;
6960           case 2:
6961             extCharset = token;
6962             break;
6963           case 3:
6964             if (token.ToLong(&extSrid) == false)
6965               extSrid = 0;
6966             break;
6967           case 4:
6968             extColumn = token;
6969             break;
6970           case 5:
6971             extCoerce2D = true;
6972             break;
6973           case 6:
6974             extCompressed = true;
6975             break;
6976         };
6977       count++;
6978     }
6979   if (count == 3 || count == 4 || count == 5 || count == 6 || count == 7)
6980     {
6981       strcpy(path, extPath.ToUTF8());
6982       strcpy(table, extTable.ToUTF8());
6983       strcpy(charset, extCharset.ToUTF8());
6984       strcpy(column, extColumn.ToUTF8());
6985       *srid = extSrid;
6986       *coerce2D = extCoerce2D;
6987       *compressed = extCompressed;
6988       return true;
6989     }
6990   return false;
6991 }
6992 
IsDotCommandLoadDbf(const char * stmt,char * path,char * table,char * charset)6993 bool MyFrame::IsDotCommandLoadDbf(const char *stmt, char *path,
6994                                   char *table, char *charset)
6995 {
6996 //
6997 // attempting to parse a .loaddbf command [SQL script]
6998 //
6999   wxString cmd = wxString::FromUTF8(stmt);
7000   wxString extPath;
7001   wxString extTable;
7002   wxString extCharset;
7003   int count = 0;
7004   wxStringTokenizer tok(cmd);
7005   while (tok.HasMoreTokens())
7006     {
7007       wxString token = tok.GetNextToken();
7008       switch (count)
7009         {
7010           case 0:
7011             extPath = token;
7012             break;
7013           case 1:
7014             extTable = token;
7015             break;
7016           case 2:
7017             extCharset = token;
7018             break;
7019         };
7020       count++;
7021     }
7022   if (count == 3)
7023     {
7024       strcpy(path, extPath.ToUTF8());
7025       strcpy(table, extTable.ToUTF8());
7026       strcpy(charset, extCharset.ToUTF8());
7027       return true;
7028     }
7029   return false;
7030 }
7031 
IsDotCommandLoadXL(const char * stmt,char * path,char * table,int * worksheetIndex,int * firstTitle)7032 bool MyFrame::IsDotCommandLoadXL(const char *stmt, char *path,
7033                                  char *table, int *worksheetIndex,
7034                                  int *firstTitle)
7035 {
7036 //
7037 // attempting to parse a .loadxl command [SQL script]
7038 //
7039   wxString cmd = wxString::FromUTF8(stmt);
7040   wxString extPath;
7041   wxString extTable;
7042   int extWorksheetIndex = 0;
7043   bool extFirstTitle = false;
7044   int count = 0;
7045   char dummy[128];
7046   wxStringTokenizer tok(cmd);
7047   while (tok.HasMoreTokens())
7048     {
7049       wxString token = tok.GetNextToken();
7050       switch (count)
7051         {
7052           case 0:
7053             extPath = token;
7054             break;
7055           case 1:
7056             extTable = token;
7057             break;
7058           case 2:
7059             strcpy(dummy, token.ToUTF8());
7060             extWorksheetIndex = atoi(dummy);
7061             break;
7062           case 3:
7063             strcpy(dummy, token.ToUTF8());
7064             if (atoi(dummy) == 1)
7065               extFirstTitle = true;
7066             break;
7067         };
7068       count++;
7069     }
7070   if (count == 3 || count == 4 || count == 5)
7071     {
7072       if (extFirstTitle == true)
7073         *firstTitle = 1;
7074       else
7075         *firstTitle = 0;
7076       strcpy(path, extPath.ToUTF8());
7077       strcpy(table, extTable.ToUTF8());
7078       *worksheetIndex = extWorksheetIndex;
7079       return true;
7080     }
7081   return false;
7082 }
7083 
IsViewGeometry(wxString & table,wxString & column)7084 bool MyFrame::IsViewGeometry(wxString & table, wxString & column)
7085 {
7086 //
7087 // checking if some table.geometry corresponds to a VIEW
7088 //
7089   int i;
7090   char **results;
7091   int rows;
7092   int columns;
7093   char *errMsg = NULL;
7094   wxString sql;
7095   int count = 0;
7096 
7097   sql =
7098     wxT
7099     ("SELECT Count(*) FROM views_geometry_columns WHERE Lower(view_name) = Lower('");
7100   sql += table;
7101   sql += wxT("') AND view_geometry = Lower('");
7102   sql += column;
7103   sql += wxT("')");
7104   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
7105                               &rows, &columns, &errMsg);
7106   if (ret != SQLITE_OK)
7107     {
7108       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
7109                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
7110       sqlite3_free(errMsg);
7111       return false;
7112     }
7113   if (rows < 1)
7114     ;
7115   else
7116     {
7117       for (i = 1; i <= rows; i++)
7118         {
7119           count = atoi(results[(i * columns) + 0]);
7120         }
7121     }
7122   sqlite3_free_table(results);
7123   if (count)
7124     return true;
7125   return false;
7126 }
7127 
ExistsTopologyMaster()7128 bool MyFrame::ExistsTopologyMaster()
7129 {
7130 //
7131 // checking if TOPOLOGY_MASTER exists
7132 //
7133   int i;
7134   char **results;
7135   int rows;
7136   int columns;
7137   char *errMsg = NULL;
7138   wxString sql;
7139   int count = 0;
7140 
7141   sql = wxT("SELECT Count(*) FROM sqlite_master ");
7142   sql += wxT("WHERE type = 'table' AND ");
7143   sql += wxT("tbl_name = 'topology_master'");
7144   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
7145                               &rows, &columns, &errMsg);
7146   if (ret != SQLITE_OK)
7147     {
7148       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
7149                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
7150       sqlite3_free(errMsg);
7151       return false;
7152     }
7153   if (rows < 1)
7154     ;
7155   else
7156     {
7157       for (i = 1; i <= rows; i++)
7158         {
7159           count = atoi(results[(i * columns) + 0]);
7160         }
7161     }
7162   sqlite3_free_table(results);
7163   if (count)
7164     return true;
7165   return false;
7166 }
7167 
ExistsTopologyMaster(wxString & dbAlias)7168 bool MyFrame::ExistsTopologyMaster(wxString & dbAlias)
7169 {
7170 //
7171 // checking if TOPOLOGY_MASTER exists [Attached DB]
7172 //
7173   int i;
7174   char **results;
7175   int rows;
7176   int columns;
7177   char *errMsg = NULL;
7178   wxString sql;
7179   int count = 0;
7180 
7181   sql = wxT("SELECT Count(*) FROM ") + dbAlias + wxT(".sqlite_master ");
7182   sql += wxT("WHERE type = 'table' AND ");
7183   sql += wxT("tbl_name = 'topology_master'");
7184   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
7185                               &rows, &columns, &errMsg);
7186   if (ret != SQLITE_OK)
7187     {
7188       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
7189                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
7190       sqlite3_free(errMsg);
7191       return false;
7192     }
7193   if (rows < 1)
7194     ;
7195   else
7196     {
7197       for (i = 1; i <= rows; i++)
7198         {
7199           count = atoi(results[(i * columns) + 0]);
7200         }
7201     }
7202   sqlite3_free_table(results);
7203   if (count)
7204     return true;
7205   return false;
7206 }
7207 
GetTopologyColumns(wxString * list)7208 void MyFrame::GetTopologyColumns(wxString * list)
7209 {
7210 //
7211 // identifying TOPOLOGY_MASTER columns
7212 //
7213   int i;
7214   char **results;
7215   int rows;
7216   int columns;
7217   char *errMsg = NULL;
7218   const char *name;
7219   int comma = false;
7220   wxString col_list;
7221 
7222   *list = col_list;
7223   int ret =
7224     sqlite3_get_table(SqliteHandle, "PRAGMA table_info(topology_master)",
7225                       &results,
7226                       &rows, &columns, &errMsg);
7227   if (ret != SQLITE_OK)
7228     {
7229       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
7230                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
7231       sqlite3_free(errMsg);
7232       return;
7233     }
7234   if (rows < 1)
7235     ;
7236   else
7237     {
7238       for (i = 1; i <= rows; i++)
7239         {
7240           name = results[(i * columns) + 1];
7241           if (comma == false)
7242             comma = true;
7243           else
7244             col_list += wxT(", ");
7245           col_list += wxString::FromUTF8(name);
7246         }
7247     }
7248   sqlite3_free_table(results);
7249   *list = col_list;
7250 }
7251 
GetTopologyColumns(wxString & dbAlias,wxString * list)7252 void MyFrame::GetTopologyColumns(wxString & dbAlias, wxString * list)
7253 {
7254 //
7255 // identifying TOPOLOGY_MASTER columns [Attached DB]
7256 //
7257   int i;
7258   char **results;
7259   int rows;
7260   int columns;
7261   char *errMsg = NULL;
7262   const char *name;
7263   int comma = false;
7264   wxString col_list;
7265   wxString sql;
7266 
7267   *list = col_list;
7268   sql = wxT("PRAGMA ") + dbAlias + wxT(".table_info(topology_master)");
7269   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(),
7270                               &results,
7271                               &rows, &columns, &errMsg);
7272   if (ret != SQLITE_OK)
7273     {
7274       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
7275                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
7276       sqlite3_free(errMsg);
7277       return;
7278     }
7279   if (rows < 1)
7280     ;
7281   else
7282     {
7283       for (i = 1; i <= rows; i++)
7284         {
7285           name = results[(i * columns) + 1];
7286           if (comma == false)
7287             comma = true;
7288           else
7289             col_list += wxT(", ");
7290           col_list += wxString::FromUTF8(name);
7291         }
7292     }
7293   sqlite3_free_table(results);
7294   *list = col_list;
7295 }
7296 
CheckIfExists(const char * name,bool * table,bool * view)7297 void MyFrame::CheckIfExists(const char *name, bool * table, bool * view)
7298 {
7299 //
7300 // checking if a Topology related Table or View actually exists
7301 //
7302   char dummy[2048];
7303   wxString sql;
7304   int i;
7305   char **results;
7306   int rows;
7307   int columns;
7308   char *errMsg = NULL;
7309 
7310   *table = false;
7311   *view = false;
7312   strcpy(dummy, name);
7313   CleanSqlString(dummy);
7314   sql = wxT("SELECT type FROM sqlite_master WHERE Lower(name) = Lower('");
7315   sql += wxString::FromUTF8(dummy);
7316   sql += wxT("')");
7317 
7318   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
7319                               &rows, &columns, &errMsg);
7320   if (ret != SQLITE_OK)
7321     {
7322       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
7323                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
7324       sqlite3_free(errMsg);
7325       return;
7326     }
7327   if (rows < 1)
7328     ;
7329   else
7330     {
7331       for (i = 1; i <= rows; i++)
7332         {
7333           name = results[(i * columns) + 0];
7334           if (strcasecmp(name, "table") == 0)
7335             *table = true;
7336           if (strcasecmp(name, "view") == 0)
7337             *view = true;
7338         }
7339     }
7340   sqlite3_free_table(results);
7341 }
7342 
CheckIfExists(wxString & dbAlias,const char * name,bool * table,bool * view)7343 void MyFrame::CheckIfExists(wxString & dbAlias, const char *name, bool * table,
7344                             bool * view)
7345 {
7346 //
7347 // checking if a Topology related Table or View actually exists [Attached DB]
7348 //
7349   char dummy[2048];
7350   wxString sql;
7351   int i;
7352   char **results;
7353   int rows;
7354   int columns;
7355   char *errMsg = NULL;
7356 
7357   *table = false;
7358   *view = false;
7359   strcpy(dummy, name);
7360   CleanSqlString(dummy);
7361   sql =
7362     wxT("SELECT type FROM ") + dbAlias +
7363     wxT(".sqlite_master WHERE Lower(name) = Lower('");
7364   sql += wxString::FromUTF8(dummy);
7365   sql += wxT("')");
7366 
7367   int ret = sqlite3_get_table(SqliteHandle, sql.ToUTF8(), &results,
7368                               &rows, &columns, &errMsg);
7369   if (ret != SQLITE_OK)
7370     {
7371       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
7372                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
7373       sqlite3_free(errMsg);
7374       return;
7375     }
7376   if (rows < 1)
7377     ;
7378   else
7379     {
7380       for (i = 1; i <= rows; i++)
7381         {
7382           name = results[(i * columns) + 0];
7383           if (strcasecmp(name, "table") == 0)
7384             *table = true;
7385           if (strcasecmp(name, "view") == 0)
7386             *view = true;
7387         }
7388     }
7389   sqlite3_free_table(results);
7390 }
7391 
GetMetaDataType()7392 int MyFrame::GetMetaDataType()
7393 {
7394 //
7395 // determining the MetaData type
7396 //
7397   int ret;
7398   int i;
7399   char **results;
7400   int rows;
7401   int columns;
7402   char sql[1024];
7403   int spatial_type = 0;
7404   strcpy(sql, "SELECT CheckSpatialMetadata()");
7405   ret = sqlite3_get_table(SqliteHandle, sql, &results, &rows, &columns, NULL);
7406   if (ret != SQLITE_OK)
7407     goto error1;
7408   if (rows < 1)
7409     ;
7410   else
7411     {
7412       for (i = 1; i <= rows; i++)
7413         spatial_type = atoi(results[(i * columns) + 0]);
7414     }
7415   sqlite3_free_table(results);
7416   if (spatial_type == 1)
7417     return METADATA_LEGACY;
7418   if (spatial_type == 3)
7419     return METADATA_CURRENT;
7420 error1:
7421   return METADATA_UNKNOWN;
7422 }
7423 
InsertIntoLog(wxString & sql_stmt)7424 void MyFrame::InsertIntoLog(wxString & sql_stmt)
7425 {
7426 //
7427 // inserting a row into sql_statements_log
7428 //
7429   char *clean;
7430   int ret;
7431   char *errMsg = NULL;
7432   wxString sql = wxT("INSERT INTO sql_statements_log ");
7433   sql += wxT("(id, time_start, user_agent, sql_statement) VALUES (");
7434   sql += wxT("NULL, strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), ");
7435   sql += wxT("'spatialite_gui', '");
7436   clean = gaiaSingleQuotedSql(sql_stmt.ToUTF8());
7437   sql += wxString::FromUTF8(clean);
7438   free(clean);
7439   sql += wxT("')");
7440   ret = sqlite3_exec(SqliteHandle, sql.ToUTF8(), NULL, 0, &errMsg);
7441   if (ret != SQLITE_OK)
7442     {
7443       wxMessageBox(wxT("InsertIntoLog: ") + wxString::FromUTF8(errMsg),
7444                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
7445       sqlite3_free(errMsg);
7446       LastSqlLogID = -1;
7447       return;
7448     }
7449   LastSqlLogID = sqlite3_last_insert_rowid(SqliteHandle);
7450 }
7451 
UpdateLog()7452 void MyFrame::UpdateLog()
7453 {
7454 //
7455 // updating sql_statements_log: success
7456 //
7457   char dummy[64];
7458   int ret;
7459   char *errMsg = NULL;
7460   wxString sql = wxT("UPDATE sql_statements_log SET ");
7461   sql += wxT("time_end = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), ");
7462   sql += wxT("success = 1, error_cause = 'success' ");
7463 #if defined(_WIN32) || defined(__MINGW32__)
7464   /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */
7465   sprintf(dummy, "WHERE id = %I64d", LastSqlLogID);
7466 #else
7467   sprintf(dummy, "WHERE id = %lld", LastSqlLogID);
7468 #endif
7469   sql += wxString::FromUTF8(dummy);
7470   ret = sqlite3_exec(SqliteHandle, sql.ToUTF8(), NULL, 0, &errMsg);
7471   if (ret != SQLITE_OK)
7472     {
7473       wxMessageBox(wxT("UpdateLog: ") + wxString::FromUTF8(errMsg),
7474                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
7475       sqlite3_free(errMsg);
7476     }
7477 }
7478 
UpdateLog(wxString & error_msg)7479 void MyFrame::UpdateLog(wxString & error_msg)
7480 {
7481 //
7482 // updating sql_statements_log: failure
7483 //
7484   char dummy[64];
7485   char *clean;
7486   int ret;
7487   char *errMsg = NULL;
7488   wxString sql = wxT("UPDATE sql_statements_log SET ");
7489   sql += wxT("time_end = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), ");
7490   sql += wxT("success = 0, error_cause = '");
7491   clean = gaiaSingleQuotedSql(error_msg.ToUTF8());
7492   sql += wxString::FromUTF8(clean);
7493   free(clean);
7494 #if defined(_WIN32) || defined(__MINGW32__)
7495   /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */
7496   sprintf(dummy, "' WHERE id = %I64d", LastSqlLogID);
7497 #else
7498   sprintf(dummy, "' WHERE id = %lld", LastSqlLogID);
7499 #endif
7500   sql += wxString::FromUTF8(dummy);
7501   ret = sqlite3_exec(SqliteHandle, sql.ToUTF8(), NULL, 0, &errMsg);
7502   if (ret != SQLITE_OK)
7503     {
7504       wxMessageBox(wxT("UpdateLog: ") + wxString::FromUTF8(errMsg),
7505                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
7506       sqlite3_free(errMsg);
7507     }
7508 }
7509 
UpdateAbortedLog()7510 void MyFrame::UpdateAbortedLog()
7511 {
7512 //
7513 // updating sql_statements_log: success
7514 //
7515   char dummy[64];
7516   int ret;
7517   char *errMsg = NULL;
7518   wxString sql = wxT("UPDATE sql_statements_log SET ");
7519   sql += wxT("time_end = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), ");
7520   sql += wxT("success = 0, error_cause = 'aborted by the user' ");
7521 #if defined(_WIN32) || defined(__MINGW32__)
7522   /* CAVEAT - M$ runtime doesn't supports %lld for 64 bits */
7523   sprintf(dummy, "WHERE id = %I64d", LastSqlLogID);
7524 #else
7525   sprintf(dummy, "WHERE id = %lld", LastSqlLogID);
7526 #endif
7527   sql += wxString::FromUTF8(dummy);
7528   ret = sqlite3_exec(SqliteHandle, sql.ToUTF8(), NULL, 0, &errMsg);
7529   if (ret != SQLITE_OK)
7530     {
7531       wxMessageBox(wxT("UpdateAbortedLog: ") + wxString::FromUTF8(errMsg),
7532                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
7533       sqlite3_free(errMsg);
7534     }
7535 }
7536 
GetNextAttachedSymbol(wxString & symbol)7537 void MyFrame::GetNextAttachedSymbol(wxString & symbol)
7538 {
7539 //
7540 // return an unused DB alias name
7541 //
7542   int ret;
7543   char **results;
7544   int rows;
7545   int columns;
7546   int i;
7547   char *errMsg = NULL;
7548   char sym[16];
7549   bool already_used = false;
7550   char x;
7551   char y;
7552   char z;
7553   ret = sqlite3_get_table(GetSqlite(), "PRAGMA database_list", &results,
7554                           &rows, &columns, &errMsg);
7555   if (ret != SQLITE_OK)
7556     {
7557       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
7558                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
7559       sqlite3_free(errMsg);
7560       return;
7561     }
7562   if (rows < 1)
7563     ;
7564   else
7565     {
7566       for (x = 'a'; x < 'z'; x++)
7567         {
7568           already_used = false;
7569           sprintf(sym, "%c", x);
7570           for (i = 1; i <= rows; i++)
7571             {
7572               if (strcasecmp(sym, results[(i * columns) + 1]) == 0)
7573                 already_used = true;
7574             }
7575           if (already_used == false)
7576             {
7577               symbol = wxString::FromUTF8(sym);
7578               goto stop;
7579             }
7580         }
7581       for (y = 'a'; y < 'z'; y++)
7582         {
7583           for (x = 'a'; x < 'z'; x++)
7584             {
7585               already_used = false;
7586               sprintf(sym, "%c%c", y, x);
7587               for (i = 1; i <= rows; i++)
7588                 {
7589                   if (strcasecmp(sym, results[(i * columns) + 1]) == 0)
7590                     already_used = true;
7591                 }
7592               if (already_used == false)
7593                 {
7594                   symbol = wxString::FromUTF8(sym);
7595                   goto stop;
7596                 }
7597             }
7598         }
7599       for (z = 'a'; z < 'z'; z++)
7600         {
7601           for (y = 'a'; y < 'z'; y++)
7602             {
7603               for (x = 'a'; x < 'z'; x++)
7604                 {
7605                   already_used = false;
7606                   sprintf(sym, "%c%c%c", z, y, x);
7607                   for (i = 1; i <= rows; i++)
7608                     {
7609                       if (strcasecmp(sym, results[(i * columns) + 1]) == 0)
7610                         already_used = true;
7611                     }
7612                   if (already_used == false)
7613                     {
7614                       symbol = wxString::FromUTF8(sym);
7615                       goto stop;
7616                     }
7617                 }
7618             }
7619         }
7620     }
7621 stop:
7622   sqlite3_free_table(results);
7623 }
7624 
DoAttachDatabase(wxString & path)7625 bool MyFrame::DoAttachDatabase(wxString & path)
7626 {
7627 //
7628 // attempting to attach another DB
7629 //
7630   int ret;
7631   char *errMsg = NULL;
7632   wxString symbol;
7633   wxString sql = wxT("ATTACH DATABASE \"");
7634   sql += path;
7635   sql += wxT("\" AS ");
7636   GetNextAttachedSymbol(symbol);
7637   sql += symbol;
7638   ret = sqlite3_exec(SqliteHandle, sql.ToUTF8(), NULL, 0, &errMsg);
7639   if (ret != SQLITE_OK)
7640     {
7641       wxMessageBox(wxT("AttachDatabase: ") + wxString::FromUTF8(errMsg),
7642                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
7643       sqlite3_free(errMsg);
7644       return false;
7645     }
7646   return true;
7647 }
7648 
IsDotCommandDumpShp(const char * stmt,char * table,char * column,char * path,char * charset,char * type)7649 bool MyFrame::IsDotCommandDumpShp(const char *stmt, char *table,
7650                                   char *column, char *path,
7651                                   char *charset, char *type)
7652 {
7653 //
7654 // attempting to parse a .dumpshp command [SQL script]
7655 //
7656   wxString cmd = wxString::FromUTF8(stmt);
7657   wxString extPath;
7658   wxString extTable;
7659   wxString extColumn;
7660   wxString extCharset;
7661   wxString extType;
7662   int count = 0;
7663   wxStringTokenizer tok(cmd);
7664   while (tok.HasMoreTokens())
7665     {
7666       wxString token = tok.GetNextToken();
7667       switch (count)
7668         {
7669           case 0:
7670             extTable = token;
7671             break;
7672           case 1:
7673             extColumn = token;
7674             break;
7675           case 2:
7676             extPath = token;
7677             break;
7678           case 3:
7679             extCharset = token;
7680             break;
7681           case 4:
7682             extType = token;
7683             break;
7684         };
7685       count++;
7686     }
7687   if (count == 4 || count == 5)
7688     {
7689       strcpy(path, extPath.ToUTF8());
7690       strcpy(table, extTable.ToUTF8());
7691       strcpy(column, extColumn.ToUTF8());
7692       strcpy(charset, extCharset.ToUTF8());
7693       strcpy(type, extType.ToUTF8());
7694       return true;
7695     }
7696   return false;
7697 }
7698 
GetHelp(wxString & html)7699 void MyFrame::GetHelp(wxString & html)
7700 {
7701 //
7702 // return the HTML Help
7703 //
7704   html =
7705     wxT("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
7706   html += wxT("<html>");
7707   html += wxT("<head>");
7708   html +=
7709     wxT
7710     ("<meta content=\"text/html; charset=UTF-8\" http-equiv=\"content-type\">");
7711   html += wxT("<title>SQLite + SpatiaLite quick Help</title>");
7712   html += wxT("</head>");
7713   html += wxT("<body bgcolor=\"#e8e8e8\">");
7714   html += wxT("<h1><a name=\"index\">SQLite + SpatiaLite quick Help</a></h1>");
7715   html += wxT("<table cellspacing=\"2\" cellpadding=\"2\">");
7716   html +=
7717     wxT
7718     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\">Index of contents</td></tr>");
7719   html +=
7720     wxT
7721     ("<tr><td bgcolor=\"#fffff0\">1.</td><td bgcolor=\"#f0fff0\"><a href=\"#c1\">SQLite SQL syntax</a></td></tr>");
7722   html +=
7723     wxT
7724     ("<tr><td bgcolor=\"#fffff0\">2.</td><td bgcolor=\"#f0fff0\"><a href=\"#c2\">SQLite SQL functions</a><ul>");
7725   html += wxT("<li><a href=\"#c21\">ordinary functions</a></li>");
7726   html += wxT("<li><a href=\"#c22\">aggregate functions</a></li>");
7727   html += wxT("</ul></td></tr>");
7728   html +=
7729     wxT
7730     ("<tr><td bgcolor=\"#fffff0\">3.</td><td bgcolor=\"#f0fff0\"><a href=\"#c3\">SpatiaLite SQL Spatial functions</a><ul>");
7731   html +=
7732     wxT
7733     ("<li><a href=\"#version\">version info [and build options] functions</a></li>");
7734   html += wxT("<li><a href=\"#generic\">generic functions</a></li>");
7735   html += wxT("<li><a href=\"#math\">math functions</a></li>");
7736   html +=
7737     wxT
7738     ("<li><a href=\"#length_cvt\">length/distance unit-conversion functions</a></li>");
7739   html +=
7740     wxT("<li><a href=\"#blob\">utility functions for BLOB objects</a></li>");
7741   html +=
7742     wxT
7743     ("<li><a href=\"#c30\">utility functions [non-standard] for geometric objects</a></li>");
7744   html +=
7745     wxT
7746     ("<li><a href=\"#c31\">functions for constructing a geometric object given its Well-known Text Representation</a></li>");
7747   html +=
7748     wxT
7749     ("<li><a href=\"#c32\">functions for constructing a geometric object given its Well-known Binary Representation</a></li>");
7750   html +=
7751     wxT
7752     ("<li><a href=\"#c33\">functions for obtaining the Well-known Text / Well-known Binary Representation of a geometric object</a></li>");
7753   html +=
7754     wxT
7755     ("<li><a href=\"#c33misc\">functions supporting exotic geometric formats</a></li>");
7756   html += wxT("<li><a href=\"#c34\">functions on type Geometry</a></li>");
7757   html +=
7758     wxT
7759     ("<li><a href=\"#repair\">Functions attempting to repair malformed Geometries</a></li>");
7760   html +=
7761     wxT("<li><a href=\"#compress\">Geometry-compression functions</a></li>");
7762   html += wxT("<li><a href=\"#cast\">Geometry-type casting functions</a></li>");
7763   html +=
7764     wxT
7765     ("<li><a href=\"#dims-cast\">Space-dimensions casting functions</a></li>");
7766   html += wxT("<li><a href=\"#c35\">functions on type Point</a></li>");
7767   html +=
7768     wxT
7769     ("<li><a href=\"#c361\">functions on type Curve [Linestring or Ring]</a></li>");
7770   html +=
7771     wxT
7772     ("<li><a href=\"#c36\">functions on type Surface [Polygon or Ring]</a></li>");
7773   html += wxT("<li><a href=\"#c37\">functions on type Polygon</a></li>");
7774   html += wxT("<li><a href=\"#c38\">functions on type GeomCollection</a></li>");
7775   html +=
7776     wxT
7777     ("<li><a href=\"#c39\">functions testing approximative spatial relationships via MBRs</a></li>");
7778   html +=
7779     wxT
7780     ("<li><a href=\"#c40\">functions testing spatial relationships</a></li>");
7781   html +=
7782     wxT
7783     ("<li><a href=\"#c41\">functions implementing spatial operators</a></li>");
7784   html +=
7785     wxT
7786     ("<li><a href=\"#c42\">functions for coordinate transformations</a></li>");
7787   html +=
7788     wxT
7789     ("<li><a href=\"#c43\">functions for Spatial-MetaData and Spatial-Index handling</a></li>");
7790   html +=
7791     wxT
7792     ("<li><a href=\"#c43style\">functions supporting SLD/SE Styled Layers</a></li>");
7793   html +=
7794     wxT
7795     ("<li><a href=\"#c43isometa\">functions supporting ISO Metadata</a></li>");
7796   html +=
7797     wxT
7798     ("<li><a href=\"#c43fdo\">functions implementing FDO/OGR compatibily</a></li>");
7799   html +=
7800     wxT("<li><a href=\"#c44\">functions for MbrCache-based queries</a></li>");
7801   html +=
7802     wxT
7803     ("<li><a href=\"#c45\">functions for R*Tree-based queries (Geometry Callbacks)</a></li>");
7804   html +=
7805     wxT("<li><a href=\"#xmlBlob\">SQL functions supporting XmlBLOB</a></li>");
7806   html += wxT("</ul></td></tr>");
7807   html += wxT("</table>");
7808   html += wxT("<h3><a name=\"c1\">SQLite SQL syntax</a></h3>");
7809   html += wxT("<table cellspacing=\"4\" cellpadding=\"2\"width=\"100%\">");
7810   html +=
7811     wxT
7812     ("<tr><td bgcolor=\"#fffff0\">ALTER TABLE</td><td bgcolor=\"#f0fff0\">sql-statement ::= ALTER TABLE [database-name .] table-name alteration<br>");
7813   html += wxT("alteration ::= RENAME TO new-table-name<br>");
7814   html += wxT("alteration ::= ADD [COLUMN] column-def<br></td></tr>");
7815   html +=
7816     wxT
7817     ("<tr><td bgcolor=\"#fffff0\">ANALYZE</td><td bgcolor=\"#f0fff0\">sql-statement ::= ANALYZE<br>");
7818   html += wxT("sql-statement ::= ANALYZE database-name<br>");
7819   html +=
7820     wxT("sql-statement ::= ANALYZE [database-name .] table-name<br></td></tr>");
7821   html +=
7822     wxT
7823     ("<tr><td bgcolor=\"#fffff0\">ATTACH DATABASE</td><td bgcolor=\"#f0fff0\">sql-statement ::= ATTACH [DATABASE] database-filename AS database-name</td></tr>");
7824   html +=
7825     wxT
7826     ("<tr><td bgcolor=\"#fffff0\">BEGIN TRANSACTION</td><td bgcolor=\"#f0fff0\">sql-statement ::= BEGIN [ DEFERRED | IMMEDIATE | EXCLUSIVE ] [TRANSACTION [name]]<br>");
7827   html += wxT("sql-statement ::= END [TRANSACTION [name]]<br>");
7828   html += wxT("sql-statement ::= COMMIT [TRANSACTION [name]]<br>");
7829   html += wxT("sql-statement ::= ROLLBACK [TRANSACTION [name]]<br></td></tr>");
7830   html +=
7831     wxT
7832     ("<tr><td bgcolor=\"#fffff0\">COMMIT TRANSACTION</td><td bgcolor=\"#f0fff0\">sql-statement ::= BEGIN [ DEFERRED | IMMEDIATE | EXCLUSIVE ] [TRANSACTION [name]]<br>");
7833   html += wxT("sql-statement ::= END [TRANSACTION [name]]<br>");
7834   html += wxT("sql-statement ::= COMMIT [TRANSACTION [name]]<br>");
7835   html += wxT("sql-statement ::= ROLLBACK [TRANSACTION [name]]<br></td></tr>");
7836   html +=
7837     wxT
7838     ("<tr><td bgcolor=\"#fffff0\">CREATE INDEX</td><td bgcolor=\"#f0fff0\">sql-statement ::= CREATE [UNIQUE] INDEX [IF NOT EXISTS] [database-name .] index-name<br>");
7839   html += wxT("ON table-name ( column-name [, column-name]* )<br>");
7840   html +=
7841     wxT
7842     ("column-name ::= name [ COLLATE collation-name] [ ASC | DESC ]</td></tr>");
7843   html +=
7844     wxT
7845     ("<tr><td bgcolor=\"#fffff0\">CREATE TABLE</td><td bgcolor=\"#f0fff0\">sql-command ::= CREATE [TEMP | TEMPORARY] TABLE [IF NOT EXISTS] [database-name .] table-name (<br>");
7846   html += wxT("column-def [, column-def]*<br>");
7847   html += wxT("[, constraint]*<br>");
7848   html += wxT(")<br>");
7849   html +=
7850     wxT
7851     ("sql-command ::= CREATE [TEMP | TEMPORARY] TABLE [database-name.] table-name AS select-statement<br>");
7852   html +=
7853     wxT
7854     ("column-def ::= name [type] [[CONSTRAINT name] column-constraint]*<br>");
7855   html += wxT("type ::= typename |<br>");
7856   html += wxT("typename ( number ) |<br>");
7857   html += wxT("typename ( number , number )<br>");
7858   html += wxT("column-constraint ::= NOT NULL [ conflict-clause ] |<br>");
7859   html +=
7860     wxT("PRIMARY KEY [sort-order] [ conflict-clause ] [AUTOINCREMENT] |<br>");
7861   html += wxT("UNIQUE [ conflict-clause ] |<br>");
7862   html += wxT("CHECK ( expr ) |<br>");
7863   html += wxT("DEFAULT value |<br>");
7864   html += wxT("COLLATE collation-name<br>");
7865   html +=
7866     wxT("constraint ::= PRIMARY KEY ( column-list ) [ conflict-clause ] |<br>");
7867   html += wxT("UNIQUE ( column-list ) [ conflict-clause ] |<br>");
7868   html += wxT("CHECK ( expr )<br>");
7869   html += wxT("conflict-clause ::= ON CONFLICT conflict-algorithm</td></tr>");
7870   html +=
7871     wxT
7872     ("<tr><td bgcolor=\"#fffff0\">CREATE TRIGGER</td><td bgcolor=\"#f0fff0\">sql-statement ::= CREATE [TEMP | TEMPORARY] TRIGGER [IF NOT EXISTS] trigger-name [ BEFORE | AFTER ]<br>");
7873   html += wxT("database-event ON [database-name .] table-name<br>");
7874   html += wxT("trigger-action<br>");
7875   html +=
7876     wxT
7877     ("sql-statement ::= CREATE [TEMP | TEMPORARY] TRIGGER [IF NOT EXISTS] trigger-name INSTEAD OF<br>");
7878   html += wxT("database-event ON [database-name .] view-name<br>");
7879   html += wxT("trigger-action<br>");
7880   html += wxT("database-event ::= DELETE |<br>");
7881   html += wxT("INSERT |<br>");
7882   html += wxT("UPDATE |<br>");
7883   html += wxT("UPDATE OF column-list<br>");
7884   html += wxT("trigger-action ::= [ FOR EACH ROW ] [ WHEN expression ]<br>");
7885   html += wxT("BEGIN<br>");
7886   html += wxT("trigger-step ; [ trigger-step ; ]*<br>");
7887   html += wxT("END<br>");
7888   html += wxT("trigger-step ::= update-statement | insert-statement |<br>");
7889   html += wxT("delete-statement | select-statement</td></tr>");
7890   html +=
7891     wxT
7892     ("<tr><td bgcolor=\"#fffff0\">CREATE VIEW</td><td bgcolor=\"#f0fff0\">sql-command ::= CREATE [TEMP | TEMPORARY] VIEW [IF NOT EXISTS] [database-name.] view-name AS select-statement</td></tr>");
7893   html +=
7894     wxT
7895     ("<tr><td bgcolor=\"#fffff0\">CREATE VIRTUAL TABLE</td><td bgcolor=\"#f0fff0\">sql-command ::= CREATE VIRTUAL TABLE [database-name .] table-name USING module-name [( arguments )]</td></tr>");
7896   html +=
7897     wxT
7898     ("<tr><td bgcolor=\"#fffff0\">DELETE</td><td bgcolor=\"#f0fff0\">sql-statement ::= DELETE FROM [database-name .] table-name [WHERE expr]</td></tr>");
7899   html +=
7900     wxT
7901     ("<tr><td bgcolor=\"#fffff0\">DETACH DATABASE</td><td bgcolor=\"#f0fff0\">sql-command ::= DETACH [DATABASE] database-name</td></tr>");
7902   html +=
7903     wxT
7904     ("<tr><td bgcolor=\"#fffff0\">DROP INDEX</td><td bgcolor=\"#f0fff0\">sql-command ::= DROP INDEX [IF EXISTS] [database-name .] index-name</td></tr>");
7905   html +=
7906     wxT
7907     ("<tr><td bgcolor=\"#fffff0\">DROP TABLE</td><td bgcolor=\"#f0fff0\">sql-command ::= DROP TABLE [IF EXISTS] [database-name.] table-name</td></tr>");
7908   html +=
7909     wxT
7910     ("<tr><td bgcolor=\"#fffff0\">DROP TRIGGER</td><td bgcolor=\"#f0fff0\">sql-statement ::= DROP TRIGGER [IF EXISTS] [database-name .] trigger-name</td></tr>");
7911   html +=
7912     wxT
7913     ("<tr><td bgcolor=\"#fffff0\">DROP VIEW</td><td bgcolor=\"#f0fff0\">sql-command ::= DROP VIEW [IF EXISTS] view-name</td></tr>");
7914   html +=
7915     wxT
7916     ("<tr><td bgcolor=\"#fffff0\">END TRANSACTION</td><td bgcolor=\"#f0fff0\">sql-statement ::= BEGIN [ DEFERRED | IMMEDIATE | EXCLUSIVE ] [TRANSACTION [name]]<br>");
7917   html += wxT("sql-statement ::= END [TRANSACTION [name]]<br>");
7918   html += wxT("sql-statement ::= COMMIT [TRANSACTION [name]]<br>");
7919   html += wxT("sql-statement ::= ROLLBACK [TRANSACTION [name]]<br></td></tr>");
7920   html +=
7921     wxT
7922     ("<tr><td bgcolor=\"#fffff0\">EXPLAIN</td><td bgcolor=\"#f0fff0\">sql-statement ::= EXPLAIN sql-statement</td></tr>");
7923   html +=
7924     wxT
7925     ("<tr><td bgcolor=\"#fffff0\">INSERT</td><td bgcolor=\"#f0fff0\">sql-statement ::= INSERT [OR conflict-algorithm] INTO [database-name .] table-name [(column-list)] VALUES(value-list) |<br>");
7926   html +=
7927     wxT
7928     ("INSERT [OR conflict-algorithm] INTO [database-name .] table-name [(column-list)] select-statement</td></tr>");
7929   html +=
7930     wxT
7931     ("<tr><td bgcolor=\"#fffff0\">ON CONFLICT clause</td><td bgcolor=\"#f0fff0\">conflict-clause ::= ON CONFLICT conflict-algorithm<br>");
7932   html +=
7933     wxT
7934     ("conflict-algorithm ::= ROLLBACK | ABORT | FAIL | IGNORE | REPLACE</td></tr>");
7935   html +=
7936     wxT
7937     ("<tr><td bgcolor=\"#fffff0\">PRAGMA</td><td bgcolor=\"#f0fff0\">sql-statement ::= PRAGMA name [= value] |<br>");
7938   html += wxT("PRAGMA function(arg)<hr>");
7939   html += wxT("PRAGMA auto_vacuum;<br>");
7940   html +=
7941     wxT("PRAGMA auto_vacuum = 0 | none | 1 | full | 2 | incremental;<hr>");
7942   html += wxT("PRAGMA cache_size;<br>");
7943   html += wxT("PRAGMA cache_size = Number-of-pages;<hr>");
7944   html += wxT("PRAGMA case_sensitive_like;<br>");
7945   html += wxT("PRAGMA case_sensitive_like = 0 | 1;<hr>");
7946   html += wxT("PRAGMA count_changes;<br>");
7947   html += wxT("PRAGMA count_changes = 0 | 1;<hr>");
7948   html += wxT("PRAGMA default_cache_size;<br>");
7949   html += wxT("PRAGMA default_cache_size = Number-of-pages;<hr>");
7950   html += wxT("PRAGMA empty_result_callbacks;<br>");
7951   html += wxT("PRAGMA empty_result_callbacks = 0 | 1;<hr>");
7952   html += wxT("PRAGMA encoding;<br>");
7953   html += wxT("PRAGMA encoding = \"UTF-8\";<br>");
7954   html += wxT("PRAGMA encoding = \"UTF-16\";<br>");
7955   html += wxT("PRAGMA encoding = \"UTF-16le\";<br>");
7956   html += wxT("PRAGMA encoding = \"UTF-16be\";<hr>");
7957   html += wxT("PRAGMA foreign_keys;<br>");
7958   html += wxT("PRAGMA foreign_keys = 0 | 1;<hr>");
7959   html += wxT("PRAGMA full_column_names;<br>");
7960   html += wxT("PRAGMA full_column_names = 0 | 1;<hr>");
7961   html += wxT("PRAGMA fullfsync;<br>");
7962   html += wxT("PRAGMA fullfsync = 0 | 1;<hr>");
7963   html += wxT("PRAGMA journal_mode;<br>");
7964   html += wxT("PRAGMA database.journal_mode;<br>");
7965   html +=
7966     wxT("PRAGMA journal_mode = DELETE | TRUNCATE | PERSIST | MEMORY | OFF<br>");
7967   html +=
7968     wxT
7969     ("PRAGMA database.journal_mode = DELETE | TRUNCATE | PERSIST | MEMORY | OFF<hr>");
7970   html += wxT("PRAGMA journal_size_limit;<br>");
7971   html += wxT("PRAGMA journal_size_limit = N<hr>");
7972   html += wxT("PRAGMA legacy_file_format;<br>");
7973   html += wxT("PRAGMA legacy_file_format = 0 | 1<hr>");
7974   html += wxT("PRAGMA locking_mode;<br>");
7975   html += wxT("PRAGMA locking_mode = NORMAL | EXCLUSIVE<hr>");
7976   html += wxT("PRAGMA page_size;<br>");
7977   html += wxT("PRAGMA page_size = bytes;<hr>");
7978   html += wxT("PRAGMA max_page_count;<br>");
7979   html += wxT("PRAGMA max_page_count = N;<hr>");
7980   html += wxT("PRAGMA read_uncommitted;<br>");
7981   html += wxT("PRAGMA read_uncommitted = 0 | 1;<hr>");
7982   html += wxT("PRAGMA recursive_triggers;<br>");
7983   html += wxT("PRAGMA recursive_triggers = 0 | 1;<hr>");
7984   html += wxT("PRAGMA reverse_unordered_selects;<br>");
7985   html += wxT("PRAGMA reverse_unordered_selects = 0 | 1;<hr>");
7986   html += wxT("PRAGMA short_column_names;<br>");
7987   html += wxT("PRAGMA short_column_names = 0 | 1;<hr>");
7988   html += wxT("PRAGMA synchronous;<br>");
7989   html += wxT("PRAGMA synchronous = FULL; (2)<br>");
7990   html += wxT("PRAGMA synchronous = NORMAL; (1)<br>");
7991   html += wxT("PRAGMA synchronous = OFF; (0)<hr>");
7992   html += wxT("PRAGMA temp_store;<br>");
7993   html += wxT("PRAGMA temp_store = DEFAULT; (0)<br>");
7994   html += wxT("PRAGMA temp_store = FILE; (1)<br>");
7995   html += wxT("PRAGMA temp_store = MEMORY; (2)<hr>");
7996   html += wxT("PRAGMA temp_store_directory;<br>");
7997   html += wxT("PRAGMA temp_store_directory = 'directory-name';<hr>");
7998   html += wxT("PRAGMA database_list;<hr>");
7999   html += wxT("PRAGMA foreign_key_list(table-name);<hr>");
8000   html += wxT("PRAGMA [database].freelist_count;<hr>");
8001   html += wxT("PRAGMA index_info(index-name);<hr>");
8002   html += wxT("PRAGMA index_list(table-name);<hr>");
8003   html += wxT("PRAGMA table_info(table-name);<hr>");
8004   html += wxT("PRAGMA [database.]schema_version;<br>");
8005   html += wxT("PRAGMA [database.]schema_version = integer ;<br>");
8006   html += wxT("PRAGMA [database.]user_version;<br>");
8007   html += wxT("PRAGMA [database.]user_version = integer ;<hr>");
8008   html += wxT("PRAGMA integrity_check;<br>");
8009   html += wxT("PRAGMA integrity_check(integer)<hr>");
8010   html += wxT("PRAGMA quick_check;<br>");
8011   html += wxT("PRAGMA quick_check(integer)<hr>");
8012   html += wxT("PRAGMA parser_trace = ON; (1)<br>");
8013   html += wxT("PRAGMA parser_trace = OFF; (0)<hr>");
8014   html += wxT("PRAGMA vdbe_trace = ON; (1)<br>");
8015   html += wxT("PRAGMA vdbe_trace = OFF; (0)<hr>");
8016   html += wxT("PRAGMA vdbe_listing = ON; (1)<br>");
8017   html += wxT("PRAGMA vdbe_listing = OFF; (0)</td></tr>");
8018   html +=
8019     wxT
8020     ("<tr><td bgcolor=\"#fffff0\">REINDEX</td><td bgcolor=\"#f0fff0\">sql-statement ::= REINDEX collation name<br>");
8021   html +=
8022     wxT
8023     ("sql-statement ::= REINDEX [database-name .] table/index-name</td></tr>");
8024   html +=
8025     wxT
8026     ("<tr><td bgcolor=\"#fffff0\">REPLACE</td><td bgcolor=\"#f0fff0\">sql-statement ::= REPLACE INTO [database-name .] table-name [( column-list )] VALUES ( value-list ) |<br>");
8027   html +=
8028     wxT
8029     ("REPLACE INTO [database-name .] table-name [( column-list )] select-statement</td></tr>");
8030   html +=
8031     wxT
8032     ("<tr><td bgcolor=\"#fffff0\">ROLLBACK TRANSACTION</td><td bgcolor=\"#f0fff0\">sql-statement ::= BEGIN [ DEFERRED | IMMEDIATE | EXCLUSIVE ] [TRANSACTION [name]]<br>");
8033   html += wxT("sql-statement ::= END [TRANSACTION [name]]<br>");
8034   html += wxT("sql-statement ::= COMMIT [TRANSACTION [name]]<br>");
8035   html += wxT("sql-statement ::= ROLLBACK [TRANSACTION [name]]<br></td></tr>");
8036   html +=
8037     wxT
8038     ("<tr><td bgcolor=\"#fffff0\">SELECT</td><td bgcolor=\"#f0fff0\">sql-statement ::= SELECT [ALL | DISTINCT] result [FROM table-list]<br>");
8039   html += wxT("[WHERE expr]<br>");
8040   html += wxT("[GROUP BY expr-list]<br>");
8041   html += wxT("[HAVING expr]<br>");
8042   html += wxT("[compound-op select]*<br>");
8043   html += wxT("[ORDER BY sort-expr-list]<br>");
8044   html += wxT("[LIMIT integer [( OFFSET | , ) integer]]<br>");
8045   html += wxT("result ::= result-column [, result-column]*<br>");
8046   html +=
8047     wxT("result-column ::= * | table-name . * | expr [ [AS] string ]<br>");
8048   html += wxT("table-list ::= table [join-op table join-args]*<br>");
8049   html += wxT("table ::= table-name [AS alias] |<br>");
8050   html += wxT("( select ) [AS alias]<br>");
8051   html +=
8052     wxT
8053     ("join-op ::= , | [NATURAL] [LEFT | RIGHT | FULL] [OUTER | INNER | CROSS] JOIN<br>");
8054   html += wxT("join-args ::= [ON expr] [USING ( id-list )]<br>");
8055   html +=
8056     wxT("sort-expr-list ::= expr [sort-order] [, expr [sort-order]]*<br>");
8057   html += wxT("sort-order ::= [ COLLATE collation-name ] [ ASC | DESC ]<br>");
8058   html +=
8059     wxT("compound_op ::= UNION | UNION ALL | INTERSECT | EXCEPT</td></tr>");
8060   html +=
8061     wxT
8062     ("<tr><td bgcolor=\"#fffff0\">UPDATE</td><td bgcolor=\"#f0fff0\">sql-statement ::= UPDATE [ OR conflict-algorithm ] [database-name .] table-name<br>");
8063   html += wxT("SET assignment [, assignment]*<br>");
8064   html += wxT("[WHERE expr]<br>");
8065   html += wxT("assignment ::= column-name = expr</td></tr>");
8066   html +=
8067     wxT
8068     ("<tr><td bgcolor=\"#fffff0\">VACUUM</td><td bgcolor=\"#f0fff0\">sql-statement ::= VACUUM</td></tr>");
8069   html += wxT("</table>");
8070   html += wxT("<a href=\"#index\">back to index</a>");
8071   html +=
8072     wxT
8073     ("<h3><a align=\"center\" bgcolor=\"#e0ffe0\" name=\"c2\">SQLite SQL functions</a></h3>");
8074   html += wxT("<table cellspacing=\"4\" cellpadding=\"2\" width=\"100%\">");
8075   html +=
8076     wxT
8077     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c21\">ordinary functions</a><br><a href=\"#index\">back to index</a></td></tr>");
8078   html +=
8079     wxT
8080     ("<tr><td bgcolor=\"#fffff0\">abs(X)</td><td bgcolor=\"#f0fff0\">Return the absolute value of the numeric argument X. ");
8081   html +=
8082     wxT
8083     ("Return NULL if X is NULL. Return 0.0 if X is not a numeric value.</td></tr>");
8084   html +=
8085     wxT
8086     ("<tr><td bgcolor=\"#fffff0\">changes()</td><td bgcolor=\"#f0fff0\">Returns the number of database rows that were changed or inserted or deleted ");
8087   html +=
8088     wxT
8089     ("by the most recently completed INSERT, DELETE, or UPDATE statement, exclusive of statements in lower-level triggers.</td></tr>");
8090   html +=
8091     wxT
8092     ("<tr><td bgcolor=\"#fffff0\">char(X1,X2,...,XN)</td><td bgcolor=\"#f0fff0\">The char(X1,X2,...,XN) function returns a string ");
8093   html +=
8094     wxT
8095     ("composed of characters having the unicode code point values of integers X1 through XN, respectively.</td></tr>");
8096   html +=
8097     wxT
8098     ("<tr><td bgcolor=\"#fffff0\">coalesce(X,Y,...)</td><td bgcolor=\"#f0fff0\">Return a copy of the first non-NULL argument. ");
8099   html +=
8100     wxT
8101     ("If all arguments are NULL then NULL is returned. There must be at least 2 arguments.</td></tr>");
8102   html +=
8103     wxT
8104     ("<tr><td bgcolor=\"#fffff0\">glob(X,Y)</td><td bgcolor=\"#f0fff0\">This function is used to implement the \"X GLOB Y\" syntax of SQLite. ");
8105   html +=
8106     wxT
8107     ("The sqlite3_create_function() interface can be used to override this function and thereby change the operation of the GLOB operator.</td></tr>");
8108   html +=
8109     wxT
8110     ("<tr><td bgcolor=\"#fffff0\">ifnull(X,Y)</td><td bgcolor=\"#f0fff0\">Return a copy of the first non-NULL argument. ");
8111   html +=
8112     wxT
8113     ("If both arguments are NULL then NULL is returned. This behaves the same as coalesce().</td></tr>");
8114   html +=
8115     wxT
8116     ("<tr><td bgcolor=\"#fffff0\">instr(X,Y)</td><td bgcolor=\"#f0fff0\">The instr(X,Y) function finds the first occurrence of string Y within string X and returns the ");
8117   html +=
8118     wxT
8119     ("number of prior characters plus 1, or 0 if Y is nowhere found within X. Or, if X and Y are both BLOBs, then instr(X,Y) returns one more than ");
8120   html +=
8121     wxT
8122     ("the number bytes prior to the first occurrence of Y, or 0 if Y does not occur anywhere within X. If both arguments X and Y to instr(X,Y) ");
8123   html +=
8124     wxT
8125     ("are non-NULL and are not BLOBs then both are interpreted as strings. If either X or Y are NULL in instr(X,Y) then the result is NULL. </td></tr>");
8126   html +=
8127     wxT
8128     ("<tr><td bgcolor=\"#fffff0\">hex(X)</td><td bgcolor=\"#f0fff0\">The argument is interpreted as a BLOB. ");
8129   html +=
8130     wxT
8131     ("The result is a hexadecimal rendering of the content of that blob.</td></tr>");
8132   html +=
8133     wxT
8134     ("<tr><td bgcolor=\"#fffff0\">last_insert_rowid()</td><td bgcolor=\"#f0fff0\">Return the ROWID of the last row insert from this connection to the database. ");
8135   html +=
8136     wxT
8137     ("This is the same value that would be returned from the sqlite3_last_insert_rowid() API function.</td></tr>");
8138   html +=
8139     wxT
8140     ("<tr><td bgcolor=\"#fffff0\">length(X)</td><td bgcolor=\"#f0fff0\">Return the string length of X in characters. ");
8141   html +=
8142     wxT
8143     ("If SQLite is configured to support UTF-8, then the number of UTF-8 characters is returned, not the number of bytes.</td></tr>");
8144   html +=
8145     wxT
8146     ("<tr><td bgcolor=\"#fffff0\">like(X,Y)<br>like(X,Y,Z)</td><td bgcolor=\"#f0fff0\">This function is used to implement the \"X LIKE Y [ESCAPE Z]\" syntax of SQL.");
8147   html +=
8148     wxT
8149     ("If the optional ESCAPE clause is present, then the user-function is invoked with three arguments. ");
8150   html += wxT("Otherwise, it is invoked with two arguments only. ");
8151   html +=
8152     wxT
8153     ("The sqlite3_create_function() interface can be used to override this function and thereby change the operation of the LIKE operator. ");
8154   html +=
8155     wxT
8156     ("When doing this, it may be important to override both the two and three argument versions of the like() function. ");
8157   html +=
8158     wxT
8159     ("Otherwise, different code may be called to implement the LIKE operator depending on whether or not an ESCAPE clause was specified.</td></tr>");
8160   html +=
8161     wxT
8162     ("<tr><td bgcolor=\"#fffff0\">load_extension(X)</br>load_extension(X,Y)</td><td bgcolor=\"#f0fff0\">Load SQLite extensions ");
8163   html +=
8164     wxT("out of the shared library file named X using the entry point Y. ");
8165   html +=
8166     wxT
8167     ("The result is a NULL. If Y is omitted then the default entry point of sqlite3_extension_init is used. ");
8168   html +=
8169     wxT
8170     ("This function raises an exception if the extension fails to load or initialize correctly.</td></tr>");
8171   html +=
8172     wxT
8173     ("<tr><td bgcolor=\"#fffff0\">lower(X)</td><td bgcolor=\"#f0fff0\">Return a copy of string X will all ASCII characters converted to lower case. ");
8174   html +=
8175     wxT
8176     ("The C library tolower() routine is used for the conversion, which means that this function might not work correctly on non-ASCII UTF-8 characters.</td></tr>");
8177   html +=
8178     wxT
8179     ("<tr><td bgcolor=\"#fffff0\">ltrim(X)<br>ltrim(X,Y)</td><td bgcolor=\"#f0fff0\">Return a string formed by removing any and all characters ");
8180   html +=
8181     wxT
8182     ("that appear in Y from the left side of X. If the Y argument is omitted, spaces are removed.</td></tr>");
8183   html +=
8184     wxT
8185     ("<tr><td bgcolor=\"#fffff0\">max(X,Y,...)</td><td bgcolor=\"#f0fff0\">Return the argument with the maximum value. ");
8186   html += wxT("Arguments may be strings in addition to numbers. ");
8187   html += wxT("The maximum value is determined by the usual sort order. ");
8188   html +=
8189     wxT
8190     ("Note that max() is a simple function when it has 2 or more arguments but converts to an aggregate function if given only a single argument.</td></tr>");
8191   html +=
8192     wxT
8193     ("<tr><td bgcolor=\"#fffff0\">min(X,Y,...)</td><td bgcolor=\"#f0fff0\">Return the argument with the minimum value. ");
8194   html += wxT("Arguments may be strings in addition to numbers. ");
8195   html += wxT("The minimum value is determined by the usual sort order. ");
8196   html +=
8197     wxT
8198     ("Note that min() is a simple function when it has 2 or more arguments but converts to an aggregate function if given only a single argument.</td></tr>");
8199   html +=
8200     wxT
8201     ("<tr><td bgcolor=\"#fffff0\">nullif(X,Y)</td><td bgcolor=\"#f0fff0\">Return the first argument if the arguments are different, otherwise return NULL.</td></tr>");
8202   html +=
8203     wxT
8204     ("<tr><td bgcolor=\"#fffff0\">quote(X)</td><td bgcolor=\"#f0fff0\">This routine return a string which is the value of its argument suitable for inclusion ");
8205   html +=
8206     wxT
8207     ("into another SQL statement. Strings are surrounded by single-quotes with escapes on interior quotes as needed. ");
8208   html +=
8209     wxT
8210     ("BLOBs are encoded as hexadecimal literals. The implementation of VACUUM uses this function. ");
8211   html +=
8212     wxT
8213     ("The function is also useful when writing triggers to implement undo/redo functionality.</td></tr>");
8214   html +=
8215     wxT
8216     ("<tr><td bgcolor=\"#fffff0\">random()</td><td bgcolor=\"#f0fff0\">Return a pseudo-random integer between -9223372036854775808 and +9223372036854775807.</td></tr>");
8217   html +=
8218     wxT
8219     ("<tr><td bgcolor=\"#fffff0\">randomblob(N)</td><td bgcolor=\"#f0fff0\">Return an N-byte blob containing pseudo-random bytes. N should be a postive integer.</td></tr>");
8220   html +=
8221     wxT
8222     ("<tr><td bgcolor=\"#fffff0\">replace(X,Y,Z)</td><td bgcolor=\"#f0fff0\">Return a string formed by substituting string Z for every occurrance of string Y in string X. ");
8223   html +=
8224     wxT("The BINARY collating sequence is used for comparisons.</td></tr>");
8225   html +=
8226     wxT
8227     ("<tr><td bgcolor=\"#fffff0\">round(X)<br>round(X,Y)</td><td bgcolor=\"#f0fff0\">Round off the number X to Y digits to the right of the decimal point. ");
8228   html += wxT("If the Y argument is omitted, 0 is assumed.</td></tr>");
8229   html +=
8230     wxT
8231     ("<tr><td bgcolor=\"#fffff0\">rtrim(X)<br>rtrim(X,Y)</td><td bgcolor=\"#f0fff0\">Return a string formed by removing any and all characters ");
8232   html +=
8233     wxT
8234     ("that appear in Y from the right side of X. If the Y argument is omitted, spaces are removed.</td></tr>");
8235   html +=
8236     wxT
8237     ("<tr><td bgcolor=\"#fffff0\">sqlite_version(X)</td><td bgcolor=\"#f0fff0\">Return the version string for the SQLite library that is running. Example: \"3.5.9\"</td></tr>");
8238   html +=
8239     wxT
8240     ("<tr><td bgcolor=\"#fffff0\">substr(X,Y,Z)<br>substr(X,Y)</td><td bgcolor=\"#f0fff0\">Return a substring of input string X that begins with the Y-th character ");
8241   html +=
8242     wxT
8243     ("and which is Z characters long. If Z is omitted then all character through the end of the string are returned. ");
8244   html += wxT("The left-most character of X is number 1. ");
8245   html +=
8246     wxT
8247     ("If Y is negative the the first character of the substring is found by counting from the right rather than the left. ");
8248   html +=
8249     wxT
8250     ("If X is string then characters indices refer to actual UTF-8 characters. If X is a BLOB then the indices refer to bytes.</td></tr>");
8251   html +=
8252     wxT
8253     ("<tr><td bgcolor=\"#fffff0\">trim(X)<br>trim(X,Y)</td><td bgcolor=\"#f0fff0\">Return a string formed by removing any and all characters that appear in Y from both ends of X. ");
8254   html += wxT("If the Y argument is omitted, spaces are removed.</td></tr>");
8255   html +=
8256     wxT
8257     ("<tr><td bgcolor=\"#fffff0\">typeof(X)</td><td bgcolor=\"#f0fff0\">Return the type of the expression X. ");
8258   html +=
8259     wxT
8260     ("The only return values are \"null\", \"integer\", \"real\", \"text\", and \"blob\".</td></tr>");
8261   html +=
8262     wxT
8263     ("<tr><td bgcolor=\"#fffff0\">unicode(X)</td><td bgcolor=\"#f0fff0\">The unicode(X) function returns the numeric unicode code point corresponding to the first ");
8264   html +=
8265     wxT
8266     ("character of the string X. If the argument to unicode(X) is not a string then the result is undefined. </td></tr>");
8267   html +=
8268     wxT
8269     ("<tr><td bgcolor=\"#fffff0\">upper(X)</td><td bgcolor=\"#f0fff0\">Return a copy of input string X converted to all upper-case letters. ");
8270   html +=
8271     wxT
8272     ("The implementation of this function uses the C library routine toupper() which means it may not work correctly on non-ASCII UTF-8 strings.</td></tr>");
8273   html +=
8274     wxT
8275     ("<tr><td bgcolor=\"#fffff0\">zeroblob(N)</td><td bgcolor=\"#f0fff0\">Return a BLOB consisting of N bytes of 0x00. ");
8276   html += wxT("SQLite manages these zeroblobs very efficiently. ");
8277   html +=
8278     wxT
8279     ("Zeroblobs can be used to reserve space for a BLOB that is later written using incremental BLOB I/O.</td></tr> ");
8280   html +=
8281     wxT
8282     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c22\">aggregate functions</a><br><a href=\"#index\">back to index</a></td></tr>");
8283   html +=
8284     wxT
8285     ("<tr><td bgcolor=\"#fffff0\">avg(X)</td><td bgcolor=\"#f0fff0\">Return the average value of all non-NULL X within a group. ");
8286   html +=
8287     wxT
8288     ("String and BLOB values that do not look like numbers are interpreted as 0. ");
8289   html +=
8290     wxT
8291     ("The result of avg() is always a floating point value even if all inputs are integers.</td></tr>");
8292   html +=
8293     wxT
8294     ("<tr><td bgcolor=\"#fffff0\">count(X)<br>count(*)</td><td bgcolor=\"#f0fff0\">The first form return a count of the number of times that X is not NULL in a group. ");
8295   html +=
8296     wxT
8297     ("The second form (with no argument) return the total number of rows in the group.</td></tr>");
8298   html +=
8299     wxT
8300     ("<tr><td bgcolor=\"#fffff0\">group_concat(X)<br>group_concat(X,Y)</td><td bgcolor=\"#f0fff0\">The result is a string which is the concatenation of all non-NULL values of X. ");
8301   html +=
8302     wxT
8303     ("If parameter Y is the separator between instances of X. A comma (\",\") is used as the separator if Y is omitted.</td></tr>");
8304   html +=
8305     wxT
8306     ("<tr><td bgcolor=\"#fffff0\">max(X)</td><td bgcolor=\"#f0fff0\">Return the maximum value of all values in the group. ");
8307   html +=
8308     wxT("The usual sort order is used to determine the maximum.</td></tr>");
8309   html +=
8310     wxT
8311     ("<tr><td bgcolor=\"#fffff0\">min(X)</td><td bgcolor=\"#f0fff0\">Return the minimum non-NULL value of all values in the group. ");
8312   html +=
8313     wxT
8314     ("The usual sort order is used to determine the minimum. NULL is only returned if all values in the group are NULL.</td></tr>");
8315   html +=
8316     wxT
8317     ("<tr><td bgcolor=\"#fffff0\">sum(X)<br>total(X)</td><td bgcolor=\"#f0fff0\">Return the numeric sum of all non-NULL values in the group. ");
8318   html +=
8319     wxT
8320     ("If there are no non-NULL input rows then sum() return NULL but total() return 0.0. ");
8321   html +=
8322     wxT
8323     ("NULL is not normally a helpful result for the sum of no rows but the SQL standard requires it and most other SQL ");
8324   html +=
8325     wxT
8326     ("database engines implement sum() that way so SQLite does it in the same way in order to be compatible. ");
8327   html +=
8328     wxT
8329     ("The non-standard total() function is provided as a convenient way to work around this design problem in the SQL language.<br>");
8330   html +=
8331     wxT
8332     ("The result of total() is always a floating point value. The result of sum() is an integer value if all non-NULL inputs are integers. ");
8333   html +=
8334     wxT
8335     ("If any input to sum() is neither an integer or a NULL then sum() return a floating point value which might be an approximation to the true sum.<br>");
8336   html +=
8337     wxT
8338     ("Sum() will throw an \"integer overflow\" exception if all inputs are integers or NULL and an integer overflow occurs at any point during the computation.");
8339   html += wxT("Total() never throws an exception.</td></tr> ");
8340   html += wxT("</table>");
8341   html += wxT("<a href=\"#index\">back to index</a>");
8342   html += wxT("<h3><a name=\"c3\">SpatiaLite SQL Spatial functions</a></h3>");
8343   html += wxT("<table cellspacing=\"4\" cellpadding=\"2\" width=\"100%\">");
8344   html +=
8345     wxT
8346     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"version\">SQL version info [and build options] functions</a></a>");
8347   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
8348   html +=
8349     wxT("<tr><td bgcolor=\"#fffff0\">spatialite_version( void ) : String</td>");
8350   html +=
8351     wxT
8352     ("<td bgcolor=\"#f0fff0\">returns the current SpatiaLite version</td></tr>");
8353   html +=
8354     wxT("<tr><td bgcolor=\"#fffff0\">proj4_version( void ) : String</td>");
8355   html +=
8356     wxT
8357     ("<td bgcolor=\"#f0fff0\">returns the current PROJ.4 version, or NULL if PROJ.4 is currently unsupported</td></tr>");
8358   html += wxT("<tr><td bgcolor=\"#fffff0\">geos_version( void ) : String</td>");
8359   html +=
8360     wxT
8361     ("<td bgcolor=\"#f0fff0\">returns the current GEOS version, or NULL if GEOS is currently unsupported</td></tr>");
8362   html +=
8363     wxT("<tr><td bgcolor=\"#fffff0\">lwgeom_version( void ) : String</td>");
8364   html +=
8365     wxT
8366     ("<td bgcolor=\"#f0fff0\">returns the current LWGEOM version, or NULL if LWGEOM is currently unsupported</td></tr>");
8367   html +=
8368     wxT("<tr><td bgcolor=\"#fffff0\">libxml2_version( void ) : String</td>");
8369   html +=
8370     wxT
8371     ("<td bgcolor=\"#f0fff0\">returns the current LibXML2 version, or NULL if LibXML2 is currently unsupported</td></tr>");
8372   html += wxT("<tr><td bgcolor=\"#fffff0\">HasIconv( void ) : Boolean</td>");
8373   html +=
8374     wxT
8375     ("<td bgcolor=\"#f0fff0\">TRUE if the underlaying library was built enabling ICONV</td></tr>");
8376   html += wxT("<tr><td bgcolor=\"#fffff0\">HasMathSQL( void ) : Boolean</td>");
8377   html +=
8378     wxT
8379     ("<td bgcolor=\"#f0fff0\">TRUE if the underlaying library was built enabling MATHSQL</td></tr>");
8380   html +=
8381     wxT("<tr><td bgcolor=\"#fffff0\">HasGeoCallbacks( void ) : Boolean</td>");
8382   html +=
8383     wxT
8384     ("<td bgcolor=\"#f0fff0\">TRUE if the underlaying library was built enabling GEOCALLBACKS</td></tr>");
8385   html += wxT("<tr><td bgcolor=\"#fffff0\">HasProj( void ) : Boolean</td>");
8386   html +=
8387     wxT
8388     ("<td bgcolor=\"#f0fff0\">TRUE if the underlaying library was built enabling PROJ</td></tr>");
8389   html += wxT("<tr><td bgcolor=\"#fffff0\">HasGeos( void ) : Boolean</td>");
8390   html +=
8391     wxT
8392     ("<td bgcolor=\"#f0fff0\">TRUE if the underlaying library was built enabling GEOS</td></tr>");
8393   html +=
8394     wxT("<tr><td bgcolor=\"#fffff0\">HasGeosAdvanced( void ) : Boolean</td>");
8395   html +=
8396     wxT
8397     ("<td bgcolor=\"#f0fff0\">TRUE if the underlaying library was built enabling GEOSADVANCED</td></tr>");
8398   html +=
8399     wxT("<tr><td bgcolor=\"#fffff0\">HasGeosTrunk( void ) : Boolean</td>");
8400   html +=
8401     wxT
8402     ("<td bgcolor=\"#f0fff0\">TRUE if the underlaying library was built enabling GEOSTRUNK</td></tr>");
8403   html += wxT("<tr><td bgcolor=\"#fffff0\">HasLwGeom( void ) : Boolean</td>");
8404   html +=
8405     wxT
8406     ("<td bgcolor=\"#f0fff0\">TRUE if the underlaying library was built enabling LWGEOM</td></tr>");
8407   html += wxT("<tr><td bgcolor=\"#fffff0\">HasLibXML2( void ) : Boolean</td>");
8408   html +=
8409     wxT
8410     ("<td bgcolor=\"#f0fff0\">TRUE if the underlaying library was built enabling LibXML2</td></tr>");
8411   html += wxT("<tr><td bgcolor=\"#fffff0\">HasEpsg( void ) : Boolean</td>");
8412   html +=
8413     wxT
8414     ("<td bgcolor=\"#f0fff0\">TRUE if the underlaying library was built enabling EPSG</td></tr>");
8415   html += wxT("<tr><td bgcolor=\"#fffff0\">HasFreeXL( void ) : Boolean</td>");
8416   html +=
8417     wxT
8418     ("<td bgcolor=\"#f0fff0\">TRUE if the underlaying library was built enabling FreeXL</td></tr>");
8419   html +=
8420     wxT
8421     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"generic\">generic SQL functions</a></a>");
8422   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
8423   html +=
8424     wxT
8425     ("<tr><td bgcolor=\"#fffff0\">CastToInteger( value Generic ) : Integer</td>");
8426   html +=
8427     wxT
8428     ("<td bgcolor=\"#f0fff0\">returns the intput value possibly casted to the Integer data-type: NULL if no conversion is possible.</td></tr>");
8429   html +=
8430     wxT
8431     ("<tr><td bgcolor=\"#fffff0\">CastToDouble( value Generic ) : Double precision</td>");
8432   html +=
8433     wxT
8434     ("<td bgcolor=\"#f0fff0\">returns the intput value possibly casted to the Double data-type: NULL if no conversion is possible.</td></tr>");
8435   html +=
8436     wxT
8437     ("<tr><td bgcolor=\"#fffff0\">CastToText( value Generic ) : Text<hr>CastToText( value Generic ) : Text</td>");
8438   html +=
8439     wxT
8440     ("<td bgcolor=\"#f0fff0\">returns the intput value possibly casted to the Text data-type: NULL if no conversion is possible.<br>");
8441   html +=
8442     wxT
8443     ("If an optional argument \"zero_pad\" is passed and the input value is of the Integer or Double type, then the returned string will be padded using as much trailing ZEROs so to ensure the required length.</td></tr>");
8444   html +=
8445     wxT("<tr><td bgcolor=\"#fffff0\">CastToBlob( value Generic ) : Blob<hr>");
8446   html += wxT("(CastToBlob (value Generic , hex_input Boolean ) : Blob</td>");
8447   html +=
8448     wxT
8449     ("<td bgcolor=\"#f0fff0\">returns the intput value possibly casted to the Blob data-type: NULL if no conversion is possible.</td></tr>");
8450   html +=
8451     wxT
8452     ("<tr><td bgcolor=\"#fffff0\">ForceAsNull( val1 Generic , val2 Generic ) : Generic</td>");
8453   html +=
8454     wxT
8455     ("<td bgcolor=\"#f0fff0\">if \"val1\" and \"val2\" are equal (and exactly of the same data-type) NULL will be returned; ");
8456   html +=
8457     wxT
8458     ("otherwise \"val1\" will be returned absolutely untouched and still preserving its originale data-type.</td></tr>");
8459   html += wxT("<tr><td bgcolor=\"#fffff0\">CreateUUID( void ) : Text</td>");
8460   html +=
8461     wxT
8462     ("<td bgcolor=\"#f0fff0\">returns a Version 4 (random) UUID (<b>Universally unique identifier</b>).</td></tr>");
8463   html += wxT("<tr><td bgcolor=\"#fffff0\">MD5Checksum( BLOB | TEXT ) : Text</td>");
8464   html +=
8465     wxT
8466     ("<td bgcolor=\"#f0fff0\">returns the MD5 checksum corresponding to the input value.<br>Will return NULL for non-BLOB input.</td></tr>");
8467   html += wxT("<tr><td bgcolor=\"#fffff0\">MD5TotalChecksum( BLOB | TEXT ) : Text</td>");
8468   html +=
8469     wxT
8470     ("<td bgcolor=\"#f0fff0\">returns a cumulative MD5 checksum.<br><b><u>Aggregate function</u></b>.</td></tr>");
8471   html +=
8472     wxT
8473     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"math\">SQL math functions</a></a>");
8474   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
8475   html +=
8476     wxT
8477     ("<tr><td bgcolor=\"#fffff0\">Abs( x Double precision ) : Double precision</td>");
8478   html +=
8479     wxT
8480     ("<td bgcolor=\"#f0fff0\">returns the absolute value of <i>x</i></td></tr>");
8481   html +=
8482     wxT
8483     ("<tr><td bgcolor=\"#fffff0\">Acos( x Double precision ) : Double precision</td>");
8484   html +=
8485     wxT
8486     ("<td bgcolor=\"#f0fff0\">returns the arc cosine of <i>x</i>, that is, the value whose cosine is <i>x</i><br>");
8487   html += wxT("returns NULL if <i>x</i> is not in the range -1 to 1</td></tr>");
8488   html +=
8489     wxT
8490     ("<tr><td bgcolor=\"#fffff0\">Asin( x Double precision ) : Double precision</td>");
8491   html +=
8492     wxT
8493     ("<td bgcolor=\"#f0fff0\">returns the arc sine of <i>x</i>, that is, the value whose sine is <i>x</i><br>");
8494   html += wxT("returns NULL if <i>x</i> is not in the range -1 to 1</td></tr>");
8495   html +=
8496     wxT
8497     ("<tr><td bgcolor=\"#fffff0\">Atan( x Double precision ) : Double precision</td>");
8498   html +=
8499     wxT
8500     ("<td bgcolor=\"#f0fff0\">returns the arc tangent of <i>x</i>, that is, the value whose tangent is <i>x</i></td></tr>");
8501   html +=
8502     wxT
8503     ("<tr><td bgcolor=\"#fffff0\">Ceil( x Double precision ) : Double precision<hr>");
8504   html += wxT("Ceiling( x Double precision ) : Double precision</td>");
8505   html +=
8506     wxT
8507     ("<td bgcolor=\"#f0fff0\">returns the smallest integer value not less than <i>x</i></td></tr>");
8508   html +=
8509     wxT
8510     ("<tr><td bgcolor=\"#fffff0\">Cos( x Double precision ) : Double precision</td>");
8511   html +=
8512     wxT
8513     ("<td bgcolor=\"#f0fff0\">returns the cosine of <i>x</i>, where <i>x</i> is given in <u>radians</u></td></tr>");
8514   html +=
8515     wxT
8516     ("<tr><td bgcolor=\"#fffff0\">Cot( x Double precision ) : Double precision</td>");
8517   html +=
8518     wxT
8519     ("<td bgcolor=\"#f0fff0\">returns the cotangent of <i>x</i>, where <i>x</i> is given in <u>radians</u></td></tr>");
8520   html +=
8521     wxT
8522     ("<tr><td bgcolor=\"#fffff0\">Degrees( x Double precision ) : Double precision</td>");
8523   html +=
8524     wxT
8525     ("<td bgcolor=\"#f0fff0\">returns the argument <i>x</i>, converted from radians to degrees</td></tr>");
8526   html +=
8527     wxT
8528     ("<tr><td bgcolor=\"#fffff0\">Exp( x Double precision ) : Double precision</td>");
8529   html +=
8530     wxT
8531     ("<td bgcolor=\"#f0fff0\">returns the value of <b><i>e</i></b> (the base of natural logarithms) raised to the power of <i>x</i><hr>");
8532   html +=
8533     wxT
8534     ("the inverse of this function is <i>Log()</i> (using a single argument only) or <i>Ln()</i></td></tr>");
8535   html +=
8536     wxT
8537     ("<tr><td bgcolor=\"#fffff0\">Floor( x Double precision ) : Double precision</td>");
8538   html +=
8539     wxT
8540     ("<td bgcolor=\"#f0fff0\">returns the largest integer value not greater than <i>x</i></td></tr>");
8541   html +=
8542     wxT
8543     ("<tr><td bgcolor=\"#fffff0\">Ln( x Double precision ) : Double precision<hr>");
8544   html += wxT("Log( x Double precision ) : Double precision</td>");
8545   html +=
8546     wxT
8547     ("<td bgcolor=\"#f0fff0\">returns the natural logarithm of <i>x</i>; that is, the base-<b><i>e</i></b> logarithm of <i>x</i><br>");
8548   html +=
8549     wxT
8550     ("If <i>x</i> is less than or equal to 0, then NULL is returned</td></tr>");
8551   html +=
8552     wxT
8553     ("<tr><td bgcolor=\"#fffff0\">Log( b Double precision, x Double precision ) : Double precision</td>");
8554   html +=
8555     wxT
8556     ("<td bgcolor=\"#f0fff0\">returns the logarithm of <i>x</i> to the base <i>b</i><br>");
8557   html +=
8558     wxT
8559     ("If <i>x</i> is less than or equal to 0, or if <i>b</i> is less than or equal to 1, then NULL is returned<hr>");
8560   html +=
8561     wxT
8562     ("<i>Log(b, x)</i>  is equivalent to <i>Log(x)</i> / <i>Log(b)</i></td></tr>");
8563   html +=
8564     wxT
8565     ("<tr><td bgcolor=\"#fffff0\">Log2( x Double precision ) : Double precision</td>");
8566   html +=
8567     wxT("<td bgcolor=\"#f0fff0\">returns the base-2 logarithm of <i>x</i><hr>");
8568   html +=
8569     wxT
8570     ("<i>Log2(x)</i>  is equivalent to <i>Log(x)</i> / <i>Log(2)</i></td></tr>");
8571   html +=
8572     wxT
8573     ("<tr><td bgcolor=\"#fffff0\">Log10( x Double precision ) : Double precision</td>");
8574   html +=
8575     wxT
8576     ("<td bgcolor=\"#f0fff0\">returns the base-10 logarithm of <i>x</i><hr>");
8577   html +=
8578     wxT
8579     ("<i>Log10(x)</i>  is equivalent to <i>Log(x)</i> / <i>Log(10)</i></td></tr>");
8580   html += wxT("<tr><td bgcolor=\"#fffff0\">PI( void ) : Double precision</td>");
8581   html +=
8582     wxT("<td bgcolor=\"#f0fff0\">returns the value of <i>PI</i></td></tr>");
8583   html +=
8584     wxT
8585     ("<tr><td bgcolor=\"#fffff0\">Pow( x Double precision, y Double precision ) : Double precision<hr>");
8586   html +=
8587     wxT
8588     ("Power( x Double precision, y Double precision ) : Double precision</td>");
8589   html +=
8590     wxT
8591     ("<td bgcolor=\"#f0fff0\">returns the value of <i>x</i> raised to the power of <i>y</i></td></tr>");
8592   html +=
8593     wxT
8594     ("<tr><td bgcolor=\"#fffff0\">Radians( x Double precision ) : Double precision</td>");
8595   html +=
8596     wxT
8597     ("<td bgcolor=\"#f0fff0\">returns the argument <i>x</i>, converted from degrees to radians</td></tr>");
8598   html +=
8599     wxT
8600     ("<tr><td bgcolor=\"#fffff0\">Round( x Double precision ) : Double precision</td>");
8601   html +=
8602     wxT
8603     ("<td bgcolor=\"#f0fff0\">returns the integer value nearest to <i>x</i></td></tr>");
8604   html +=
8605     wxT
8606     ("<tr><td bgcolor=\"#fffff0\">Sign( x Double precision ) : Double precision</td>");
8607   html +=
8608     wxT
8609     ("<td bgcolor=\"#f0fff0\">returns the sign of the argument as -1, 0, or 1, ");
8610   html +=
8611     wxT
8612     ("depending on whether <i>x</i> is negative, zero, or positive.</td></tr>");
8613   html +=
8614     wxT
8615     ("<tr><td bgcolor=\"#fffff0\">Sin( x Double precision ) : Double precision</td>");
8616   html +=
8617     wxT
8618     ("<td bgcolor=\"#f0fff0\">returns the sine of <i>x</i>, where <i>x</i> is given in <u>radians</u></td></tr>");
8619   html +=
8620     wxT
8621     ("<tr><td bgcolor=\"#fffff0\">Sqrt( x Double precision ) : Double precision</td>");
8622   html +=
8623     wxT
8624     ("<td bgcolor=\"#f0fff0\">returns the square root of a non-negative number <i>x</i></td></tr>");
8625   html +=
8626     wxT
8627     ("<tr><td bgcolor=\"#fffff0\">Stddev_pop( x Double precision ) : Double precision</td>");
8628   html +=
8629     wxT
8630     ("<td bgcolor=\"#f0fff0\">returns the population standard deviation of the input values<br>");
8631   html += wxT("<b><u>aggregate function</u></b></u></td></tr>");
8632   html +=
8633     wxT
8634     ("<tr><td bgcolor=\"#fffff0\">Stddev_samp( x Double precision ) : Double precision</td>");
8635   html +=
8636     wxT
8637     ("<td bgcolor=\"#f0fff0\">returns the sample standard deviation of the input values<br>");
8638   html += wxT("<b><u>aggregate function</u></b></u></td></tr>");
8639   html +=
8640     wxT
8641     ("<tr><td bgcolor=\"#fffff0\">Tan( x Double precision ) : Double precision</td>");
8642   html +=
8643     wxT
8644     ("<td bgcolor=\"#f0fff0\">returns the tangent of <i>x</i>, where <i>x</i> is given in <u>radians</u></td></tr>");
8645   html +=
8646     wxT
8647     ("<tr><td bgcolor=\"#fffff0\">Var_pop( x Double precision ) : Double precision</td>");
8648   html +=
8649     wxT
8650     ("<td bgcolor=\"#f0fff0\">returns the population variance of the input values (<i>square of the population standard deviation</i>)<br>");
8651   html += wxT("<b><u>aggregate function</u></b></u></td></tr>");
8652   html +=
8653     wxT
8654     ("<tr><td bgcolor=\"#fffff0\">Var_samp( x Double precision ) : Double precision</td>");
8655   html +=
8656     wxT
8657     ("<td bgcolor=\"#f0fff0\">returns the sample variance of the input values (<i>square of the sample standard deviation</i>)<br>");
8658   html += wxT("<b><u>aggregate function</u></b></u></td></tr>");
8659   html +=
8660     wxT
8661     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"length_cvt\">SQL length/distance unit-conversion functions</a></a>");
8662   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
8663   html +=
8664     wxT
8665     ("<tr><td bgcolor=\"#fffff0\">CvtToKm( x Double precision ) : Double precision<hr>CvtFromKm( x Double precision ) : Double precision</td>");
8666   html += wxT("<td bgcolor=\"#f0fff0\">meters / kilometers</td></tr>");
8667   html +=
8668     wxT
8669     ("<tr><td bgcolor=\"#fffff0\">CvtToDm( x Double precision ) : Double precision<hr>CvtFromDm( x Double precision ) : Double precision</td>");
8670   html += wxT("<td bgcolor=\"#f0fff0\">meters / decimeters</td></tr>");
8671   html +=
8672     wxT
8673     ("<tr><td bgcolor=\"#fffff0\">CvtToCm( x Double precision ) : Double precision<hr>CvtFromCm( x Double precision ) : Double precision</td>");
8674   html += wxT("<td bgcolor=\"#f0fff0\">meters / centimeters</td></tr>");
8675   html +=
8676     wxT
8677     ("<tr><td bgcolor=\"#fffff0\">CvtToMm( x Double precision ) : Double precision<hr>CvtFromMm( x Double precision ) : Double precision</td>");
8678   html += wxT("<td bgcolor=\"#f0fff0\">meters / millimeters</td></tr>");
8679   html +=
8680     wxT
8681     ("<tr><td bgcolor=\"#fffff0\">CvtToKmi( x Double precision ) : Double precision<hr>CvtFromKmi( x Double precision ) : Double precision</td>");
8682   html +=
8683     wxT
8684     ("<td bgcolor=\"#f0fff0\">meters / internation nautical miles</td></tr>");
8685   html +=
8686     wxT
8687     ("<tr><td bgcolor=\"#fffff0\">CvtToIn( x Double precision ) : Double precision<hr>CvtFromIn( x Double precision ) : Double precision</td>");
8688   html +=
8689     wxT("<td bgcolor=\"#f0fff0\">meters / international inches</td></tr>");
8690   html +=
8691     wxT
8692     ("<tr><td bgcolor=\"#fffff0\">CvtToFt( x Double precision ) : Double precision<hr>CvtFromFt( x Double precision ) : Double precision</td>");
8693   html += wxT("<td bgcolor=\"#f0fff0\">meters / international feet</td></tr>");
8694   html +=
8695     wxT
8696     ("<tr><td bgcolor=\"#fffff0\">CvtToYd( x Double precision ) : Double precision<hr>CvtFromYd( x Double precision ) : Double precision</td>");
8697   html += wxT("<td bgcolor=\"#f0fff0\">meters / international yards</td></tr>");
8698   html +=
8699     wxT
8700     ("<tr><td bgcolor=\"#fffff0\">CvtToMi( x Double precision ) : Double precision<hr>CvtFromMi( x Double precision ) : Double precision</td>");
8701   html +=
8702     wxT
8703     ("<td bgcolor=\"#f0fff0\">meters / international statute miles</td></tr>");
8704   html +=
8705     wxT
8706     ("<tr><td bgcolor=\"#fffff0\">CvtToFath( x Double precision ) : Double precision<hr>CvtFromFath( x Double precision ) : Double precision</td>");
8707   html +=
8708     wxT("<td bgcolor=\"#f0fff0\">meters / international fathoms</td></tr>");
8709   html +=
8710     wxT
8711     ("<tr><td bgcolor=\"#fffff0\">CvtToCh( x Double precision ) : Double precision<hr>CvtFromCh( x Double precision ) : Double precision</td>");
8712   html +=
8713     wxT("<td bgcolor=\"#f0fff0\">meters / international chains</td></tr>");
8714   html +=
8715     wxT
8716     ("<tr><td bgcolor=\"#fffff0\">CvtToLink( x Double precision ) : Double precision<hr>CvtFromLink( x Double precision ) : Double precision</td>");
8717   html += wxT("<td bgcolor=\"#f0fff0\">meters / international links</td></tr>");
8718   html +=
8719     wxT
8720     ("<tr><td bgcolor=\"#fffff0\">CvtToUsIn( x Double precision ) : Double precision<hr>CvtFromUsIn( x Double precision ) : Double precision</td>");
8721   html += wxT("<td bgcolor=\"#f0fff0\">meters / U.S. inches</td></tr>");
8722   html +=
8723     wxT
8724     ("<tr><td bgcolor=\"#fffff0\">CvtToUsFt( x Double precision ) : Double precision<hr>CvtFromUsFt( x Double precision ) : Double precision</td>");
8725   html += wxT("<td bgcolor=\"#f0fff0\">meters / U.S. feet</td></tr>");
8726   html +=
8727     wxT
8728     ("<tr><td bgcolor=\"#fffff0\">CvtToUsYd( x Double precision ) : Double precision<hr>CvtFromUsYd( x Double precision ) : Double precision</td>");
8729   html += wxT("<td bgcolor=\"#f0fff0\">meters / U.S. yards</td></tr>");
8730   html +=
8731     wxT
8732     ("<tr><td bgcolor=\"#fffff0\">CvtToUsMi( x Double precision ) : Double precision<hr>CvtFromUsMi( x Double precision ) : Double precision</td>");
8733   html += wxT("<td bgcolor=\"#f0fff0\">meters / U.S. statute miles</td></tr>");
8734   html +=
8735     wxT
8736     ("<tr><td bgcolor=\"#fffff0\">CvtToUsCh( x Double precision ) : Double precision<hr>CvtFromUsCh( x Double precision ) : Double precision</td>");
8737   html += wxT("<td bgcolor=\"#f0fff0\">meters / U.S. chains</td></tr>");
8738   html +=
8739     wxT
8740     ("<tr><td bgcolor=\"#fffff0\">CvtToIndFt( x Double precision ) : Double precision<hr>CvtFromIndFt( x Double precision ) : Double precision</td>");
8741   html += wxT("<td bgcolor=\"#f0fff0\">meters / indian feet</td></tr>");
8742   html +=
8743     wxT
8744     ("<tr><td bgcolor=\"#fffff0\">CvtToIndYd( x Double precision ) : Double precision<hr>CvtFromIndYd( x Double precision ) : Double precision</td>");
8745   html += wxT("<td bgcolor=\"#f0fff0\">meters / indian yards</td></tr>");
8746   html +=
8747     wxT
8748     ("<tr><td bgcolor=\"#fffff0\">CvtToIndCh( x Double precision ) : Double precision<hr>CvtFromIndCh( x Double precision ) : Double precision</td>");
8749   html += wxT("<td bgcolor=\"#f0fff0\">meters / indian chains</td></tr>");
8750   html +=
8751     wxT
8752     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"blob\">SQL utility functions for BLOB objects</a></a>");
8753   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
8754   html +=
8755     wxT("<tr><td bgcolor=\"#fffff0\">IsZipBlob( content Blob ) : Integer</td>");
8756   html +=
8757     wxT
8758     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
8759   html +=
8760     wxT
8761     ("TRUE if this BLOB object corresponds to a valid ZIP-compressed file</td></tr>");
8762   html +=
8763     wxT("<tr><td bgcolor=\"#fffff0\">IsPdfBlob( content Blob ) : Integer</td>");
8764   html +=
8765     wxT
8766     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
8767   html +=
8768     wxT
8769     ("TRUE if this BLOB object corresponds to a valid PDF document</td></tr>");
8770   html +=
8771     wxT("<tr><td bgcolor=\"#fffff0\">IsGifBlob( image Blob ) : Integer</td>");
8772   html +=
8773     wxT
8774     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
8775   html +=
8776     wxT("TRUE if this BLOB object corresponds to a valid GIF image</td></tr>");
8777   html +=
8778     wxT("<tr><td bgcolor=\"#fffff0\">IsPngBlob( image Blob ) : Integer</td>");
8779   html +=
8780     wxT
8781     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
8782   html +=
8783     wxT("TRUE if this BLOB object corresponds to a valid PNG image</td></tr>");
8784   html +=
8785     wxT("<tr><td bgcolor=\"#fffff0\">IsTiffBlob( image Blob ) : Integer</td>");
8786   html +=
8787     wxT
8788     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
8789   html +=
8790     wxT("TRUE if this BLOB object corresponds to a valid TIFF image</td></tr>");
8791   html +=
8792     wxT("<tr><td bgcolor=\"#fffff0\">IsJpegBlob( image Blob ) : Integer</td>");
8793   html +=
8794     wxT
8795     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
8796   html +=
8797     wxT("TRUE if this BLOB object corresponds to a valid JPEG image</td></tr>");
8798   html +=
8799     wxT("<tr><td bgcolor=\"#fffff0\">IsExifBlob( image Blob ) : Integer</td>");
8800   html +=
8801     wxT
8802     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
8803   html += wxT("TRUE if this BLOB object corresponds to a valid EXIF image<br>");
8804   html +=
8805     wxT
8806     ("<u>Please note:</u> any valid EXIF image is a valid JPEG as well</td></tr>");
8807   html +=
8808     wxT
8809     ("<tr><td bgcolor=\"#fffff0\">IsExifGpsBlob( image Blob ) : Integer</td>");
8810   html +=
8811     wxT
8812     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
8813   html +=
8814     wxT("TRUE if this BLOB object corresponds to a valid EXIF-GPS image<br>");
8815   html +=
8816     wxT
8817     ("<u>Please note:</u> any valid EXIF-GPS image is a valid EXIF and JPEG as well</td></tr>");
8818   html +=
8819     wxT("<tr><td bgcolor=\"#fffff0\">IsWebpBlob( image Blob ) : Integer</td>");
8820   html +=
8821     wxT
8822     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
8823   html +=
8824     wxT("TRUE if this BLOB object corresponds to a valid WebP image</td></tr>");
8825   html +=
8826     wxT
8827     ("<tr><td bgcolor=\"#fffff0\">GetMimeType( payload Blob ) : String</td>");
8828   html += wxT("<td bgcolor=\"#f0fff0\">The return type is Text.<br>");
8829   html +=
8830     wxT
8831     ("NULL could be returned for an invalid argument or if no valid mime-type is detected.</td></tr>");
8832   html +=
8833     wxT
8834     ("<tr><td bgcolor=\"#fffff0\">BlobFromFile( filepath String ) : BLOB</td>");
8835   html +=
8836     wxT
8837     ("<td bgcolor=\"#f0fff0\">If filepath corresponds to some valid pathname, and the corresponding file ");
8838   html +=
8839     wxT
8840     ("can be actually accessed in read mode, then the whole file content will be returned as a BLOB value.<br>");
8841   html +=
8842     wxT
8843     ("Otherwise NULL will be returned.<br><u>Please note:</u> SQLite doesn't support BLOB values bigger than SQLITE_MAX_LENGTH (usually, 1 GB).<hr>");
8844   html +=
8845     wxT
8846     ("<u>Please note</u>: security restrictions apply to this function, which is really supported only when the environment variable \"SPATIALTE_SECURITY=relaxed\" is explicitly set.</td></tr>");
8847   html +=
8848     wxT
8849     ("<tr><td bgcolor=\"#fffff0\">BlobToFile( payload BLOB , filepath String ) : Integer</td>");
8850   html +=
8851     wxT
8852     ("<td bgcolor=\"#f0fff0\">If payload is of the BLOB-type, and if filepath corresponds to some valid pathname ");
8853   html +=
8854     wxT
8855     ("(accessible in write/create mode), then the corresponding file will be created/overwritten so to contain the payload.<br>");
8856   html +=
8857     wxT
8858     ("The return type is Integer, with a return value of 1 for success, 0 for failure.<hr>");
8859   html +=
8860     wxT
8861     ("<u>Please note</u>: security restrictions apply to this function, which is really supported only when the environment variable \"SPATIALTE_SECURITY=relaxed\" is explicitly set.</td></tr>");
8862   html +=
8863     wxT("<tr><td bgcolor=\"#fffff0\">CountUnsafeTriggers( ) : Integer</td>");
8864   html +=
8865     wxT
8866     ("<td bgcolor=\"#f0fff0\">This SQL function checks if the currently connected DB does contain any potentially malicious Trigger; ");
8867   html +=
8868     wxT
8869     ("carefully checking this conditions is a minimal precaution expected to be always verified before eventually activating the \"SPATIALITE_SECURITY=relaxed\" mode.<hr>");
8870   html +=
8871     wxT
8872     ("The return type is Integer (total count of suspected Triggers); 0 means that the currently connected DB should be considered absolutely safe.</td></tr>");
8873   html +=
8874     wxT
8875     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c30\">SQL utility functions [<i>non-standard</i>] for geometric objects</a></a>");
8876   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
8877   html +=
8878     wxT
8879     ("<tr><td bgcolor=\"#fffff0\">GeomFromExifGpsBlob( image Blob ) : Geometry</td>");
8880   html +=
8881     wxT
8882     ("<td bgcolor=\"#f0fff0\">a POINT Geometry will be returned representing the GPS long/lat contained within EXIF-GPS <i>metadata</i>	for the BLOB image<br>");
8883   html +=
8884     wxT
8885     ("NULL will be returned if for any reason it's not possible to build such a POINT</td></tr>");
8886   html +=
8887     wxT
8888     ("<tr><td bgcolor=\"#fffff0\">ST_Point( x Double precision , y Double precision ) : Geometry</td>");
8889   html +=
8890     wxT
8891     ("<td bgcolor=\"#f0fff0\">simply an alias-name for MakePoint() (SRID is never supported).</td></tr>");
8892   html +=
8893     wxT
8894     ("<tr><td bgcolor=\"#fffff0\">MakePoint( x Double precision , y Double precision [ , SRID Integer] ) : Geometry</td>");
8895   html +=
8896     wxT
8897     ("<td bgcolor=\"#f0fff0\">a Geometry will be returned representing the POINT defined by [x y] coordinates</td></tr>");
8898   html +=
8899     wxT
8900     ("<tr><td bgcolor=\"#fffff0\">MakePointZ( x Double precision , y Double precision , z Double precision [ , SRID Integer] ) : Geometry</td>");
8901   html +=
8902     wxT
8903     ("<td bgcolor=\"#f0fff0\">a Geometry will be returned representing the POINT Z defined by [x y z] coordinates</td></tr>");
8904   html +=
8905     wxT
8906     ("<tr><td bgcolor=\"#fffff0\">MakePointM( x Double precision , y Double precision , m Double precision [ , SRID Integer] ) : Geometry</td>");
8907   html +=
8908     wxT
8909     ("<td bgcolor=\"#f0fff0\">a Geometry will be returned representing the POINT M defined by [x y m] coordinates</td></tr>");
8910   html +=
8911     wxT
8912     ("<tr><td bgcolor=\"#fffff0\">MakePointZM( x Double precision , y Double precision , z Double precision , m Double precision ");
8913   html += wxT("[ , SRID Integer] ) : Geometry</td>");
8914   html +=
8915     wxT
8916     ("<td bgcolor=\"#f0fff0\">a Geometry will be returned representing the POINT ZM defined by [x y z m] coordinates</td></tr>");
8917   html +=
8918     wxT
8919     ("<tr><td bgcolor=\"#fffff0\">MakeLine( pt1 PointGeometry , pt2 PointGeometry ) : LinestringGeometry</td>");
8920   html +=
8921     wxT
8922     ("<td bgcolor=\"#f0fff0\">a Linestring Geometry will be returned representing the segment connecting pt1 to pt2<br>");
8923   html += wxT("NULL will be returned if any error is encountered</td></tr>");
8924   html +=
8925     wxT
8926     ("<tr><td bgcolor=\"#fffff0\">MakeLine( geom PointGeometry ) : LinestringGeometry</td>");
8927   html +=
8928     wxT
8929     ("<td bgcolor=\"#f0fff0\">a Linestring Geometry will be returned connecting all the input Points (accordingly to input sequence)<br>");
8930   html += wxT("<b><u>aggregate function</u></b><br>");
8931   html += wxT("NULL will be returned if any error is encountered</td></tr>");
8932   html +=
8933     wxT
8934     ("<tr><td bgcolor=\"#fffff0\">MakeLine( geom MultiPointGeometry , direction Boolean ) : LinestringGeometry</td>");
8935   html +=
8936     wxT
8937     ("<td bgcolor=\"#f0fff0\">a Linestring Geometry will be returned connecting all the input Points (accordingly to input sequence); \"direction=FALSE\" implies reverse order.<br>");
8938   html +=
8939     wxT
8940     ("<u>Please note</u>: similar to the previuous one, but this one is an ordinary (not aggregate) function; a MultiPoint input is always expected.<hr>");
8941   html += wxT("NULL will be returned if any error is encountered</td></tr>");
8942   html +=
8943     wxT
8944     ("<tr><td bgcolor=\"#fffff0\">MakeCircle( cx Double , cy Double , radius Double [ , SRID Integer [ , step Double ] ] ) : LinestringGeometry</td>");
8945   html +=
8946     wxT
8947     ("<td bgcolor=\"#f0fff0\">will return a closed LINESTRING approximating the Circle defined by \"cx\", \"cy\" and \"radius\".<br>");
8948   html +=
8949     wxT
8950     ("The optional argument \"step\" if specified defines how many points will be interpolated on the circumference; a point will be set every \"step\" degrees.<br>");
8951   html +=
8952     wxT
8953     ("The implicit default setting corresponds to a point every 10 degrees.</td></tr>");
8954   html +=
8955     wxT
8956     ("<tr><td bgcolor=\"#fffff0\">MakeEllipse( cx Double , cy Double , x_axis Double , y_axus Double [ , SRID Integer [ , step Double ] ] ) : LinestringGeometry</td>");
8957   html +=
8958     wxT
8959     ("<td bgcolor=\"#f0fff0\">will return a closed LINESTRING approximating the Ellipsee defined by \"cx\", \"cy\" and \"x_axis\", \"y_axis\".<br>");
8960   html +=
8961     wxT
8962     ("The optional argument \"step\" if specified defines how many points will be interpolated on the ellipse; a point will be set every \"step\" degrees.<br>");
8963   html +=
8964     wxT
8965     ("The implicit default setting corresponds to a point every 10 degrees.</td></tr>");
8966   html +=
8967     wxT
8968     ("<tr><td bgcolor=\"#fffff0\">MakeArc( cx Double , cy Double , radius Double , start Double , stop Double [ , SRID Integer [ , step Double ] ] ) : LinestringGeometry</td>");
8969   html +=
8970     wxT
8971     ("<td bgcolor=\"#f0fff0\">will return a LINESTRING approximating the Circular Arc defined by \"cx\", \"cy\" and \"radius\"; the arc's extremities will be defined by \"start\", \"stop\" angles expressed in degrees.<br>");
8972   html +=
8973     wxT
8974     ("The optional argument \"step\" if specified defines how many points will be interpolated on the circumference; a point will be set every \"step\" degrees.<br>");
8975   html +=
8976     wxT
8977     ("The implicit default setting corresponds to a point every 10 degrees.</td></tr>");
8978   html +=
8979     wxT
8980     ("<tr><td bgcolor=\"#fffff0\">MakeEllipticArc( cx Double , cy Double , x_axis Double , y_axis Double, start Double , stop Double [ , SRID Integer [ , step Double ] ] ) : LinestringGeometry</td>");
8981   html +=
8982     wxT
8983     ("<td bgcolor=\"#f0fff0\">will return a LINESTRING approximating the Elliptic Arc defined by \"cx\", \"cy\" and \"x_axis\", \"y_axis\"; the arc's extremities will be defined by \"start\", \"stop\" angles expressed in degrees.<br>");
8984   html +=
8985     wxT
8986     ("The optional argument \"step\" if specified defines how many points will be interpolated on the ellipse; a point will be set every \"step\" degrees.<br>");
8987   html +=
8988     wxT
8989     ("The implicit default setting corresponds to a point every 10 degrees.</td></tr>");
8990   html +=
8991     wxT
8992     ("<tr><td bgcolor=\"#fffff0\">MakeCircularSector( cx Double , cy Double , radius Double , start Double , stop Double [ , SRID Integer [ , step Double ] ] ) : PolygonGeometry</td>");
8993   html +=
8994     wxT
8995     ("<td bgcolor=\"#f0fff0\">will return a POLYGON approximating the Circular Sector defined by \"cx\", \"cy\" and \"radius\"; the arc's extremities will be defined by \"start\", \"stop\" angles expressed in degrees.<br>");
8996   html +=
8997     wxT
8998     ("The optional argument \"step\" if specified defines how many points will be interpolated on the circumference; a point will be set every \"step\" degrees.<br>");
8999   html +=
9000     wxT
9001     ("The implicit default setting corresponds to a point every 10 degrees.</td></tr>");
9002   html +=
9003     wxT
9004     ("<tr><td bgcolor=\"#fffff0\">MakeEllipticSector( cx Double , cy Double , x_axis Double , y_axis Double, start Double , stop Double [ , SRID Integer [ , step Double ] ] ) : PolygonGeometry</td>");
9005   html +=
9006     wxT
9007     ("<td bgcolor=\"#f0fff0\">will return a POLYGON approximating the Elliptic Sector defined by \"cx\", \"cy\" and \"x_axis\", \"y_axis\"; the arc's extremities will be defined by \"start\", \"stop\" angles expressed in degrees.<br>");
9008   html +=
9009     wxT
9010     ("The optional argument \"step\" if specified defines how many points will be interpolated on the ellipse; a point will be set every \"step\" degrees.<br>");
9011   html +=
9012     wxT
9013     ("The implicit default setting corresponds to a point every 10 degrees.</td></tr>");
9014   html +=
9015     wxT
9016     ("<tr><td bgcolor=\"#fffff0\">MakeCircularStripe( cx Double , cy Double , radius_1 Double , radius_2 Double, start Double , stop Double [ , SRID Integer [ , step Double ] ] ) : PolygonGeometry</td>");
9017   html +=
9018     wxT
9019     ("<td bgcolor=\"#f0fff0\">will return a POLYGON approximating the Circular Stripe delimited by two arcs sharing the same Centre \"cx\", \"cy\" ");
9020   html +=
9021     wxT
9022     ("but having different radii \"radius_1\", \"radius_2\"; the arc's extremities will be defined by \"start\", \"stop\" angles expressed in degrees.<br>");
9023   html +=
9024     wxT
9025     ("The optional argument \"step\" if specified defines how many points will be interpolated on the circumference; a point will be set every \"step\" degrees.<br>");
9026   html +=
9027     wxT
9028     ("The implicit default setting corresponds to a point every 10 degrees.</td></tr>");
9029   html +=
9030     wxT
9031     ("<tr><td bgcolor=\"#fffff0\">Collect( geom1 Geometry , geom2 Geometry ) : Geometry<hr>");
9032   html += wxT("ST_Collect( geom1 Geometry , geom2 Geometry ) : Geometry</td>");
9033   html +=
9034     wxT
9035     ("<td bgcolor=\"#f0fff0\">a generic Geometry (possibly a GEOMETRYCOLLECTION) will be returned merging geom1 and geom2<br>");
9036   html += wxT("NULL will be returned if any error is encountered</td></tr>");
9037   html +=
9038     wxT("<tr><td bgcolor=\"#fffff0\">Collect( geom Geometry ) : Geometry<hr>");
9039   html += wxT("ST_Collect( geom1 Geometry , geom2 Geometry ) : Geometry</td>");
9040   html +=
9041     wxT
9042     ("<td bgcolor=\"#f0fff0\">a generic Geometry (possibly a GEOMETRYCOLLECTION) will be returned merging input Geometries all together<br>");
9043   html += wxT("<b><u>aggregate function</u></b><br>");
9044   html += wxT("NULL will be returned if any error is encountered</td></tr>");
9045   html +=
9046     wxT
9047     ("<tr><td bgcolor=\"#fffff0\">BuildArea( geom Geometry  ) : Geometry<hr>");
9048   html += wxT("ST_BuildArea( geom Geometry  ) : Geometry</td>");
9049   html +=
9050     wxT
9051     ("<td bgcolor=\"#f0fff0\">a Geometry (actually corresponding to a POLYGON or MULTIPOLYGON) will be returned.<br>");
9052   html += wxT
9053     ("The input Geometry is expected to represent a LINESTRING or a MULTILINESTRING.<br>The input Geometry can be an arbitrary collection ");
9054   html += wxT
9055     ("of sparse Linestrings: this function will then try to (possibly) reassemble them into one (or more) polygon(s).");
9056   html += wxT
9057     ("<br>If the second [optional] argument is TRUE then a MULTIPOLYGON will be returned anyway.<br>");
9058   html += wxT("NULL will be returned if any error is encountered</td></tr>");
9059   html +=
9060     wxT
9061     ("<tr><td bgcolor=\"#fffff0\">Polygonize( geom Geometry ) : Geometry<hr>");
9062   html += wxT("ST_Polygonize( geom Geometry ) : Geometry</td>");
9063   html +=
9064     wxT
9065     ("<td bgcolor=\"#f0fff0\">Exactly the same as ST_BuildArea, but implemented as an <u>aggregate function</u>.<br>");
9066   html += wxT("NULL will be returned if any error is encountered</td></tr>");
9067   html +=
9068     wxT
9069     ("<tr><td bgcolor=\"#fffff0\">LineMerge( geom Geometry ) : Geometry<hr>");
9070   html += wxT("ST_LineMerge( geom Geometry ) : Geometry</td>");
9071   html +=
9072     wxT
9073     ("<td bgcolor=\"#f0fff0\">a Geometry (actually corresponding to a LINESTRING or MULTILINESTRING) will be returned.<br>");
9074   html += wxT
9075     ("The input Geometry is expected to represent a LINESTRING or a MULTILINESTRING.<br>The input Geometry can be an arbitrary collection ");
9076   html += wxT
9077     ("of sparse Linestrings: this function will then try to (possibly) reassemble them into one (or more) polygon(s).");
9078   html += wxT
9079     ("<br>If the second [optional] argument is TRUE then a MULTIPOLYGON will be returned anyway.<br>");
9080   html += wxT("NULL will be returned if any error is encountered</td></tr>");
9081   html +=
9082     wxT
9083     ("<tr><td bgcolor=\"#fffff0\">LinesFromRings( geom Geometry ) : Geometry<hr>");
9084   html += wxT("ST_LinesFromRings( geom Geometry ) : Geometry</td>");
9085   html +=
9086     wxT
9087     ("<td bgcolor=\"#f0fff0\">a Geometry (actually corresponding to a LINESTRING or MULTILINESTRING) will be returned.<br>");
9088   html +=
9089     wxT
9090     ("The input Geometry is expected to be a POLYGON or MULTIPOLYGON; any RING will then be transformed into the corresponding LINESTRING.<br>");
9091   html += wxT("NULL will be returned if any error is encountered</td></tr>");
9092   html +=
9093     wxT
9094     ("<tr><td bgcolor=\"#fffff0\">LinesCutAtNodes( geom1 Geometry , geom2 Geometry ) : Geometry<hr>");
9095   html +=
9096     wxT
9097     ("ST_LinesCutAtNodes( geom1 Geometry , geom2 Geometry ) : Geometry</td>");
9098   html +=
9099     wxT
9100     ("<td bgcolor=\"#f0fff0\">a Geometry (actually corresponding to a LINESTRING or MULTILINESTRING) will be returned.<br>");
9101   html +=
9102     wxT
9103     ("The first input Geometry is expected to be a LINESTRING or MULTILINESTRING (Lines); ");
9104   html +=
9105     wxT
9106     ("the second input Geometry is expected to be a POINT or MULTIPOINT (Nodes).<br>");
9107   html +=
9108     wxT
9109     ("any Line will then be possibly split in two halves where some vertex exactely intercepts a Node.<br>");
9110   html += wxT("NULL will be returned if any error is encountered</td></tr>");
9111   html +=
9112     wxT
9113     ("<tr><td bgcolor=\"#fffff0\">RingsCutAtNodes( geom Geometry ) : Geometry<hr>");
9114   html += wxT("ST_RingsCutAtNodes( geom Geometry ) : Geometry</td>");
9115   html +=
9116     wxT
9117     ("<td bgcolor=\"#f0fff0\">a Geometry (actually corresponding to a LINESTRING or MULTILINESTRING) will be returned.<br>");
9118   html +=
9119     wxT
9120     ("The input Geometry is expected to be a POLYGON or MULTIPOLYGON (Rings); ");
9121   html +=
9122     wxT
9123     ("any self-intersection or intersection between Rings is assumed to represent a Node.<br>");
9124   html +=
9125     wxT
9126     ("any Ring will then be possibly split in two halves where some vertex exactely intercepts a Node.<br>");
9127   html += wxT("NULL will be returned if any error is encountered</td></tr>");
9128   html +=
9129     wxT
9130     ("<tr><td bgcolor=\"#fffff0\">DissolveSegments( geom Geometry ) : Geometry<hr>");
9131   html += wxT("ST_DissolveSegments( geom Geometry ) : Geometry</td>");
9132   html +=
9133     wxT
9134     ("<td bgcolor=\"#f0fff0\">a Geometry (actually corresponding to a LINESTRING, MULTILINESTRING or GEOMETRYCOLLECTION) will be returned.<br>");
9135   html +=
9136     wxT
9137     ("The input Geometry is arbitrary: any POINT will remain unaffected, but any LINESTRING or RING will be dissolved into elementary segments.<br>");
9138   html += wxT("NULL will be returned if any error is encountered</td></tr>");
9139   html +=
9140     wxT
9141     ("<tr><td bgcolor=\"#fffff0\">DissolvePoints( geom Geometry ) : Geometry<hr>");
9142   html += wxT("ST_DissolvePoints( geom Geometry ) : Geometry</td>");
9143   html +=
9144     wxT
9145     ("<td bgcolor=\"#f0fff0\">a Geometry (actually corresponding to a POINT or MULTIPOINT) will be returned.<br>");
9146   html +=
9147     wxT
9148     ("The input Geometry is arbitrary: any POINT will remain unaffected, but any LINESTRING or RING will be dissolved into elementary Points corresponding to each Vertex.<br>");
9149   html += wxT("NULL will be returned if any error is encountered</td></tr>");
9150   html +=
9151     wxT
9152     ("<tr><td bgcolor=\"#fffff0\">CollectionExtract( geom Geometry, type Integer ) : Geometry<hr>");
9153   html +=
9154     wxT("ST_CollectionExtract( geom Geometry, type Integer ) : Geometry</td>");
9155   html +=
9156     wxT
9157     ("<td bgcolor=\"#f0fff0\">Given a GEOMETRYCOLLECTION, returns a MULTI* geometry consisting only of the specified type.<br>");
9158   html +=
9159     wxT
9160     ("Sub-geometries that are not the specified type are ignored.<br>(1=POINT-type, 2=LINESTRING-type, 3=POLYGON-type)<br>");
9161   html +=
9162     wxT
9163     ("NULL will be returned if any error is encountered (or when no item of required type is found)</td></tr>");
9164   html +=
9165     wxT
9166     ("<tr><td bgcolor=\"#fffff0\">ST_Locate_Along_Measure( geom Geometry, m_value Double precision ) : Geometry</td>");
9167   html +=
9168     wxT
9169     ("<td bgcolor=\"#f0fff0\">Return a derived geometry collection value with elements that match the specified measure.<br>");
9170   html +=
9171     wxT
9172     ("NULL will be returned if any error is encountered (or when no element corresponding to the given measure is found).<br>");
9173   html +=
9174     wxT
9175     ("Please note: NULL will be returned anyway if Geometry doesn't support M-dimension, or if it contains any Polygon, or if it's of the GeometryCollection type.</td></tr>");
9176   html +=
9177     wxT
9178     ("<tr><td bgcolor=\"#fffff0\">ST_Locate_Between_Measures( geom Geometry, m_start Double precision , m_end Double precision ) : Geometry</td>");
9179   html +=
9180     wxT
9181     ("<td bgcolor=\"#f0fff0\">Return a derived geometry collection value with elements that match the specified range of measures.<br>");
9182   html +=
9183     wxT
9184     ("NULL will be returned if any error is encountered (or when no element corresponding to the given range if measures is found).<br>");
9185   html +=
9186     wxT
9187     ("Please note: NULL will be returned anyway if Geometry doesn't support M-dimension, or if it contains any Polygon, or if it's of the GeometryCollection type.</td></tr>");
9188   html +=
9189     wxT
9190     ("<tr><td bgcolor=\"#fffff0\">SquareGrid( geom Geometry [ , size Double precision [ , edges_only Boolean [ , origin Geometry  ]] ) : Geometry<hr>");
9191   html +=
9192     wxT
9193     ("ST_SquareGrid( geom Geometry [ , size Double precision [ , edges_only Boolean [ , origin Geometry  ]] ) : Geometry</td>");
9194   html +=
9195     wxT
9196     ("<td bgcolor=\"#f0fff0\">return a grid of square cells (having the edge length of size) precisely covering the input Geometry (expected to be a Polygon or MultiPolygon).<br>");
9197   html +=
9198     wxT
9199     ("The returned Geometry will usually be of the MultiPolygon type (a collection of Squares), but will be a MultiLinestring if the optional edges_only argument is set to TRUE<br>");
9200   html +=
9201     wxT
9202     ("If the optional origin argument (expected to be a Point) is not specified then the (0,0) grid origin will be assumed by default.<br>");
9203   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
9204   html +=
9205     wxT
9206     ("<tr><td bgcolor=\"#fffff0\">TriangularGrid( geom Geometry [ , size Double precision [ , edges_only Boolean [ , origin Geometry  ]] ) : Geometry<hr>");
9207   html +=
9208     wxT
9209     ("ST_TriangularGrid( geom Geometry [ , size Double precision [ , edges_only Boolean [ , origin Geometry  ]] ) : Geometry</td>");
9210   html +=
9211     wxT
9212     ("<td bgcolor=\"#f0fff0\">return a grid of square cells (having the edge length of size) precisely covering the input Geometry (expected to be a Polygon or MultiPolygon).<br>");
9213   html +=
9214     wxT
9215     ("The returned Geometry will usually be of the MultiPolygon type (a collection of Triangles), but will be a MultiLinestring if the optional edges_only argument is set to TRUE<br>");
9216   html +=
9217     wxT
9218     ("If the optional origin argument (expected to be a Point) is not specified then the (0,0) grid origin will be assumed by default.<br>");
9219   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
9220   html +=
9221     wxT
9222     ("<tr><td bgcolor=\"#fffff0\">HexagonalGrid( geom Geometry [ , size Double precision [ , edges_only Boolean [ , origin Geometry  ]] ) : Geometry<hr>");
9223   html +=
9224     wxT
9225     ("ST_HexagonalGrid( geom Geometry [ , size Double precision [ , edges_only Boolean [ , origin Geometry  ]] ) : Geometry</td>");
9226   html +=
9227     wxT
9228     ("<td bgcolor=\"#f0fff0\">return a grid of square cells (having the edge length of size) precisely covering the input Geometry (expected to be a Polygon or MultiPolygon).<br>");
9229   html +=
9230     wxT
9231     ("The returned Geometry will usually be of the MultiPolygon type (a collection of Hexagons), but will be a MultiLinestring if the optional edges_only argument is set to TRUE<br>");
9232   html +=
9233     wxT
9234     ("If the optional origin argument (expected to be a Point) is not specified then the (0,0) grid origin will be assumed by default.<br>");
9235   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
9236   html +=
9237     wxT
9238     ("<tr><td bgcolor=\"#fffff0\">DelaunayTriangulation( geom Geometry [ , edges_only Boolean [ , tolerance Double precision  ]] ) : Geometry<hr>");
9239   html +=
9240     wxT
9241     ("ST_DelaunayTriangulation( geom Geometry [ , edges_only Boolean [ , tolerance Double precision ]] ) : Geometry</td>");
9242   html +=
9243     wxT
9244     ("<td bgcolor=\"#f0fff0\">Return the Delaunay Triangulation corresponding to the input Geometry.<br>");
9245   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
9246   html +=
9247     wxT
9248     ("<tr><td bgcolor=\"#fffff0\">VoronojDiagram( geom Geometry [ , edges_only Boolean [ , extra_frame_size Double precision [ , tolerance Double precision ]]] ) : Geometry<hr>");
9249   html +=
9250     wxT
9251     ("ST_VoronojDiagram( geom Geometry [ , edges_only Boolean [ , extra_frame_size Double precision [ , tolerance Double precision ]]] ) : Geometry</td>");
9252   html +=
9253     wxT
9254     ("<td bgcolor=\"#f0fff0\">Return the Voronoj Diagram corresponding to the input Geometry.<br>");
9255   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
9256   html +=
9257     wxT
9258     ("<tr><td bgcolor=\"#fffff0\">ConcaveHull( geom Geometry [ , factor Double precision [ , allow_hols Boolean [ , tolerance Double precision  ]]] ) : Geometry<hr>");
9259   html +=
9260     wxT
9261     ("ST_ConcaveHull( geom Geometry [ , factor Double precision [ , allow_hols Boolean [ , tolerance Double precision  ]]] ) : Geometry</td>");
9262   html +=
9263     wxT
9264     ("<td bgcolor=\"#f0fff0\">Return the ConcaveHull corresponding to the input Geometry.<br>");
9265   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
9266   html +=
9267     wxT
9268     ("<tr><td bgcolor=\"#fffff0\">MakeValid( geom Geometry ) : Geometry<hr>");
9269   html += wxT("ST_MakeValid( geom Geometry ) : Geometry</td>");
9270   html +=
9271     wxT
9272     ("<td bgcolor=\"#f0fff0\">Return a surely valid version of the input Geometry.<br>");
9273   html +=
9274     wxT
9275     ("If the input Geometry was already valid, then it will be returned exactly as it was.<br>");
9276   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
9277   html +=
9278     wxT
9279     ("<tr><td bgcolor=\"#fffff0\">MakeValidDiscarded( geom Geometry ) : Geometry<hr>");
9280   html += wxT("ST_MakeValidDiscarded( geom Geometry ) : Geometry</td>");
9281   html +=
9282     wxT
9283     ("<td bgcolor=\"#f0fff0\">Return all elements that would be eventually discarded by ST_MakeValid() while validating the same input Geometry.<br>");
9284   html +=
9285     wxT
9286     ("NULL will be returned if any error is encountered, or if no discarded item exists.</td></tr>");
9287   html +=
9288     wxT
9289     ("<tr><td bgcolor=\"#fffff0\">Segmentize( geom Geometry , dist Double precision ) : Geometry<hr>");
9290   html +=
9291     wxT
9292     ("ST_Segmentize( geom Geometry , dist Double precision ) : Geometry</td>");
9293   html +=
9294     wxT
9295     ("<td bgcolor=\"#f0fff0\">return a new Geometry corresponding to the input Geometry; as much Linestring / Ring vertices ");
9296   html +=
9297     wxT
9298     ("as required will be eventually interpolated so to ensure that no segment will be longer than dist.<br>");
9299   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
9300   html +=
9301     wxT
9302     ("<tr><td bgcolor=\"#fffff0\">Split( geom Geometry , blade Geometry ) : Geometry<hr>");
9303   html += wxT("ST_Split( geom Geometry , blade Geometry ) : Geometry</td>");
9304   html +=
9305     wxT
9306     ("<td bgcolor=\"#f0fff0\">return a new Geometry collecting all items resulting by splitting the input Geometry by the blade.<br>");
9307   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
9308   html +=
9309     wxT
9310     ("<tr><td bgcolor=\"#fffff0\">SplitLeft( geom Geometry , blade Geometry ) : Geometry<hr>");
9311   html += wxT("ST_SplitLeft( geom Geometry , blade Geometry ) : Geometry</td>");
9312   html +=
9313     wxT
9314     ("<td bgcolor=\"#f0fff0\">return a new Geometry collecting all items resulting by splitting the input Geometry by the blade and falling on the left side.<br>");
9315   html +=
9316     wxT
9317     ("All items not affected by the split operation (i.e. not intersecting the blade) will be returned into the left collection.<br>");
9318   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
9319   html +=
9320     wxT
9321     ("<tr><td bgcolor=\"#fffff0\">SplitRight( geom Geometry , blade Geometry ) : Geometry<hr>");
9322   html +=
9323     wxT("ST_SplitRight( geom Geometry , blade Geometry ) : Geometry</td>");
9324   html +=
9325     wxT
9326     ("<td bgcolor=\"#f0fff0\">return a new Geometry collecting all items resulting by splitting the input Geometry by the blade and falling on the right side.<br>");
9327   html +=
9328     wxT
9329     ("NULL will be returned if any error is encountered (or if the right side is empty).</td></tr>");
9330   html +=
9331     wxT
9332     ("<tr><td bgcolor=\"#fffff0\">Azimuth( pt1 Geometry , pt2 Geometry ) : Double precision<hr>");
9333   html +=
9334     wxT("ST_Azimuth( pt1 Geometry , pt2 Geometry ) : Double precision</td>");
9335   html +=
9336     wxT
9337     ("<td bgcolor=\"#f0fff0\">return the angle (in radians) from the horizontal of the vector defined by pt1 and pt2.<br>");
9338   html += wxT("Both pt1 and pt2 are expected to be simple Points.<br>");
9339   html +=
9340     wxT
9341     ("Starting since 4.1.0 if both points supports \"long/lat\" coords the returned Azimuth will be precisely computed on the ellipsoid.<br>");
9342   html += wxT("NULL will be returned if any error is encountered.<hr>");
9343   html += wxT("On the clock: 12=0; 3=PI/2; 6=PI; 9=3PI/2</td></tr>");
9344   html +=
9345     wxT
9346     ("<tr><td bgcolor=\"#fffff0\">Project( start_point Geometry, distance Double precision, azimuth Double precision ) : Geometry<hr>");
9347   html +=
9348     wxT
9349     ("Project( start_point Geometry, distance Double precision, azimuth Double precision ) : Geometry</td>");
9350   html +=
9351     wxT
9352     ("<td bgcolor=\"#f0fff0\">return a new Point projected from a start point using a bearing and distance.<br>");
9353   html +=
9354     wxT
9355     ("start_point is expected to be simple long/lat Point.<br>distance is expected to be measured in meters; ");
9356   html +=
9357     wxT
9358     ("azimuth (aka bearing or heading) has the same identical meaning as in ST_Azimuth().<br>");
9359   html += wxT("NULL is returned on failure or on invalid arguments.</td></tr>");
9360   html +=
9361     wxT
9362     ("<tr><td bgcolor=\"#fffff0\">SnapToGrid( geom Geometry , size Double precision  ) : Geometry<br>");
9363   html +=
9364     wxT
9365     ("SnapToGrid( geom Geometry , size_x Double precision , size_y Double precision ) : Geometry<br>");
9366   html +=
9367     wxT
9368     ("SnapToGrid( geom Geometry , origin_x Double precision , origin_y Double precision , size_x Double precision , size_y Double precision ) : Geometry<br>");
9369   html +=
9370     wxT
9371     ("SnapToGrid( geom Geometry , origin Geometry , size_x Double precision , size_y Double precision , size_z Double precision , size_m Double precision ) : Geometry<hr>");
9372   html +=
9373     wxT
9374     ("ST_SnapToGrid( geom Geometry , size Double precision  ) : Geometry<br>");
9375   html +=
9376     wxT
9377     ("ST_SnapToGrid( geom Geometry , size_x Double precision , size_y Double precision )  ) : Geometry<br>");
9378   html +=
9379     wxT
9380     ("ST_SnapToGrid( geom Geometry , origin_x Double precision , origin_y Double precision , size_x Double precision , size_y Double precision )  ) : Geometry<br>");
9381   html +=
9382     wxT
9383     ("ST_SnapToGrid( geom Geometry , origin Geometry , size_x Double precision , size_y Double precision, size_z Double precision , size_m Double precision ) : Geometry</td>");
9384   html +=
9385     wxT
9386     ("<td bgcolor=\"#f0fff0\">return a new Geometry corresponding to the input Geometry; all points and vertices will be snapped to the grid defined by its origin and size(s).<br>");
9387   html += wxT("Removes all consecutive points falling on the same cell.<br>");
9388   html +=
9389     wxT
9390     ("All collapsed geometries will be stripped from the returned Geometry.<br>");
9391   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
9392   html +=
9393     wxT("<tr><td bgcolor=\"#fffff0\">GeoHash( geom Geometry ) : String<hr>");
9394   html += wxT("ST_GeoHash( geom Geometry ) : String</td>");
9395   html +=
9396     wxT
9397     ("<td bgcolor=\"#f0fff0\">Return a GeoHash representation (geohash.org) of the geometry.<br>");
9398   html +=
9399     wxT
9400     ("A GeoHash encodes a point into a text form that is sortable and searchable based on prefixing.<hr>");
9401   html +=
9402     wxT
9403     ("ST_GeoHash will not work with geometries that are not in geographic (lon/lat) coordinates</td></tr>");
9404   html +=
9405     wxT
9406     ("<tr><td bgcolor=\"#fffff0\">AsX3D( geom Geometry [ , precision Integer [ , options Integer [ , refid String ]]] ) : String<hr>");
9407   html +=
9408     wxT
9409     ("ST_AsX3D( geom Geometry [ , precision Integer [ , options Integer [ , refid String ]]] ) : String</td>");
9410   html +=
9411     wxT
9412     ("<td bgcolor=\"#f0fff0\">Returns a geometry as an X3D XML formatted node element</td></tr>");
9413   html +=
9414     wxT
9415     ("<tr><td bgcolor=\"#fffff0\">MaxDistance( geom1 Geometry , geom2 Geometry ) : Double precision<hr>");
9416   html +=
9417     wxT
9418     ("ST_MaxDistance( geom1 Geometry , geom2 Geometry ) : Double precision</td>");
9419   html +=
9420     wxT
9421     ("<td bgcolor=\"#f0fff0\">return the max distance between geom1 and geom2</td></tr>");
9422   html +=
9423     wxT
9424     ("<tr><td bgcolor=\"#fffff0\">ST_3DDistance( geom1 Geometry , geom2 Geometry ) : Double precision</td>");
9425   html +=
9426     wxT
9427     ("<td bgcolor=\"#f0fff0\">return the 3D-distance between geom1 and geom2 (considering Z coordinates)</td></tr>");
9428   html +=
9429     wxT
9430     ("<tr><td bgcolor=\"#fffff0\">ST_Max3DDistance( geom1 Geometry , geom2 Geometry ) : Double precision</td>");
9431   html +=
9432     wxT
9433     ("<td bgcolor=\"#f0fff0\">return the max 3D-distance between geom1 and geom2 (considering Z coordinates)</td></tr>");
9434   html +=
9435     wxT
9436     ("<tr><td bgcolor=\"#fffff0\">BuildMbr( x1 Double precision , y1 Double precision , x2 Double precision , y2 Double precision, [ , SRID Integer] ) : Geometry</td>");
9437   html +=
9438     wxT
9439     ("<td bgcolor=\"#f0fff0\">[x1 y1] and [x2 y2] are assumed to be Points identifying a line segment;");
9440   html +=
9441     wxT
9442     ("then a Geometry will be returned representing the MBR for this line segment</td></tr>");
9443   html +=
9444     wxT
9445     ("<tr><td bgcolor=\"#fffff0\">BuildCircleMbr( x Double precision , y Double precision , radius Double precision [ , SRID Integer] ) : Geometry</td>");
9446   html +=
9447     wxT
9448     ("<td bgcolor=\"#f0fff0\">[x y] is assumed to be the center of a circle of given radius; then a Geometry will be returned representing the MBR for this circle</td></tr>");
9449   html +=
9450     wxT("<tr><td bgcolor=\"#fffff0\">Extent( geom Geometry ) : Geometry</td>");
9451   html +=
9452     wxT
9453     ("<td bgcolor=\"#f0fff0\">return a geometric object representing the bounding box that encloses a set of input values<br>");
9454   html += wxT("<b><u>aggregate function</u></b></td></tr>");
9455   html +=
9456     wxT("<tr><td bgcolor=\"#fffff0\">ToGARS( geom Geometry ) : String</td>");
9457   html +=
9458     wxT
9459     ("<td bgcolor=\"#f0fff0\">geom is expected to represent a POINT (longitude and latitude coords); ");
9460   html +=
9461     wxT("the corresponding GARS area designation code will be returned.<hr>");
9462   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
9463   html +=
9464     wxT
9465     ("<tr><td bgcolor=\"#fffff0\">GARSMbr( GARS_code String ) : Geometry</td>");
9466   html +=
9467     wxT
9468     ("<td bgcolor=\"#f0fff0\">code is assumed to represent a valid GARS area designation code; ");
9469   html +=
9470     wxT
9471     ("a Geometry will be returned representing the MBR for the corresponding GARS area.<hr>");
9472   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
9473   html +=
9474     wxT
9475     ("<tr><td bgcolor=\"#fffff0\">MbrMinX( geom Geometry) : Double precision<hr>");
9476   html += wxT("ST_MbrMinX( geom Geometry) : Double precision<hr>");
9477   html += wxT("ST_MinX( geom Geometry) : Double precision</td>");
9478   html +=
9479     wxT
9480     ("<td bgcolor=\"#f0fff0\">return the x-coordinate for geom MBR's leftmost side as a double precision number.<br>");
9481   html +=
9482     wxT("NULL will be returned if geom isn't a valid Geometry.</td></tr>");
9483   html +=
9484     wxT
9485     ("<tr><td bgcolor=\"#fffff0\">MbrMinY( geom Geometry) : Double precision<hr>");
9486   html += wxT("ST_MbrMinY( geom Geometry) : Double precision<hr>");
9487   html += wxT("ST_MinY( geom Geometry) : Double precision</td>");
9488   html +=
9489     wxT
9490     ("<td bgcolor=\"#f0fff0\">return the y-coordinate for geom MBR's lowermost side as a double precision number.<br>");
9491   html +=
9492     wxT("NULL will be returned if geom isn't a valid Geometry.</td></tr>");
9493   html +=
9494     wxT
9495     ("<tr><td bgcolor=\"#fffff0\">MbrMaxX( geom Geometry) : Double precision<hr>");
9496   html += wxT("ST_MbrMaxX( geom Geometry) : Double precision<hr>");
9497   html += wxT("ST_MaxX( geom Geometry) : Double precision</td>");
9498   html +=
9499     wxT
9500     ("<td bgcolor=\"#f0fff0\">return the x-coordinate for geom MBR's rightmost side as a double precision number.<br>");
9501   html +=
9502     wxT("NULL will be returned if geom isn't a valid Geometry.</td></tr>");
9503   html +=
9504     wxT
9505     ("<tr><td bgcolor=\"#fffff0\">MbrMaxY( geom Geometry) : Double precision<hr>");
9506   html += wxT("ST_MbrMaxY( geom Geometry) : Double precision<hr>");
9507   html += wxT("ST_MaxY( geom Geometry) : Double precision</td>");
9508   html +=
9509     wxT
9510     ("<td bgcolor=\"#f0fff0\">return the y-coordinate for geom MBR's uppermost side as a double precision number.<br>");
9511   html +=
9512     wxT("NULL will be returned if geom isn't a valid Geometry.</td></tr>");
9513   html +=
9514     wxT
9515     ("<tr><td bgcolor=\"#fffff0\">ST_MinZ( geom Geometry) : Double precision</td>");
9516   html +=
9517     wxT
9518     ("<td bgcolor=\"#f0fff0\">return the minimum Z-coordinate value for geom as a double precision number.<br>");
9519   html +=
9520     wxT
9521     ("NULL will be returned if geom isn't a valid Geometry or if geom has no Z dimension.</td></tr>");
9522   html +=
9523     wxT
9524     ("<tr><td bgcolor=\"#fffff0\">ST_MaxZ( geom Geometry) : Double precision</td>");
9525   html +=
9526     wxT
9527     ("<td bgcolor=\"#f0fff0\">return the maximum Z-coordinate value for geom as a double precision number.<br>");
9528   html +=
9529     wxT
9530     ("NULL will be returned if geom isn't a valid Geometry or if geom has no Z dimension.</td></tr>");
9531   html +=
9532     wxT
9533     ("<tr><td bgcolor=\"#fffff0\">ST_MinM( geom Geometry) : Double precision</td>");
9534   html +=
9535     wxT
9536     ("<td bgcolor=\"#f0fff0\">return the minimum M-coordinate value for geom as a double precision number.<br>");
9537   html +=
9538     wxT
9539     ("NULL will be returned if geom isn't a valid Geometry or if geom has no M dimension.</td></tr>");
9540   html +=
9541     wxT
9542     ("<tr><td bgcolor=\"#fffff0\">ST_MaxM( geom Geometry) : Double precision</td>");
9543   html +=
9544     wxT
9545     ("<td bgcolor=\"#f0fff0\">return the maximum M-coordinate value for geom as a double precision number.<br>");
9546   html +=
9547     wxT
9548     ("NULL will be returned if geom isn't a valid Geometry or if geom has no M dimension.</td></tr>");
9549   html +=
9550     wxT
9551     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c31\">functions for constructing a geometric object given its Well-known Text Representation</a>");
9552   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
9553   html +=
9554     wxT
9555     ("<tr><td bgcolor=\"#fffff0\">GeomFromText( wkt String [ , SRID Integer] ) : Geometry<hr>");
9556   html +=
9557     wxT("ST_GeomFromText( wkt String [ , SRID Integer] ) : Geometry</td>");
9558   html +=
9559     wxT
9560     ("<td bgcolor=\"#f0fff0\">construct a geometric object given its Well-known text Representation</td></tr>");
9561   html +=
9562     wxT
9563     ("<tr><td bgcolor=\"#fffff0\">ST_WKTToSQL( wkt String ) : Geometry</td>");
9564   html +=
9565     wxT
9566     ("<td bgcolor=\"#f0fff0\">SQL/MM alias name for ST_GeomFromText: SRID=0 is assumed.</td></tr>");
9567   html +=
9568     wxT
9569     ("<tr><td bgcolor=\"#fffff0\">PointFromText( wktPoint String [ , SRID Integer] ) : Point<hr>");
9570   html +=
9571     wxT("ST_PointFromText( wktPoint String [ , SRID Integer] ) : Point</td>");
9572   html += wxT("<td bgcolor=\"#f0fff0\">construct a Point</td></tr>");
9573   html +=
9574     wxT
9575     ("<tr><td bgcolor=\"#fffff0\">LineFromText( wktLineString String [ , SRID Integer] ) : Linestring<hr>");
9576   html +=
9577     wxT
9578     ("ST_LineFromText( wktLineString String [ , SRID Integer] ) : Linestring<hr>");
9579   html +=
9580     wxT
9581     ("LineStringFromText( wktLineString String [ , SRID Integer] ) : Linestring<hr>");
9582   html +=
9583     wxT
9584     ("ST_LineStringFromText( wktLineString String [ , SRID Integer] ) : Linestring</td>");
9585   html += wxT("<td bgcolor=\"#f0fff0\">construct a Linestring</td></tr>");
9586   html +=
9587     wxT
9588     ("<tr><td bgcolor=\"#fffff0\">PolyFromText( wktPolygon String [ , SRID Integer] ) : Polygon<hr>");
9589   html +=
9590     wxT("ST_PolyFromText( wktPolygon String [ , SRID Integer] ) : Polygon<hr>");
9591   html +=
9592     wxT("PolygonFromText( wktPolygon String [ , SRID Integer] ) : Polygon<hr>");
9593   html +=
9594     wxT
9595     ("ST_PolygonFromText( wktPolygon String [ , SRID Integer] ) : Polygon</td>");
9596   html += wxT("<td bgcolor=\"#f0fff0\">construct a Polygon</td></tr>");
9597   html +=
9598     wxT
9599     ("<tr><td bgcolor=\"#fffff0\">MPointFromText( wktMultiPoint String [ , SRID Integer] ) : MultiPoint<hr>");
9600   html +=
9601     wxT
9602     ("ST_MPointFromText( wktMultiPoint String [ , SRID Integer] ) : MultiPoint<hr>");
9603   html +=
9604     wxT
9605     ("MultiPointFromText( wktMultiPoint String [ , SRID Integer] ) : MultiPoint<hr>");
9606   html +=
9607     wxT
9608     ("ST_MultiPointFromText( wktMultiPoint String [ , SRID Integer] ) : MultiPoint</td>");
9609   html += wxT("<td bgcolor=\"#f0fff0\">construct a MultiPoint</td></tr>");
9610   html +=
9611     wxT
9612     ("<tr><td bgcolor=\"#fffff0\">MLineFromText( wktMultiLineString String [ , SRID Integer] ) : MultiLinestring<hr>");
9613   html +=
9614     wxT
9615     ("ST_MLineFromText( wktMultiLineString String [ , SRID Integer] ) : MultiLinestring<hr>");
9616   html +=
9617     wxT
9618     ("MultiLineStringFromText( wktMultiLineString String [ , SRID Integer] ) : MultiLinestring<hr>");
9619   html +=
9620     wxT
9621     ("ST_MultiLineStringFromText( wktMultiLineString String [ , SRID Integer] ) : MultiLinestring</td>");
9622   html += wxT("<td bgcolor=\"#f0fff0\">construct a MultiLinestring</td></tr>");
9623   html +=
9624     wxT
9625     ("<tr><td bgcolor=\"#fffff0\">MPolyFromText( wktMultiPolygon String [ , SRID Integer] ) : MultiPolygon<hr>");
9626   html +=
9627     wxT
9628     ("ST_MPolyFromText( wktMultiPolygon String [ , SRID Integer] ) : MultiPolygon<hr>");
9629   html +=
9630     wxT
9631     ("MultiPolygonFromText( wktMultiPolygon String [ , SRID Integer] ) : MultiPolygon<hr>");
9632   html +=
9633     wxT
9634     ("ST_MultiPolygonFromText( wktMultiPolygon String [ , SRID Integer] ) : MultiPolygon</td>");
9635   html += wxT("<td bgcolor=\"#f0fff0\">construct a MultiPolygon</td></tr>");
9636   html +=
9637     wxT
9638     ("<tr><td bgcolor=\"#fffff0\">GeomCollFromText( wktGeometryCollection String [ , SRID Integer] ) : GeometryCollection<hr>");
9639   html +=
9640     wxT
9641     ("ST_GeomCollFromText( wktGeometryCollection String [ , SRID Integer] ) : GeometryCollection<hr>");
9642   html +=
9643     wxT
9644     ("GeometryCollectionFromText( wktGeometryCollection String [ , SRID Integer] ) : GeometryCollection<hr>");
9645   html +=
9646     wxT
9647     ("ST_GeometryCollectionFromText( wktGeometryCollection String [ , SRID Integer] ) : GeometryCollection</td>");
9648   html +=
9649     wxT("<td bgcolor=\"#f0fff0\">construct a GeometryCollection</td></tr>");
9650   html +=
9651     wxT
9652     ("<tr><td bgcolor=\"#fffff0\">BdPolyFromText( wktMultilinestring String [ , SRID Integer] ) : Polygon<hr>");
9653   html +=
9654     wxT
9655     ("ST_BdPolyFromText( wktMultilinestring String [ , SRID Integer] ) : Polygon</td>");
9656   html +=
9657     wxT
9658     ("<td bgcolor=\"#f0fff0\">Construct a Polygon given an arbitrary collection of closed ");
9659   html +=
9660     wxT
9661     ("linestrings as a MultiLineString text representation.<hr>see also: BuildArea(), Polygonize()</td></tr>");
9662   html +=
9663     wxT
9664     ("<tr><td bgcolor=\"#fffff0\">BdMPolyFromText( wktMultilinestring String [ , SRID Integer] ) : MultiPolygon<hr>");
9665   html +=
9666     wxT
9667     ("ST_BdMPolyFromText( wktMultilinestring String [ , SRID Integer] ) : MultiPolygon</td>");
9668   html +=
9669     wxT
9670     ("<td bgcolor=\"#f0fff0\">Construct a MultiPolygon given an arbitrary collection of closed ");
9671   html +=
9672     wxT
9673     ("linestrings as a MultiLineString text representation.<hr>see also: BuildArea(), Polygonize()</td></tr>");
9674   html +=
9675     wxT
9676     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c32\">functions for constructing a geometric object given its Well-known Binary Representation</a>");
9677   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
9678   html +=
9679     wxT
9680     ("<tr><td bgcolor=\"#fffff0\">GeomFromWKB( wkbGeometry Binary [ , SRID Integer] ) : Geometry<hr>");
9681   html +=
9682     wxT
9683     ("ST_GeomFromWKB( wkbGeometry Binary [ , SRID Integer] ) : Geometry</td>");
9684   html +=
9685     wxT
9686     ("<td bgcolor=\"#f0fff0\">construct a geometric object given its Well-known binary Representation</td></tr>");
9687   html +=
9688     wxT
9689     ("<tr><td bgcolor=\"#fffff0\">ST_WKBToSQL( wkbGeometry Binary ) : Geometry</td>");
9690   html +=
9691     wxT
9692     ("<td bgcolor=\"#f0fff0\">SQL/MM alias name for ST_GeomFromWKB: SRID=0 is assumed.</td></tr>");
9693   html +=
9694     wxT
9695     ("<tr><td bgcolor=\"#fffff0\">PointFromWKB( wkbPoint Binary [ , SRID Integer] ) : Point<hr>");
9696   html +=
9697     wxT("ST_PointFromWKB( wkbPoint Binary [ , SRID Integer] ) : Point</td>");
9698   html += wxT("<td bgcolor=\"#f0fff0\">construct a Point</td></tr>");
9699   html +=
9700     wxT
9701     ("<tr><td bgcolor=\"#fffff0\">LineFromWKB( wkbLineString Binary [ , SRID Integer] ) : Linestring<hr>");
9702   html +=
9703     wxT
9704     ("ST_LineFromWKB( wkbLineString Binary [ , SRID Integer] ) : Linestring<hr>");
9705   html +=
9706     wxT
9707     ("LineStringFromWKB( wkbLineString Binary [ , SRID Integer] ) : Linestring<hr>");
9708   html +=
9709     wxT
9710     ("ST_LineStringFromWKB ( wkbLineString Binary [ , SRID Integer] ) : Linestring</td>");
9711   html += wxT("<td bgcolor=\"#f0fff0\">construct a Linestring</td></tr>");
9712   html +=
9713     wxT
9714     ("<tr><td bgcolor=\"#fffff0\">PolyFromWKB( wkbPolygon Binary [ , SRID Integer] ) : Polygon<hr>");
9715   html +=
9716     wxT("ST_PolyFromWKB( wkbPolygon Binary [ , SRID Integer] ) : Polygon<hr>");
9717   html +=
9718     wxT("PolygonFromWKB( wkbPolygon Binary [ , SRID Integer] ) : Polygon<hr>");
9719   html +=
9720     wxT
9721     ("ST_PolygonFromWKB( wkbPolygon Binary [ , SRID Integer] ) : Polygon</td>");
9722   html += wxT("<td bgcolor=\"#f0fff0\">construct a Polygon</td></tr>");
9723   html +=
9724     wxT
9725     ("<tr><td bgcolor=\"#fffff0\">MPointFromWKB( wkbMultiPoint Binary [ , SRID Integer] ) : MultiPoint<hr>");
9726   html +=
9727     wxT
9728     ("ST_MPointFromWKB( wkbMultiPoint Binary [ , SRID Integer] ) : MultiPoint<hr>");
9729   html +=
9730     wxT
9731     ("MultiPointFromWKB( wkbMultiPoint Binary [ , SRID Integer] ) : MultiPoint<hr>");
9732   html +=
9733     wxT
9734     ("ST_MultiPointFromWKB( wkbMultiPoint Binary [ , SRID Integer] ) : MultiPoint</td>");
9735   html += wxT("<td bgcolor=\"#f0fff0\">construct a MultiPoint</td></tr>");
9736   html +=
9737     wxT
9738     ("<tr><td bgcolor=\"#fffff0\">MLineFromWKB( wkbMultiLineString Binary [ , SRID Integer] ) : MultiLinestring<hr>");
9739   html +=
9740     wxT
9741     ("ST_MLineFromWKB( wkbMultiLineString Binary [ , SRID Integer] ) : MultiLinestring<hr>");
9742   html +=
9743     wxT
9744     ("MultiLineStringFromWKB( wkbMultiLineString Binary [ , SRID Integer] ) : MultiLinestring<hr>");
9745   html +=
9746     wxT
9747     ("ST_MultiLineStringFromWKB( wkbMultiLineString Binary [ , SRID Integer] ) : MultiLinestring</td>");
9748   html += wxT("<td bgcolor=\"#f0fff0\">construct a MultiLinestring</td></tr>");
9749   html +=
9750     wxT
9751     ("<tr><td bgcolor=\"#fffff0\">MPolyFromWKB( wkbMultiPolygon Binary [ , SRID Integer] ) : MultiPolygon<hr>");
9752   html +=
9753     wxT
9754     ("ST_MPolyFromWKB( wkbMultiPolygon Binary [ , SRID Integer] ) : MultiPolygon<hr>");
9755   html +=
9756     wxT
9757     ("MultiPolygonFromWKB( wkbMultiPolygon Binary [ , SRID Integer] ) : MultiPolygon<hr>");
9758   html +=
9759     wxT
9760     ("ST_MultiPolygonFromWKB( wkbMultiPolygon Binary [ , SRID Integer] ) : MultiPolygon</td>");
9761   html += wxT("<td bgcolor=\"#f0fff0\">construct a MultiPolygon</td></tr>");
9762   html +=
9763     wxT
9764     ("<tr><td bgcolor=\"#fffff0\">GeomCollFromWKB( wkbGeometryCollection Binary [ , SRID Integer] ) : GeometryCollection<hr>");
9765   html +=
9766     wxT
9767     ("ST_GeomCollFromWKB( wkbGeometryCollection Binary [ , SRID Integer] ) : GeometryCollection<hr>");
9768   html +=
9769     wxT
9770     ("GeometryCollectionFromWKB( wkbGeometryCollection Binary [ , SRID Integer] ) : GeometryCollection<hr>");
9771   html +=
9772     wxT
9773     ("ST_GeometryCollectionFromWKB( wkbGeometryCollection Binary [ , SRID Integer] ) : GeometryCollection</td>");
9774   html +=
9775     wxT("<td bgcolor=\"#f0fff0\">construct a GeometryCollection</td></tr>");
9776   html +=
9777     wxT
9778     ("<tr><td bgcolor=\"#fffff0\">BdPolyFromWKB( wkbMultilinestring Binary [ , SRID Integer] ) : Polygon<hr>");
9779   html +=
9780     wxT
9781     ("ST_BdPolyFromWKB( wkbMultilinestring Binary [ , SRID Integer] ) : Polygon</td>");
9782   html +=
9783     wxT
9784     ("<td bgcolor=\"#f0fff0\">Construct a Polygon given an arbitrary collection of closed ");
9785   html +=
9786     wxT
9787     ("linestrings as a MultiLineString binary representation.<hr>see also: BuildArea(), Polygonize()</td></tr>");
9788   html +=
9789     wxT
9790     ("<tr><td bgcolor=\"#fffff0\">BdMPolyFromWKB( wkbMultilinestring Binary [ , SRID Integer] ) : MultiPolygon<hr>");
9791   html +=
9792     wxT
9793     ("ST_BdMPolyFromWKB( wkbMultilinestring Binary [ , SRID Integer] ) : MultiPolygon</td>");
9794   html +=
9795     wxT
9796     ("<td bgcolor=\"#f0fff0\">Construct a MultiPolygon given an arbitrary collection of closed ");
9797   html +=
9798     wxT
9799     ("linestrings as a MultiLineString binary representation.<hr>see also: BuildArea(), Polygonize()</td></tr>");
9800   html +=
9801     wxT
9802     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c33\">functions for obtaining the Well-known Text / Well-known Binary Representation of a geometric object</a>");
9803   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
9804   html +=
9805     wxT("<tr><td bgcolor=\"#fffff0\">AsText( geom Geometry ) : String<hr>");
9806   html +=
9807     wxT
9808     ("ST_AsText( geom Geometry ) : String</td><td bgcolor=\"#f0fff0\">return the Well-known Text representation</td></tr>");
9809   html +=
9810     wxT
9811     ("<tr><td bgcolor=\"#fffff0\">AsWKT( geom Geometry [ , precision Integer ] ) : String</td>");
9812   html +=
9813     wxT
9814     ("<td bgcolor=\"#f0fff0\">return the Well-known Text representation<hr>always return strictly conformant 2D WKT</td></tr>");
9815   html +=
9816     wxT("<tr><td bgcolor=\"#fffff0\">AsBinary( geom Geometry ) : Binary<hr>");
9817   html +=
9818     wxT
9819     ("ST_AsBinary( geom Geometry ) : Binary</td><td bgcolor=\"#f0fff0\">return the Well-known Binary representation</td></tr>");
9820   html +=
9821     wxT
9822     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c33misc\">SQL functions supporting exotic geometric formats</a>");
9823   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
9824   html +=
9825     wxT
9826     ("<tr><td bgcolor=\"#fffff0\">AsSVG( geom Geometry, [ , relative Integer [ , precision Integer ] ] ) : String</td>");
9827   html +=
9828     wxT
9829     ("<td bgcolor=\"#f0fff0\">returns the SVG [<i>Scalable Vector Graphics</i>] representation</td></tr>");
9830   html +=
9831     wxT
9832     ("<tr><td bgcolor=\"#fffff0\">AsKML( geom Geometry [ , precision Integer ] ) : String<br>");
9833   html +=
9834     wxT
9835     ("AsKML( name String, description String, geom Geometry [ , precision Integer ] ) : String</td>");
9836   html +=
9837     wxT
9838     ("<td bgcolor=\"#f0fff0\">returns the KML [<i>Keyhole Markup Language</i>] representation</td></tr>");
9839   html +=
9840     wxT
9841     ("<tr><td bgcolor=\"#fffff0\">GeomFromKml( KmlGeometry String ) : Geometry</td><td bgcolor=\"#f0fff0\">construct a geometric object given its KML Representation</td></tr>");
9842   html +=
9843     wxT
9844     ("<tr><td bgcolor=\"#fffff0\">AsGML( geom Geometry [ , precision Integer ] ) : String<br>");
9845   html +=
9846     wxT
9847     ("AsGML( version Integer, geom Geometry [ , precision Integer ] ) : String</td>");
9848   html +=
9849     wxT
9850     ("<td bgcolor=\"#f0fff0\">returns the GML [<i>Geography Markup Language</i>] representation</td></tr>");
9851   html +=
9852     wxT
9853     ("<tr><td bgcolor=\"#fffff0\">GeomFromGML( gmlGeometry String ) : Geometry</td><td bgcolor=\"#f0fff0\">construct a geometric object given its GML Representation</td></tr>");
9854   html +=
9855     wxT
9856     ("<tr><td bgcolor=\"#fffff0\">AsGeoJSON( geom Geometry [ , precision Integer [ , options Integer ] ] ) : String</td>");
9857   html +=
9858     wxT
9859     ("<td bgcolor=\"#f0fff0\">returns the GeoJSON [<i>Geographic JavaScript Object Notation</i>] representation</td></tr>");
9860   html +=
9861     wxT
9862     ("<tr><td bgcolor=\"#fffff0\">GeomFromGeoJSON( GeoJSONGeometry String ) : Geometry</td><td bgcolor=\"#f0fff0\">construct a geometric object given its GeoJSON Representation</td></tr>");
9863   html +=
9864     wxT
9865     ("<tr><td bgcolor=\"#fffff0\">AsEWKB( geom Geometry ) : String</td><td bgcolor=\"#f0fff0\">returns the EWKB [<i>Extended Well Known Binary</i>] representation</td></tr>");
9866   html +=
9867     wxT
9868     ("<tr><td bgcolor=\"#fffff0\">GeomFromEWKB( ewkbGeometry String ) : Geometry</td><td bgcolor=\"#f0fff0\">construct a geometric object given its EWKB Representation</td></tr>");
9869   html +=
9870     wxT
9871     ("<tr><td bgcolor=\"#fffff0\">AsEWKT( geom Geometry ) : String</td><td bgcolor=\"#f0fff0\">returns the EWKT [<i>Extended Well Known Text</i>] representation</td></tr>");
9872   html +=
9873     wxT
9874     ("<tr><td bgcolor=\"#fffff0\">GeomFromEWKT( ewktGeometry String ) : Geometry</td><td bgcolor=\"#f0fff0\">construct a geometric object given its EWKT Representation</td></tr>");
9875   html +=
9876     wxT
9877     ("<tr><td bgcolor=\"#fffff0\">AsFGF( geom Geometry ) : String</td><td bgcolor=\"#f0fff0\">returns the FGF [<i>FDO Geometry Binary Format</i>] representation</td></tr>");
9878   html +=
9879     wxT
9880     ("<tr><td bgcolor=\"#fffff0\">GeomFromFGF( fgfGeometry Binary [ , SRID Integer] ) : Geometry</td><td bgcolor=\"#f0fff0\">construct a geometric object given its FGF binary Representation</td></tr>");
9881   html +=
9882     wxT
9883     ("<tr><td bgcolor=\"#fffff0\">ExportDXF( out_dir String , filename String , sql_query String , layer_col_name String , ");
9884   html +=
9885     wxT
9886     ("geom_col_name String , label_col_name String , text_height_col_name String , text_rotation_col_name String , geom_filter Geometry [ , precision Integer ] ) : Integer</td>");
9887   html +=
9888     wxT
9889     ("<td bgcolor=\"#f0fff0\">Exports a whole DXF file.<br>Will return 0 (i.e. FALSE) on failure, any other value (i.e. TRUE) on success.<hr>");
9890   html +=
9891     wxT
9892     ("Please note this SQL function open the doors to many potential security issues, and thus is always disabled by default.<br>");
9893   html +=
9894     wxT
9895     ("Explicitly setting the environmente variable SPATIALITE_SECURITY=relaxed is absolutely required in order to effectively enable this function.</td></tr>");
9896   html +=
9897     wxT
9898     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c34\">functions on type Geometry</a>");
9899   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
9900   html +=
9901     wxT("<tr><td bgcolor=\"#fffff0\">Dimension( geom Geometry ) : Integer<hr>");
9902   html += wxT("ST_Dimension( geom Geometry ) : Integer</td>");
9903   html +=
9904     wxT
9905     ("<td bgcolor=\"#f0fff0\">return the dimension of the geometric object, which is less than or equal to the dimension of the coordinate space</td></tr>");
9906   html +=
9907     wxT
9908     ("<tr><td bgcolor=\"#fffff0\">CoordDimension( geom Geometry ) : String</td>");
9909   html +=
9910     wxT
9911     ("<td bgcolor=\"#f0fff0\">return the dimension model used by the geometric object as:<br>'XY', 'XYZ', 'XYM' or 'XYZM'</td></tr>");
9912   html +=
9913     wxT("<tr><td bgcolor=\"#fffff0\">ST_NDims( geom Geometry ) : Integer</td>");
9914   html +=
9915     wxT
9916     ("<td bgcolor=\"#f0fff0\">return the number of dimensions used by the geometric object as:<br>2, 3 or 4</td></tr>");
9917   html +=
9918     wxT("<tr><td bgcolor=\"#fffff0\">ST_Is3D( geom Geometry ) : Integer</td>");
9919   html +=
9920     wxT("<td bgcolor=\"#f0fff0\">Checks if geom has the Z dimension.<br>");
9921   html +=
9922     wxT
9923     ("The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a ");
9924   html += wxT("function invocation on invalid arguments.</td></tr>");
9925   html +=
9926     wxT
9927     ("<tr><td bgcolor=\"#fffff0\">ST_IsMeasured( geom Geometry ) : Integer</td>");
9928   html +=
9929     wxT("<td bgcolor=\"#f0fff0\">Checks if geom has the M dimension.<br>");
9930   html +=
9931     wxT
9932     ("The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a ");
9933   html += wxT("function invocation on invalid arguments.</td></tr>");
9934   html +=
9935     wxT
9936     ("<tr><td bgcolor=\"#fffff0\">GeometryType( geom Geometry ) : String<hr>");
9937   html += wxT("ST_GeometryType( geom Geometry ) : String</td>");
9938   html +=
9939     wxT
9940     ("<td bgcolor=\"#f0fff0\">return the name of the instantiable subtype of Geometry of which this geometric object is a member, as a string</td></tr>");
9941   html +=
9942     wxT("<tr><td bgcolor=\"#fffff0\">SRID( geom Geometry ) : Integer<hr>");
9943   html += wxT("ST_SRID( geom <i>Geometry</i> ) : <i>Integer</i></td>");
9944   html +=
9945     wxT
9946     ("<td bgcolor=\"#f0fff0\">return the Spatial Reference System ID for this geometric object</td></tr>");
9947   html +=
9948     wxT
9949     ("<tr><td bgcolor=\"#fffff0\">SetSRID( geom Geometry , SRID Integer ) : Integer</td>");
9950   html +=
9951     wxT
9952     ("<td bgcolor=\"#f0fff0\">directly sets the Spatial Reference System ID for this geometric object [no reprojection is applied].<br>");
9953   html +=
9954     wxT
9955     ("The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a ");
9956   html += wxT("function invocation on NULL arguments</td></tr>");
9957   html +=
9958     wxT("<tr><td bgcolor=\"#fffff0\">IsEmpty( geom Geometry ) : Integer<hr>");
9959   html += wxT("ST_IsEmpty( geom Geometry ) : Integer</td>");
9960   html +=
9961     wxT
9962     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
9963   html +=
9964     wxT("TRUE if this geometric object corresponds to the empty set</td></tr>");
9965   html +=
9966     wxT("<tr><td bgcolor=\"#fffff0\">IsSimple( geom Geometry ) : Integer<hr>");
9967   html += wxT("ST_IsSimple( geom <i>Geometry</i> ) : <i>Integer</i></td>");
9968   html +=
9969     wxT
9970     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
9971   html +=
9972     wxT
9973     ("TRUE if this geometric object is simple, as defined in the Geometry Model</td></tr>");
9974   html +=
9975     wxT("<tr><td bgcolor=\"#fffff0\">IsValid( geom Geometry ) : Integer<hr>");
9976   html += wxT("ST_IsValid( geom Geometry ) : Integer</td>");
9977   html +=
9978     wxT
9979     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
9980   html +=
9981     wxT
9982     ("TRUE if this geometric object does not contains any topological error</td></tr>");
9983   html +=
9984     wxT("<tr><td bgcolor=\"#fffff0\">Boundary( geom Geometry ) : Geometry<hr>");
9985   html += wxT("ST_Boundary( geom Geometry ) : Geometry</td>");
9986   html +=
9987     wxT
9988     ("<td bgcolor=\"#f0fff0\">return a geometric object that is the combinatorial boundary of g as defined in the Geometry Model</td></tr>");
9989   html +=
9990     wxT("<tr><td bgcolor=\"#fffff0\">Envelope( geom Geometry ) : Geometry<hr>");
9991   html += wxT("ST_Envelope( geom Geometry ) : Geometry</td>");
9992   html +=
9993     wxT
9994     ("<td bgcolor=\"#f0fff0\">return the rectangle bounding g as a Polygon. ");
9995   html +=
9996     wxT
9997     ("The Polygon is defined by the corner points of the bounding box [(MINX, MINY),(MAXX, MINY), (MAXX, MAXY), (MINX, MAXY), (MINX, MINY)].</td></tr>");
9998   html +=
9999     wxT
10000     ("<tr><td bgcolor=\"#fffff0\">ST_Expand( geom Geometry , amount Double ) : Geometry</td>");
10001   html +=
10002     wxT
10003     ("<td bgcolor=\"#f0fff0\">return the rectangle bounding g as a Polygon.<br>");
10004   html +=
10005     wxT
10006     ("The bounding rectangle is expanded in all directions by an amount specified by the second argument.</td></tr>");
10007   html +=
10008     wxT
10009     ("<tr><td bgcolor=\"#fffff0\">ST_NPoints( geom Geometry ) : Integer</td>");
10010   html +=
10011     wxT
10012     ("<td bgcolor=\"#f0fff0\">return the total number of Points (this including any Linestring/Polygon vertex)</td></tr>");
10013   html +=
10014     wxT
10015     ("<tr><td bgcolor=\"#fffff0\">ST_NRings( geom Geometry ) : Integer</td>");
10016   html +=
10017     wxT
10018     ("<td bgcolor=\"#f0fff0\">return the total number of Rings (this including both Exterior and Interior Rings)</td></tr>");
10019   html +=
10020     wxT
10021     ("<tr><td bgcolor=\"#fffff0\">ST_Reverse( geom Geometry ) : geom Geometry</td>");
10022   html +=
10023     wxT
10024     ("<td bgcolor=\"#f0fff0\">returns a new Geometry [if possible] or NULL<hr>");
10025   html += wxT("Any Linestring or Ring will be in reverse order.</td></tr>");
10026   html +=
10027     wxT
10028     ("<tr><td bgcolor=\"#fffff0\">ST_ForceLHR( geom Geometry ) : geom Geometry</td>");
10029   html +=
10030     wxT
10031     ("<td bgcolor=\"#f0fff0\">returns a new Geometry [if possible] or NULL<hr>");
10032   html +=
10033     wxT
10034     ("Any Polygon will be oriented accordingly to Left Hand Rule (Exterior Ring clockwise, ");
10035   html += wxT("Interior Rings counter-clockwise).</td></tr>");
10036   html +=
10037     wxT
10038     ("<tr><td bgcolor=\"#fffff0\">AddPoint( line Linestring , point Point [ , position Integer ] ) : Linestring<hr>");
10039   html +=
10040     wxT
10041     ("ST_AddPoint( line Linestring , point Point [ , position Integer ] ) : Linestring</td>");
10042   html +=
10043     wxT
10044     ("<td bgcolor=\"#f0fff0\">Adds a new Point into the input Linestring immediately before \"position\" (zero-based index)<br>");
10045   html +=
10046     wxT
10047     ("A negative \"position\" (default) means appending the new Point to the end of the input Linestring.<br>");
10048   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
10049   html +=
10050     wxT
10051     ("<tr><td bgcolor=\"#fffff0\">SetPoint( line Linestring , position Integer , point Point ) : Linestring<hr>");
10052   html +=
10053     wxT
10054     ("ST_SetPoint( line Linestring , position Integer , point Point ) : Linestring</td>");
10055   html +=
10056     wxT
10057     ("<td bgcolor=\"#f0fff0\">Replaces the Point into the input Linestring at \"position\" (zero-based index)<br>");
10058   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
10059   html +=
10060     wxT
10061     ("<tr><td bgcolor=\"#fffff0\">RemovePoint( line Linestring , position Integer ) : Linestring<hr>");
10062   html +=
10063     wxT
10064     ("ST_RemovePoint( line Linestring , position Integer ) : Linestring</td>");
10065   html +=
10066     wxT
10067     ("<td bgcolor=\"#f0fff0\">Removes the Point into the input Linestring at \"position\" (zero-based index)<br>");
10068   html += wxT("NULL will be returned if any error is encountered.</td></tr>");
10069   html +=
10070     wxT
10071     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"repair\">Functions attempting to repair malformed Geometries</a>");
10072   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
10073   html +=
10074     wxT
10075     ("<tr><td bgcolor=\"#fffff0\">SanitizeGeometry( geom Geometry ) : geom Geometry</td>");
10076   html +=
10077     wxT
10078     ("<td bgcolor=\"#f0fff0\">returns a (possibly) sanitized Geometry or NULL</td></tr>");
10079   html +=
10080     wxT
10081     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"compress\">Geometry-compression functions</a>");
10082   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
10083   html +=
10084     wxT
10085     ("<tr><td bgcolor=\"#fffff0\">CompressGeometry( geom Geometry ) : geom Geometry</td>");
10086   html +=
10087     wxT
10088     ("<td bgcolor=\"#f0fff0\">returns a compressed Geometry or NULL</td></tr>");
10089   html +=
10090     wxT
10091     ("<tr><td bgcolor=\"#fffff0\">UncompressGeometry( geom Geometry ) : geom Geometry</td>");
10092   html +=
10093     wxT
10094     ("<td bgcolor=\"#f0fff0\">returns an uncompressed Geometry or NULL</td></tr>");
10095   html +=
10096     wxT
10097     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"cast\">Geometry-type casting functions</a>");
10098   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
10099   html +=
10100     wxT
10101     ("<tr><td bgcolor=\"#fffff0\">CastToPoint( geom Geometry ) : geom Geometry</td>");
10102   html +=
10103     wxT
10104     ("<td bgcolor=\"#f0fff0\">returns a POINT-type Geometry [if possible] or NULL</td></tr>");
10105   html +=
10106     wxT
10107     ("<tr><td bgcolor=\"#fffff0\">CastToLinestring( geom Geometry ) : geom Geometry</td>");
10108   html +=
10109     wxT
10110     ("<td bgcolor=\"#f0fff0\">returns a LINESTRING-type Geometry [if possible] or NULL</td></tr>");
10111   html +=
10112     wxT
10113     ("<tr><td bgcolor=\"#fffff0\">CastToPolygon( geom Geometry ) : geom Geometry</td>");
10114   html +=
10115     wxT
10116     ("<td bgcolor=\"#f0fff0\">returns a POLYGON-type Geometry [if possible] or NULL</td></tr>");
10117   html +=
10118     wxT
10119     ("<tr><td bgcolor=\"#fffff0\">CastToMultiPoint( geom Geometry ) : geom Geometry</td>");
10120   html +=
10121     wxT
10122     ("<td bgcolor=\"#f0fff0\">returns a MULTIPOINT-type Geometry [if possible] or NULL</td></tr>");
10123   html +=
10124     wxT
10125     ("<tr><td bgcolor=\"#fffff0\">CastToMultiLinestring( geom Geometry ) : geom Geometry</td>");
10126   html +=
10127     wxT
10128     ("<td bgcolor=\"#f0fff0\">returns a MULTILINESTRING-type Geometry [if possible] or NULL</td></tr>");
10129   html +=
10130     wxT
10131     ("<tr><td bgcolor=\"#fffff0\">CastToMultiPolygon( geom Geometry ) : geom Geometry</td>");
10132   html +=
10133     wxT
10134     ("<td bgcolor=\"#f0fff0\">returns a MULTIPOLYGON-type Geometry [if possible] or NULL</td></tr>");
10135   html +=
10136     wxT
10137     ("<tr><td bgcolor=\"#fffff0\">CastToGeometryCollection( geom Geometry ) : geom Geometry</td>");
10138   html +=
10139     wxT
10140     ("<td bgcolor=\"#f0fff0\">returns a GEOMETRYCOLLECTION-type Geometry [if possible] or NULL</td></tr>");
10141   html +=
10142     wxT
10143     ("<tr><td bgcolor=\"#fffff0\">CastToMulti( geom Geometry ) : geom Geometry<hr>");
10144   html += wxT("ST_Multi( geom Geometry ) : geom Geometry</td>");
10145   html +=
10146     wxT
10147     ("<td bgcolor=\"#f0fff0\">returns a MULTIPOINT-, MULTILINESTRING- or MULTIPOLYGON-type Geometry [if possible]: NULL in any other case</td></tr>");
10148   html +=
10149     wxT
10150     ("<tr><td bgcolor=\"#fffff0\">CastToSingle( geom Geometry ) : geom Geometry</td>");
10151   html +=
10152     wxT
10153     ("<td bgcolor=\"#f0fff0\">returns a POINT-, LINESTRING- or POLYGON-type Geometry [if possible]: NULL in any other case</td></tr>");
10154   html +=
10155     wxT
10156     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"dims-cast\">Space-dimensions casting functions</a>");
10157   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
10158   html +=
10159     wxT
10160     ("<tr><td bgcolor=\"#fffff0\">CastToXY( geom Geometry ) : geom Geometry</td>");
10161   html +=
10162     wxT
10163     ("<td bgcolor=\"#f0fff0\">returns a Geometry using the [XY] space dimension</td></tr>");
10164   html +=
10165     wxT
10166     ("<tr><td bgcolor=\"#fffff0\">CastToXYZ( geom Geometry ) : geom Geometry</td>");
10167   html +=
10168     wxT
10169     ("<td bgcolor=\"#f0fff0\">returns a Geometry using the [XYZ] space dimension</td></tr>");
10170   html +=
10171     wxT
10172     ("<tr><td bgcolor=\"#fffff0\">CastToXYM( geom Geometry ) : geom Geometry</td>");
10173   html +=
10174     wxT
10175     ("<td bgcolor=\"#f0fff0\">returns a Geometry using the [XYM] space dimension</td></tr>");
10176   html +=
10177     wxT
10178     ("<tr><td bgcolor=\"#fffff0\">CastToXYZM( geom Geometry ) : geom Geometry</td>");
10179   html +=
10180     wxT
10181     ("<td bgcolor=\"#f0fff0\">returns a Geometry using the [XYZM] space dimension</td></tr>");
10182   html +=
10183     wxT
10184     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c35\">functions on type Point</a>");
10185   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
10186   html +=
10187     wxT("<tr><td bgcolor=\"#fffff0\">X( pt Point ) : Double precision<hr>");
10188   html +=
10189     wxT
10190     ("ST_X( pt Point ) : Double precision</td><td bgcolor=\"#f0fff0\">return the x-coordinate of Point p as a double precision number</td></tr>");
10191   html +=
10192     wxT("<tr><td bgcolor=\"#fffff0\">Y( pt Point ) : Double precision<hr>");
10193   html +=
10194     wxT
10195     ("ST_Y( pt Point ) : Double precision</td><td bgcolor=\"#f0fff0\">return the y-coordinate of Point p as a double precision number</td></tr>");
10196   html +=
10197     wxT("<tr><td bgcolor=\"#fffff0\">Z( pt Point ) : Double precision<hr>");
10198   html +=
10199     wxT
10200     ("ST_Z( pt Point ) : Double precision</td><td bgcolor=\"#f0fff0\">return the z-coordinate of Point p as a double precision number");
10201   html += wxT("or NULL if no z-coordinate is available</td></tr>");
10202   html +=
10203     wxT("<tr><td bgcolor=\"#fffff0\">M( pt Point ) : Double precision<hr>");
10204   html +=
10205     wxT
10206     ("ST_M( pt Point ) : Double precision</td><td bgcolor=\"#f0fff0\">return the m-coordinate of Point p as a double precision number<br>");
10207   html += wxT("or NULL if no m-coordinate is available</td></tr>");
10208   html +=
10209     wxT
10210     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c361\">functions on type Curve [Linestring or Ring]</a></td></tr>");
10211   html += wxT("<tr><td bgcolor=\"#fffff0\">StartPoint( c Curve ) : Point<hr>");
10212   html +=
10213     wxT
10214     ("ST_StartPoint( c Curve ) : Point</td><td bgcolor=\"#f0fff0\">return a Point containing the first Point of c</td></tr>");
10215   html += wxT("<tr><td bgcolor=\"#fffff0\">EndPoint( c Curve ) : Point<hr>");
10216   html +=
10217     wxT
10218     ("ST_EndPoint( c Curve ) : Point</td><td bgcolor=\"#f0fff0\">return a Point containing the last Point of c</td></tr>");
10219   html +=
10220     wxT
10221     ("<tr><td bgcolor=\"#fffff0\">NumPoints( line LineString ) : Integer<hr>");
10222   html +=
10223     wxT
10224     ("ST_NumPoints( line LineString ) : Integer</td><td bgcolor=\"#f0fff0\">return the number of Points in the LineString</td></tr>");
10225   html +=
10226     wxT
10227     ("<tr><td bgcolor=\"#fffff0\">PointN( line LineString , n Integer ) : Point<hr>");
10228   html +=
10229     wxT
10230     ("ST_PointN( line LineString , n Integer ) : Point</td><td bgcolor=\"#f0fff0\">return a Point containing Point n of line</td></tr>");
10231   html +=
10232     wxT
10233     ("<tr><td bgcolor=\"#fffff0\">GLength( c Curve [ , use_ellipsoid Boolean ] ) : Double precision<hr>");
10234   html +=
10235     wxT
10236     ("ST_Length( c Curve [ , use_ellipsoid Boolean ] ) : Double precision</td><td bgcolor=\"#f0fff0\">return the length of c</td></tr>");
10237   html +=
10238     wxT
10239     ("<tr><td bgcolor=\"#fffff0\">Perimeter( s Surface [ , use_ellipsoid Boolean ] ) : Double precision<hr>");
10240   html +=
10241     wxT
10242     ("ST_Perimeter( s Surface [ , use_ellipsoid Boolean ] ) : Double precision</td><td bgcolor=\"#f0fff0\">return the perimeter of s</td></tr>");
10243   html +=
10244     wxT
10245     ("<tr><td bgcolor=\"#fffff0\">GeodesicLength( c Curve ) : Double precision</td><td bgcolor=\"#f0fff0\">return the geodesic length of c");
10246   html +=
10247     wxT
10248     (" measured on the Ellipsoid [<i>only for <b>geographic</b> SRIDs</i>]</td></tr>");
10249   html +=
10250     wxT
10251     ("<tr><td bgcolor=\"#fffff0\">GreatCircleLength( c Curve ) : Double precision</td><td bgcolor=\"#f0fff0\">return the Great Circle length of c");
10252   html += wxT(" [<i>only for <b>geographic</b> SRIDs</i>]</td></tr>");
10253   html += wxT("<tr><td bgcolor=\"#fffff0\">IsClosed( c Curve ) : Integer<hr>");
10254   html += wxT("ST_IsClosed( c Curve ) : Integer</td>");
10255   html +=
10256     wxT
10257     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments<br>");
10258   html +=
10259     wxT
10260     ("return TRUE if c is closed, i.e., if StartPoint(c) = EndPoint(c)</td></tr>");
10261   html += wxT("<tr><td bgcolor=\"#fffff0\">IsRing( c Curve ) : Integer<hr>");
10262   html += wxT("ST_IsRing( c Curve ) : Integer</td>");
10263   html +=
10264     wxT
10265     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments<br>");
10266   html +=
10267     wxT
10268     ("return TRUE if c is a ring, i.e., if c is closed and simple. A simple Curve does not pass through the same Point more than once.</td></tr>");
10269   html +=
10270     wxT
10271     ("<tr><td bgcolor=\"#fffff0\">PointOnSurface( s Surface/Curve ) : Point<hr>");
10272   html +=
10273     wxT
10274     ("ST_PointOnSurface( s Surface ) : Point</td><td bgcolor=\"#f0fff0\">return a Point guaranteed to lie on the Surface (or Curve)</td></tr>");
10275   html +=
10276     wxT
10277     ("<tr><td bgcolor=\"#fffff0\">Simplify( c Curve , tolerance Double precision ) : Curve<hr>");
10278   html +=
10279     wxT("ST_Simplify( c Curve , tolerance Double precision ) : Curve<hr>");
10280   html +=
10281     wxT("ST_Generalize( c Curve , tolerance Double precision ) : Curve</td>");
10282   html +=
10283     wxT
10284     ("<td bgcolor=\"#f0fff0\">return a geometric object representing a simplified version of c applying the Douglas-Peukert algorithm with given tolerance</td></tr>");
10285   html +=
10286     wxT
10287     ("<tr><td bgcolor=\"#fffff0\">SimplifyPreserveTopology( c Curve , tolerance Double precision ) : Curve<hr>");
10288   html +=
10289     wxT
10290     ("ST_SimplifyPreserveTopology( c Curve , tolerance Double precision ) : Curve</td>");
10291   html +=
10292     wxT
10293     ("<td bgcolor=\"#f0fff0\">return a geometric object representing a simplified version of c ");
10294   html +=
10295     wxT
10296     ("applying the Douglas-Peukert algorithm with given tolerance and respecting topology</td></tr>");
10297   html +=
10298     wxT
10299     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c36\">functions on type Surface [Polygon or Ring]</a>");
10300   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
10301   html += wxT("<tr><td bgcolor=\"#fffff0\">Centroid( s Surface ) : Point<hr>");
10302   html +=
10303     wxT
10304     ("ST_Centroid( s Surface ) : Point</td><td bgcolor=\"#f0fff0\">return the centroid of s, which may lie outside s</td></tr>");
10305   html +=
10306     wxT
10307     ("<tr><td bgcolor=\"#fffff0\">Area( s Surface [ , use_ellipsoid Boolean ] ) : Double precision<hr>");
10308   html +=
10309     wxT
10310     ("ST_Area( s Surface [ , use_ellipsoid Boolean ] ) : Double precision</td><td bgcolor=\"#f0fff0\">return the area of s</td></tr>");
10311   html +=
10312     wxT
10313     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c37\">functions on type Polygon</a>");
10314   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
10315   html +=
10316     wxT
10317     ("<tr><td bgcolor=\"#fffff0\">ExteriorRing( polyg Polygon ) : LineString<hr>");
10318   html +=
10319     wxT
10320     ("ST_ExteriorRing( polyg Polygon ) : LineString</td><td bgcolor=\"#f0fff0\">return the exteriorRing of p</td></tr>");
10321   html +=
10322     wxT
10323     ("<tr><td bgcolor=\"#fffff0\">NumInteriorRing( polyg Polygon ) : Integer<hr>NumInteriorRings( polyg Polygon ) : Integer<hr>");
10324   html += wxT("ST_NumInteriorRing( polyg Polygon ) : Integer</td>");
10325   html +=
10326     wxT("<td bgcolor=\"#f0fff0\">return the number of interiorRings</td></tr>");
10327   html +=
10328     wxT
10329     ("<tr><td bgcolor=\"#fffff0\">InteriorRingN( polyg Polygon , n Integer ) : LineString<hr>");
10330   html +=
10331     wxT("ST_InteriorRingN( polyg Polygon , n Integer ) : LineString</td>");
10332   html +=
10333     wxT
10334     ("<td bgcolor=\"#f0fff0\">return the nth interiorRing. The order of Rings is not geometrically significant.</td></tr>");
10335   html +=
10336     wxT
10337     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c38\">functions on type GeomCollection</a>");
10338   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
10339   html +=
10340     wxT
10341     ("<tr><td bgcolor=\"#fffff0\">NumGeometries( geom GeomCollection ) : Integer<hr>");
10342   html +=
10343     wxT
10344     ("ST_NumGeometries( geom GeomCollection ) : Integer</td><td bgcolor=\"#f0fff0\">return the number of geometries</td></tr>");
10345   html +=
10346     wxT
10347     ("<tr><td bgcolor=\"#fffff0\">GeometryN( geom GeomCollection , n Integer ) : Geometry<hr>");
10348   html +=
10349     wxT("ST_GeometryN( geom GeomCollection , n Integer ) : Geometry</td>");
10350   html +=
10351     wxT
10352     ("<td bgcolor=\"#f0fff0\">return the nth geometric object in the collection. The order of the elements in the collection is not geometrically significant.</td></tr>");
10353   html +=
10354     wxT
10355     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c39\">functions testing approximative spatial relationships via MBRs</a>");
10356   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
10357   html +=
10358     wxT
10359     ("<tr><td bgcolor=\"#fffff0\">MbrEqual( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10360   html +=
10361     wxT
10362     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
10363   html += wxT("TRUE if g1 and g2 have equal MBRs</td></tr>");
10364   html +=
10365     wxT
10366     ("<tr><td bgcolor=\"#fffff0\">MbrDisjoint( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10367   html +=
10368     wxT
10369     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
10370   html +=
10371     wxT
10372     ("TRUE if the intersection of g1 and g2 MBRs is the empty set</td></tr>");
10373   html +=
10374     wxT
10375     ("<tr><td bgcolor=\"#fffff0\">MbrTouches( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10376   html +=
10377     wxT
10378     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
10379   html +=
10380     wxT
10381     ("TRUE if the only Points in common between g1 and g2 MBRs lie in the union of the boundaries of g1 and g2</td></tr>");
10382   html +=
10383     wxT
10384     ("<tr><td bgcolor=\"#fffff0\">MbrWithin( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10385   html +=
10386     wxT
10387     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
10388   html += wxT("TRUE if g1 MBR is completely contained in g2 MBR</td></tr>");
10389   html +=
10390     wxT
10391     ("<tr><td bgcolor=\"#fffff0\">MbrOverlaps( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10392   html +=
10393     wxT
10394     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
10395   html +=
10396     wxT
10397     ("TRUE if the intersection of g1 and g2 MBRs results in a value of the same dimension as g1 and g2 that is different from both g1 and g2</td></tr>");
10398   html +=
10399     wxT
10400     ("<tr><td bgcolor=\"#fffff0\">MbrIntersects( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10401   html +=
10402     wxT
10403     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments<br>");
10404   html +=
10405     wxT
10406     ("convenience predicate: TRUE if the intersection of g1 and g2 MBRs is not empty</td></tr>");
10407   html +=
10408     wxT
10409     ("<tr><td bgcolor=\"#fffff0\">ST_EnvIntersects( geom1 Geometry , geom2 Geometry ) : Integer<hr>");
10410   html +=
10411     wxT
10412     ("ST_EnvelopesIntersects( geom1 Geometry , geom2 Geometry ) : Integer<hr>");
10413   html +=
10414     wxT
10415     ("ST_EnvIntersects( geom1 Geometry , x1 Double precision , y1 Double precision , x2 Double precision , y2 Double precision ) : Integer<hr>");
10416   html +=
10417     wxT
10418     ("ST_EnvelopesIntersects( geom1 Geometry , x1 Double precision , y1 Double precision , x2 Double precision , y2 Double precision ) : Integer</td>");
10419   html +=
10420     wxT
10421     ("<td bgcolor=\"#f0fff0\">The first form simply is an alias name for MbrIntersects; the other form allows to define the second MBR by two extreme points [x1, y1] and [x2, y2].<br>");
10422   html +=
10423     wxT
10424     ("The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on invalid arguments<br>");
10425   html +=
10426     wxT
10427     ("convenience predicate: TRUE if the intersection of both MBRs is not empty</td></tr>");
10428   html +=
10429     wxT
10430     ("<tr><td bgcolor=\"#fffff0\">MbrContains( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10431   html +=
10432     wxT
10433     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments<br>");
10434   html +=
10435     wxT
10436     ("convenience predicate: TRUE if g2 MBR is completely contained in g1 MBR</td></tr>");
10437   html +=
10438     wxT
10439     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c40\">functions testing spatial relationships</a>");
10440   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
10441   html +=
10442     wxT
10443     ("<tr><td bgcolor=\"#fffff0\">Equals( geom1 Geometry , geom2 Geometry ) : Integer<hr>");
10444   html += wxT("ST_Equals( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10445   html +=
10446     wxT
10447     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
10448   html += wxT("TRUE if g1 and g2 are equal</td></tr>");
10449   html +=
10450     wxT
10451     ("<tr><td bgcolor=\"#fffff0\">Disjoint( geom1 Geometry , geom2 Geometry ) : Integer<hr>");
10452   html += wxT("ST_Disjoint( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10453   html +=
10454     wxT
10455     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
10456   html +=
10457     wxT("TRUE if the intersection of g1 and g2 is the empty set</td></tr>");
10458   html +=
10459     wxT
10460     ("<tr><td bgcolor=\"#fffff0\">Touches( geom1 Geometry , geom2 Geometry ) : Integer<hr>");
10461   html += wxT("ST_Touches( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10462   html +=
10463     wxT
10464     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
10465   html +=
10466     wxT
10467     ("TRUE if the only Points in common between g1 and g2 lie in the union of the boundaries of g1 and g2</td></tr>");
10468   html +=
10469     wxT
10470     ("<tr><td bgcolor=\"#fffff0\">Within( geom1 Geometry , geom2 Geometry ) : Integer<hr>");
10471   html += wxT("ST_Within( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10472   html +=
10473     wxT
10474     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
10475   html += wxT("TRUE if g1 is completely contained in g2</td></tr>");
10476   html +=
10477     wxT
10478     ("<tr><td bgcolor=\"#fffff0\">Overlaps( geom1 Geometry , geom2 Geometry ) : Integer<hr>");
10479   html += wxT("ST_Overlaps( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10480   html +=
10481     wxT
10482     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
10483   html +=
10484     wxT
10485     ("TRUE if the intersection of g1 and g2 results in a value of the same dimension as g1 and g2 that is different from both g1 and g2</td></tr>");
10486   html +=
10487     wxT
10488     ("<tr><td bgcolor=\"#fffff0\">Crosses( geom1 Geometry , geom2 Geometry ) : Integer<hr>");
10489   html += wxT("ST_Crosses( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10490   html +=
10491     wxT
10492     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
10493   html +=
10494     wxT
10495     ("TRUE if the intersection of g1 and g2 results in a value whose dimension is less than the maximum dimension of g1 and g2 ");
10496   html +=
10497     wxT
10498     ("and the intersection value includes Points interior to both g1 and g2, and the intersection value is not equal to either g1 or g2</td></tr>");
10499   html +=
10500     wxT
10501     ("<tr><td bgcolor=\"#fffff0\">Intersects( geom1 Geometry , geom2 Geometry ) : Integer<hr>");
10502   html +=
10503     wxT("ST_Intersects( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10504   html +=
10505     wxT
10506     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments<br>");
10507   html +=
10508     wxT
10509     ("convenience predicate: TRUE if the intersection of g1 and g2 is not empty</td></tr>");
10510   html +=
10511     wxT
10512     ("<tr><td bgcolor=\"#fffff0\">Contains( geom1 Geometry , geom2 Geometry ) : Integer<hr>");
10513   html += wxT("ST_Contains( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10514   html +=
10515     wxT
10516     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments<br>");
10517   html +=
10518     wxT
10519     ("convenience predicate: TRUE if g2 is completely contained in g1</td></tr>");
10520   html +=
10521     wxT
10522     ("<tr><td bgcolor=\"#fffff0\">Covers( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10523   html +=
10524     wxT
10525     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments<br>");
10526   html +=
10527     wxT("convenience predicate: TRUE if g1 completely covers g2</td></tr>");
10528   html +=
10529     wxT
10530     ("<tr><td bgcolor=\"#fffff0\">CoveredBy( geom1 Geometry , geom2 Geometry ) : Integer</td>");
10531   html +=
10532     wxT
10533     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments<br>");
10534   html +=
10535     wxT
10536     ("convenience predicate: TRUE if g1 is completely covered by g2</td></tr>");
10537   html +=
10538     wxT
10539     ("<tr><td bgcolor=\"#fffff0\">Relate( geom1 Geometry , geom2 Geometry , patternMatrix String ) : Integer<hr>");
10540   html +=
10541     wxT
10542     ("ST_Relate( geom1 Geometry , geom2 Geometry , patternMatrix String ) : Integer</td>");
10543   html +=
10544     wxT
10545     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.<br>");
10546   html +=
10547     wxT
10548     ("return TRUE if the spatial relationship specified by the patternMatrix holds</td></tr>");
10549   html +=
10550     wxT
10551     ("<tr><td bgcolor=\"#fffff0\">Distance( geom1 Geometry , geom2 Geometry [ , use_ellipsoid Boolean ] ) : Double precision<hr>");
10552   html +=
10553     wxT
10554     ("ST_Distance( geom1 Geometry , geom2 Geometry [ , use_ellipsoid Boolean ] ) : Double precision</td>");
10555   html +=
10556     wxT
10557     ("<td bgcolor=\"#f0fff0\">return the distance between geom1 and geom2</td></tr>");
10558   html +=
10559     wxT
10560     ("<tr><td bgcolor=\"#fffff0\">HausdorffDistance( geom1 Geometry , geom2 Geometry ) : Double precision<hr>");
10561   html +=
10562     wxT
10563     ("ST_HausdorffDistance( geom1 Geometry , geom2 Geometry ) : Double precision</td>");
10564   html +=
10565     wxT
10566     ("<td bgcolor=\"#f0fff0\">return the Hausdorff Distance between geom1 and geom2</td></tr>");
10567   html +=
10568     wxT
10569     ("<tr><td bgcolor=\"#fffff0\">PtDistWithin( geom1 Geometry , geom2 Geometry , range Double precision [ , use_spheroid Integer ] ) : Integer</td>");
10570   html +=
10571     wxT
10572     ("<td bgcolor=\"#f0fff0\">checks if the distance between geom1 and geom2 is within the given range.<br>");
10573   html +=
10574     wxT
10575     ("As a special case if both geoms are simple WGS84 POINTs (SRID=4326) distances are expessed in meters.</td></tr>");
10576   html +=
10577     wxT
10578     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c41\">functions implementing spatial operators</a>");
10579   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
10580   html +=
10581     wxT
10582     ("<tr><td bgcolor=\"#fffff0\">Intersection( geom1 Geometry , geom2 Geometry ) : Geometry<hr>");
10583   html +=
10584     wxT("ST_Intersection( geom1 Geometry , geom2 Geometry ) : Geometry</td>");
10585   html +=
10586     wxT
10587     ("<td bgcolor=\"#f0fff0\">return a geometric object that is the intersection of geometric objects geom1 and geom2</td></tr>");
10588   html +=
10589     wxT
10590     ("<tr><td bgcolor=\"#fffff0\">Difference( geom1 Geometry , geom2 Geometry ) : Geometry<hr>");
10591   html +=
10592     wxT("ST_Difference( geom1 Geometry , geom2 Geometry ) : Geometry</td>");
10593   html +=
10594     wxT
10595     ("<td bgcolor=\"#f0fff0\">return a geometric object that is the closure of the set difference of geom1 and geom2</td></tr>");
10596   html +=
10597     wxT
10598     ("<tr><td bgcolor=\"#fffff0\">GUnion( geom1 Geometry , geom2 Geometry ) : Geometry<hr>");
10599   html += wxT("ST_Union( geom1 Geometry , geom2 Geometry ) : Geometry</td>");
10600   html +=
10601     wxT
10602     ("<td bgcolor=\"#f0fff0\">return a geometric object that is the set union of geom1 and geom2</td></tr>");
10603   html +=
10604     wxT("<tr><td bgcolor=\"#fffff0\">GUnion( geom Geometry ) : Geometry<hr>");
10605   html += wxT("ST_Union( geom Geometry ) : Geometry</td>");
10606   html +=
10607     wxT
10608     ("<td bgcolor=\"#f0fff0\">return a geometric object that is the set union of input values<br>");
10609   html += wxT("<b><u>aggregate function</u></b></td></tr>");
10610   html +=
10611     wxT
10612     ("<tr><td bgcolor=\"#fffff0\">SymDifference( geom1 Geometry , geom2 Geometry ) : Geometry<hr>");
10613   html +=
10614     wxT("ST_SymDifference( geom1 Geometry , geom2 Geometry ) : Geometry</td>");
10615   html +=
10616     wxT
10617     ("<td bgcolor=\"#f0fff0\">return a geometric object that is the closure of the set symmetric difference of geom1 and geom2 (logical XOR of space)</td></tr>");
10618   html +=
10619     wxT
10620     ("<tr><td bgcolor=\"#fffff0\">Buffer( geom Geometry , dist Double precision ) : Geometry<hr>");
10621   html +=
10622     wxT("ST_Buffer( geom Geometry , dist Double precision ) : Geometry</td>");
10623   html +=
10624     wxT
10625     ("<td bgcolor=\"#f0fff0\">return a geometric object defined by buffering a distance d around geom, ");
10626   html +=
10627     wxT
10628     ("where dist is in the distance units for the Spatial Reference of geom</td></tr>");
10629   html +=
10630     wxT
10631     ("<tr><td bgcolor=\"#fffff0\">ConvexHull( geom Geometry ) : Geometry<hr>");
10632   html += wxT("ST_ConvexHull( geom Geometry ) : Geometry</td>");
10633   html +=
10634     wxT
10635     ("<td bgcolor=\"#f0fff0\">return a geometric object that is the convex hull of geom</td></tr>");
10636   html +=
10637     wxT
10638     ("<tr><td bgcolor=\"#fffff0\">OffsetCurve( geom Curve , radius Double precision, left_or_right Integer ) : Curve<hr>");
10639   html +=
10640     wxT
10641     ("ST_OffsetCurve( geom Curve , radius Double precision, left_or_right Integer ) : Curve</td>");
10642   html +=
10643     wxT
10644     ("<td bgcolor=\"#f0fff0\">return a geometric object representing the corresponding left- (or right-sided) offset curve<br>");
10645   html +=
10646     wxT
10647     ("NULL if returned whenever is not possible deriving an offset curve from the original geometry<br>");
10648   html +=
10649     wxT("[a single not-closed LINESTRING is expected as input]</td></tr>");
10650   html +=
10651     wxT
10652     ("<tr><td bgcolor=\"#fffff0\">SingleSidedBuffer( geom Curve , radius Double precision, left_or_right Integer ) : Curve<hr>");
10653   html +=
10654     wxT
10655     ("ST_SingleSidedBuffer( geom Curve , radius Double precision, left_or_right Integer ) : Curve</td>");
10656   html +=
10657     wxT
10658     ("<td bgcolor=\"#f0fff0\">return a geometric object representing the corresponding left- (or right-sided) single-sided buffer<br>");
10659   html +=
10660     wxT
10661     ("NULL if returned whenever is not possible deriving a single-sided buffer from the original geometry<br>");
10662   html +=
10663     wxT("[a single not-closed LINESTRING is expected as input]</td></tr>");
10664   html +=
10665     wxT
10666     ("<tr><td bgcolor=\"#fffff0\">SharedPaths( geom1 Geometry , geom2 Geometry ) : Geometry<hr>");
10667   html +=
10668     wxT("ST_SharedPaths( geom1 Geometry , geom2 Geometry ) : Geometry</td>");
10669   html +=
10670     wxT
10671     ("<td bgcolor=\"#f0fff0\">return a geometric object (of the MULTILINESTRING type) representing any common edge shared by both geometries<br>");
10672   html += wxT("NULL if returned is no common edge exists</td></tr>");
10673   html +=
10674     wxT
10675     ("<tr><td bgcolor=\"#fffff0\">Line_Interpolate_Point( line Curve , fraction Double precision ) : Point<hr>");
10676   html +=
10677     wxT
10678     ("ST_Line_Interpolate_Point( line Curve , fraction Double precision ) : Point</td>");
10679   html +=
10680     wxT
10681     ("<td bgcolor=\"#f0fff0\">return a point interpolated along a line.<br>Second argument (between 0.0 and 1.0) representing fraction");
10682   html += wxT("of total length of linestring the point has to be located.<br>");
10683   html += wxT("NULL if returned for invalid arguments</td></tr>");
10684   html +=
10685     wxT
10686     ("<tr><td bgcolor=\"#fffff0\">Line_Interpolate_Equidistant_Points( line Curve , distance Double precision ) : Point<hr>");
10687   html +=
10688     wxT
10689     ("ST_Line_Interpolate_Equidistant_Points( line Curve , distance Double precision ) : Point</td>");
10690   html +=
10691     wxT
10692     ("<td bgcolor=\"#f0fff0\">return a set of equidistant points interpolated along a line; the returned geometry ");
10693   html +=
10694     wxT
10695     ("always corresponds to a MULTIPOINT supporting the M coordinate (representing the progressive distance for each interpolated Point).<br>");
10696   html +=
10697     wxT
10698     ("Second argument represents the regular distance between interpolated points.<br>");
10699   html += wxT("NULL if returned for invalid arguments</td></tr>");
10700   html +=
10701     wxT
10702     ("<tr><td bgcolor=\"#fffff0\">Line_Locatate_Point( line Curve , point Point ) : Double precision<hr>");
10703   html +=
10704     wxT
10705     ("ST_Line_Locate_Point( line Curve , point Point ) : Double precision</td>");
10706   html +=
10707     wxT
10708     ("<td bgcolor=\"#f0fff0\">return a number (between 0.0 and 1.0) representing the location of the closest point on LineString");
10709   html += wxT("to the given Point, as a fraction of total 2d line length.<br>");
10710   html += wxT("NULL if returned for invalid arguments</td></tr>");
10711   html +=
10712     wxT
10713     ("<tr><td bgcolor=\"#fffff0\">Line_Substring( line Curve , start_fraction Double precision , end_fraction Double precision ) : Curve<hr>");
10714   html +=
10715     wxT
10716     ("ST_Line_Substring( line Curve , start_fraction Double precision , end_fraction Double precision ) : Curve</td>");
10717   html +=
10718     wxT
10719     ("<td bgcolor=\"#f0fff0\">Return a Linestring being a substring of the input one starting and ending at the given fractions of total 2d length.<br>");
10720   html +=
10721     wxT
10722     ("Second and third arguments are expected to be in the range between 0.0 and 1.0.<br>");
10723   html += wxT("NULL if returned for invalid arguments</td></tr>");
10724   html +=
10725     wxT
10726     ("<tr><td bgcolor=\"#fffff0\">ClosestPoint( geom1 Geometry , geom2 Geometry ) : Point<hr>");
10727   html +=
10728     wxT("ST_ClosestPoint( geom1 Geometry , geom2 Geometry ) : Point</td>");
10729   html +=
10730     wxT
10731     ("<td bgcolor=\"#f0fff0\">Returns the Point on geom1 that is closest to geom2.<br>");
10732   html +=
10733     wxT
10734     ("NULL is returned for invalid arguments (or if distance is ZERO)</td></tr>");
10735   html +=
10736     wxT
10737     ("<tr><td bgcolor=\"#fffff0\">ShortestLine( geom1 Geometry , geom2 Geometry ) : Curve<hr>");
10738   html +=
10739     wxT("ST_ShortestLine( geom1 Geometry , geom2 Geometry ) : Curve</td>");
10740   html +=
10741     wxT
10742     ("<td bgcolor=\"#f0fff0\">Returns the shortest line between two geometries.<br>");
10743   html +=
10744     wxT
10745     ("NULL is returned for invalid arguments (or if distance is ZERO)</td></tr>");
10746   html +=
10747     wxT
10748     ("<tr><td bgcolor=\"#fffff0\">Snap( geom1 Geometry , geom2 Geometry , tolerance Double precision ) : Geometry<hr>");
10749   html +=
10750     wxT
10751     ("ST_Snap( geom1 Geometry , geom2 Geometry , tolerance Double precision ) : Geometry</td>");
10752   html +=
10753     wxT
10754     ("<td bgcolor=\"#f0fff0\">Returns a new Geometry representing a modified geom1, so to \"snap\" vertices ");
10755   html +=
10756     wxT
10757     ("and segments to geom2 vertices; a snap distance tolerance is used to control where snapping is performed.<br>");
10758   html += wxT("NULL is returned for invalid arguments</td></tr>");
10759   html +=
10760     wxT
10761     ("<tr><td bgcolor=\"#fffff0\">LineMerge( geom Geometry ) : Geometry<hr>");
10762   html += wxT("ST_LineMerge( geom Geometry ) : Geometry</td>");
10763   html +=
10764     wxT
10765     ("<td bgcolor=\"#f0fff0\">a Geometry (actually corresponding to a LINESTRING or MULTILINESTRING) will be returned.");
10766   html +=
10767     wxT
10768     ("The input Geometry is expected to represent a LINESTRING or a MULTILINESTRING.<br>The input Geometry can be an ");
10769   html +=
10770     wxT
10771     ("arbitrary collection of sparse line fragments: this function will then try to (possibly) reassemble them into one");
10772   html += wxT("(or more) Linestring(s).<br>");
10773   html += wxT("NULL is returned for invalid arguments</td></tr>");
10774   html +=
10775     wxT
10776     ("<tr><td bgcolor=\"#fffff0\">UnaryUnion( geom Geometry ) : Geometry<hr>");
10777   html += wxT("ST_UnaryUnion( geom Geometry ) : Geometry</td>");
10778   html +=
10779     wxT
10780     ("<td bgcolor=\"#f0fff0\">Exactely the same as ST_Union, but applied to a single Geometry.<br>");
10781   html +=
10782     wxT
10783     ("(set union of elementary Geometries within a MULTI- or GEOMETRYCOLLECTION complex Geometry).<br>");
10784   html += wxT("NULL will be returned if any error is encountered</td></tr>");
10785   html +=
10786     wxT
10787     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c42\">functions for coordinate transformations</a>");
10788   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
10789   html +=
10790     wxT
10791     ("<tr><td bgcolor=\"#fffff0\">Transform( geom Geometry , newSRID Integer ) : Geometry<br>");
10792   html +=
10793     wxT("ST_Transform( geom Geometry , newSRID Integer ) : Geometry</td>");
10794   html +=
10795     wxT
10796     ("<td bgcolor=\"#f0fff0\">return a geometric object obtained by reprojecting coordinates into the Reference System identified by newSRID</td></tr>");
10797   html +=
10798     wxT
10799     ("<tr><td bgcolor=\"#fffff0\">SridFromAuthCRS( auth_name String , auth_SRID Integer ) : Integer</td>");
10800   html +=
10801     wxT
10802     ("<td bgcolor=\"#f0fff0\">return the internal SRID corresponding to auth_name and auth_SRID<br>-1 will be returned if no such CRS is defined</td></tr>");
10803   html +=
10804     wxT
10805     ("<tr><td bgcolor=\"#fffff0\">ShiftCoords( geom Geometry , shiftX Double precision , shiftY Double precision ) : Geometry<hr>");
10806   html +=
10807     wxT
10808     ("ShiftCoordinates( geom Geometry , shiftX Double precision , shiftY Double precision ) : Geometry</td>");
10809   html +=
10810     wxT
10811     ("<td bgcolor=\"#f0fff0\">return a geometric object obtained by translating coordinates according to shiftX and shiftY values</td></tr>");
10812   html +=
10813     wxT
10814     ("<tr><td bgcolor=\"#fffff0\">ST_Translate( geom Geometry , shiftX Double precision , shiftY Double precision , shiftZ Double Precision ) : Geometry</td>");
10815   html +=
10816     wxT
10817     ("<td bgcolor=\"#f0fff0\">return a geometric object obtained by translating coordinates according to shiftX, shiftY and shiftZ values</td></tr>");
10818   html +=
10819     wxT
10820     ("<tr><td bgcolor=\"#fffff0\">ST_Shift_Longitude( geom Geometry ) : Geometry</td>");
10821   html +=
10822     wxT
10823     ("<td bgcolor=\"#f0fff0\">return a geometric object obtained by translating any negative longitude by 360.<hr>");
10824   html +=
10825     wxT
10826     ("Only meaningful for geographic (longitude/latitude) coordinates.</td></tr>");
10827   html +=
10828     wxT
10829     ("<tr><td bgcolor=\"#fffff0\">NormalizeLonLat( geom Geometry ) : Geometry</td>");
10830   html +=
10831     wxT
10832     ("<td bgcolor=\"#f0fff0\">return a geometric object obtained by normalizing any longitude in the range");
10833   html += wxT("[-180 / +180] and any latitude in the range [-90 / + 90].<hr>");
10834   html +=
10835     wxT
10836     ("Only meaningful for geographic (longitude/latitude) coordinates.</td></tr>");
10837   html +=
10838     wxT
10839     ("<tr><td bgcolor=\"#fffff0\">ScaleCoords( geom Geometry , scaleX Double precision [ , scaleY Double precision ] ) : Geometry<hr>");
10840   html +=
10841     wxT
10842     ("ScaleCoordinates( geom Geometry , scaleX Double precision [ , scaleY Double precision ] ) : Geometry</td>");
10843   html +=
10844     wxT
10845     ("<td bgcolor=\"#f0fff0\">return a geometric object obtained by scaling coordinates according to scaleX and scaleY values<br>");
10846   html +=
10847     wxT
10848     ("if only one scale factor is specified, then an isotropic scaling occurs [i.e. the same scale factor is applied to both axis]");
10849   html +=
10850     wxT
10851     ("otherwise an anisotropic scaling occurs [i.e. each axis is scaled according to its own scale factor]</td></tr>");
10852   html +=
10853     wxT
10854     ("<tr><td bgcolor=\"#fffff0\">RotateCoords( geom Geometry , angleInDegrees Double precision ) : Geometry<hr>");
10855   html +=
10856     wxT
10857     ("RotateCoordinates( geom Geometry , angleInDegrees Double precision ) : Geometry</td>");
10858   html +=
10859     wxT
10860     ("<td bgcolor=\"#f0fff0\">return a geometric object obtained by rotating coordinates according to angleInDegrees value<br>");
10861   html += wxT("Positive angle = clockwise rotation</td></tr>");
10862   html +=
10863     wxT
10864     ("<tr><td bgcolor=\"#fffff0\">ReflectCoords( geom Geometry , xAxis Integer , yAxis Integer ) : Geometry<hr>");
10865   html +=
10866     wxT
10867     ("ReflectCoordinates( geom Geometry , xAxis Integer , yAxis Integer ) : Geometry</td>");
10868   html +=
10869     wxT
10870     ("<td bgcolor=\"#f0fff0\">return a geometric object obtained by reflecting coordinates according to xAxis and yAxis switches<br>");
10871   html +=
10872     wxT
10873     ("i.e. if xAxis is 0 (FALSE), then x-coordinates remains untouched; otherwise x-coordinates will be reflected</td></tr>");
10874   html +=
10875     wxT
10876     ("<tr><td bgcolor=\"#fffff0\">SwapCoords( geom Geometry ) : Geometry<hr>SwapCoordinates( geom Geometry ) : Geometry</td>");
10877   html +=
10878     wxT
10879     ("<td bgcolor=\"#f0fff0\">return a geometric object obtained by swapping x- and y-coordinates</td></tr>");
10880   html +=
10881     wxT
10882     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c43\">functions for Spatial-MetaData and Spatial-Index handling</a>");
10883   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
10884   html += wxT
10885     ("<tr><td bgcolor=\"#fffff0\">InitSpatialMetaData( void ) : Integer<hr>");
10886   html += wxT("InitSpatialMetaData( transaction Integer ) : Integer<hr>");
10887   html += wxT("InitSpatialMetaData( mode String ) : Integer<hr>");
10888   html +=
10889     wxT
10890     ("InitSpatialMetaData( transaction Integer , mode String ) : Integer</td>");
10891   html +=
10892     wxT
10893     ("<td bgcolor=\"#f0fff0\">Creates the geometry_columns and spatial_ref_sys metadata tables");
10894   html +=
10895     wxT
10896     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE<hr>");
10897   html +=
10898     wxT
10899     ("the first form (no args) will automatically populate spatial_ref_sys inserting any possible ESPG SRID definition<br>");
10900   html +=
10901     wxT
10902     ("if the arg 'WGS84' (alias 'WGS84_ONLY') is specified, then only WGS84-releated EPSG SRIDs will be inserted<br>");
10903   html +=
10904     wxT
10905     ("if the arg 'NONE' (alias 'EMPTY') is specified, no EPSG SRID will be inserted at all</td></tr>");
10906   html +=
10907     wxT
10908     ("<tr><td bgcolor=\"#fffff0\">InsertEpsgSrid( srid <i>Integer</i> ) : Integer</td>");
10909   html +=
10910     wxT
10911     ("<td bgcolor=\"#f0fff0\">Attempts to insert into spatial_ref_sys the EPSG definition uniquely identified by srid<br>");
10912   html +=
10913     wxT
10914     ("[the corresponding EPSG SRID definition will be copied from the inlined dataset defined in libspatialite<hr>");
10915   html +=
10916     wxT
10917     ("the return type is Integer, with a return value of 1 for success or 0 for failure</td></tr>");
10918   html +=
10919     wxT
10920     ("<tr><td bgcolor=\"#fffff0\">AddGeometryColumn( table String , column String , srid Integer , geom_type String , dimension String [ , not_null Integer ] ) : Integer</td>");
10921   html +=
10922     wxT
10923     ("<td bgcolor=\"#f0fff0\">Creates a new geometry column updating the Spatial Metadata tables and creating any required trigger in order to enforce constraints<br>");
10924   html +=
10925     wxT
10926     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
10927   html +=
10928     wxT
10929     ("<tr><td bgcolor=\"#fffff0\">RecoverGeometryColumn( table String , column String , srid Integer , geom_type String , dimension String ) : Integer</td>");
10930   html +=
10931     wxT
10932     ("<td bgcolor=\"#f0fff0\">Validates an existing ordinary column in order to possibly transform it in a real geometry column, ");
10933   html +=
10934     wxT
10935     ("thus updating the Spatial Metadata tables and creating any required trigger in order to enforce constraints<br>");
10936   html +=
10937     wxT
10938     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
10939   html +=
10940     wxT
10941     ("<tr><td bgcolor=\"#fffff0\">DiscardGeometryColumn( table String , column String ) : Integer</td>");
10942   html +=
10943     wxT
10944     ("<td bgcolor=\"#f0fff0\">Removes a geometry column from Spatial MetaData tables and drops any related trigger<br>");
10945   html +=
10946     wxT
10947     ("the column itself still continues to exist untouched as an ordinary, unconstrained column<br>");
10948   html +=
10949     wxT
10950     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
10951   html +=
10952     wxT
10953     ("<tr><td bgcolor=\"#fffff0\">RegisterVirtualGeometry( table String ) : Integer</td>");
10954   html +=
10955     wxT
10956     ("<td bgcolor=\"#f0fff0\">Registers a VirtualShape table into Spatial MetaData tables; the VirtualShape table should be already created in some previous steo.<br>");
10957   html +=
10958     wxT
10959     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
10960   html +=
10961     wxT
10962     ("<tr><td bgcolor=\"#fffff0\">DropVirtualGeometry( table String ) : Integer</td>");
10963   html +=
10964     wxT
10965     ("<td bgcolor=\"#f0fff0\">Removes a VirtualShape table from Spatial MetaData tables, dropping the VirtualShape table as well.<br>");
10966   html +=
10967     wxT
10968     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
10969   html +=
10970     wxT
10971     ("<tr><td bgcolor=\"#fffff0\">CreateSpatialIndex( table String , column String ) : Integer</td>");
10972   html +=
10973     wxT
10974     ("<td bgcolor=\"#f0fff0\">Builds an RTree Spatial Index on a geometry column, ");
10975   html +=
10976     wxT
10977     ("creating any required trigger required in order to enforce full data coherency between the main table and Spatial Index<br>");
10978   html +=
10979     wxT
10980     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
10981   html +=
10982     wxT
10983     ("<tr><td bgcolor=\"#fffff0\">DisableSpatialIndex( table String , column String ) : Integer</td>");
10984   html +=
10985     wxT
10986     ("<td bgcolor=\"#f0fff0\">Disables an RTree Spatial Index, removing any related trigger<br>");
10987   html +=
10988     wxT
10989     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
10990   html +=
10991     wxT("<tr><td bgcolor=\"#fffff0\">CheckSpatialIndex( void ) : Integer<hr>");
10992   html +=
10993     wxT("CheckSpatialIndex( table String , column String ) : Integer</td>");
10994   html +=
10995     wxT
10996     ("<td bgcolor=\"#f0fff0\">Checks an RTree Spatial Index for validity and consistency<br>");
10997   html +=
10998     wxT
10999     ("- if no arguments are passed, then any RTree defined into geometry_columns will be checked<br>");
11000   html +=
11001     wxT
11002     ("- otherwise only the RTree corresponding to table and column will be checked<br>");
11003   html +=
11004     wxT
11005     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
11006   html +=
11007     wxT
11008     ("<tr><td bgcolor=\"#fffff0\">RecoverSpatialIndex( [ no_check Integer ] ) : Integer<hr>");
11009   html +=
11010     wxT
11011     ("RecoverSpatialIndex( table String , column String [ , no_check Integer ] ) : Integer</td>");
11012   html +=
11013     wxT
11014     ("<td bgcolor=\"#f0fff0\">Recovers a (possibly broken) RTree Spatial Index<br>");
11015   html +=
11016     wxT
11017     ("- if no arguments are passed, then any RTree defined into geometry_columns will be recovered<br>");
11018   html +=
11019     wxT
11020     ("- otherwise only the RTree corresponding to table and column will be recovered<br>");
11021   html +=
11022     wxT("- the optional argument no_check will be interpreted as follows:<br>");
11023   html +=
11024     wxT
11025     ("&nbsp;&nbsp;* if no_check = FALSE (default) the RTree will be checked first: ");
11026   html += wxT("and only an invalid RTree will be then actually rebuilt<br>");
11027   html +=
11028     wxT
11029     ("&nbsp;&nbsp;* if no_check = TRUE the RTree will be unconditionally rebuilt from scratch anyway<br>");
11030   html +=
11031     wxT
11032     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
11033   html +=
11034     wxT
11035     ("<tr><td bgcolor=\"#fffff0\">UpdateLayerStatistics( void ) : Integer<hr>");
11036   html +=
11037     wxT
11038     ("UpdateLayerStatistics( table String [, column String ] ) : Integer</td>");
11039   html +=
11040     wxT
11041     ("<td bgcolor=\"#f0fff0\">Updates the internal Layer Statistics [Feature Count and Total Extent]<br>");
11042   html +=
11043     wxT
11044     ("- if no arguments are passed, then internal statics will be updated for any possible Geometry Column ");
11045   html += wxT("defined in the current DB<br>");
11046   html +=
11047     wxT
11048     ("- otherwise statistics will be updated only for Geometry Columns corresponding to the given table<br>");
11049   html +=
11050     wxT
11051     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
11052   html +=
11053     wxT
11054     ("<tr><td bgcolor=\"#fffff0\">GetLayerExtent( table String [ , column String [ , mode Boolean] ] ) : Geometry</td>");
11055   html +=
11056     wxT
11057     ("<td bgcolor=\"#f0fff0\">Return the Envelope corresponding to the Total Extent of some Layer; ");
11058   html +=
11059     wxT
11060     ("if the Table/Layer only contains a single Geometry column passing the column name isn't strictly required.<br>");
11061   html +=
11062     wxT
11063     ("NULL will be returned if any error occurs or if the required table isn't a Layer.</td></tr>");
11064   html +=
11065     wxT
11066     ("<tr><td bgcolor=\"#fffff0\">CreateTopologyTables( SRID Integer , dims String ) : Integer<hr>");
11067   html +=
11068     wxT
11069     ("CreateTopologyTables( prefix String , SRID Integer , dims String ) : Integer</td>");
11070   html +=
11071     wxT("<td bgcolor=\"#f0fff0\">Creates a set of <b>Topology</b> tables.<br>");
11072   html +=
11073     wxT
11074     ("<ul><li>the SRIDargument is mandatory</li><li>the dims argument must be 'XY' or 'XYZ': 2 or 3 are valid aliases</li>");
11075   html +=
11076     wxT
11077     ("<li>the optionalargument prefix can be used to support more Topology sets on the same DB: ");
11078   html +=
11079     wxT
11080     ("if omitted a \"topo_\" prefix will be assumed by default</li></ul><hr>");
11081   html +=
11082     wxT
11083     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE (failure).</td></tr>");
11084   html +=
11085     wxT
11086     ("<tr><td bgcolor=\"#fffff0\">CreateRasterCoveragesTable( void ) : Integer</td>");
11087   html +=
11088     wxT
11089     ("<td bgcolor=\"#f0fff0\">Creates the <b>raster_coverages</b> table required by RasterLite-2<hr>");
11090   html +=
11091     wxT
11092     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE (failure).</td></tr>");
11093   html +=
11094     wxT
11095     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c43style\">functions supporting SLD/SE Styled Layers</a>");
11096   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
11097   html +=
11098     wxT("<tr><td bgcolor=\"#fffff0\">CreateStylingTables( ) : Integer<hr>");
11099   html += wxT("CreateStylingTables( relaxed Integer ) : Integer</td>");
11100   html +=
11101     wxT
11102     ("<td bgcolor=\"#f0fff0\">Creates a set of tables supporting <b>SLD/SE Styled Layers</b>.<br>");
11103   html +=
11104     wxT
11105     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
11106   html +=
11107     wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
11108   html +=
11109     wxT
11110     ("<tr><td bgcolor=\"#fffff0\">RegisterExternalGraphic( xlink_href String , resource BLOB ) : Integer<hr>");
11111   html +=
11112     wxT
11113     ("RagisterExternalGraphic( xlink_href String , resource BLOB , title String , abstract String , file_name String ) : Integer</td>");
11114   html +=
11115     wxT
11116     ("<td bgcolor=\"#f0fff0\">Inserts (or updates) an <b>External Graphic Resource</b>.<br>");
11117   html +=
11118     wxT
11119     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
11120   html +=
11121     wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
11122   html +=
11123     wxT
11124     ("<tr><td bgcolor=\"#fffff0\">RegisterVectorStyledLayer( f_table_name String , f_geometry_column String , style BLOB ) : Integer<hr>");
11125   html +=
11126     wxT
11127     ("RegisterVectorStyledLayer( f_table_name String , f_geometry_column String , style_id Integer , style BLOB ) : Integer</td>");
11128   html +=
11129     wxT
11130     ("<td bgcolor=\"#f0fff0\">Inserts (or updates) a <b>Vector Styled Layer</b> definition.<br>");
11131   html +=
11132     wxT
11133     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
11134   html +=
11135     wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
11136   html +=
11137     wxT
11138     ("<tr><td bgcolor=\"#fffff0\">RegisterRasterStyledLayer( coverage_name String , style BLOB ) : Integer<hr>");
11139   html +=
11140     wxT
11141     ("RegisterRasterStyledLayer( coverage_name String , style_id Integer , style BLOB ) : Integer</td>");
11142   html +=
11143     wxT
11144     ("<td bgcolor=\"#f0fff0\">Inserts (or updates) a <b>Raster Styled Layer</b> definition.<br>");
11145   html +=
11146     wxT
11147     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
11148   html +=
11149     wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
11150   html +=
11151     wxT
11152     ("<tr><td bgcolor=\"#fffff0\">RegisterStyledGroup( group_name String , f_table_name String , f_geometry_colum String , style_id Integer [ , paint_order Integer ] ) : Integer<hr>");
11153   html +=
11154     wxT
11155     ("RegisterStyledGroup( group_name String, coverage_name String , style_id Integer [ , paint_order Integer ] ) : Integer</td>");
11156   html +=
11157     wxT
11158     ("<td bgcolor=\"#f0fff0\">Inserts (or updates) a <b>Styled Group</b> definition.<br>");
11159   html +=
11160     wxT
11161     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
11162   html +=
11163     wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
11164   html +=
11165     wxT
11166     ("<tr><td bgcolor=\"#fffff0\">SetStyledGroupInfos( group_name String , title String , abstract String ) : Integer</td>");
11167   html +=
11168     wxT
11169     ("<td bgcolor=\"#f0fff0\">Inserts (or updates) the descriptive infos associated to a <b>Styled Group</b><br>");
11170   html +=
11171     wxT
11172     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
11173   html +=
11174     wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
11175   html +=
11176     wxT
11177     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c43isometa\">functions implementing ISO Metadata</a>");
11178   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
11179   html +=
11180     wxT("<tr><td bgcolor=\"#fffff0\">CreateIsoMetadataTables( ) : Integer<hr>");
11181   html += wxT("CreateIsoMetadataTables( relaxed Integer ) : Integer</td>");
11182   html +=
11183     wxT
11184     ("<td bgcolor=\"#f0fff0\">Creates a set of tables supporting <b>ISO Metadata</b>.<br>");
11185   html +=
11186     wxT
11187     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
11188   html +=
11189     wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
11190   html +=
11191     wxT
11192     ("<tr><td bgcolor=\"#fffff0\">RegisterIsoMetadata( scope String , metadata BLOB ) : Integer<hr>");
11193   html +=
11194     wxT
11195     ("RegisterIsoMetadata( scope String , metadata BLOB , id Integer ) : Integer<hr>");
11196   html +=
11197     wxT
11198     ("RagisterIsoMetadata( scope String , metadata BLOB , fileIdentifier String ) : Integer</td>");
11199   html +=
11200     wxT
11201     ("<td bgcolor=\"#f0fff0\">Inserts (or updates) an <b>ISO Metadata</b> definition.<br>");
11202   html +=
11203     wxT
11204     ("The first form (two arguments only) always performs an INSERT; if one the optional arguments \"id\" or \"fileIdentifier\" an UPDATE could be eventually performed if a corresponding metadata row is already defined.<br>");
11205   html +=
11206     wxT
11207     ("the return type is Integer, with a return value of 1 for TRUE (success) or 0 for FALSE ");
11208   html +=
11209     wxT("(failure): -1 will be returned on invalid argumentes.</td></tr>");
11210   html +=
11211     wxT
11212     ("<tr><td bgcolor=\"#fffff0\">GetIsoMetadataId( fileIdentifier String ) : Integer</td>");
11213   html +=
11214     wxT
11215     ("<td bgcolor=\"#f0fff0\">Return the unique \"id\" corresponding to the ISO Metadata definition identified by <b>fileIdentifier</b>.<hr>");
11216   html +=
11217     wxT
11218     ("If no corresponding ISO Metadata definition exists, this function will always return ZERO; -1 will be returned for invalid arguments.</td></tr>");
11219   html +=
11220     wxT
11221     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c43fdo\">functions implementing FDO/OGR compatibily</a>");
11222   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
11223   html +=
11224     wxT
11225     ("<tr><td bgcolor=\"#fffff0\">CheckSpatialMetaData( void ) : Integer</td>");
11226   html +=
11227     wxT
11228     ("<td bgcolor=\"#f0fff0\">Checks the Spatial Metadata type, then returning:<br>");
11229   html +=
11230     wxT
11231     ("<b>0</b> if the <i>geometry_columns</i> and <i>spatial_ref_sys</i> table does not exist, ");
11232   html +=
11233     wxT
11234     ("or if their actual layout doesn't corresponds to any known implementation<br>");
11235   html +=
11236     wxT
11237     ("<b>1</b> if both tables exist, and their layout is the one used by <i>SpatiaLite legacy</i> (older versions including 3.0.1)<br>");
11238   html +=
11239     wxT
11240     ("<b>2</b> if both tables exist, and their layout is the one used by <i>FDO/OGR</i><br>");
11241   html +=
11242     wxT
11243     ("<b>3</b> if both tables exist, and their layout is the one currently used by <i>SpatiaLite</i> (3.1.0 or any subsequent version)</td></tr>");
11244   html +=
11245     wxT("<tr><td bgcolor=\"#fffff0\">AutoFDOStart( void ) : Integer</td>");
11246   html +=
11247     wxT
11248     ("<td bgcolor=\"#f0fff0\">This function will inspect the Spatial Metadata, then automatically creating/refreshing a <i>VirtualFDO</i>");
11249   html +=
11250     wxT
11251     (" wrapper for each FDO/OGR geometry table<br>the return type is Integer [how many VirtualFDO tables have been created]</td></tr>");
11252   html += wxT("<tr><td bgcolor=\"#fffff0\">AutoFDOStop( void ) : Integer</td>");
11253   html +=
11254     wxT
11255     ("<td bgcolor=\"#f0fff0\">This function will inspect the Spatial Metadata, then automatically destroying any <i>VirtualFDO</i>");
11256   html +=
11257     wxT
11258     (" wrapper found<br>the return type is Integer [how many VirtualFDO tables have been destroyed]</td></tr>");
11259   html +=
11260     wxT
11261     ("<tr><td bgcolor=\"#fffff0\">InitFDOSpatialMetaData( void ) : Integer</td>");
11262   html +=
11263     wxT
11264     ("<td bgcolor=\"#f0fff0\">Creates the geometry_columns and spatial_ref_sys metadata tables");
11265   html +=
11266     wxT
11267     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE<br>");
11268   html +=
11269     wxT
11270     ("<u>Please note:</u> Spatial Metadata created using this function will have the FDO/OGR layout, and not the SpatiaLite's own</td></tr>");
11271   html +=
11272     wxT
11273     ("<tr><td bgcolor=\"#fffff0\">AddFDOGeometryColumn( table String , column String , srid Integer , geom_type String , dimension Integer , geometry_type String ) : Integer</td>");
11274   html +=
11275     wxT
11276     ("<td bgcolor=\"#f0fff0\">Creates a new geometry column updating the FDO/OGR Spatial Metadata tables<br>");
11277   html +=
11278     wxT
11279     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
11280   html +=
11281     wxT
11282     ("<tr><td bgcolor=\"#fffff0\">RecoverFDOGeometryColumn( table String , column String , srid Integer , geom_type String , dimension Integer , geometry_type String ) : Integer</td>");
11283   html +=
11284     wxT
11285     ("<td bgcolor=\"#f0fff0\">Validates an existing ordinary column in order to possibly transform it in a real geometry column, ");
11286   html += wxT("thus updating the FDO/OGR Spatial Metadata tables<br>");
11287   html +=
11288     wxT
11289     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
11290   html +=
11291     wxT
11292     ("<tr><td bgcolor=\"#fffff0\">DiscardFDOGeometryColumn( table String , column String ) : Integer</td>");
11293   html +=
11294     wxT
11295     ("<td bgcolor=\"#f0fff0\">Removes a geometry column from FDO/OGR Spatial MetaData tables<br>");
11296   html +=
11297     wxT
11298     ("the column itself still continues to exist untouched as an ordinary column<br>");
11299   html +=
11300     wxT
11301     ("the return type is Integer, with a return value of 1 for TRUE or 0 for FALSE</td></tr>");
11302   html +=
11303     wxT
11304     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c44\">functions for MbrCache-based queries</a>");
11305   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
11306   html +=
11307     wxT
11308     ("<tr><td bgcolor=\"#fffff0\">FilterMbrWithin( x1 Double precision , y1 Double precision , x2 Double precision , y2 Double precision  ) : Integer</td>");
11309   html +=
11310     wxT
11311     ("<td bgcolor=\"#f0fff0\">Retrieves from an MbrCache any entity whose MBR falls within");
11312   html +=
11313     wxT
11314     (" the rectangle identified by extreme points x1 y1 and x2 y2</td></tr>");
11315   html +=
11316     wxT
11317     ("<tr><td bgcolor=\"#fffff0\">FilterMbrContains( x1 Double precision , y1 Double precision , x2 Double precision , y2 Double precision  ) : Integer</td>");
11318   html +=
11319     wxT
11320     ("<td bgcolor=\"#f0fff0\">Retrieves from an MbrCache any entity whose MBR contains");
11321   html +=
11322     wxT
11323     (" the rectangle identified by extreme points x1 y1 and x2 y2</td></tr>");
11324   html +=
11325     wxT
11326     ("<tr><td bgcolor=\"#fffff0\">FilterMbrIntersects( x1 Double precision , y1 Double precision , x2 Double precision , y2 Double precision  ) : Integer</td>");
11327   html +=
11328     wxT
11329     ("<td bgcolor=\"#f0fff0\">Retrieves from an MbrCache any entity whose MBR intersects");
11330   html +=
11331     wxT
11332     (" the rectangle identified by extreme points x1 y1 and x2 y2</td></tr>");
11333   html +=
11334     wxT
11335     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"c45\">functions for R*Tree-based queries (Geometry Callbacks)</a>");
11336   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
11337   html +=
11338     wxT
11339     ("<tr><td bgcolor=\"#fffff0\">RTreeWithin( x1 Double precision , y1 Double precision , x2 Double precision , y2 Double precision  ) : Integer</td>");
11340   html +=
11341     wxT
11342     ("<td bgcolor=\"#f0fff0\">*DEPRECATED* (alias-name for RTreeIntersects)</td></tr>");
11343   html +=
11344     wxT
11345     ("<tr><td bgcolor=\"#fffff0\">RTreeContains( x1 Double precision , y1 Double precision , x2 Double precision , y2 Double precision  ) : Integer</td>");
11346   html +=
11347     wxT
11348     ("<td bgcolor=\"#f0fff0\">*DEPRECATED* (alias-name for RTreeIntersects)</td></tr>");
11349   html +=
11350     wxT
11351     ("<tr><td bgcolor=\"#fffff0\">RTreeIntersects( x1 Double precision , y1 Double precision , x2 Double precision , y2 Double precision  ) : Integer</td>");
11352   html +=
11353     wxT
11354     ("<td bgcolor=\"#f0fff0\">Retrieves from an R*Tree any entity whose MBR intersects");
11355   html +=
11356     wxT
11357     (" the rectangle identified by extreme points x1 y1 and x2 y2</td></tr>");
11358   html +=
11359     wxT
11360     ("<tr><td bgcolor=\"#fffff0\">RTreeDistWithin( x Double precision , y Double precision , radius Double precision ) : Integer</td>");
11361   html +=
11362     wxT
11363     ("<td bgcolor=\"#f0fff0\">Retrieves from an R*Tree any entity whose MBR intersects");
11364   html +=
11365     wxT
11366     (" the square square circumscribed on the given circle  (x y center, radius)</td></tr>");
11367   html +=
11368     wxT
11369     ("<tr><td align=\"center\" bgcolor=\"#e0ffe0\" colspan=\"2\"><a name=\"xmlBlob\">SQL functions supporting XmlBLOB</a>");
11370   html += wxT("<br><a href=\"#index\">back to index</a></td></tr>");
11371   html +=
11372     wxT
11373     ("<tr><td bgcolor=\"#fffff0\">XB_Create( xmlPayload BLOB ) : XmlBLOB<hr>");
11374   html +=
11375     wxT("XB_Create( xmlPayload BLOB , compressed Boolean  ) : XmlBLOB<hr>");
11376   html +=
11377     wxT
11378     ("XB_Create( xmlPayload BLOB , compressed Boolean ,  schemaURI Text ) : XmlBLOB<hr>");
11379   html +=
11380     wxT
11381     ("XB_Create( xmlPayload BLOB , compressed Boolean , internalSchemaURI Boolean  ) : XmlBLOB</td>");
11382   html +=
11383     wxT
11384     ("<td bgcolor=\"#f0fff0\">Construct an XmlBLOB object starting from an XmlDocument.<hr>");
11385   html +=
11386     wxT
11387     ("NULL will be returned for not well-formed XmlDocuments, or when XML validation is required but XmlDocument fails to pass validation for any reason.</td></tr>");
11388   html +=
11389     wxT
11390     ("<tr><td bgcolor=\"#fffff0\">XB_GetPayload( xmlObject BLOB [ , indent Integer ]  ) : String</td>");
11391   html +=
11392     wxT
11393     ("<td bgcolor=\"#f0fff0\">Extracts a generic BLOB from an XmlBLOB object, exactly corresponding to the original XmlDocument and fully preserving the original character encoding.</td></tr>");
11394   html +=
11395     wxT
11396     ("<tr><td bgcolor=\"#fffff0\">XB_GetDocument( xmlObject BLOB [ , indent Integer ]  ) : String</td>");
11397   html +=
11398     wxT
11399     ("<td bgcolor=\"#f0fff0\">Extracts an XmlDocument from an XmlBLOB object; the returned XmlDocument will always be UTF-8 encoded (TEXT), irrespectively from the original internal encoding declaration.</td></tr>");
11400   html +=
11401     wxT
11402     ("<tr><td bgcolor=\"#fffff0\">XB_SchemaValidate( xmlObject BLOB , schemaURI Text  [ , compressed Boolean ]  ) : XmlBLOB<hr>");
11403   html +=
11404     wxT
11405     ("XB_SchemaValidate( xmlObject BLOB , internalSchemaURI Boolean  [ , compressed Boolean ]  ) : XmlBLOB</td>");
11406   html +=
11407     wxT
11408     ("<td bgcolor=\"#f0fff0\">Construct an XML validated XmlBLOB object starting from an XmlDocument.<hr>");
11409   html +=
11410     wxT
11411     ("NULL will be returned if the input XmlBLOB fails to pass validation for any reason.</td></tr>");
11412   html +=
11413     wxT
11414     ("<tr><td bgcolor=\"#fffff0\">XB_Compress( xmlObject BLOB ) : XmlBLOB</td>");
11415   html +=
11416     wxT
11417     ("<td bgcolor=\"#f0fff0\">A new compressed XmlBLOB object will be returned.</td></tr>");
11418   html +=
11419     wxT
11420     ("<tr><td bgcolor=\"#fffff0\">XB_Uncompress( xmlObject BLOB ) : XmlBLOB</td>");
11421   html +=
11422     wxT
11423     ("<td bgcolor=\"#f0fff0\">A new uncompressed XmlBLOB object will be returned.</td></tr>");
11424   html +=
11425     wxT
11426     ("<tr><td bgcolor=\"#fffff0\">XB_IsValid( xmlObject BLOB ) : Integer</td>");
11427   html +=
11428     wxT
11429     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, ");
11430   html +=
11431     wxT
11432     ("and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.</td></tr>");
11433   html +=
11434     wxT
11435     ("<tr><td bgcolor=\"#fffff0\">XB_IsCompressed( xmlObject BLOB ) : Integer</td>");
11436   html +=
11437     wxT
11438     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, ");
11439   html +=
11440     wxT
11441     ("and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.</td></tr>");
11442   html +=
11443     wxT
11444     ("<tr><td bgcolor=\"#fffff0\">XB_IsSchemaValidated( xmlObject BLOB ) : Integer</td>");
11445   html +=
11446     wxT
11447     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, ");
11448   html +=
11449     wxT
11450     ("and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.</td></tr>");
11451   html +=
11452     wxT
11453     ("<tr><td bgcolor=\"#fffff0\">XB_IsIsoMetadata( xmlObject BLOB ) : Integer</td>");
11454   html +=
11455     wxT
11456     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, ");
11457   html +=
11458     wxT
11459     ("and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.</td></tr>");
11460   html +=
11461     wxT
11462     ("<tr><td bgcolor=\"#fffff0\">XB_IsSldSeVectorStyle( xmlObject BLOB ) : Integer</td>");
11463   html +=
11464     wxT
11465     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, ");
11466   html +=
11467     wxT
11468     ("and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.</td></tr>");
11469   html +=
11470     wxT
11471     ("<tr><td bgcolor=\"#fffff0\">XB_IsSldSeRasterStyle( xmlObject BLOB ) : Integer</td>");
11472   html +=
11473     wxT
11474     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, ");
11475   html +=
11476     wxT
11477     ("and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.</td></tr>");
11478   html +=
11479     wxT
11480     ("<tr><td bgcolor=\"#fffff0\">XB_IsSvg( xmlObject BLOB ) : Integer</td>");
11481   html +=
11482     wxT
11483     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, ");
11484   html +=
11485     wxT
11486     ("and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.</td></tr>");
11487   html +=
11488     wxT
11489     ("<tr><td bgcolor=\"#fffff0\">XB_GetDocumentSize( xmlObject BLOB ) : Integer</td>");
11490   html +=
11491     wxT
11492     ("<td bgcolor=\"#f0fff0\">Will return the size in bytes of the corresponding uncompressed XmlDocument.</td></tr>");
11493   html +=
11494     wxT
11495     ("<tr><td bgcolor=\"#fffff0\">XB_GetEncoding( xmlObject BLOB ) : String</td>");
11496   html +=
11497     wxT
11498     ("<td bgcolor=\"#f0fff0\">Will return the character encoding internally declared by the XmlDocument corresponding to the input XmlBLOB.</td></tr>");
11499   html +=
11500     wxT
11501     ("<tr><td bgcolor=\"#fffff0\">XB_GetSchemaURI( xmlObject BLOB ) : String</td>");
11502   html +=
11503     wxT
11504     ("<td bgcolor=\"#f0fff0\">Will return the Schema URI effectively used to validate an XmlBLOB.</td></tr>");
11505   html +=
11506     wxT
11507     ("<tr><td bgcolor=\"#fffff0\">XB_GetInternalSchemaURI( xmlPayload BLOB ) : String</td>");
11508   html +=
11509     wxT
11510     ("<td bgcolor=\"#f0fff0\">Will return the Schema URI internally declared by the input XmlDocument.</td></tr>");
11511   html +=
11512     wxT
11513     ("<tr><td bgcolor=\"#fffff0\">XB_GetFileId( xmlObject BLOB ) : String</td>");
11514   html +=
11515     wxT
11516     ("<td bgcolor=\"#f0fff0\">Will return the FileId defined within the XmlBLOB (if any).</td></tr>");
11517   html +=
11518     wxT
11519     ("<tr><td bgcolor=\"#fffff0\">XB_SetFileId( xmlObject BLOB , fileId String ) : XmlBLOB</td>");
11520   html +=
11521     wxT
11522     ("<td bgcolor=\"#f0fff0\">Will return a new XmlBLOB by replacing the FileIdentifier value.</td></tr>");
11523   html +=
11524     wxT
11525     ("<tr><td bgcolor=\"#fffff0\">XB_AddFileId( xmlObject BLOB , fileId String , IdNameSpacePrefix String , IdNameSpaceURI String , CsNameSpacePrefix String , CsNameSpaceURI String ) : XmlBLOB</td>");
11526   html +=
11527     wxT
11528     ("<td bgcolor=\"#f0fff0\">Will return a new XmlBLOB by inserting a FileIdentifier value.</td></tr>");
11529   html +=
11530     wxT
11531     ("<tr><td bgcolor=\"#fffff0\">XB_GetParentId( xmlObject BLOB ) : String</td>");
11532   html +=
11533     wxT
11534     ("<td bgcolor=\"#f0fff0\">Will return the ParentId defined within the XmlBLOB (if any).</td></tr>");
11535   html +=
11536     wxT
11537     ("<tr><td bgcolor=\"#fffff0\">XB_SetParentId( xmlObject BLOB , parentId String ) : XmlBLOB</td>");
11538   html +=
11539     wxT
11540     ("<td bgcolor=\"#f0fff0\">Will return a new XmlBLOB by replacing the ParentIdentifier value.</td></tr>");
11541   html +=
11542     wxT
11543     ("<tr><td bgcolor=\"#fffff0\">XB_AddParentId( xmlObject BLOB , parentId String , IdNameSpacePrefix String , IdNameSpaceURI String , CsNameSpacePrefix String , CsNameSpaceURI String ) : XmlBLOB</td>");
11544   html +=
11545     wxT
11546     ("<td bgcolor=\"#f0fff0\">Will return a new XmlBLOB by inserting a ParentIdentifier value.</td></tr>");
11547   html +=
11548     wxT
11549     ("<tr><td bgcolor=\"#fffff0\">XB_GetTitle( xmlObject BLOB ) : String</td>");
11550   html +=
11551     wxT
11552     ("<td bgcolor=\"#f0fff0\">Will return the Title defined within the XmlBLOB (if any).</td></tr>");
11553   html +=
11554     wxT
11555     ("<tr><td bgcolor=\"#fffff0\">XB_GetAbstract( xmlObject BLOB ) : String</td>");
11556   html +=
11557     wxT
11558     ("<td bgcolor=\"#f0fff0\">Will return the Abstract defined within the XmlBLOB (if any).</td></tr>");
11559   html +=
11560     wxT
11561     ("<tr><td bgcolor=\"#fffff0\">XB_GetGeometry( xmlObject BLOB ) : Geometry</td>");
11562   html +=
11563     wxT
11564     ("<td bgcolor=\"#f0fff0\">Will return the Geometry defined within the XmlBLOB (if any).</td></tr>");
11565   html +=
11566     wxT
11567     ("<tr><td bgcolor=\"#fffff0\">XB_GetLastParseError( void ) : String</td>");
11568   html +=
11569     wxT
11570     ("<td bgcolor=\"#f0fff0\">Will return the most recent XML parsing error (if any).</td></tr>");
11571   html +=
11572     wxT
11573     ("<tr><td bgcolor=\"#fffff0\">XB_GetLastValidateError( void ) : String</td>");
11574   html +=
11575     wxT
11576     ("<td bgcolor=\"#f0fff0\">Will return the most recent XML validating error (if any).</td></tr>");
11577   html +=
11578     wxT
11579     ("<tr><td bgcolor=\"#fffff0\">XB_IsValidXPathExpression( expr Text ) : Integer</td>");
11580   html +=
11581     wxT
11582     ("<td bgcolor=\"#f0fff0\">The return type is Integer, with a return value of 1 for TRUE, 0 for FALSE, ");
11583   html +=
11584     wxT
11585     ("and -1 for UNKNOWN corresponding to a function invocation on NULL arguments.</td></tr>");
11586   html +=
11587     wxT
11588     ("<tr><td bgcolor=\"#fffff0\">XB_GetLastXPathError( void ) : String</td>");
11589   html +=
11590     wxT
11591     ("<td bgcolor=\"#f0fff0\">Will return the most recent XPath error (if any).</td></tr>");
11592   html +=
11593     wxT("<tr><td bgcolor=\"#fffff0\">XB_CacheFlush( void ) : Boolean</td>");
11594   html +=
11595     wxT
11596     ("<td bgcolor=\"#f0fff0\">Reset the internal XML Schema cache to its initial empty state.</td></tr>");
11597   html +=
11598     wxT("<tr><td bgcolor=\"#fffff0\">XB_CacheFlush( void ) : Boolean</td>");
11599   html +=
11600     wxT
11601     ("<td bgcolor=\"#f0fff0\">Reset the internal XML Schema cache to its initial empty state.</td></tr>");
11602   html +=
11603     wxT
11604     ("<tr><td bgcolor=\"#fffff0\">XB_LoadXML( filepath-or-URL String ) : BLOB</td>");
11605   html +=
11606     wxT
11607     ("<td bgcolor=\"#f0fff0\">If \"filepath-or-URL\" corresponds to some valid local pathname, and the corresponding file (expected to contain a well-formed XML Document) ");
11608   html +=
11609     wxT
11610     ("can be actually accessed in read mode, then the whole file content will be returned as a BLOB value.<br>");
11611   html +=
11612     wxT
11613     ("This function is even able to acces a remote XML Document identified by an URL.<br>Otherwise NULL will be returned.<br>");
11614   html +=
11615     wxT
11616     ("<u>Please note:</u> SQLite doesn't support BLOB values bigger than SQLITE_MAX_LENGTH (usually, 1 GB).<hr>");
11617   html +=
11618     wxT
11619     ("<u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always disabled by default.<br>");
11620   html +=
11621     wxT
11622     ("Explicitly setting the environmente variable \"SPATIALITE_SECURITY=relaxed\" is absolutely required in order to effectively enable this function.<br>");
11623   html += wxT("Please see: CountUnsafeTriggers().</td></tr>");
11624   html +=
11625     wxT
11626     ("<tr><td bgcolor=\"#fffff0\">XB_StoreXML( XmlObject XmlBLOB , filepath String ) : Integer<hr>");
11627   html +=
11628     wxT
11629     ("XB_StoreXML( XmlObject XmlBLOB , filepath String , indent Integer ) : Integer</td>");
11630   html +=
11631     wxT
11632     ("<td bgcolor=\"#f0fff0\">If \"XmlObject\" is of the XmlBLOB-type, and if \"filepath\" corresponds to some valid pathname ");
11633   html +=
11634     wxT
11635     ("(accessible in write/create mode), then the corresponding file will be created/overwritten so to ");
11636   html +=
11637     wxT
11638     ("contain the corresponding XML Document (fully preserving the original character encoding).<br>");
11639   html +=
11640     wxT
11641     ("If the optional argument \"indent\" is set to some positive value then the returned XmlDocument will be nicely formatted and properly indented by the required factor; ");
11642   html +=
11643     wxT
11644     ("ZERO will cause the whole XmlDocument to be returned as a single line. (default setting is <i>negative</i> indenting, i.e. not reformatting at all).<hr>");
11645   html +=
11646     wxT
11647     ("The return type is Integer, with a return value of 1 for success, 0 for failure and -1 for invalid arguments.<hr>");
11648   html +=
11649     wxT
11650     ("<u>Please note well</u>: this SQL function open the doors to many potential security issues, and thus is always disabled by default.<br>");
11651   html +=
11652     wxT
11653     ("Explicitly setting the environmente variable \"SPATIALITE_SECURITY=relaxed\" is absolutely required in order to effectively enable this function.<br>");
11654   html += wxT("Please see: CountUnsafeTriggers().</td></tr>");
11655   html += wxT("</table>");
11656   html += wxT("<a href=\"#index\">back to index</a>");
11657   html += wxT("</body>");
11658   html += wxT("</html>");
11659 }
11660