1 /*
2 / TableTree.cpp
3 / tree control to show tables, columns, indices and triggers
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 <float.h>
27 
28 #include "Classdef.h"
29 
30 #include "wx/filename.h"
31 #include "wx/imaglist.h"
32 
33 #if defined(_WIN32) && !defined(__MINGW32__)
34 #define strcasecmp	_stricmp
35 #endif
36 
37 //
38 // ICONs in XPM format [universally portable]
39 //
40 #include "icons/db.xpm"
41 #include "icons/table.xpm"
42 #include "icons/geotable.xpm"
43 #include "icons/vtable.xpm"
44 #include "icons/geovtable.xpm"
45 #include "icons/composer.xpm"
46 #include "icons/view.xpm"
47 #include "icons/geoview.xpm"
48 #include "icons/pkey.xpm"
49 #include "icons/column.xpm"
50 #include "icons/index.xpm"
51 #include "icons/trigger.xpm"
52 #include "icons/geometry.xpm"
53 #include "icons/spatialidx.xpm"
54 #include "icons/mbrcache.xpm"
55 #include "icons/kill_spindex.xpm"
56 #include "icons/dumpshp.xpm"
57 #include "icons/tmp_table.xpm"
58 #include "icons/tmp_view.xpm"
59 #include "icons/malformed_geoms.xpm"
60 #include "icons/statistics.xpm"
61 #include "icons/map_preview.xpm"
62 #include "icons/tables.xpm"
63 #include "icons/foreign_key.xpm"
64 #include "icons/primary_key.xpm"
65 #include "icons/topology.xpm"
66 #include "icons/attach.xpm"
67 #include "icons/checkgeom.xpm"
68 #include "icons/sanegeom.xpm"
69 
MyTableTree(MyFrame * parent,wxWindowID id)70 MyTableTree::MyTableTree(MyFrame * parent, wxWindowID id):wxTreeCtrl(parent, id)
71 {
72 //
73 // constructor: TREE control to show DB objects
74 //
75   MainFrame = parent;
76   Root = AddRoot(wxT("no current DB"));
77   RootUserData = AppendItem(Root, wxT("User Data"));
78   RootIsoMetadata = AppendItem(Root, wxT("ISO / INSPIRE Metadata"));
79   RootStyling = AppendItem(Root, wxT("Styling (SLD/SE)"));
80   RootTopologies = AppendItem(Root, wxT("Topologies"));
81   RootMetadata = AppendItem(Root, wxT("Metadata"));
82   RootInternal = AppendItem(Root, wxT("Internal Data"));
83   RootSpatialIndex = AppendItem(Root, wxT("Spatial Index"));
84 // setting up icons
85   Images = new wxImageList(16, 16, true);
86   wxIcon icons[22];
87   icons[0] = wxIcon(db_xpm);
88   icons[1] = wxIcon(table_xpm);
89   icons[2] = wxIcon(pkey_xpm);
90   icons[3] = wxIcon(column_xpm);
91   icons[4] = wxIcon(index_xpm);
92   icons[5] = wxIcon(trigger_xpm);
93   icons[6] = wxIcon(geometry_xpm);
94   icons[7] = wxIcon(spatialidx_xpm);
95   icons[8] = wxIcon(vtable_xpm);
96   icons[9] = wxIcon(view_xpm);
97   icons[10] = wxIcon(geotable_xpm);
98   icons[11] = wxIcon(mbrcache_xpm);
99   icons[12] = wxIcon(geoview_xpm);
100   icons[13] = wxIcon(geovtable_xpm);
101   icons[14] = wxIcon(tmp_table_xpm);
102   icons[15] = wxIcon(tmp_view_xpm);
103   icons[16] = wxIcon(malformed_geoms_xpm);
104   icons[17] = wxIcon(tables_xpm);
105   icons[18] = wxIcon(foreign_key_xpm);
106   icons[19] = wxIcon(primary_key_xpm);
107   icons[20] = wxIcon(topology_xpm);
108   icons[21] = wxIcon(attach_xpm);
109   Images->Add(icons[0]);
110   Images->Add(icons[1]);
111   Images->Add(icons[2]);
112   Images->Add(icons[3]);
113   Images->Add(icons[4]);
114   Images->Add(icons[5]);
115   Images->Add(icons[6]);
116   Images->Add(icons[7]);
117   Images->Add(icons[8]);
118   Images->Add(icons[9]);
119   Images->Add(icons[10]);
120   Images->Add(icons[11]);
121   Images->Add(icons[12]);
122   Images->Add(icons[13]);
123   Images->Add(icons[14]);
124   Images->Add(icons[15]);
125   Images->Add(icons[16]);
126   Images->Add(icons[17]);
127   Images->Add(icons[18]);
128   Images->Add(icons[19]);
129   Images->Add(icons[20]);
130   Images->Add(icons[21]);
131   SetImageList(Images);
132   SetItemImage(Root, 0);
133   SetItemImage(RootUserData, 17);
134   SetItemImage(RootTopologies, 17);
135   SetItemImage(RootStyling, 17);
136   SetItemImage(RootIsoMetadata, 17);
137   SetItemImage(RootMetadata, 17);
138   SetItemImage(RootInternal, 17);
139   SetItemImage(RootSpatialIndex, 17);
140 // setting up event handlers
141   Connect(wxID_ANY, wxEVT_COMMAND_TREE_SEL_CHANGED,
142           (wxObjectEventFunction) & MyTableTree::OnSelChanged);
143   Connect(wxID_ANY, wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK,
144           (wxObjectEventFunction) & MyTableTree::OnRightClick);
145   Connect(Tree_QueryViewComposer, wxEVT_COMMAND_MENU_SELECTED,
146           (wxObjectEventFunction) & MyTableTree::OnCmdQueryViewComposer);
147   Connect(Tree_NewTable, wxEVT_COMMAND_MENU_SELECTED,
148           (wxObjectEventFunction) & MyTableTree::OnCmdNewTable);
149   Connect(Tree_NewView, wxEVT_COMMAND_MENU_SELECTED,
150           (wxObjectEventFunction) & MyTableTree::OnCmdNewView);
151   Connect(Tree_NewIndex, wxEVT_COMMAND_MENU_SELECTED,
152           (wxObjectEventFunction) & MyTableTree::OnCmdNewIndex);
153   Connect(Tree_NewTrigger, wxEVT_COMMAND_MENU_SELECTED,
154           (wxObjectEventFunction) & MyTableTree::OnCmdNewTrigger);
155   Connect(Tree_NewColumn, wxEVT_COMMAND_MENU_SELECTED,
156           (wxObjectEventFunction) & MyTableTree::OnCmdNewColumn);
157   Connect(Tree_Show, wxEVT_COMMAND_MENU_SELECTED,
158           (wxObjectEventFunction) & MyTableTree::OnCmdShow);
159   Connect(Tree_Drop, wxEVT_COMMAND_MENU_SELECTED,
160           (wxObjectEventFunction) & MyTableTree::OnCmdDrop);
161   Connect(Tree_Detach, wxEVT_COMMAND_MENU_SELECTED,
162           (wxObjectEventFunction) & MyTableTree::OnCmdDetachDB);
163   Connect(Tree_Rename, wxEVT_COMMAND_MENU_SELECTED,
164           (wxObjectEventFunction) & MyTableTree::OnCmdRename);
165   Connect(Tree_Select, wxEVT_COMMAND_MENU_SELECTED,
166           (wxObjectEventFunction) & MyTableTree::OnCmdSelect);
167   Connect(Tree_Refresh, wxEVT_COMMAND_MENU_SELECTED,
168           (wxObjectEventFunction) & MyTableTree::OnCmdRefresh);
169   Connect(Tree_Recover, wxEVT_COMMAND_MENU_SELECTED,
170           (wxObjectEventFunction) & MyTableTree::OnCmdRecover);
171   Connect(Tree_ShowSql, wxEVT_COMMAND_MENU_SELECTED,
172           (wxObjectEventFunction) & MyTableTree::OnCmdShowSql);
173   Connect(Tree_SpatialIndex, wxEVT_COMMAND_MENU_SELECTED,
174           (wxObjectEventFunction) & MyTableTree::OnCmdSpatialIndex);
175   Connect(Tree_CheckSpatialIndex, wxEVT_COMMAND_MENU_SELECTED,
176           (wxObjectEventFunction) & MyTableTree::OnCmdCheckSpatialIndex);
177   Connect(Tree_RecoverSpatialIndex, wxEVT_COMMAND_MENU_SELECTED,
178           (wxObjectEventFunction) & MyTableTree::OnCmdRecoverSpatialIndex);
179   Connect(Tree_MbrCache, wxEVT_COMMAND_MENU_SELECTED,
180           (wxObjectEventFunction) & MyTableTree::OnCmdMbrCache);
181   Connect(Tree_RebuildTriggers, wxEVT_COMMAND_MENU_SELECTED,
182           (wxObjectEventFunction) & MyTableTree::OnCmdRebuildTriggers);
183   Connect(Tree_GisLayerAuth, wxEVT_COMMAND_MENU_SELECTED,
184           (wxObjectEventFunction) & MyTableTree::OnCmdGisLayerAuth);
185   Connect(Tree_CheckGeometry, wxEVT_COMMAND_MENU_SELECTED,
186           (wxObjectEventFunction) & MyTableTree::OnCmdCheckGeometry);
187   Connect(Tree_Extent, wxEVT_COMMAND_MENU_SELECTED,
188           (wxObjectEventFunction) & MyTableTree::OnCmdExtent);
189   Connect(Tree_UpdateLayerStatistics, wxEVT_COMMAND_MENU_SELECTED,
190           (wxObjectEventFunction) & MyTableTree::OnCmdUpdateLayerStatistics);
191   Connect(Tree_UpdateLayerStatisticsAll, wxEVT_COMMAND_MENU_SELECTED,
192           (wxObjectEventFunction) & MyTableTree::OnCmdUpdateLayerStatisticsAll);
193   Connect(Tree_ElementaryGeoms, wxEVT_COMMAND_MENU_SELECTED,
194           (wxObjectEventFunction) & MyTableTree::OnCmdElementaryGeometries);
195   Connect(Tree_MalformedGeometries, wxEVT_COMMAND_MENU_SELECTED,
196           (wxObjectEventFunction) & MyTableTree::OnCmdMalformedGeometries);
197   Connect(Tree_RepairPolygons, wxEVT_COMMAND_MENU_SELECTED,
198           (wxObjectEventFunction) & MyTableTree::OnCmdRepairPolygons);
199   Connect(Tree_SetSrid, wxEVT_COMMAND_MENU_SELECTED,
200           (wxObjectEventFunction) & MyTableTree::OnCmdSetSrid);
201   Connect(Tree_DumpShp, wxEVT_COMMAND_MENU_SELECTED,
202           (wxObjectEventFunction) & MyTableTree::OnCmdDumpShp);
203   Connect(Tree_DumpKml, wxEVT_COMMAND_MENU_SELECTED,
204           (wxObjectEventFunction) & MyTableTree::OnCmdDumpKml);
205   Connect(Tree_DumpTxtTab, wxEVT_COMMAND_MENU_SELECTED,
206           (wxObjectEventFunction) & MyTableTree::OnCmdDumpTxtTab);
207   Connect(Tree_DumpCsv, wxEVT_COMMAND_MENU_SELECTED,
208           (wxObjectEventFunction) & MyTableTree::OnCmdDumpCsv);
209   Connect(Tree_DumpHtml, wxEVT_COMMAND_MENU_SELECTED,
210           (wxObjectEventFunction) & MyTableTree::OnCmdDumpHtml);
211   Connect(Tree_DumpDif, wxEVT_COMMAND_MENU_SELECTED,
212           (wxObjectEventFunction) & MyTableTree::OnCmdDumpDif);
213   Connect(Tree_DumpSylk, wxEVT_COMMAND_MENU_SELECTED,
214           (wxObjectEventFunction) & MyTableTree::OnCmdDumpSylk);
215   Connect(Tree_DumpDbf, wxEVT_COMMAND_MENU_SELECTED,
216           (wxObjectEventFunction) & MyTableTree::OnCmdDumpDbf);
217   Connect(Tree_DumpPostGIS, wxEVT_COMMAND_MENU_SELECTED,
218           (wxObjectEventFunction) & MyTableTree::OnCmdDumpPostGIS);
219   Connect(Tree_Edit, wxEVT_COMMAND_MENU_SELECTED,
220           (wxObjectEventFunction) & MyTableTree::OnCmdEdit);
221   Connect(Tree_DropColumn, wxEVT_COMMAND_MENU_SELECTED,
222           (wxObjectEventFunction) & MyTableTree::OnCmdDropColumn);
223   Connect(Tree_RenameColumn, wxEVT_COMMAND_MENU_SELECTED,
224           (wxObjectEventFunction) & MyTableTree::OnCmdRenameColumn);
225   Connect(Tree_ColumnStats, wxEVT_COMMAND_MENU_SELECTED,
226           (wxObjectEventFunction) & MyTableTree::OnCmdColumnStats);
227   Connect(Tree_MapPreview, wxEVT_COMMAND_MENU_SELECTED,
228           (wxObjectEventFunction) & MyTableTree::OnCmdMapPreview);
229   Connect(Tree_CheckDuplicates, wxEVT_COMMAND_MENU_SELECTED,
230           (wxObjectEventFunction) & MyTableTree::OnCmdCheckDuplicates);
231   Connect(Tree_RemoveDuplicates, wxEVT_COMMAND_MENU_SELECTED,
232           (wxObjectEventFunction) & MyTableTree::OnCmdRemoveDuplicates);
233   Connect(Tree_CheckGeom, wxEVT_COMMAND_MENU_SELECTED,
234           (wxObjectEventFunction) & MyTableTree::OnCmdCheckGeometries);
235   Connect(Tree_SaneGeom, wxEVT_COMMAND_MENU_SELECTED,
236           (wxObjectEventFunction) & MyTableTree::OnCmdSanitizeGeometries);
237 }
238 
FlushAll()239 void MyTableTree::FlushAll()
240 {
241 // resetting to the initial empty state
242   wxTreeItemId child;
243   wxTreeItemIdValue cookie;
244   bool ok = true;
245   DeleteChildren(RootUserData);
246   DeleteTopologies(RootTopologies);
247   DeleteChildren(RootStyling);
248   DeleteChildren(RootIsoMetadata);
249   DeleteChildren(RootMetadata);
250   DeleteChildren(RootInternal);
251   DeleteChildren(RootSpatialIndex);
252   while (ok)
253     {
254       ok = false;
255       child = GetFirstChild(Root, cookie);
256       while (true)
257         {
258           bool kill = true;
259           if (child.IsOk() == false)
260             break;
261           if (child == RootUserData)
262             kill = false;
263           if (child == RootTopologies)
264             kill = false;
265           if (child == RootStyling)
266             kill = false;
267           if (child == RootIsoMetadata)
268             kill = false;
269           if (child == RootMetadata)
270             kill = false;
271           if (child == RootInternal)
272             kill = false;
273           if (child == RootSpatialIndex)
274             kill = false;
275           if (kill == true)
276             {
277               Delete(child);
278               ok = true;
279               break;
280             }
281           child = GetNextChild(Root, cookie);
282         }
283     }
284 }
285 
DeleteTopologies(wxTreeItemId & RootTopologies)286 void MyTableTree::DeleteTopologies(wxTreeItemId & RootTopologies)
287 {
288 // deleting Topology Nodes
289   Topologies.Flush();
290   DeleteChildren(RootTopologies);
291 }
292 
GetRootNode(wxString & tableName)293 wxTreeItemId & MyTableTree::GetRootNode(wxString & tableName)
294 {
295 //
296 // determines the Table Root Node
297 //
298   if (tableName == wxT("geometry_columns"))
299     return RootMetadata;
300   if (tableName == wxT("views_geometry_columns"))
301     return RootMetadata;
302   if (tableName == wxT("virts_geometry_columns"))
303     return RootMetadata;
304   if (tableName == wxT("spatial_ref_sys"))
305     return RootMetadata;
306   if (tableName == wxT("geom_cols_ref_sys"))
307     return RootMetadata;
308   if (tableName == wxT("geometry_columns_time"))
309     return RootMetadata;
310   if (tableName == wxT("spatialite_history"))
311     return RootMetadata;
312   if (tableName == wxT("raster_coverages"))
313     return RootMetadata;
314   if (tableName == wxT("raster_coverages_ref_sys"))
315     return RootMetadata;
316   if (tableName == wxT("vector_layers"))
317     return RootMetadata;
318   if (tableName == wxT("topology_master"))
319     return RootMetadata;
320 
321   if (tableName == wxT("sqlite_stat1"))
322     return RootInternal;
323   if (tableName == wxT("sqlite_stat3"))
324     return RootInternal;
325   if (tableName == wxT("sqlite_sequence"))
326     return RootInternal;
327   if (tableName == wxT("layer_params"))
328     return RootInternal;
329   if (tableName == wxT("layer_statistics"))
330     return RootInternal;
331   if (tableName == wxT("geometry_columns_statistics"))
332     return RootInternal;
333   if (tableName == wxT("views_layer_statistics"))
334     return RootInternal;
335   if (tableName == wxT("views_geometry_columns_statistics"))
336     return RootInternal;
337   if (tableName == wxT("virts_layer_statistics"))
338     return RootInternal;
339   if (tableName == wxT("virts_geometry_columns_statistics"))
340     return RootInternal;
341   if (tableName == wxT("geometry_columns_field_infos"))
342     return RootInternal;
343   if (tableName == wxT("views_geometry_columns_field_infos"))
344     return RootInternal;
345   if (tableName == wxT("virts_geometry_columns_field_infos"))
346     return RootInternal;
347   if (tableName == wxT("geometry_columns_auth"))
348     return RootInternal;
349   if (tableName == wxT("views_geometry_columns_auth"))
350     return RootInternal;
351   if (tableName == wxT("virts_geometry_columns_auth"))
352     return RootInternal;
353   if (tableName == wxT("vector_layers_auth"))
354     return RootInternal;
355   if (tableName == wxT("vector_layers_statistics"))
356     return RootInternal;
357   if (tableName == wxT("vector_layers_field_infos"))
358     return RootInternal;
359   if (tableName == wxT("layer_sub_classes"))
360     return RootInternal;
361   if (tableName == wxT("layer_table_layout"))
362     return RootInternal;
363   if (tableName == wxT("pattern_bitmaps"))
364     return RootInternal;
365   if (tableName == wxT("symbol_bitmaps"))
366     return RootInternal;
367   if (tableName == wxT("project_defs"))
368     return RootInternal;
369   if (tableName == wxT("raster_pyramids"))
370     return RootInternal;
371   if (tableName == wxT("rasterlite2_styles"))
372     return RootInternal;
373   if (tableName == wxT("rasterlite2_metadata"))
374     return RootInternal;
375   if (tableName == wxT("sql_statements_log"))
376     return RootInternal;
377 
378   if (tableName == wxT("SE_external_graphics"))
379     return RootStyling;
380   if (tableName == wxT("SE_external_graphics_view"))
381     return RootStyling;
382   if (tableName == wxT("SE_raster_styled_layers"))
383     return RootStyling;
384   if (tableName == wxT("SE_raster_styled_layers_view"))
385     return RootStyling;
386   if (tableName == wxT("SE_vector_styled_layers"))
387     return RootStyling;
388   if (tableName == wxT("SE_vector_styled_layers_view"))
389     return RootStyling;
390   if (tableName == wxT("SE_styled_groups"))
391     return RootStyling;
392   if (tableName == wxT("SE_styled_group_refs"))
393     return RootStyling;
394   if (tableName == wxT("SE_styled_groups_view"))
395     return RootStyling;
396 
397   if (tableName == wxT("ISO_metadata"))
398     return RootIsoMetadata;
399   if (tableName == wxT("ISO_metadata_reference"))
400     return RootIsoMetadata;
401   if (tableName == wxT("ISO_metadata_view"))
402     return RootIsoMetadata;
403 
404   if (tableName == wxT("SpatialIndex"))
405     return RootSpatialIndex;
406   if (MainFrame->IsSpatialIndex(tableName) == true)
407     return RootSpatialIndex;
408   wxTreeItemId *topologyNode = Topologies.FindNode(tableName);
409   if (topologyNode != NULL)
410     return *topologyNode;
411   return RootUserData;
412 }
413 
GetRootNode(wxString & tableName,RootNodes * nodes)414 wxTreeItemId & MyTableTree::GetRootNode(wxString & tableName, RootNodes * nodes)
415 {
416 //
417 // determines the Table Root Node [Attached DB]
418 //
419   if (tableName == wxT("geometry_columns"))
420     return nodes->GetRootMetadata();
421   if (tableName == wxT("views_geometry_columns"))
422     return nodes->GetRootMetadata();
423   if (tableName == wxT("virts_geometry_columns"))
424     return nodes->GetRootMetadata();
425   if (tableName == wxT("spatial_ref_sys"))
426     return nodes->GetRootMetadata();
427   if (tableName == wxT("geom_cols_ref_sys"))
428     return nodes->GetRootMetadata();
429   if (tableName == wxT("geometry_columns_time"))
430     return nodes->GetRootMetadata();
431   if (tableName == wxT("spatialite_history"))
432     return nodes->GetRootMetadata();
433   if (tableName == wxT("vector_layers"))
434     return nodes->GetRootMetadata();
435   if (tableName == wxT("topology_master"))
436     return nodes->GetRootMetadata();
437 
438   if (tableName == wxT("sqlite_stat1"))
439     return nodes->GetRootInternal();
440   if (tableName == wxT("sqlite_sequence"))
441     return nodes->GetRootInternal();
442   if (tableName == wxT("layer_params"))
443     return nodes->GetRootInternal();
444   if (tableName == wxT("layer_statistics"))
445     return nodes->GetRootInternal();
446   if (tableName == wxT("geometry_columns_statistics"))
447     return nodes->GetRootInternal();
448   if (tableName == wxT("views_layer_statistics"))
449     return nodes->GetRootInternal();
450   if (tableName == wxT("views_geometry_columns_statistics"))
451     return nodes->GetRootInternal();
452   if (tableName == wxT("virts_layer_statistics"))
453     return nodes->GetRootInternal();
454   if (tableName == wxT("virts_geometry_columns_statistics"))
455     return nodes->GetRootInternal();
456   if (tableName == wxT("geometry_columns_field_infos"))
457     return nodes->GetRootInternal();
458   if (tableName == wxT("views_geometry_columns_field_infos"))
459     return nodes->GetRootInternal();
460   if (tableName == wxT("virts_geometry_columns_field_infos"))
461     return nodes->GetRootInternal();
462   if (tableName == wxT("geometry_columns_auth"))
463     return nodes->GetRootInternal();
464   if (tableName == wxT("views_geometry_columns_auth"))
465     return nodes->GetRootInternal();
466   if (tableName == wxT("virts_geometry_columns_auth"))
467     return nodes->GetRootInternal();
468   if (tableName == wxT("vector_layers_auth"))
469     return nodes->GetRootInternal();
470   if (tableName == wxT("vector_layers_statistics"))
471     return nodes->GetRootInternal();
472   if (tableName == wxT("vector_layers_field_infos"))
473     return nodes->GetRootInternal();
474   if (tableName == wxT("layer_sub_classes"))
475     return nodes->GetRootInternal();
476   if (tableName == wxT("layer_table_layout"))
477     return nodes->GetRootInternal();
478   if (tableName == wxT("pattern_bitmaps"))
479     return nodes->GetRootInternal();
480   if (tableName == wxT("symbol_bitmaps"))
481     return nodes->GetRootInternal();
482   if (tableName == wxT("project_defs"))
483     return nodes->GetRootInternal();
484   if (tableName == wxT("raster_pyramids"))
485     return nodes->GetRootInternal();
486   if (tableName == wxT("rasterlite2_styles"))
487     return nodes->GetRootInternal();
488   if (tableName == wxT("rasterlite2_metadata"))
489     return nodes->GetRootInternal();
490   if (tableName == wxT("sql_statements_log"))
491     return nodes->GetRootInternal();
492 
493   if (tableName == wxT("SpatialIndex"))
494     return nodes->GetRootSpatialIndex();
495   if (MainFrame->IsSpatialIndex(nodes->GetDbAlias(), tableName) == true)
496     return nodes->GetRootSpatialIndex();
497   wxTreeItemId *topologyNode = Topologies.FindNode(tableName);
498   if (topologyNode != NULL)
499     return *topologyNode;
500   return nodes->GetRootUserData();
501 }
502 
AddTable(wxString & tableName,bool virtualTable,bool tmp)503 void MyTableTree::AddTable(wxString & tableName, bool virtualTable, bool tmp)
504 {
505 //
506 // appends a table to the TREE list
507 //
508   MyTableInfo list;
509   MyColumnInfo *col;
510   MyIndexInfo *idx;
511   MyTriggerInfo *trgr;
512   wxTreeItemId item;
513   wxTreeItemId item2;
514   wxString columnInfo;
515   wxString indexInfo;
516   wxString triggerInfo;
517   int icon = 1;
518   if (virtualTable == true)
519     icon = 8;
520   if (tmp == true)
521     icon = 14;
522   wxTreeItemId rootNode = GetRootNode(tableName);
523   item = AppendItem(rootNode, tableName, icon);
524   if (virtualTable == true)
525     SetItemData(item,
526                 (wxTreeItemData *) (new MyObject(MY_VTABLE, tableName, tmp)));
527   else
528     SetItemData(item,
529                 (wxTreeItemData *) (new MyObject(MY_TABLE, tableName, tmp)));
530   MainFrame->GetTableColumns(tableName, &list);
531   MainFrame->GetTableIndices(tableName, &list);
532   MainFrame->GetTableTriggers(tableName, &list);
533   col = list.GetFirstColumn();
534   while (col)
535     {
536       int icon;
537       if (col->IsPrimaryKey() == true)
538         icon = 2;
539       else
540         {
541           if (col->IsGeometry() == true)
542             {
543               if (virtualTable == false)
544                 SetItemImage(item, 10);
545               else
546                 SetItemImage(item, 13);
547               if (col->IsGeometryIndex() == true)
548                 icon = 7;
549               else if (col->IsMbrCache() == true)
550                 icon = 11;
551               else
552                 icon = 6;
553           } else
554             icon = 3;
555         }
556       columnInfo = col->GetName();
557       item2 = AppendItem(item, columnInfo, icon);
558       if (virtualTable == true)
559         {
560           if (col->IsGeometry() == true)
561             {
562               SetItemData(item2,
563                           (wxTreeItemData *) (new
564                                               MyObject(MY_VIRTUAL_GEOMETRY,
565                                                        tableName,
566                                                        col->GetName())));
567           } else
568             SetItemData(item2,
569                         (wxTreeItemData *) (new
570                                             MyObject(MY_VIRTUAL_COLUMN,
571                                                      tableName,
572                                                      col->GetName())));
573       } else
574         {
575           if (col->IsGeometry() == true)
576             {
577               if (col->IsGeometryIndex() == true)
578                 SetItemData(item2,
579                             (wxTreeItemData *) (new
580                                                 MyObject(MY_GEOMETRY_INDEX,
581                                                          tableName,
582                                                          col->GetName())));
583               else if (col->IsMbrCache() == true)
584                 SetItemData(item2,
585                             (wxTreeItemData *) (new
586                                                 MyObject(MY_GEOMETRY_CACHED,
587                                                          tableName,
588                                                          col->GetName())));
589               else
590                 SetItemData(item2,
591                             (wxTreeItemData *) (new
592                                                 MyObject(MY_GEOMETRY, tableName,
593                                                          col->GetName())));
594           } else
595             SetItemData(item2,
596                         (wxTreeItemData *) (new
597                                             MyObject(MY_COLUMN, tableName,
598                                                      col->GetName())));
599         }
600       col = col->GetNext();
601     }
602 // setting up Primary Key
603   bool ok_pk = false;
604   idx = list.GetFirstIndex();
605   while (idx)
606     {
607       indexInfo = idx->GetName();
608       if (indexInfo.StartsWith(wxT("sqlite_autoindex_")) == true)
609         {
610           item2 = AppendItem(item, wxT("PrimaryKey"), 19);
611           MainFrame->GetPrimaryKeyFields(indexInfo, item2);
612           ok_pk = true;
613           break;
614         }
615       idx = idx->GetNext();
616     }
617   if (ok_pk == false)
618     {
619       col = list.GetFirstColumn();
620       while (col)
621         {
622           if (col->IsPrimaryKey() == true)
623             {
624               ok_pk = true;
625               break;
626             }
627           col = col->GetNext();
628         }
629       if (ok_pk == true)
630         {
631           item2 = AppendItem(item, wxT("PrimaryKey"), 19);
632           col = list.GetFirstColumn();
633           while (col)
634             {
635               if (col->IsPrimaryKey() == true)
636                 {
637                   AppendItem(item2, col->GetName(), 2);
638                   break;
639                 }
640               col = col->GetNext();
641             }
642         }
643     }
644 // setting up Foreign Keys
645   MainFrame->GetForeignKeys(tableName, item);
646   idx = list.GetFirstIndex();
647   while (idx)
648     {
649       // setting up Indices
650       indexInfo = idx->GetName();
651       if (indexInfo.StartsWith(wxT("sqlite_autoindex_")) == true)
652         {
653           idx = idx->GetNext();
654           continue;
655         }
656       item2 = AppendItem(item, indexInfo, 4);
657       SetItemData(item2,
658                   (wxTreeItemData *) (new MyObject(MY_INDEX, idx->GetName())));
659       MainFrame->GetIndexFields(indexInfo, item2);
660       idx = idx->GetNext();
661     }
662   trgr = list.GetFirstTrigger();
663   while (trgr)
664     {
665       // setting up Triggers
666       triggerInfo = trgr->GetName();
667       item2 = AppendItem(item, triggerInfo, 5);
668       SetItemData(item2,
669                   (wxTreeItemData *) (new
670                                       MyObject(MY_TRIGGER, trgr->GetName())));
671       trgr = trgr->GetNext();
672     }
673 }
674 
AddView(wxString & viewName,bool tmp)675 void MyTableTree::AddView(wxString & viewName, bool tmp)
676 {
677 //
678 // appends a view to the TREE list
679   MyViewInfo list;
680   MyColumnInfo *col;
681   MyTriggerInfo *trgr;
682   wxTreeItemId item;
683   wxTreeItemId item2;
684   wxString columnInfo;
685   wxString triggerInfo;
686   int icon = 9;
687   if (tmp == true)
688     icon = 15;
689   wxTreeItemId rootNode = GetRootNode(viewName);
690   item = AppendItem(rootNode, viewName, icon);
691   SetItemData(item, (wxTreeItemData *) (new MyObject(MY_VIEW, viewName, tmp)));
692   MainFrame->GetViewColumns(viewName, &list);
693   MainFrame->GetViewTriggers(viewName, &list);
694   col = list.GetFirst();
695   while (col)
696     {
697       columnInfo = col->GetName();
698       if (col->IsGeometry() == true)
699         {
700           SetItemImage(item, 12);
701           if (col->IsGeometryIndex() == true)
702             icon = 7;
703           else if (col->IsMbrCache() == true)
704             icon = 11;
705           else
706             icon = 6;
707       } else
708         icon = 3;
709       item2 = AppendItem(item, columnInfo, icon);
710       if (col->IsGeometry() == true)
711         {
712           if (col->IsGeometryIndex() == true)
713             SetItemData(item2,
714                         (wxTreeItemData *) (new
715                                             MyObject(MY_VIEW_GEOMETRY_INDEX,
716                                                      viewName,
717                                                      col->GetName())));
718           else if (col->IsMbrCache() == true)
719             SetItemData(item2,
720                         (wxTreeItemData *) (new
721                                             MyObject(MY_VIEW_GEOMETRY_CACHED,
722                                                      viewName,
723                                                      col->GetName())));
724           else
725             SetItemData(item2,
726                         (wxTreeItemData *) (new
727                                             MyObject(MY_VIEW_GEOMETRY, viewName,
728                                                      col->GetName())));
729       } else
730         SetItemData(item2,
731                     (wxTreeItemData *) (new
732                                         MyObject(MY_VIEW_COLUMN, viewName,
733                                                  col->GetName())));
734       col = col->GetNext();
735     }
736   trgr = list.GetFirstTrigger();
737   while (trgr)
738     {
739       // setting up Triggers
740       triggerInfo = trgr->GetName();
741       item2 = AppendItem(item, triggerInfo, 5);
742       SetItemData(item2,
743                   (wxTreeItemData *) (new
744                                       MyObject(MY_TRIGGER, trgr->GetName())));
745       trgr = trgr->GetNext();
746     }
747 }
748 
AddTable(wxString & dbAlias,wxString & tableName,bool virtualTable,RootNodes * nodes)749 void MyTableTree::AddTable(wxString & dbAlias,
750                            wxString & tableName, bool virtualTable,
751                            RootNodes * nodes)
752 {
753 //
754 // appends a table to the TREE list [ATTACHED DB]
755 //
756   MyTableInfo list;
757   MyColumnInfo *col;
758   MyIndexInfo *idx;
759   MyTriggerInfo *trgr;
760   wxTreeItemId item;
761   wxTreeItemId item2;
762   wxString columnInfo;
763   wxString indexInfo;
764   wxString triggerInfo;
765   int icon = 1;
766   if (virtualTable == true)
767     icon = 8;
768   wxTreeItemId rootNode = GetRootNode(tableName, nodes);
769   item = AppendItem(rootNode, tableName, icon);
770   if (virtualTable == true)
771     SetItemData(item,
772                 (wxTreeItemData *) (new
773                                     MyObject(MY_VTABLE, true, dbAlias,
774                                              tableName)));
775   else
776     SetItemData(item,
777                 (wxTreeItemData *) (new
778                                     MyObject(MY_TABLE, true, dbAlias,
779                                              tableName)));
780   MainFrame->GetTableColumns(dbAlias, tableName, &list);
781   MainFrame->GetTableIndices(dbAlias, tableName, &list);
782   MainFrame->GetTableTriggers(dbAlias, tableName, &list);
783   col = list.GetFirstColumn();
784   while (col)
785     {
786       int icon;
787       if (col->IsPrimaryKey() == true)
788         icon = 2;
789       else
790         {
791           if (col->IsGeometry() == true)
792             {
793               if (virtualTable == false)
794                 SetItemImage(item, 10);
795               else
796                 SetItemImage(item, 13);
797               if (col->IsGeometryIndex() == true)
798                 icon = 7;
799               else if (col->IsMbrCache() == true)
800                 icon = 11;
801               else
802                 icon = 6;
803           } else
804             icon = 3;
805         }
806       columnInfo = col->GetName();
807       item2 = AppendItem(item, columnInfo, icon);
808       if (virtualTable == true)
809         {
810           if (col->IsGeometry() == true)
811             {
812               SetItemData(item2,
813                           (wxTreeItemData *) (new
814                                               MyObject(MY_VIRTUAL_GEOMETRY,
815                                                        tableName,
816                                                        col->GetName())));
817           } else
818             SetItemData(item2,
819                         (wxTreeItemData *) (new
820                                             MyObject(MY_VIRTUAL_COLUMN,
821                                                      tableName,
822                                                      col->GetName())));
823       } else
824         {
825           if (col->IsGeometry() == true)
826             {
827               if (col->IsGeometryIndex() == true)
828                 SetItemData(item2,
829                             (wxTreeItemData *) (new
830                                                 MyObject(MY_GEOMETRY_INDEX,
831                                                          tableName,
832                                                          col->GetName())));
833               else if (col->IsMbrCache() == true)
834                 SetItemData(item2,
835                             (wxTreeItemData *) (new
836                                                 MyObject(MY_GEOMETRY_CACHED,
837                                                          tableName,
838                                                          col->GetName())));
839               else
840                 SetItemData(item2,
841                             (wxTreeItemData *) (new
842                                                 MyObject(MY_GEOMETRY, tableName,
843                                                          col->GetName())));
844           } else
845             SetItemData(item2,
846                         (wxTreeItemData *) (new
847                                             MyObject(MY_COLUMN, tableName,
848                                                      col->GetName())));
849         }
850       col = col->GetNext();
851     }
852 // setting up Primary Key
853   bool ok_pk = false;
854   idx = list.GetFirstIndex();
855   while (idx)
856     {
857       indexInfo = idx->GetName();
858       if (indexInfo.StartsWith(wxT("sqlite_autoindex_")) == true)
859         {
860           item2 = AppendItem(item, wxT("PrimaryKey"), 19);
861           MainFrame->GetPrimaryKeyFields(dbAlias, indexInfo, item2);
862           ok_pk = true;
863           break;
864         }
865       idx = idx->GetNext();
866     }
867   if (ok_pk == false)
868     {
869       col = list.GetFirstColumn();
870       while (col)
871         {
872           if (col->IsPrimaryKey() == true)
873             {
874               ok_pk = true;
875               break;
876             }
877           col = col->GetNext();
878         }
879       if (ok_pk == true)
880         {
881           item2 = AppendItem(item, wxT("PrimaryKey"), 19);
882           col = list.GetFirstColumn();
883           while (col)
884             {
885               if (col->IsPrimaryKey() == true)
886                 {
887                   AppendItem(item2, col->GetName(), 2);
888                   break;
889                 }
890               col = col->GetNext();
891             }
892         }
893     }
894 // setting up Foreign Keys
895   MainFrame->GetForeignKeys(dbAlias, tableName, item);
896   idx = list.GetFirstIndex();
897   while (idx)
898     {
899       // setting up Indices
900       indexInfo = idx->GetName();
901       if (indexInfo.StartsWith(wxT("sqlite_autoindex_")) == true)
902         {
903           idx = idx->GetNext();
904           continue;
905         }
906       item2 = AppendItem(item, indexInfo, 4);
907       SetItemData(item2,
908                   (wxTreeItemData *) (new MyObject(MY_INDEX, idx->GetName())));
909       MainFrame->GetIndexFields(dbAlias, indexInfo, item2);
910       idx = idx->GetNext();
911     }
912   trgr = list.GetFirstTrigger();
913   while (trgr)
914     {
915       // setting up Triggers
916       triggerInfo = trgr->GetName();
917       item2 = AppendItem(item, triggerInfo, 5);
918       SetItemData(item2,
919                   (wxTreeItemData *) (new
920                                       MyObject(MY_TRIGGER, trgr->GetName())));
921       trgr = trgr->GetNext();
922     }
923 }
924 
AddView(wxString & dbAlias,wxString & viewName,RootNodes * nodes)925 void MyTableTree::AddView(wxString & dbAlias,
926                           wxString & viewName, RootNodes * nodes)
927 {
928 //
929 // appends a view to the TREE list [ATTACHED DB]
930   MyViewInfo list;
931   MyColumnInfo *col;
932   MyTriggerInfo *trgr;
933   wxTreeItemId item;
934   wxTreeItemId item2;
935   wxString columnInfo;
936   wxString triggerInfo;
937   int icon = 9;
938   wxTreeItemId rootNode = GetRootNode(viewName, nodes);
939   item = AppendItem(rootNode, viewName, icon);
940   SetItemData(item,
941               (wxTreeItemData *) (new
942                                   MyObject(MY_VIEW, true, dbAlias, viewName)));
943   MainFrame->GetViewColumns(dbAlias, viewName, &list);
944   MainFrame->GetViewTriggers(dbAlias, viewName, &list);
945   col = list.GetFirst();
946   while (col)
947     {
948       columnInfo = col->GetName();
949       if (col->IsGeometry() == true)
950         {
951           SetItemImage(item, 12);
952           if (col->IsGeometryIndex() == true)
953             icon = 7;
954           else if (col->IsMbrCache() == true)
955             icon = 11;
956           else
957             icon = 6;
958       } else
959         icon = 3;
960       item2 = AppendItem(item, columnInfo, icon);
961       if (col->IsGeometry() == true)
962         {
963           if (col->IsGeometryIndex() == true)
964             SetItemData(item2,
965                         (wxTreeItemData *) (new
966                                             MyObject(MY_VIEW_GEOMETRY_INDEX,
967                                                      viewName,
968                                                      col->GetName())));
969           else if (col->IsMbrCache() == true)
970             SetItemData(item2,
971                         (wxTreeItemData *) (new
972                                             MyObject(MY_VIEW_GEOMETRY_CACHED,
973                                                      viewName,
974                                                      col->GetName())));
975           else
976             SetItemData(item2,
977                         (wxTreeItemData *) (new
978                                             MyObject(MY_VIEW_GEOMETRY, viewName,
979                                                      col->GetName())));
980       } else
981         SetItemData(item2,
982                     (wxTreeItemData *) (new
983                                         MyObject(MY_VIEW_COLUMN, viewName,
984                                                  col->GetName())));
985       col = col->GetNext();
986     }
987   trgr = list.GetFirstTrigger();
988   while (trgr)
989     {
990       // setting up Triggers
991       triggerInfo = trgr->GetName();
992       item2 = AppendItem(item, triggerInfo, 5);
993       SetItemData(item2,
994                   (wxTreeItemData *) (new
995                                       MyObject(MY_TRIGGER, trgr->GetName())));
996       trgr = trgr->GetNext();
997     }
998 }
999 
OnSelChanged(wxTreeEvent & event)1000 void MyTableTree::OnSelChanged(wxTreeEvent & event)
1001 {
1002 //
1003 // selecting some node [mouse action]
1004 //
1005   wxTreeItemId item = event.GetItem();
1006   if (item == Root || item == RootUserData || item == RootTopologies
1007       || item == RootStyling || item == RootIsoMetadata || item == RootMetadata
1008       || item == RootInternal || item == RootSpatialIndex)
1009     return;
1010   MyObject *obj = (MyObject *) GetItemData(item);
1011   if (obj == NULL)
1012     return;
1013   CurrentItem = item;
1014 }
1015 
OnRightClick(wxTreeEvent & event)1016 void MyTableTree::OnRightClick(wxTreeEvent & event)
1017 {
1018 //
1019 // right click on some node [mouse action]
1020 //
1021   wxMenu *menu = new wxMenu();
1022   wxMenuItem *menuItem;
1023   wxString title;
1024   bool table = false;
1025   bool canEdit = false;
1026   bool view = false;
1027   bool column = false;
1028   bool geometry = false;
1029   bool geometry_index = false;
1030   bool geometry_cached = false;
1031   bool view_column = false;
1032   bool view_geometry = false;
1033   bool virtual_column = false;
1034   bool virtual_geometry = false;
1035   bool index = false;
1036   bool trigger = false;
1037   bool attached_db = false;
1038   bool metadata = MainFrame->CheckMetadata();
1039   if (MainFrame->IsConnected() == false)
1040     return;
1041   wxTreeItemId item = event.GetItem();
1042   SelectItem(item);
1043   wxPoint pt = event.GetPoint();
1044   if (item == Root || item == RootUserData || item == RootTopologies
1045       || item == RootStyling || item == RootIsoMetadata || item == RootMetadata
1046       || item == RootInternal || item == RootSpatialIndex)
1047     {
1048       CurrentItem = wxTreeItemId();
1049       menuItem = new wxMenuItem(menu, Tree_Refresh, wxT("&Refresh"));
1050       menu->Append(menuItem);
1051       menu->AppendSeparator();
1052       menuItem =
1053         new wxMenuItem(menu, Tree_QueryViewComposer,
1054                        wxT("Query/View &Composer"));
1055       menuItem->SetBitmap(wxBitmap(composer_xpm));
1056       menu->Append(menuItem);
1057       menu->AppendSeparator();
1058       menuItem = new wxMenuItem(menu, Tree_NewTable, wxT("Create New &Table"));
1059       menu->Append(menuItem);
1060       menuItem = new wxMenuItem(menu, Tree_NewView, wxT("Create New &View"));
1061       menu->Append(menuItem);
1062       menuItem =
1063         new wxMenuItem(menu, Tree_UpdateLayerStatisticsAll,
1064                        wxT("Update Layer &Statistics"));
1065       menu->Append(menuItem);
1066       PopupMenu(menu, pt);
1067       return;
1068     }
1069   MyObject *obj = (MyObject *) GetItemData(item);
1070   if (obj == NULL)
1071     {
1072       CurrentItem = wxTreeItemId();
1073       menuItem = new wxMenuItem(menu, Tree_Refresh, wxT("&Refresh"));
1074       menu->Append(menuItem);
1075       menu->AppendSeparator();
1076       menuItem =
1077         new wxMenuItem(menu, Tree_QueryViewComposer,
1078                        wxT("Query/View &Composer"));
1079       menuItem->SetBitmap(wxBitmap(composer_xpm));
1080       menu->Append(menuItem);
1081       menu->AppendSeparator();
1082       menuItem = new wxMenuItem(menu, Tree_NewTable, wxT("Create New &Table"));
1083       menu->Append(menuItem);
1084       menuItem = new wxMenuItem(menu, Tree_NewView, wxT("Create New &View"));
1085       menu->Append(menuItem);
1086       PopupMenu(menu, pt);
1087       return;
1088     }
1089   switch (obj->GetType())
1090     {
1091       case MY_VTABLE:
1092       case MY_TABLE:
1093         table = true;
1094         break;
1095       case MY_VIEW:
1096         view = true;
1097         break;
1098       case MY_COLUMN:
1099         column = true;
1100         break;
1101       case MY_GEOMETRY:
1102         geometry = true;
1103         break;
1104       case MY_GEOMETRY_INDEX:
1105         geometry_index = true;
1106         break;
1107       case MY_GEOMETRY_CACHED:
1108         geometry_cached = true;
1109         break;
1110       case MY_VIEW_COLUMN:
1111         view_column = true;
1112         break;
1113       case MY_VIEW_GEOMETRY:
1114       case MY_VIEW_GEOMETRY_INDEX:
1115       case MY_VIEW_GEOMETRY_CACHED:
1116         view_geometry = true;
1117         break;
1118       case MY_VIRTUAL_COLUMN:
1119         virtual_column = true;
1120         break;
1121       case MY_VIRTUAL_GEOMETRY:
1122         virtual_geometry = true;
1123         break;
1124       case MY_INDEX:
1125         index = true;
1126         break;
1127       case MY_TRIGGER:
1128         trigger = true;
1129       case MY_ATTACHED:
1130         attached_db = true;
1131         break;
1132     };
1133   if (obj->GetType() == MY_TABLE)
1134     canEdit = true;
1135   CurrentItem = item;
1136   menuItem = new wxMenuItem(menu, Tree_Refresh, wxT("&Refresh"));
1137   menu->Append(menuItem);
1138   if (table == true)
1139     {
1140       if (obj->IsAttached() == true)
1141         {
1142           wxString title =
1143             wxT("Table: ") + obj->GetDbAlias() + wxT(".") + obj->GetName();
1144           menu->SetTitle(title);
1145           menu->AppendSeparator();
1146           menuItem = new wxMenuItem(menu, Tree_Select, wxT("&Query table"));
1147           menu->Append(menuItem);
1148           menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show columns"));
1149           menu->Append(menuItem);
1150           menuItem =
1151             new wxMenuItem(menu, Tree_ShowSql, wxT("&Show CREATE statement"));
1152           menu->Append(menuItem);
1153       } else
1154         {
1155           wxString title = wxT("Table: ") + obj->GetName();
1156           menu->SetTitle(title);
1157           menu->AppendSeparator();
1158           menuItem =
1159             new wxMenuItem(menu, Tree_QueryViewComposer,
1160                            wxT("Query/View &Composer"));
1161           menuItem->SetBitmap(wxBitmap(composer_xpm));
1162           menu->Append(menuItem);
1163           menu->AppendSeparator();
1164           menuItem =
1165             new wxMenuItem(menu, Tree_NewTable, wxT("Create New &Table"));
1166           menu->Append(menuItem);
1167           menuItem =
1168             new wxMenuItem(menu, Tree_NewView, wxT("Create New &View"));
1169           menu->Append(menuItem);
1170           menuItem =
1171             new wxMenuItem(menu, Tree_UpdateLayerStatistics,
1172                            wxT("Update Layer &Statistics"));
1173           menu->Append(menuItem);
1174           menu->AppendSeparator();
1175           if (canEdit == true)
1176             {
1177               menuItem =
1178                 new wxMenuItem(menu, Tree_Edit, wxT("&Edit table rows"));
1179               menu->Append(menuItem);
1180           } else
1181             {
1182               menuItem = new wxMenuItem(menu, Tree_Select, wxT("&Query table"));
1183               menu->Append(menuItem);
1184             }
1185           menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show columns"));
1186           menu->Append(menuItem);
1187           menuItem =
1188             new wxMenuItem(menu, Tree_ShowSql, wxT("&Show CREATE statement"));
1189           menu->Append(menuItem);
1190           menu->AppendSeparator();
1191           wxMenu *maintenanceMenu = new wxMenu();
1192           menuItem =
1193             new wxMenuItem(maintenanceMenu, Tree_NewColumn,
1194                            wxT("Add New &Column"));
1195           maintenanceMenu->Append(menuItem);
1196           menuItem =
1197             new wxMenuItem(maintenanceMenu, Tree_Rename, wxT("&Rename table"));
1198           maintenanceMenu->Append(menuItem);
1199           menuItem =
1200             new wxMenuItem(maintenanceMenu, Tree_Drop, wxT("&Drop table"));
1201           maintenanceMenu->Append(menuItem);
1202           maintenanceMenu->AppendSeparator();
1203           menuItem =
1204             new wxMenuItem(maintenanceMenu, Tree_NewIndex,
1205                            wxT("Create New &Index"));
1206           maintenanceMenu->Append(menuItem);
1207           menuItem =
1208             new wxMenuItem(maintenanceMenu, Tree_NewTrigger,
1209                            wxT("Create New &Trigger"));
1210           maintenanceMenu->Append(menuItem);
1211           if (obj->GetType() == MY_TABLE)
1212             {
1213               maintenanceMenu->AppendSeparator();
1214               menuItem =
1215                 new wxMenuItem(maintenanceMenu, Tree_CheckDuplicates,
1216                                wxT("Check &Duplicate rows"));
1217               maintenanceMenu->Append(menuItem);
1218               menuItem =
1219                 new wxMenuItem(maintenanceMenu, Tree_RemoveDuplicates,
1220                                wxT("Remove Duplicate rows"));
1221             }
1222           maintenanceMenu->Append(menuItem);
1223           menu->AppendSubMenu(maintenanceMenu, wxT("&Maintenance"));
1224           menu->AppendSeparator();
1225           menuItem =
1226             new wxMenuItem(menu, Tree_DumpTxtTab, wxT("Export as &Txt/Tab"));
1227           menu->Append(menuItem);
1228           menuItem = new wxMenuItem(menu, Tree_DumpCsv, wxT("Export as &CSV"));
1229           menu->Append(menuItem);
1230           menuItem =
1231             new wxMenuItem(menu, Tree_DumpHtml, wxT("Export as &HTML"));
1232           menu->Append(menuItem);
1233           menuItem = new wxMenuItem(menu, Tree_DumpDif, wxT("Export as &DIF"));
1234           menu->Append(menuItem);
1235           menuItem =
1236             new wxMenuItem(menu, Tree_DumpSylk, wxT("Export as &SYLK"));
1237           menu->Append(menuItem);
1238           menuItem = new wxMenuItem(menu, Tree_DumpDbf, wxT("Export as &DBF"));
1239           menu->Append(menuItem);
1240           menuItem =
1241             new wxMenuItem(menu, Tree_DumpPostGIS,
1242                            wxT("SQL Dump for &PostGIS"));
1243           menu->Append(menuItem);
1244         }
1245     }
1246   if (view == true)
1247     {
1248       if (obj->IsAttached() == true)
1249         {
1250           wxString title =
1251             wxT("View: ") + obj->GetDbAlias() + wxT(".") + obj->GetName();
1252           menu->SetTitle(title);
1253           menu->AppendSeparator();
1254           menuItem = new wxMenuItem(menu, Tree_Select, wxT("&Query view"));
1255           menu->Append(menuItem);
1256           menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show columns"));
1257           menu->Append(menuItem);
1258           menuItem =
1259             new wxMenuItem(menu, Tree_ShowSql, wxT("&Show CREATE statement"));
1260           menu->Append(menuItem);
1261       } else
1262         {
1263           wxString title = wxT("View: ") + obj->GetName();
1264           menu->SetTitle(title);
1265           menu->AppendSeparator();
1266           menuItem =
1267             new wxMenuItem(menu, Tree_QueryViewComposer,
1268                            wxT("Query/View &Composer"));
1269           menuItem->SetBitmap(wxBitmap(composer_xpm));
1270           menu->Append(menuItem);
1271           menu->AppendSeparator();
1272           menuItem =
1273             new wxMenuItem(menu, Tree_NewTable, wxT("Create New &Table"));
1274           menu->Append(menuItem);
1275           menuItem =
1276             new wxMenuItem(menu, Tree_NewView, wxT("Create New &View"));
1277           menu->Append(menuItem);
1278           menuItem =
1279             new wxMenuItem(menu, Tree_UpdateLayerStatistics,
1280                            wxT("Update Layer &Statistics"));
1281           menu->Append(menuItem);
1282           menu->AppendSeparator();
1283           menuItem = new wxMenuItem(menu, Tree_Select, wxT("&Query view"));
1284           menu->Append(menuItem);
1285           menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show columns"));
1286           menu->Append(menuItem);
1287           menuItem =
1288             new wxMenuItem(menu, Tree_ShowSql, wxT("&Show CREATE statement"));
1289           menu->Append(menuItem);
1290           menu->AppendSeparator();
1291           menuItem = new wxMenuItem(menu, Tree_Drop, wxT("&Drop view"));
1292           menu->Append(menuItem);
1293           menu->AppendSeparator();
1294           menuItem =
1295             new wxMenuItem(menu, Tree_DumpTxtTab, wxT("Export as &Txt/Tab"));
1296           menu->Append(menuItem);
1297           menuItem = new wxMenuItem(menu, Tree_DumpCsv, wxT("Export as &CSV"));
1298           menu->Append(menuItem);
1299           menuItem =
1300             new wxMenuItem(menu, Tree_DumpHtml, wxT("Export as &HTML"));
1301           menu->Append(menuItem);
1302           menuItem = new wxMenuItem(menu, Tree_DumpDif, wxT("Export as &DIF"));
1303           menu->Append(menuItem);
1304           menuItem =
1305             new wxMenuItem(menu, Tree_DumpSylk, wxT("Export as &SYLK"));
1306           menu->Append(menuItem);
1307           menuItem = new wxMenuItem(menu, Tree_DumpDbf, wxT("Export as &DBF"));
1308           menu->Append(menuItem);
1309           menuItem =
1310             new wxMenuItem(menu, Tree_DumpPostGIS,
1311                            wxT("SQL Dump for &PostGIS"));
1312           menu->Append(menuItem);
1313         }
1314     }
1315   if (column == true)
1316     {
1317       wxString title =
1318         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
1319       menu->SetTitle(title);
1320       menu->AppendSeparator();
1321       if (MainFrame->IsPrimaryKey(obj->GetName(), obj->GetColumn()) == false)
1322         {
1323           menuItem = new wxMenuItem(menu, Tree_DropColumn, wxT("&Drop Column"));
1324           menu->Append(menuItem);
1325           menuItem =
1326             new wxMenuItem(menu, Tree_RenameColumn, wxT("&Rename Column"));
1327           menu->Append(menuItem);
1328           menu->AppendSeparator();
1329         }
1330       menuItem =
1331         new wxMenuItem(menu, Tree_CheckGeometry, wxT("&Check geometries"));
1332       menu->Append(menuItem);
1333       menuItem = new wxMenuItem(menu, Tree_MapPreview, wxT("&Map Preview"));
1334       menuItem->SetBitmap(wxBitmap(map_preview_xpm));
1335       menu->Append(menuItem);
1336       menuItem = new wxMenuItem(menu, Tree_Extent, wxT("&Extent"));
1337       menu->Append(menuItem);
1338       menuItem =
1339         new wxMenuItem(menu, Tree_UpdateLayerStatistics,
1340                        wxT("Update Layer &Statistics"));
1341       menu->Append(menuItem);
1342       menuItem = new wxMenuItem(menu, Tree_SetSrid, wxT("&Set SRID"));
1343       menu->Append(menuItem);
1344       if (metadata == true)
1345         {
1346           menu->AppendSeparator();
1347           menuItem =
1348             new wxMenuItem(menu, Tree_Recover, wxT("&Recover geometry column"));
1349           menu->Append(menuItem);
1350         }
1351       menu->AppendSeparator();
1352       menuItem =
1353         new wxMenuItem(menu, Tree_ColumnStats, wxT("&Statistic snapshot"));
1354       menuItem->SetBitmap(wxBitmap(statistics_xpm));
1355       menu->Append(menuItem);
1356     }
1357   if (view_column == true)
1358     {
1359       wxString title =
1360         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
1361       menu->SetTitle(title);
1362       menu->AppendSeparator();
1363       menuItem =
1364         new wxMenuItem(menu, Tree_ColumnStats, wxT("&Statistic snapshot"));
1365       menuItem->SetBitmap(wxBitmap(statistics_xpm));
1366       menu->Append(menuItem);
1367     }
1368   if (virtual_column == true)
1369     {
1370       wxString title =
1371         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
1372       menu->SetTitle(title);
1373       menu->AppendSeparator();
1374       menuItem =
1375         new wxMenuItem(menu, Tree_ColumnStats, wxT("&Statistic snapshot"));
1376       menuItem->SetBitmap(wxBitmap(statistics_xpm));
1377       menu->Append(menuItem);
1378     }
1379   if (geometry == true)
1380     {
1381       wxString title =
1382         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
1383       menu->SetTitle(title);
1384       menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show Spatial Metadata"));
1385       menu->Append(menuItem);
1386       menu->AppendSeparator();
1387       menuItem =
1388         new wxMenuItem(menu, Tree_CheckGeom, wxT("&LWGEOM Check geometries"));
1389       menuItem->SetBitmap(wxBitmap(checkgeom_xpm));
1390       menu->Append(menuItem);
1391       menuItem =
1392         new wxMenuItem(menu, Tree_SaneGeom, wxT("&LWGEOM Sanitize geometries"));
1393       menuItem->SetBitmap(wxBitmap(sanegeom_xpm));
1394       menu->Append(menuItem);
1395       menu->AppendSeparator();
1396       menuItem =
1397         new wxMenuItem(menu, Tree_GisLayerAuth,
1398                        wxT("&GIS layer authorizations"));
1399       menu->Append(menuItem);
1400       menuItem =
1401         new wxMenuItem(menu, Tree_CheckGeometry, wxT("&Check geometries"));
1402       menu->Append(menuItem);
1403       menuItem = new wxMenuItem(menu, Tree_Extent, wxT("&Extent"));
1404       menu->Append(menuItem);
1405       menuItem =
1406         new wxMenuItem(menu, Tree_UpdateLayerStatistics,
1407                        wxT("Update Layer &Statistics"));
1408       menu->Append(menuItem);
1409       menu->AppendSeparator();
1410       menuItem =
1411         new wxMenuItem(menu, Tree_SpatialIndex, wxT("&Build Spatial Index"));
1412       menuItem->SetBitmap(wxBitmap(spatialidx_xpm));
1413       menu->Append(menuItem);
1414       menuItem = new wxMenuItem(menu, Tree_MbrCache, wxT("Build &MBR cache"));
1415       menuItem->SetBitmap(wxBitmap(mbrcache_xpm));
1416       menu->Append(menuItem);
1417       menu->AppendSeparator();
1418       menuItem =
1419         new wxMenuItem(menu, Tree_RebuildTriggers,
1420                        wxT("Rebuild Geometry &Triggers"));
1421       menu->Append(menuItem);
1422       menu->AppendSeparator();
1423       menuItem =
1424         new wxMenuItem(menu, Tree_DumpShp, wxT("Export as &Shapefile"));
1425       menuItem->SetBitmap(wxBitmap(dumpshp_xpm));
1426       menu->Append(menuItem);
1427       menuItem = new wxMenuItem(menu, Tree_DumpKml, wxT("Export as &KML"));
1428       menu->Append(menuItem);
1429       menu->AppendSeparator();
1430       menuItem =
1431         new wxMenuItem(menu, Tree_ElementaryGeoms,
1432                        wxT("&separating elementary Geometries"));
1433       menu->Append(menuItem);
1434       menu->AppendSeparator();
1435       menuItem =
1436         new wxMenuItem(menu, Tree_MalformedGeometries,
1437                        wxT("&Malformed geometries"));
1438       menuItem->SetBitmap(wxBitmap(malformed_geoms_xpm));
1439       menu->Append(menuItem);
1440       menuItem =
1441         new wxMenuItem(menu, Tree_RepairPolygons, wxT("&Repair Polygons"));
1442       menu->Append(menuItem);
1443       menu->AppendSeparator();
1444       menuItem = new wxMenuItem(menu, Tree_MapPreview, wxT("&Map Preview"));
1445       menuItem->SetBitmap(wxBitmap(map_preview_xpm));
1446       menu->Append(menuItem);
1447     }
1448   if (geometry_index == true)
1449     {
1450       wxString title =
1451         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
1452       menu->SetTitle(title);
1453       menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show Spatial Metadata"));
1454       menu->Append(menuItem);
1455       menuItem =
1456         new wxMenuItem(menu, Tree_GisLayerAuth,
1457                        wxT("&GIS layer authorizations"));
1458       menu->Append(menuItem);
1459       menu->AppendSeparator();
1460       menuItem =
1461         new wxMenuItem(menu, Tree_CheckGeom, wxT("&LWGEOM Check geometries"));
1462       menuItem->SetBitmap(wxBitmap(checkgeom_xpm));
1463       menu->Append(menuItem);
1464       menuItem =
1465         new wxMenuItem(menu, Tree_SaneGeom, wxT("&LWGEOM Sanitize geometries"));
1466       menuItem->SetBitmap(wxBitmap(sanegeom_xpm));
1467       menu->Append(menuItem);
1468       menu->AppendSeparator();
1469       menuItem =
1470         new wxMenuItem(menu, Tree_CheckGeometry, wxT("&Check geometries"));
1471       menu->Append(menuItem);
1472       menuItem = new wxMenuItem(menu, Tree_Extent, wxT("&Extent"));
1473       menu->Append(menuItem);
1474       menuItem =
1475         new wxMenuItem(menu, Tree_UpdateLayerStatistics,
1476                        wxT("Update Layer &Statistics"));
1477       menu->Append(menuItem);
1478       menu->AppendSeparator();
1479       menuItem =
1480         new wxMenuItem(menu, Tree_SpatialIndex, wxT("&Remove Spatial Index"));
1481       menuItem->SetBitmap(wxBitmap(kill_spindex_xpm));
1482       menu->Append(menuItem);
1483       menuItem =
1484         new wxMenuItem(menu, Tree_CheckSpatialIndex,
1485                        wxT("&Check Spatial Index"));
1486       menu->Append(menuItem);
1487       menuItem =
1488         new wxMenuItem(menu, Tree_RecoverSpatialIndex,
1489                        wxT("&Recover Spatial Index"));
1490       menu->Append(menuItem);
1491       menu->AppendSeparator();
1492       menuItem =
1493         new wxMenuItem(menu, Tree_RebuildTriggers,
1494                        wxT("Rebuild Geometry &Triggers"));
1495       menu->Append(menuItem);
1496       menu->AppendSeparator();
1497       menuItem =
1498         new wxMenuItem(menu, Tree_DumpShp, wxT("Export as &Shapefile"));
1499       menuItem->SetBitmap(wxBitmap(dumpshp_xpm));
1500       menu->Append(menuItem);
1501       menuItem = new wxMenuItem(menu, Tree_DumpKml, wxT("Export as &KML"));
1502       menu->Append(menuItem);
1503       menu->AppendSeparator();
1504       menuItem =
1505         new wxMenuItem(menu, Tree_ElementaryGeoms,
1506                        wxT("&separating elementary Geometries"));
1507       menu->Append(menuItem);
1508       menu->AppendSeparator();
1509       menuItem =
1510         new wxMenuItem(menu, Tree_MalformedGeometries,
1511                        wxT("&Malformed geometries"));
1512       menuItem->SetBitmap(wxBitmap(malformed_geoms_xpm));
1513       menu->Append(menuItem);
1514       menuItem =
1515         new wxMenuItem(menu, Tree_RepairPolygons, wxT("&Repair Polygons"));
1516       menu->Append(menuItem);
1517       menu->AppendSeparator();
1518       menuItem = new wxMenuItem(menu, Tree_MapPreview, wxT("&Map Preview"));
1519       menuItem->SetBitmap(wxBitmap(map_preview_xpm));
1520       menu->Append(menuItem);
1521     }
1522   if (geometry_cached == true)
1523     {
1524       wxString title =
1525         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
1526       menu->SetTitle(title);
1527       menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show Spatial Metadata"));
1528       menu->Append(menuItem);
1529       menuItem =
1530         new wxMenuItem(menu, Tree_GisLayerAuth,
1531                        wxT("&GIS layer authorizations"));
1532       menu->Append(menuItem);
1533       menu->AppendSeparator();
1534       menuItem =
1535         new wxMenuItem(menu, Tree_CheckGeom, wxT("&LWGEOM Check geometries"));
1536       menuItem->SetBitmap(wxBitmap(checkgeom_xpm));
1537       menu->Append(menuItem);
1538       menuItem =
1539         new wxMenuItem(menu, Tree_SaneGeom, wxT("&LWGEOM Sanitize geometries"));
1540       menuItem->SetBitmap(wxBitmap(sanegeom_xpm));
1541       menu->Append(menuItem);
1542       menu->AppendSeparator();
1543       menuItem =
1544         new wxMenuItem(menu, Tree_CheckGeometry, wxT("&Check geometries"));
1545       menu->Append(menuItem);
1546       menuItem = new wxMenuItem(menu, Tree_Extent, wxT("&Extent"));
1547       menu->Append(menuItem);
1548       menuItem =
1549         new wxMenuItem(menu, Tree_UpdateLayerStatistics,
1550                        wxT("Update Layer &Statistics"));
1551       menu->Append(menuItem);
1552       menu->AppendSeparator();
1553       menuItem = new wxMenuItem(menu, Tree_MbrCache, wxT("&Remove MBR cache"));
1554       menuItem->SetBitmap(wxBitmap(kill_spindex_xpm));
1555       menu->Append(menuItem);
1556       menu->AppendSeparator();
1557       menuItem =
1558         new wxMenuItem(menu, Tree_RebuildTriggers,
1559                        wxT("Rebuild Geometry &Triggers"));
1560       menu->Append(menuItem);
1561       menu->AppendSeparator();
1562       menuItem =
1563         new wxMenuItem(menu, Tree_DumpShp, wxT("Export as &Shapefile"));
1564       menuItem->SetBitmap(wxBitmap(dumpshp_xpm));
1565       menu->Append(menuItem);
1566       menuItem = new wxMenuItem(menu, Tree_DumpKml, wxT("Export as &KML"));
1567       menu->Append(menuItem);
1568       menu->AppendSeparator();
1569       menuItem =
1570         new wxMenuItem(menu, Tree_ElementaryGeoms,
1571                        wxT("&separating elementary Geometries"));
1572       menu->Append(menuItem);
1573       menu->AppendSeparator();
1574       menuItem =
1575         new wxMenuItem(menu, Tree_MalformedGeometries,
1576                        wxT("&Malformed geometries"));
1577       menuItem->SetBitmap(wxBitmap(malformed_geoms_xpm));
1578       menu->Append(menuItem);
1579       menuItem =
1580         new wxMenuItem(menu, Tree_RepairPolygons, wxT("&Repair Polygons"));
1581       menu->Append(menuItem);
1582       menu->AppendSeparator();
1583       menuItem = new wxMenuItem(menu, Tree_MapPreview, wxT("&Map Preview"));
1584       menuItem->SetBitmap(wxBitmap(map_preview_xpm));
1585       menu->Append(menuItem);
1586     }
1587   if (view_geometry == true)
1588     {
1589       wxString title =
1590         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
1591       menu->SetTitle(title);
1592       menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show Spatial Metadata"));
1593       menu->Append(menuItem);
1594       menuItem =
1595         new wxMenuItem(menu, Tree_GisLayerAuth,
1596                        wxT("&GIS layer authorizations"));
1597       menu->Append(menuItem);
1598       menuItem = new wxMenuItem(menu, Tree_Extent, wxT("&Extent"));
1599       menu->Append(menuItem);
1600       menuItem =
1601         new wxMenuItem(menu, Tree_UpdateLayerStatistics,
1602                        wxT("Update Layer &Statistics"));
1603       menu->Append(menuItem);
1604       menu->AppendSeparator();
1605       menuItem =
1606         new wxMenuItem(menu, Tree_DumpShp, wxT("Export as &Shapefile"));
1607       menuItem->SetBitmap(wxBitmap(dumpshp_xpm));
1608       menu->Append(menuItem);
1609       menuItem = new wxMenuItem(menu, Tree_DumpKml, wxT("Export as &KML"));
1610       menu->Append(menuItem);
1611       menu->AppendSeparator();
1612       menuItem =
1613         new wxMenuItem(menu, Tree_ElementaryGeoms,
1614                        wxT("&separating elementary Geometries"));
1615       menu->Append(menuItem);
1616       menu->AppendSeparator();
1617       menuItem =
1618         new wxMenuItem(menu, Tree_MalformedGeometries,
1619                        wxT("&Malformed geometries"));
1620       menuItem->SetBitmap(wxBitmap(malformed_geoms_xpm));
1621       menu->Append(menuItem);
1622       menu->AppendSeparator();
1623       menuItem = new wxMenuItem(menu, Tree_MapPreview, wxT("&Map Preview"));
1624       menuItem->SetBitmap(wxBitmap(map_preview_xpm));
1625       menu->Append(menuItem);
1626     }
1627   if (virtual_geometry == true)
1628     {
1629       wxString title =
1630         wxT("Column: ") + obj->GetName() + wxT(".") + obj->GetColumn();
1631       menu->SetTitle(title);
1632       menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show Spatial Metadata"));
1633       menu->Append(menuItem);
1634       menuItem =
1635         new wxMenuItem(menu, Tree_GisLayerAuth,
1636                        wxT("&GIS layer authorizations"));
1637       menu->Append(menuItem);
1638       menuItem = new wxMenuItem(menu, Tree_Extent, wxT("&Extent"));
1639       menu->Append(menuItem);
1640       menuItem =
1641         new wxMenuItem(menu, Tree_UpdateLayerStatistics,
1642                        wxT("Update Layer &Statistics"));
1643       menu->Append(menuItem);
1644       menu->AppendSeparator();
1645       menuItem = new wxMenuItem(menu, Tree_DumpKml, wxT("Export as &KML"));
1646       menu->Append(menuItem);
1647       menu->AppendSeparator();
1648       menuItem =
1649         new wxMenuItem(menu, Tree_ElementaryGeoms,
1650                        wxT("&separating elementary Geometries"));
1651       menu->Append(menuItem);
1652       menu->AppendSeparator();
1653       menuItem =
1654         new wxMenuItem(menu, Tree_MalformedGeometries,
1655                        wxT("&Malformed geometries"));
1656       menuItem->SetBitmap(wxBitmap(malformed_geoms_xpm));
1657       menu->Append(menuItem);
1658       menu->AppendSeparator();
1659       menuItem = new wxMenuItem(menu, Tree_MapPreview, wxT("&Map Preview"));
1660       menuItem->SetBitmap(wxBitmap(map_preview_xpm));
1661       menu->Append(menuItem);
1662     }
1663   if (index == true)
1664     {
1665       wxString title = wxT("Index: ") + obj->GetName();
1666       menu->SetTitle(title);
1667       menu->AppendSeparator();
1668       menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show index"));
1669       menu->Append(menuItem);
1670       menu->AppendSeparator();
1671       menuItem = new wxMenuItem(menu, Tree_Drop, wxT("&Drop index"));
1672       menu->Append(menuItem);
1673     }
1674   if (trigger == true)
1675     {
1676       wxString title = wxT("Trigger: ") + obj->GetName();
1677       menu->SetTitle(title);
1678       menu->AppendSeparator();
1679       menuItem = new wxMenuItem(menu, Tree_Show, wxT("&Show trigger"));
1680       menu->Append(menuItem);
1681       menu->AppendSeparator();
1682       menuItem = new wxMenuItem(menu, Tree_Drop, wxT("&Drop trigger"));
1683       menu->Append(menuItem);
1684     }
1685   if (attached_db == true)
1686     {
1687       wxString title = wxT("Attached DB: ") + obj->GetName();
1688       menu->SetTitle(title);
1689       menu->AppendSeparator();
1690       menuItem = new wxMenuItem(menu, Tree_Detach, wxT("&Detach Database"));
1691       menu->Append(menuItem);
1692     }
1693   PopupMenu(menu, pt);
1694 }
1695 
OnCmdQueryViewComposer(wxCommandEvent & WXUNUSED (event))1696 void MyTableTree::OnCmdQueryViewComposer(wxCommandEvent & WXUNUSED(event))
1697 {
1698 //
1699 // menu event - query/view composer invoked
1700 //
1701   MainFrame->QueryViewComposer();
1702 }
1703 
OnCmdNewTable(wxCommandEvent & WXUNUSED (event))1704 void MyTableTree::OnCmdNewTable(wxCommandEvent & WXUNUSED(event))
1705 {
1706 //
1707 // menu event - new table creation required
1708 //
1709   wxString sql;
1710   sql = wxT("CREATE TABLE ...table-name... (\n");
1711   sql += wxT("...column1,\n...column2,\n...columnN)");
1712   MainFrame->SetSql(sql, false);
1713 }
1714 
OnCmdNewView(wxCommandEvent & WXUNUSED (event))1715 void MyTableTree::OnCmdNewView(wxCommandEvent & WXUNUSED(event))
1716 {
1717 //
1718 // menu event - new view creation required
1719 //
1720   wxString sql;
1721   sql = wxT("CREATE VIEW ...view-name... AS\n");
1722   sql += wxT("SELECT ...sql-select-statement...");
1723   MainFrame->SetSql(sql, false);
1724 }
1725 
OnCmdNewIndex(wxCommandEvent & WXUNUSED (event))1726 void MyTableTree::OnCmdNewIndex(wxCommandEvent & WXUNUSED(event))
1727 {
1728 //
1729 // menu event - new index creation required
1730 //
1731   wxString sql;
1732   char xname[1024];
1733   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
1734   if (obj == NULL)
1735     return;
1736   if (obj->GetType() == MY_TABLE)
1737     {
1738       sql = wxT("CREATE [ UNIQUE ] INDEX ...index-name...\nON ");
1739       strcpy(xname, obj->GetName().ToUTF8());
1740       MainFrame->DoubleQuotedSql(xname);
1741       sql += wxString::FromUTF8(xname);
1742       sql += wxT("\n(\n...column1, column2, columnN...\n)");
1743       MainFrame->SetSql(sql, false);
1744     }
1745 }
1746 
OnCmdNewTrigger(wxCommandEvent & WXUNUSED (event))1747 void MyTableTree::OnCmdNewTrigger(wxCommandEvent & WXUNUSED(event))
1748 {
1749 //
1750 // menu event - new trigger creation required
1751 //
1752   wxString sql;
1753   char xname[1024];
1754   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
1755   if (obj == NULL)
1756     return;
1757   if (obj->GetType() == MY_TABLE)
1758     {
1759       sql = wxT("CREATE TRIGGER ...trigger-name...\n[ BEFORE | AFTER ]\n");
1760       sql += wxT("[ INSERT | UPDATE | DELETE ]\nON ");
1761       strcpy(xname, obj->GetName().ToUTF8());
1762       MainFrame->DoubleQuotedSql(xname);
1763       sql += wxString::FromUTF8(xname);
1764       sql += wxT("\n...sql-statement...");
1765       MainFrame->SetSql(sql, false);
1766     }
1767 }
1768 
OnCmdNewColumn(wxCommandEvent & WXUNUSED (event))1769 void MyTableTree::OnCmdNewColumn(wxCommandEvent & WXUNUSED(event))
1770 {
1771 //
1772 // menu event - new column creation required
1773 //
1774   wxString sql;
1775   char xname[1024];
1776   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
1777   if (obj == NULL)
1778     return;
1779   if (obj->GetType() == MY_TABLE)
1780     {
1781       sql = wxT("ALTER TABLE ");
1782       strcpy(xname, obj->GetName().ToUTF8());
1783       MainFrame->DoubleQuotedSql(xname);
1784       sql += wxString::FromUTF8(xname);
1785       sql += wxT("\nADD COLUMN ...column-name column-type...");
1786       MainFrame->SetSql(sql, false);
1787     }
1788 }
1789 
OnCmdSelect(wxCommandEvent & WXUNUSED (event))1790 void MyTableTree::OnCmdSelect(wxCommandEvent & WXUNUSED(event))
1791 {
1792 //
1793 // menu event - examining table rows required
1794 //
1795   wxString sql;
1796   char xname[1024];
1797   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
1798   if (obj == NULL)
1799     return;
1800   sql = wxT("SELECT * FROM ");
1801   if (obj->IsAttached() == true)
1802     sql += obj->GetDbAlias() + wxT(".");
1803   strcpy(xname, obj->GetName().ToUTF8());
1804   MainFrame->DoubleQuotedSql(xname);
1805   sql += wxString::FromUTF8(xname);
1806   MainFrame->SetSql(sql, true);
1807 }
1808 
OnCmdShow(wxCommandEvent & WXUNUSED (event))1809 void MyTableTree::OnCmdShow(wxCommandEvent & WXUNUSED(event))
1810 {
1811 //
1812 // menu event - examining full infos required
1813 //
1814   wxString sql;
1815   char xname[1024];
1816   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
1817   if (obj == NULL)
1818     return;
1819   if (obj->GetType() == MY_TABLE || obj->GetType() == MY_VTABLE
1820       || obj->GetType() == MY_VIEW)
1821     {
1822       if (obj->IsAttached() == true)
1823         sql = wxT("PRAGMA ") + obj->GetDbAlias() + wxT(".table_info(");
1824       else
1825         sql = wxT("PRAGMA table_info(");
1826       strcpy(xname, obj->GetName().ToUTF8());
1827       MainFrame->DoubleQuotedSql(xname);
1828       sql += wxString::FromUTF8(xname);
1829       sql += wxT(")");
1830     }
1831   if (obj->GetType() == MY_GEOMETRY || obj->GetType() == MY_GEOMETRY_INDEX
1832       || obj->GetType() == MY_GEOMETRY_CACHED)
1833     {
1834       sql = wxT("SELECT *\nFROM geom_cols_ref_sys\n");
1835       sql += wxT("WHERE Lower(f_table_name) = Lower('");
1836       strcpy(xname, obj->GetName().ToUTF8());
1837       MainFrame->CleanSqlString(xname);
1838       sql += wxString::FromUTF8(xname);
1839       sql += wxT("')\nAND Lower(f_geometry_column) = Lower('");
1840       strcpy(xname, obj->GetColumn().ToUTF8());
1841       MainFrame->CleanSqlString(xname);
1842       sql += wxString::FromUTF8(xname);
1843       sql += wxT("')");
1844     }
1845   if (obj->GetType() == MY_VIEW_GEOMETRY
1846       || obj->GetType() == MY_VIEW_GEOMETRY_INDEX
1847       || obj->GetType() == MY_VIEW_GEOMETRY_CACHED)
1848     {
1849       sql = wxT("SELECT *\nFROM views_geometry_columns AS a\n");
1850       sql += wxT("JOIN geometry_columns AS b ON (");
1851       sql += wxT("Lower(a.f_table_name) = Lower(b.f_table_name) AND ");
1852       sql += wxT("Lower(a.f_geometry_column) = Lower(b.f_geometry_column))\n");
1853       sql += wxT("JOIN spatial_ref_sys USING (srid)\n");
1854       sql += wxT("WHERE Lower(view_name) = Lower('");
1855       strcpy(xname, obj->GetName().ToUTF8());
1856       MainFrame->CleanSqlString(xname);
1857       sql += wxString::FromUTF8(xname);
1858       sql += wxT("')\nAND Lower(view_geometry) = Lower('");
1859       strcpy(xname, obj->GetColumn().ToUTF8());
1860       MainFrame->CleanSqlString(xname);
1861       sql += wxString::FromUTF8(xname);
1862       sql += wxT("')");
1863     }
1864   if (obj->GetType() == MY_VIRTUAL_GEOMETRY)
1865     {
1866       sql = wxT("SELECT *\nFROM virts_geometry_columns\n");
1867       sql += wxT("JOIN spatial_ref_sys USING (srid)\n");
1868       sql += wxT("WHERE Lower(virt_name) = Lower('");
1869       strcpy(xname, obj->GetName().ToUTF8());
1870       MainFrame->CleanSqlString(xname);
1871       sql += wxString::FromUTF8(xname);
1872       sql += wxT("')\nAND Lower(virt_geometry) = Lower('");
1873       strcpy(xname, obj->GetColumn().ToUTF8());
1874       MainFrame->CleanSqlString(xname);
1875       sql += wxString::FromUTF8(xname);
1876       sql += wxT("')");
1877     }
1878   if (obj->GetType() == MY_INDEX)
1879     {
1880       sql = wxT("PRAGMA index_info(");
1881       strcpy(xname, obj->GetName().ToUTF8());
1882       MainFrame->DoubleQuotedSql(xname);
1883       sql += wxString::FromUTF8(xname);
1884       sql += wxT(")");
1885     }
1886   if (obj->GetType() == MY_TRIGGER)
1887     {
1888       sql =
1889         wxT
1890         ("SELECT sql FROM sqlite_master\nWHERE type = 'trigger' AND name = '");
1891       strcpy(xname, obj->GetName().ToUTF8());
1892       MainFrame->CleanSqlString(xname);
1893       sql += wxString::FromUTF8(xname);
1894       sql += wxT("'");
1895     }
1896   if (sql.Len() < 1)
1897     return;
1898   MainFrame->SetSql(sql, true);
1899 }
1900 
OnCmdDrop(wxCommandEvent & WXUNUSED (event))1901 void MyTableTree::OnCmdDrop(wxCommandEvent & WXUNUSED(event))
1902 {
1903 //
1904 // menu event - dropping some object required
1905 //
1906   wxString sql;
1907   wxString sql2;
1908   wxString msg;
1909   char *errMsg = NULL;
1910   int ret;
1911   wxString name;
1912   char xname[1024];
1913   sqlite3 *sqlite = MainFrame->GetSqlite();
1914   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
1915   if (obj == NULL)
1916     return;
1917   if (obj->GetType() == MY_TABLE)
1918     {
1919       sql = wxT("DROP TABLE IF EXISTS ");
1920       strcpy(xname, obj->GetName().ToUTF8());
1921       MainFrame->DoubleQuotedSql(xname);
1922       sql += wxString::FromUTF8(xname);
1923       msg = wxT("Do you really intend to drop the Table named: ");
1924       msg += obj->GetName();
1925       msg += wxT("\n[and any other related object] ?");
1926     }
1927   if (obj->GetType() == MY_VTABLE)
1928     {
1929       msg = wxT("Do you really intend to drop the VirtualTable named: ");
1930       msg += obj->GetName();
1931       msg += wxT(" ?");
1932       sql = wxT("DROP TABLE IF EXISTS ");
1933       strcpy(xname, obj->GetName().ToUTF8());
1934       MainFrame->DoubleQuotedSql(xname);
1935       sql += wxString::FromUTF8(xname);
1936     }
1937   if (obj->GetType() == MY_VIEW)
1938     {
1939       msg = wxT("Do you really intend to drop the View named: ");
1940       msg += obj->GetName();
1941       msg += wxT(" ?");
1942       sql = wxT("DROP VIEW IF EXISTS ");
1943       strcpy(xname, obj->GetName().ToUTF8());
1944       MainFrame->DoubleQuotedSql(xname);
1945       sql += wxString::FromUTF8(xname);
1946     }
1947   if (obj->GetType() == MY_INDEX)
1948     {
1949       msg = wxT("Do you really intend to drop the Index named: ");
1950       msg += obj->GetName();
1951       msg += wxT(" ?");
1952       sql = wxT("DROP INDEX IF EXISTS ");
1953       strcpy(xname, obj->GetName().ToUTF8());
1954       MainFrame->DoubleQuotedSql(xname);
1955       sql += wxString::FromUTF8(xname);
1956     }
1957   if (obj->GetType() == MY_TRIGGER)
1958     {
1959       msg = wxT("Do you really intend to drop the Trigger named: ");
1960       msg += obj->GetName();
1961       msg += wxT(" ?");
1962       sql = wxT("DROP TRIGGER IF EXISTS ");
1963       strcpy(xname, obj->GetName().ToUTF8());
1964       MainFrame->DoubleQuotedSql(xname);
1965       sql += wxString::FromUTF8(xname);
1966     }
1967   wxMessageDialog confirm(this, msg, wxT("Confirming DROP"),
1968                           wxOK | wxCANCEL | wxICON_QUESTION);
1969   ret = confirm.ShowModal();
1970   if (ret != wxID_OK)
1971     return;
1972   ::wxBeginBusyCursor();
1973   if (obj->GetType() == MY_TABLE)
1974     {
1975       strcpy(xname, obj->GetName().ToUTF8());
1976       gaiaDropTable(sqlite, xname);
1977     }
1978   if (obj->GetType() == MY_VTABLE)
1979     {
1980       strcpy(xname, obj->GetName().ToUTF8());
1981       gaiaDropTable(sqlite, xname);
1982     }
1983   if (obj->GetType() == MY_VIEW)
1984     {
1985       strcpy(xname, obj->GetName().ToUTF8());
1986       gaiaDropTable(sqlite, xname);
1987     }
1988   ret = sqlite3_exec(sqlite, sql.ToUTF8(), NULL, NULL, &errMsg);
1989   if (ret != SQLITE_OK)
1990     {
1991       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
1992                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1993       sqlite3_free(errMsg);
1994       ::wxEndBusyCursor();
1995       goto rollback;
1996     }
1997   ::wxEndBusyCursor();
1998   wxMessageBox(wxT("Selected object '") + obj->GetName() +
1999                wxT("' was successfully removed"), wxT("spatialite_gui"),
2000                wxOK | wxICON_INFORMATION, this);
2001   MainFrame->InitTableTree();
2002   return;
2003 rollback:
2004   ret = sqlite3_exec(sqlite, "ROLLBACK", NULL, NULL, &errMsg);
2005   if (ret != SQLITE_OK)
2006     {
2007       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2008                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2009       sqlite3_free(errMsg);
2010       ::wxEndBusyCursor();
2011       return;
2012     }
2013   ::wxEndBusyCursor();
2014   wxMessageBox(wxT
2015                ("An error occurred\n\na ROLLBACK was automatically performed"),
2016                wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
2017 }
2018 
OnCmdRename(wxCommandEvent & WXUNUSED (event))2019 void MyTableTree::OnCmdRename(wxCommandEvent & WXUNUSED(event))
2020 {
2021 //
2022 // menu event - table renaming required
2023 //
2024   wxString sql;
2025   char xname[1024];
2026   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
2027   if (obj == NULL)
2028     return;
2029   if (obj->GetType() == MY_TABLE || obj->GetType() == MY_VTABLE)
2030     {
2031       sql = wxT("ALTER TABLE ");
2032       strcpy(xname, obj->GetName().ToUTF8());
2033       MainFrame->DoubleQuotedSql(xname);
2034       sql += wxString::FromUTF8(xname);
2035       sql += wxT("\nRENAME TO ...new-table-name...");
2036       MainFrame->SetSql(sql, false);
2037     }
2038 }
2039 
OnCmdDetachDB(wxCommandEvent & WXUNUSED (event))2040 void MyTableTree::OnCmdDetachDB(wxCommandEvent & WXUNUSED(event))
2041 {
2042 //
2043 // menu event - DETACH DATABASE
2044 //
2045   wxString sql;
2046   int ret;
2047   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
2048   if (obj == NULL)
2049     return;
2050   if (obj->GetType() == MY_ATTACHED)
2051     {
2052       wxString msg = wxT("Do you really intend to detach this database ?\n\n");
2053       msg += obj->GetName();
2054       msg += wxT(" AS ");
2055       msg += obj->GetDbAlias();
2056       wxMessageDialog confirm(this, msg, wxT("Confirming DETACH DATABASE"),
2057                               wxOK | wxCANCEL | wxICON_QUESTION);
2058       ret = confirm.ShowModal();
2059       if (ret != wxID_OK)
2060         return;
2061 
2062       char *errMsg = NULL;
2063       sqlite3 *sqlite = MainFrame->GetSqlite();
2064       wxString sql = wxT("DETACH DATABASE ") + obj->GetDbAlias();
2065       ret = sqlite3_exec(sqlite, sql.ToUTF8(), NULL, NULL, &errMsg);
2066       if (ret != SQLITE_OK)
2067         {
2068           wxMessageBox(wxT("SQLite SQL error: ") +
2069                        wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
2070                        wxOK | wxICON_ERROR, this);
2071           sqlite3_free(errMsg);
2072           return;
2073         }
2074       MainFrame->InitTableTree();
2075     }
2076 }
2077 
OnCmdRefresh(wxCommandEvent & WXUNUSED (event))2078 void MyTableTree::OnCmdRefresh(wxCommandEvent & WXUNUSED(event))
2079 {
2080 //
2081 // menu event - refreshing the Tree
2082 //
2083   MainFrame->InitTableTree();
2084 }
2085 
OnCmdRecover(wxCommandEvent & WXUNUSED (event))2086 void MyTableTree::OnCmdRecover(wxCommandEvent & WXUNUSED(event))
2087 {
2088 //
2089 // menu event - Recover Geometry
2090 //
2091   char *errMsg = NULL;
2092   int ret;
2093   wxString sql;
2094   int i;
2095   char **results;
2096   int rows;
2097   int columns;
2098   int retval = 0;
2099   int srid = -1;
2100   char dummy[128];
2101   wxString type;
2102   wxString dims;
2103   RecoverDialog dlg;
2104   char xname[1024];
2105   sqlite3 *sqlite = MainFrame->GetSqlite();
2106   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
2107   if (obj == NULL)
2108     return;
2109   if (obj->GetType() == MY_COLUMN)
2110     {
2111       // trying to recover a geometry column
2112       if (MainFrame->CheckMetadata() == false)
2113         {
2114           wxMessageBox(wxT
2115                        ("Missing Spatial Metadata tables\n\ntry to run the 'init_spatialite.sql' script ..."),
2116                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2117           return;
2118         }
2119       dlg.Create(MainFrame, obj->GetName(), obj->GetColumn());
2120       ret = dlg.ShowModal();
2121       if (ret == wxID_OK)
2122         {
2123           srid = dlg.GetSrid();
2124           type = dlg.GetType();
2125           dims = dlg.GetDimension();
2126           ::wxBeginBusyCursor();
2127           ret = sqlite3_exec(sqlite, "BEGIN", NULL, NULL, &errMsg);
2128           if (ret != SQLITE_OK)
2129             {
2130               wxMessageBox(wxT("SQLite SQL error: ") +
2131                            wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
2132                            wxOK | wxICON_ERROR, this);
2133               sqlite3_free(errMsg);
2134               ::wxEndBusyCursor();
2135               return;
2136             }
2137           sql = wxT("SELECT RecoverGeometryColumn('");
2138           strcpy(xname, obj->GetName().ToUTF8());
2139           MainFrame->CleanSqlString(xname);
2140           sql += wxString::FromUTF8(xname);
2141           sql += wxT("', '");
2142           strcpy(xname, obj->GetColumn().ToUTF8());
2143           MainFrame->CleanSqlString(xname);
2144           sql += wxString::FromUTF8(xname);
2145           sprintf(dummy, "', %d, '", srid);
2146           sql += wxString::FromUTF8(dummy);
2147           sql += type;
2148           sql += wxT("', '");
2149           sql += dims;
2150           sql += wxT("')");
2151           ret =
2152             sqlite3_get_table(sqlite, sql.ToUTF8(), &results, &rows, &columns,
2153                               &errMsg);
2154           if (ret != SQLITE_OK)
2155             {
2156               wxMessageBox(wxT("SQLite SQL error: ") +
2157                            wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
2158                            wxOK | wxICON_ERROR, this);
2159               sqlite3_free(errMsg);
2160               goto rollback;
2161             }
2162           if (rows < 1)
2163             ;
2164           else
2165             {
2166               for (i = 1; i <= rows; i++)
2167                 {
2168                   if (results[(i * columns) + 0])
2169                     retval = atoi(results[(i * columns) + 0]);
2170                 }
2171             }
2172           sqlite3_free_table(results);
2173           if (!retval)
2174             goto rollback;
2175           ret = sqlite3_exec(sqlite, "COMMIT", NULL, NULL, &errMsg);
2176           if (ret != SQLITE_OK)
2177             {
2178               wxMessageBox(wxT("SQLite SQL error: ") +
2179                            wxString::FromUTF8(errMsg), wxT("spatialite_gui"),
2180                            wxOK | wxICON_ERROR, this);
2181               sqlite3_free(errMsg);
2182               ::wxEndBusyCursor();
2183               return;
2184             }
2185           ::wxEndBusyCursor();
2186           wxMessageBox(wxT("Geometry column ") + obj->GetName() +
2187                        wxT(".") + obj->GetColumn() +
2188                        wxT(" was successfully recovered"),
2189                        wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
2190         }
2191     }
2192   return;
2193 rollback:
2194   ret = sqlite3_exec(sqlite, "ROLLBACK", NULL, NULL, &errMsg);
2195   if (ret != SQLITE_OK)
2196     {
2197       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2198                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2199       sqlite3_free(errMsg);
2200       ::wxEndBusyCursor();
2201       return;
2202     }
2203   ::wxEndBusyCursor();
2204   wxMessageBox(wxT
2205                ("Geometry column doesn't satisfies required constraints\n\na ROLLBACK was automatically performed"),
2206                wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
2207 }
2208 
OnCmdShowSql(wxCommandEvent & WXUNUSED (event))2209 void MyTableTree::OnCmdShowSql(wxCommandEvent & WXUNUSED(event))
2210 {
2211 //
2212 // menu event - Showing CREATE TABLE statement
2213 //
2214   wxString sql;
2215   char xname[1024];
2216   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
2217   if (obj == NULL)
2218     return;
2219   if (obj->GetType() == MY_TABLE || obj->GetType() == MY_VTABLE)
2220     {
2221       sql = wxT("SELECT sql FROM ");
2222       if (obj->IsAttached() == true)
2223         sql += obj->GetDbAlias() + wxT(".");
2224       if (obj->IsTemporary() == true)
2225         sql += wxT("sqlite_temp_master");
2226       else
2227         sql += wxT("sqlite_master");
2228       sql += wxT("\nWHERE type = 'table' AND name = '");
2229       strcpy(xname, obj->GetName().ToUTF8());
2230       MainFrame->CleanSqlString(xname);
2231       sql += wxString::FromUTF8(xname);
2232       sql += wxT("'");
2233       MainFrame->SetSql(sql, true);
2234     }
2235   if (obj->GetType() == MY_VIEW)
2236     {
2237       sql = wxT("SELECT sql FROM ");
2238       if (obj->IsAttached() == true)
2239         sql += obj->GetDbAlias() + wxT(".");
2240       if (obj->IsTemporary() == true)
2241         sql += wxT("sqlite_temp_master");
2242       else
2243         sql += wxT("sqlite_master");
2244       sql += wxT("\nWHERE type = 'view' AND name = '");
2245       strcpy(xname, obj->GetName().ToUTF8());
2246       MainFrame->CleanSqlString(xname);
2247       sql += wxString::FromUTF8(xname);
2248       sql += wxT("'");
2249       MainFrame->SetSql(sql, true);
2250     }
2251 }
2252 
OnCmdCheckSpatialIndex(wxCommandEvent & WXUNUSED (event))2253 void MyTableTree::OnCmdCheckSpatialIndex(wxCommandEvent & WXUNUSED(event))
2254 {
2255 //
2256 // menu event - Check Spatial Index for validity
2257 //
2258   char *errMsg = NULL;
2259   int ret;
2260   wxString sql;
2261   wxString msg;
2262   int i;
2263   char **results;
2264   int rows;
2265   int columns;
2266   int retval = 0;
2267   char xtable[1024];
2268   char xcolumn[1024];
2269   sqlite3 *sqlite = MainFrame->GetSqlite();
2270   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
2271   if (obj->GetType() == MY_GEOMETRY_INDEX)
2272     {
2273       // checking the Spatial Index
2274       ::wxBeginBusyCursor();
2275       strcpy(xtable, obj->GetName().ToUTF8());
2276       MainFrame->CleanSqlString(xtable);
2277       strcpy(xcolumn, obj->GetColumn().ToUTF8());
2278       MainFrame->CleanSqlString(xcolumn);
2279       sql = wxT("SELECT CheckSpatialIndex('");
2280       sql += wxString::FromUTF8(xtable);
2281       sql += wxT("', '");
2282       sql += wxString::FromUTF8(xcolumn);
2283       sql += wxT("')");
2284       ret =
2285         sqlite3_get_table(sqlite, sql.ToUTF8(), &results, &rows, &columns,
2286                           &errMsg);
2287       if (ret != SQLITE_OK)
2288         {
2289           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2290                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2291           sqlite3_free(errMsg);
2292           return;
2293         }
2294       if (rows < 1)
2295         ;
2296       else
2297         {
2298           for (i = 1; i <= rows; i++)
2299             {
2300               if (results[(i * columns) + 0])
2301                 retval = atoi(results[(i * columns) + 0]);
2302             }
2303         }
2304       sqlite3_free_table(results);
2305       ::wxEndBusyCursor();
2306       if (retval)
2307         wxMessageBox(wxT("Spatial Index idx_") + obj->GetName() +
2308                      wxT("_") + obj->GetColumn() +
2309                      wxT(" is valid and consistent"), wxT("spatialite_gui"),
2310                      wxOK | wxICON_INFORMATION, this);
2311       else
2312         wxMessageBox(wxT("Spatial Index idx_") + obj->GetName() +
2313                      wxT("_") + obj->GetColumn() +
2314                      wxT(" is invalid and inconsistent\n") +
2315                      wxT
2316                      ("Please, recover this Spatial Index as soon as possible"),
2317                      wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
2318     }
2319 }
2320 
OnCmdRecoverSpatialIndex(wxCommandEvent & WXUNUSED (event))2321 void MyTableTree::OnCmdRecoverSpatialIndex(wxCommandEvent & WXUNUSED(event))
2322 {
2323 //
2324 // menu event - Recover Spatial Index (rebuilding from scratch)
2325 //
2326   char *errMsg = NULL;
2327   int ret;
2328   wxString sql;
2329   wxString msg;
2330   int i;
2331   char **results;
2332   int rows;
2333   int columns;
2334   int retval = 0;
2335   char xtable[1024];
2336   char xcolumn[1024];
2337   sqlite3 *sqlite = MainFrame->GetSqlite();
2338   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
2339   if (obj->GetType() == MY_GEOMETRY_INDEX)
2340     {
2341       // recovering the Spatial Index
2342       ::wxBeginBusyCursor();
2343       strcpy(xtable, obj->GetName().ToUTF8());
2344       MainFrame->CleanSqlString(xtable);
2345       strcpy(xcolumn, obj->GetColumn().ToUTF8());
2346       MainFrame->CleanSqlString(xcolumn);
2347       sql = wxT("SELECT RecoverSpatialIndex('");
2348       sql += wxString::FromUTF8(xtable);
2349       sql += wxT("', '");
2350       sql += wxString::FromUTF8(xcolumn);
2351       sql += wxT("')");
2352       ret =
2353         sqlite3_get_table(sqlite, sql.ToUTF8(), &results, &rows, &columns,
2354                           &errMsg);
2355       if (ret != SQLITE_OK)
2356         {
2357           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2358                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2359           sqlite3_free(errMsg);
2360           return;
2361         }
2362       if (rows < 1)
2363         ;
2364       else
2365         {
2366           for (i = 1; i <= rows; i++)
2367             {
2368               if (results[(i * columns) + 0])
2369                 retval = atoi(results[(i * columns) + 0]);
2370             }
2371         }
2372       sqlite3_free_table(results);
2373       ::wxEndBusyCursor();
2374       if (retval)
2375         wxMessageBox(wxT("Spatial Index idx_") + obj->GetName() +
2376                      wxT("_") + obj->GetColumn() +
2377                      wxT(" was succesfully recovered"), wxT("spatialite_gui"),
2378                      wxOK | wxICON_INFORMATION, this);
2379       else
2380         wxMessageBox(wxT("ERROR: unable to recover Spatial Index idx_") +
2381                      obj->GetName() + wxT("_") + obj->GetColumn(),
2382                      wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2383     }
2384 }
2385 
OnCmdSpatialIndex(wxCommandEvent & WXUNUSED (event))2386 void MyTableTree::OnCmdSpatialIndex(wxCommandEvent & WXUNUSED(event))
2387 {
2388 //
2389 // menu event - Spatial Index creation-destruction
2390 //
2391   char *errMsg = NULL;
2392   int ret;
2393   wxString sql;
2394   wxString msg;
2395   int i;
2396   char **results;
2397   int rows;
2398   int columns;
2399   int retval = 0;
2400   wxString name;
2401   char xname[1024];
2402   char xtable[1024];
2403   char xcolumn[1024];
2404   sqlite3 *sqlite = MainFrame->GetSqlite();
2405   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
2406   if (obj == NULL)
2407     return;
2408   if (obj->GetType() == MY_GEOMETRY)
2409     {
2410       // creating the Spatial Index
2411       ::wxBeginBusyCursor();
2412       ret = sqlite3_exec(sqlite, "BEGIN", NULL, NULL, &errMsg);
2413       if (ret != SQLITE_OK)
2414         {
2415           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2416                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2417           sqlite3_free(errMsg);
2418           ::wxEndBusyCursor();
2419           return;
2420         }
2421       strcpy(xtable, obj->GetName().ToUTF8());
2422       MainFrame->CleanSqlString(xtable);
2423       strcpy(xcolumn, obj->GetColumn().ToUTF8());
2424       MainFrame->CleanSqlString(xcolumn);
2425       sql = wxT("SELECT CreateSpatialIndex('");
2426       sql += wxString::FromUTF8(xtable);
2427       sql += wxT("', '");
2428       sql += wxString::FromUTF8(xcolumn);
2429       sql += wxT("')");
2430       ret =
2431         sqlite3_get_table(sqlite, sql.ToUTF8(), &results, &rows, &columns,
2432                           &errMsg);
2433       if (ret != SQLITE_OK)
2434         {
2435           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2436                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2437           sqlite3_free(errMsg);
2438           goto rollback;
2439         }
2440       if (rows < 1)
2441         ;
2442       else
2443         {
2444           for (i = 1; i <= rows; i++)
2445             {
2446               if (results[(i * columns) + 0])
2447                 retval = atoi(results[(i * columns) + 0]);
2448             }
2449         }
2450       sqlite3_free_table(results);
2451       if (!retval)
2452         goto rollback;
2453       ret = sqlite3_exec(sqlite, "COMMIT", NULL, NULL, &errMsg);
2454       if (ret != SQLITE_OK)
2455         {
2456           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2457                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2458           sqlite3_free(errMsg);
2459           ::wxEndBusyCursor();
2460           return;
2461         }
2462       ::wxEndBusyCursor();
2463       wxMessageBox(wxT("Spatial Index idx_") + obj->GetName() +
2464                    wxT("_") + obj->GetColumn() +
2465                    wxT(" was successfully created"), wxT("spatialite_gui"),
2466                    wxOK | wxICON_INFORMATION, this);
2467       MainFrame->InitTableTree();
2468   } else if (obj->GetType() == MY_GEOMETRY_INDEX)
2469     {
2470       // dropping the Spatial Index
2471       ::wxBeginBusyCursor();
2472       ret = sqlite3_exec(sqlite, "BEGIN", NULL, NULL, &errMsg);
2473       if (ret != SQLITE_OK)
2474         {
2475           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2476                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2477           sqlite3_free(errMsg);
2478           ::wxEndBusyCursor();
2479           return;
2480         }
2481       strcpy(xtable, obj->GetName().ToUTF8());
2482       MainFrame->CleanSqlString(xtable);
2483       strcpy(xcolumn, obj->GetColumn().ToUTF8());
2484       MainFrame->CleanSqlString(xcolumn);
2485       sql = wxT("SELECT DisableSpatialIndex('");
2486       sql += wxString::FromUTF8(xtable);
2487       sql += wxT("', '");
2488       sql += wxString::FromUTF8(xcolumn);
2489       sql += wxT("')");
2490       msg = wxT("Do you really intend to delete the SpatialIndex\n");
2491       msg += wxT("on column ");
2492       msg += obj->GetName();
2493       msg += wxT(".");
2494       msg += obj->GetColumn();
2495       msg += wxT(" ?");
2496       wxMessageDialog confirm(this, msg, wxT("Confirming Delete Spatial Index"),
2497                               wxOK | wxCANCEL | wxICON_QUESTION);
2498       ret = confirm.ShowModal();
2499       if (ret != wxID_OK)
2500         return;
2501       ret =
2502         sqlite3_get_table(sqlite, sql.ToUTF8(), &results, &rows, &columns,
2503                           &errMsg);
2504       if (ret != SQLITE_OK)
2505         {
2506           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2507                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2508           sqlite3_free(errMsg);
2509           goto rollback;
2510         }
2511       if (rows < 1)
2512         ;
2513       else
2514         {
2515           for (i = 1; i <= rows; i++)
2516             {
2517               if (results[(i * columns) + 0])
2518                 retval = atoi(results[(i * columns) + 0]);
2519             }
2520         }
2521       sqlite3_free_table(results);
2522       if (!retval)
2523         goto rollback;
2524       sql = wxT("DROP TABLE IF EXISTS ");
2525       name = wxT("idx_");
2526       name += obj->GetName();
2527       name += wxT("_");
2528       name += obj->GetColumn();
2529       strcpy(xname, name.ToUTF8());
2530       MainFrame->DoubleQuotedSql(xname);
2531       sql += wxString::FromUTF8(xname);
2532       ret = sqlite3_exec(sqlite, sql.ToUTF8(), NULL, NULL, &errMsg);
2533       if (ret != SQLITE_OK)
2534         {
2535           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2536                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2537           sqlite3_free(errMsg);
2538           ::wxEndBusyCursor();
2539           return;
2540         }
2541       ret = sqlite3_exec(sqlite, "COMMIT", NULL, NULL, &errMsg);
2542       if (ret != SQLITE_OK)
2543         {
2544           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2545                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2546           sqlite3_free(errMsg);
2547           ::wxEndBusyCursor();
2548           return;
2549         }
2550       ::wxEndBusyCursor();
2551       wxMessageBox(wxT("Spatial Index idx_") + obj->GetName() +
2552                    wxT("_") + obj->GetColumn() +
2553                    wxT(" was successfully removed"), wxT("spatialite_gui"),
2554                    wxOK | wxICON_INFORMATION, this);
2555       MainFrame->InitTableTree();
2556     }
2557   return;
2558 rollback:
2559   ret = sqlite3_exec(sqlite, "ROLLBACK", NULL, NULL, &errMsg);
2560   if (ret != SQLITE_OK)
2561     {
2562       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2563                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2564       sqlite3_free(errMsg);
2565       ::wxEndBusyCursor();
2566       return;
2567     }
2568   ::wxEndBusyCursor();
2569   wxMessageBox(wxT
2570                ("An error occurred\n\na ROLLBACK was automatically performed"),
2571                wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
2572 }
2573 
OnCmdMbrCache(wxCommandEvent & WXUNUSED (event))2574 void MyTableTree::OnCmdMbrCache(wxCommandEvent & WXUNUSED(event))
2575 {
2576 //
2577 // menu event - MBR cache creation-destruction
2578 //
2579   char *errMsg = NULL;
2580   int ret;
2581   wxString sql;
2582   wxString msg;
2583   int i;
2584   char **results;
2585   int rows;
2586   int columns;
2587   int retval = 0;
2588   wxString name;
2589   char xname[1024];
2590   char xtable[1024];
2591   char xcolumn[1024];
2592   sqlite3 *sqlite = MainFrame->GetSqlite();
2593   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
2594   if (obj == NULL)
2595     return;
2596   if (obj->GetType() == MY_GEOMETRY)
2597     {
2598       // creating the MBR cache
2599       ::wxBeginBusyCursor();
2600       ret = sqlite3_exec(sqlite, "BEGIN", NULL, NULL, &errMsg);
2601       if (ret != SQLITE_OK)
2602         {
2603           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2604                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2605           sqlite3_free(errMsg);
2606           ::wxEndBusyCursor();
2607           return;
2608         }
2609       strcpy(xtable, obj->GetName().ToUTF8());
2610       MainFrame->CleanSqlString(xtable);
2611       strcpy(xcolumn, obj->GetColumn().ToUTF8());
2612       MainFrame->CleanSqlString(xcolumn);
2613       sql = wxT("SELECT CreateMbrCache('");
2614       sql += wxString::FromUTF8(xtable);
2615       sql += wxT("', '");
2616       sql += wxString::FromUTF8(xcolumn);
2617       sql += wxT("')");
2618       ret =
2619         sqlite3_get_table(sqlite, sql.ToUTF8(), &results, &rows, &columns,
2620                           &errMsg);
2621       if (ret != SQLITE_OK)
2622         {
2623           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2624                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2625           sqlite3_free(errMsg);
2626           goto rollback;
2627         }
2628       if (rows < 1)
2629         ;
2630       else
2631         {
2632           for (i = 1; i <= rows; i++)
2633             {
2634               if (results[(i * columns) + 0])
2635                 retval = atoi(results[(i * columns) + 0]);
2636             }
2637         }
2638       sqlite3_free_table(results);
2639       if (!retval)
2640         goto rollback;
2641       ret = sqlite3_exec(sqlite, "COMMIT", NULL, NULL, &errMsg);
2642       if (ret != SQLITE_OK)
2643         {
2644           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2645                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2646           sqlite3_free(errMsg);
2647           ::wxEndBusyCursor();
2648           return;
2649         }
2650       ::wxEndBusyCursor();
2651       wxMessageBox(wxT("MBR cache cache_") + obj->GetName() +
2652                    wxT("_") + obj->GetColumn() +
2653                    wxT(" was successfully created"), wxT("spatialite_gui"),
2654                    wxOK | wxICON_INFORMATION, this);
2655       MainFrame->InitTableTree();
2656   } else if (obj->GetType() == MY_GEOMETRY_CACHED)
2657     {
2658       // dropping the MBR cache
2659       ::wxBeginBusyCursor();
2660       ret = sqlite3_exec(sqlite, "BEGIN", NULL, NULL, &errMsg);
2661       if (ret != SQLITE_OK)
2662         {
2663           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2664                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2665           sqlite3_free(errMsg);
2666           ::wxEndBusyCursor();
2667           return;
2668         }
2669       strcpy(xtable, obj->GetName().ToUTF8());
2670       MainFrame->CleanSqlString(xtable);
2671       strcpy(xcolumn, obj->GetColumn().ToUTF8());
2672       MainFrame->CleanSqlString(xcolumn);
2673       sql = wxT("SELECT DisableSpatialIndex('");
2674       sql += wxString::FromUTF8(xtable);
2675       sql += wxT("', '");
2676       sql += wxString::FromUTF8(xcolumn);
2677       sql += wxT("')");
2678       msg = wxT("Do you really intend to delete the MBR cache\n");
2679       msg += wxT("on column ");
2680       msg += obj->GetName();
2681       msg += wxT(".");
2682       msg += obj->GetColumn();
2683       msg += wxT(" ?");
2684       wxMessageDialog confirm(this, msg, wxT("Confirming Delete MBR cache"),
2685                               wxOK | wxCANCEL | wxICON_QUESTION);
2686       ret = confirm.ShowModal();
2687       if (ret != wxID_OK)
2688         return;
2689       ret =
2690         sqlite3_get_table(sqlite, sql.ToUTF8(), &results, &rows, &columns,
2691                           &errMsg);
2692       if (ret != SQLITE_OK)
2693         {
2694           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2695                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2696           sqlite3_free(errMsg);
2697           goto rollback;
2698         }
2699       if (rows < 1)
2700         ;
2701       else
2702         {
2703           for (i = 1; i <= rows; i++)
2704             {
2705               if (results[(i * columns) + 0])
2706                 retval = atoi(results[(i * columns) + 0]);
2707             }
2708         }
2709       sqlite3_free_table(results);
2710       if (!retval)
2711         goto rollback;
2712       sql = wxT("DROP TABLE IF EXISTS ");
2713       name = wxT("cache_");
2714       name += obj->GetName();
2715       name += wxT("_");
2716       name += obj->GetColumn();
2717       strcpy(xname, name.ToUTF8());
2718       MainFrame->DoubleQuotedSql(xname);
2719       sql += wxString::FromUTF8(xname);
2720       ret = sqlite3_exec(sqlite, sql.ToUTF8(), NULL, NULL, &errMsg);
2721       if (ret != SQLITE_OK)
2722         {
2723           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2724                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2725           sqlite3_free(errMsg);
2726           ::wxEndBusyCursor();
2727           return;
2728         }
2729       ret = sqlite3_exec(sqlite, "COMMIT", NULL, NULL, &errMsg);
2730       if (ret != SQLITE_OK)
2731         {
2732           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2733                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2734           sqlite3_free(errMsg);
2735           ::wxEndBusyCursor();
2736           return;
2737         }
2738       ::wxEndBusyCursor();
2739       wxMessageBox(wxT("MBR cache cache_") + obj->GetName() +
2740                    wxT("_") + obj->GetColumn() +
2741                    wxT(" was successfully removed"), wxT("spatialite_gui"),
2742                    wxOK | wxICON_INFORMATION, this);
2743       MainFrame->InitTableTree();
2744     }
2745   return;
2746 rollback:
2747   ret = sqlite3_exec(sqlite, "ROLLBACK", NULL, NULL, &errMsg);
2748   if (ret != SQLITE_OK)
2749     {
2750       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2751                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2752       sqlite3_free(errMsg);
2753       ::wxEndBusyCursor();
2754       return;
2755     }
2756   ::wxEndBusyCursor();
2757   wxMessageBox(wxT
2758                ("An error occurred\n\na ROLLBACK was automatically performed"),
2759                wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
2760 }
2761 
OnCmdRebuildTriggers(wxCommandEvent & WXUNUSED (event))2762 void MyTableTree::OnCmdRebuildTriggers(wxCommandEvent & WXUNUSED(event))
2763 {
2764 //
2765 // menu event - rebuilding Geometry Triggers
2766 //
2767   wxString sql;
2768   char xtable[1024];
2769   char xcolumn[1024];
2770   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
2771   if (obj == NULL)
2772     return;
2773   if (obj->GetType() == MY_COLUMN || obj->GetType() == MY_GEOMETRY
2774       || obj->GetType() == MY_GEOMETRY_INDEX
2775       || obj->GetType() == MY_GEOMETRY_CACHED)
2776     {
2777       strcpy(xtable, obj->GetName().ToUTF8());
2778       MainFrame->CleanSqlString(xtable);
2779       strcpy(xcolumn, obj->GetColumn().ToUTF8());
2780       MainFrame->CleanSqlString(xcolumn);
2781       sql = wxT("SELECT RebuildGeometryTriggers('");
2782       sql += wxString::FromUTF8(xtable);
2783       sql += wxT("', '");
2784       sql += wxString::FromUTF8(xcolumn);
2785       sql += wxT("')");
2786       MainFrame->SetSql(sql, true);
2787     }
2788 }
2789 
OnCmdGisLayerAuth(wxCommandEvent & WXUNUSED (event))2790 void MyTableTree::OnCmdGisLayerAuth(wxCommandEvent & WXUNUSED(event))
2791 {
2792 //
2793 // menu event - setting the GIS Layer auth
2794 //
2795   wxString sql;
2796   int ret;
2797   char **results;
2798   int rows;
2799   int columns;
2800   int i;
2801   char *errMsg = NULL;
2802   char *value;
2803   bool readOnly = false;
2804   bool hidden = false;
2805   GisLayerAuthDialog dlg;
2806   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
2807   if (obj == NULL)
2808     return;
2809   if (obj->GetType() == MY_GEOMETRY || obj->GetType() == MY_GEOMETRY_INDEX
2810       || obj->GetType() == MY_GEOMETRY_CACHED
2811       || obj->GetType() == MY_VIEW_GEOMETRY)
2812     {
2813       sql = wxT("SELECT read_only, hidden FROM geometry_columns AS a ");
2814       sql += wxT("LEFT JOIN geometry_columns_auth AS b ON ");
2815       sql += wxT("(Lower(a.f_table_name) = Lower(b.f_table_name) AND ");
2816       sql += wxT("Lower(a.f_geometry_column) = Lower(b.f_geometry_column)) ");
2817       sql += wxT("WHERE Lower(f_table_name) = Lower('");
2818       sql += obj->GetName();
2819       sql += wxT("') AND Lower(f_geometry_column) = Lower('");
2820       sql += obj->GetColumn();
2821       sql += wxT("')");
2822     }
2823   if (obj->GetType() == MY_VIEW_GEOMETRY_INDEX
2824       || obj->GetType() == MY_VIEW_GEOMETRY_CACHED
2825       || obj->GetType() == MY_VIRTUAL_GEOMETRY)
2826     {
2827       sql = wxT("SELECT read_only, hidden FROM views_geometry_columns ");
2828       sql += wxT("LEFT JOIN geometry_columns_auth AS x ON ");
2829       sql += wxT("(Lower(view_name) = Lower(x.f_table_name) AND ");
2830       sql += wxT("Lower(view_geometry) = Lower(x.f_geometry_column)) ");
2831       sql += wxT("WHERE Lower(view_name) = Lower('");
2832       sql += obj->GetName();
2833       sql += wxT("') AND Lower(view_geometry) = Lower('");
2834       sql += obj->GetColumn();
2835       sql += wxT("')");
2836     }
2837   if (obj->GetType() == MY_VIRTUAL_GEOMETRY)
2838     {
2839       sql = wxT("SELECT read_only, hidden FROM virts_geometry_columns ");
2840       sql += wxT("LEFT JOIN geometry_columns_auth ON ");
2841       sql += wxT("(Lower(virt_name) = Lower(f_table_name) AND ");
2842       sql += wxT("Lower(virt_geometry) = Lower(f_geometry_column)) ");
2843       sql += wxT("WHERE Lower(virt_name) = Lower('");
2844       sql += obj->GetName();
2845       sql += wxT("') AND Lower(virt_geometry) = Lower('");
2846       sql += obj->GetColumn();
2847       sql += wxT("')");
2848     }
2849   if (sql.Len() == 0)
2850     return;
2851   ret = sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(), &results,
2852                           &rows, &columns, &errMsg);
2853   if (ret != SQLITE_OK)
2854     {
2855       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2856                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2857       sqlite3_free(errMsg);
2858       return;
2859     }
2860   if (rows < 1)
2861     ;
2862   else
2863     {
2864       for (i = 1; i <= rows; i++)
2865         {
2866           value = results[(i * columns) + 0];
2867           if (value)
2868             {
2869               if (atoi(value) == 0)
2870                 readOnly = false;
2871               else
2872                 readOnly = true;
2873             }
2874           value = results[(i * columns) + 1];
2875           if (value)
2876             {
2877               if (atoi(value) == 0)
2878                 hidden = false;
2879               else
2880                 hidden = true;
2881             }
2882         }
2883     }
2884   sqlite3_free_table(results);
2885   dlg.Create(MainFrame, obj->GetName(), obj->GetColumn(), readOnly, hidden);
2886   ret = dlg.ShowModal();
2887   if (ret == wxID_OK)
2888     {
2889       // updating the GEOMETRY_COLUMNS_AUTH table
2890       sql = wxT("INSERT OR REPLACE INTO geometry_columns_auth ");
2891       sql += wxT("(f_table_name, f_geometry_column, read_only, hidden) ");
2892       sql += wxT("VALUES ('");
2893       sql += obj->GetName();
2894       sql += wxT("', '");
2895       sql += obj->GetColumn();
2896       if (dlg.IsHidden() == true)
2897         sql += wxT("', 0, 1)");
2898       else if (dlg.IsReadOnly() == true)
2899         sql += wxT("', 1, 0)");
2900       else
2901         sql += wxT("', 0, 0)");
2902       ret =
2903         sqlite3_exec(MainFrame->GetSqlite(), sql.ToUTF8(), NULL, NULL, &errMsg);
2904       if (ret != SQLITE_OK)
2905         {
2906           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2907                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2908           sqlite3_free(errMsg);
2909         }
2910     }
2911 }
2912 
OnCmdCheckGeometry(wxCommandEvent & WXUNUSED (event))2913 void MyTableTree::OnCmdCheckGeometry(wxCommandEvent & WXUNUSED(event))
2914 {
2915 //
2916 // menu event - checking geometries
2917 //
2918   wxString sql;
2919   char xname[1024];
2920   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
2921   if (obj == NULL)
2922     return;
2923   if (obj->GetType() == MY_COLUMN || obj->GetType() == MY_GEOMETRY
2924       || obj->GetType() == MY_GEOMETRY_INDEX
2925       || obj->GetType() == MY_GEOMETRY_CACHED)
2926     {
2927       sql = wxT("SELECT Count(*), GeometryType(");
2928       strcpy(xname, obj->GetColumn().ToUTF8());
2929       MainFrame->DoubleQuotedSql(xname);
2930       sql += wxString::FromUTF8(xname);
2931       sql += wxT("), Srid(");
2932       strcpy(xname, obj->GetColumn().ToUTF8());
2933       MainFrame->DoubleQuotedSql(xname);
2934       sql += wxString::FromUTF8(xname);
2935       sql += wxT("), CoordDimension(");
2936       strcpy(xname, obj->GetColumn().ToUTF8());
2937       MainFrame->DoubleQuotedSql(xname);
2938       sql += wxString::FromUTF8(xname);
2939       sql += wxT(")\nFROM ");
2940       strcpy(xname, obj->GetName().ToUTF8());
2941       MainFrame->DoubleQuotedSql(xname);
2942       sql += wxString::FromUTF8(xname);
2943       sql += wxT("\nGROUP BY 2, 3, 4");
2944       MainFrame->SetSql(sql, true);
2945     }
2946 }
2947 
OnCmdExtent(wxCommandEvent & WXUNUSED (event))2948 void MyTableTree::OnCmdExtent(wxCommandEvent & WXUNUSED(event))
2949 {
2950 //
2951 // menu event - computing Extent
2952 //
2953   wxString sql;
2954   char xname[1024];
2955   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
2956   if (obj == NULL)
2957     return;
2958   if (obj->GetType() == MY_COLUMN || obj->GetType() == MY_GEOMETRY
2959       || obj->GetType() == MY_GEOMETRY_INDEX
2960       || obj->GetType() == MY_GEOMETRY_CACHED
2961       || obj->GetType() == MY_VIEW_GEOMETRY
2962       || obj->GetType() == MY_VIEW_GEOMETRY_INDEX
2963       || obj->GetType() == MY_VIEW_GEOMETRY_CACHED
2964       || obj->GetType() == MY_VIRTUAL_COLUMN
2965       || obj->GetType() == MY_VIRTUAL_GEOMETRY)
2966     {
2967       sql = wxT("SELECT Min(MbrMinX(");
2968       strcpy(xname, obj->GetColumn().ToUTF8());
2969       MainFrame->DoubleQuotedSql(xname);
2970       sql += wxString::FromUTF8(xname);
2971       sql += wxT(")), Min(MbrMinY(");
2972       strcpy(xname, obj->GetColumn().ToUTF8());
2973       MainFrame->DoubleQuotedSql(xname);
2974       sql += wxString::FromUTF8(xname);
2975       sql += wxT(")), Max(MbrMaxX(");
2976       strcpy(xname, obj->GetColumn().ToUTF8());
2977       MainFrame->DoubleQuotedSql(xname);
2978       sql += wxString::FromUTF8(xname);
2979       sql += wxT(")), Max(MbrMaxY(");
2980       strcpy(xname, obj->GetColumn().ToUTF8());
2981       MainFrame->DoubleQuotedSql(xname);
2982       sql += wxString::FromUTF8(xname);
2983       sql += wxT("))\nFROM ");
2984       strcpy(xname, obj->GetName().ToUTF8());
2985       MainFrame->DoubleQuotedSql(xname);
2986       sql += wxString::FromUTF8(xname);
2987       MainFrame->SetSql(sql, true);
2988     }
2989 }
2990 
OnCmdUpdateLayerStatistics(wxCommandEvent & WXUNUSED (event))2991 void MyTableTree::OnCmdUpdateLayerStatistics(wxCommandEvent & WXUNUSED(event))
2992 {
2993 //
2994 // menu event - Updating Layer Statistics
2995 //
2996   wxString sql;
2997   char xname[1024];
2998   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
2999   if (obj == NULL)
3000     return;
3001   if (obj->GetType() == MY_COLUMN || obj->GetType() == MY_GEOMETRY
3002       || obj->GetType() == MY_GEOMETRY_INDEX
3003       || obj->GetType() == MY_GEOMETRY_CACHED
3004       || obj->GetType() == MY_VIEW_GEOMETRY
3005       || obj->GetType() == MY_VIEW_GEOMETRY_INDEX
3006       || obj->GetType() == MY_VIEW_GEOMETRY_CACHED
3007       || obj->GetType() == MY_VIRTUAL_COLUMN
3008       || obj->GetType() == MY_VIRTUAL_GEOMETRY)
3009     {
3010       sql = wxT("SELECT UpdateLayerStatistics('");
3011       strcpy(xname, obj->GetName().ToUTF8());
3012       MainFrame->CleanSqlString(xname);
3013       sql += wxString::FromUTF8(xname);
3014       sql += wxT("', '");
3015       strcpy(xname, obj->GetColumn().ToUTF8());
3016       MainFrame->CleanSqlString(xname);
3017       sql += wxString::FromUTF8(xname);
3018       sql += wxT("')");
3019       MainFrame->SetSql(sql, true);
3020     }
3021   if (obj->GetType() == MY_VTABLE || obj->GetType() == MY_TABLE
3022       || obj->GetType() == MY_VIEW)
3023     {
3024       sql = wxT("SELECT UpdateLayerStatistics('");
3025       strcpy(xname, obj->GetName().ToUTF8());
3026       MainFrame->CleanSqlString(xname);
3027       sql += wxString::FromUTF8(xname);
3028       sql += wxT("')");
3029       MainFrame->SetSql(sql, true);
3030     }
3031 }
3032 
3033 void MyTableTree::
OnCmdUpdateLayerStatisticsAll(wxCommandEvent & WXUNUSED (event))3034 OnCmdUpdateLayerStatisticsAll(wxCommandEvent & WXUNUSED(event))
3035 {
3036 //
3037 // menu event - Updating Layer Statistics [ALL]
3038 //
3039   wxString sql = wxT("SELECT UpdateLayerStatistics()");
3040   MainFrame->SetSql(sql, true);
3041 }
3042 
OnCmdElementaryGeometries(wxCommandEvent & WXUNUSED (event))3043 void MyTableTree::OnCmdElementaryGeometries(wxCommandEvent & WXUNUSED(event))
3044 {
3045 //
3046 // menu event - creating a derived table (elementary geometries)
3047 //
3048   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
3049   if (obj == NULL)
3050     return;
3051   if (obj->GetType() == MY_GEOMETRY || obj->GetType() == MY_GEOMETRY_INDEX
3052       || obj->GetType() == MY_GEOMETRY_CACHED
3053       || obj->GetType() == MY_VIEW_GEOMETRY
3054       || obj->GetType() == MY_VIEW_GEOMETRY_INDEX
3055       || obj->GetType() == MY_VIEW_GEOMETRY_CACHED
3056       || obj->GetType() == MY_VIRTUAL_GEOMETRY)
3057     {
3058       ElementaryGeomsDialog dlg;
3059       dlg.Create(MainFrame, obj->GetName(), obj->GetColumn());
3060       if (dlg.ShowModal() == wxID_OK)
3061         {
3062           wxString outTable = dlg.GetOutTable();
3063           wxString pKey = dlg.GetPrimaryKey();
3064           wxString multiID = dlg.GetMultiID();
3065           wxString type = dlg.GetType();
3066           int srid = dlg.GetSrid();
3067           wxString coordDims = dlg.GetCoordDims();
3068           bool spIdx = dlg.IsSpatialIndex();
3069           ::wxBeginBusyCursor();
3070           bool ret =
3071             MainFrame->DoElementaryGeometries(obj->GetName(), obj->GetColumn(),
3072                                               outTable, pKey, multiID, type,
3073                                               srid, coordDims, spIdx);
3074           ::wxEndBusyCursor();
3075           if (ret)
3076             MainFrame->InitTableTree();
3077         }
3078     }
3079 }
3080 
OnCmdMalformedGeometries(wxCommandEvent & WXUNUSED (event))3081 void MyTableTree::OnCmdMalformedGeometries(wxCommandEvent & WXUNUSED(event))
3082 {
3083 //
3084 // menu event - identifying malformed geometries
3085 //
3086   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
3087   if (obj == NULL)
3088     return;
3089   if (obj->GetType() == MY_GEOMETRY || obj->GetType() == MY_GEOMETRY_INDEX
3090       || obj->GetType() == MY_GEOMETRY_CACHED
3091       || obj->GetType() == MY_VIEW_GEOMETRY
3092       || obj->GetType() == MY_VIEW_GEOMETRY_INDEX
3093       || obj->GetType() == MY_VIEW_GEOMETRY_CACHED
3094       || obj->GetType() == MY_VIRTUAL_GEOMETRY)
3095     {
3096       bool repair = true;
3097       if (obj->GetType() == MY_VIEW_GEOMETRY
3098           || obj->GetType() == MY_VIEW_GEOMETRY_INDEX
3099           || obj->GetType() == MY_VIEW_GEOMETRY_CACHED
3100           || obj->GetType() == MY_VIRTUAL_GEOMETRY)
3101         repair = false;
3102       MalformedGeomsList *list =
3103         MainFrame->FindMalformedGeoms(obj->GetName(), obj->GetColumn(), repair);
3104       if (list->GetFirst() == NULL)
3105         {
3106           delete list;
3107           wxString msg = wxT("Any geometry found in ");
3108           msg += obj->GetName();
3109           msg += wxT(".");
3110           msg += obj->GetColumn();
3111           msg += wxT(" is valid");
3112           wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION,
3113                        this);
3114           return;
3115       } else
3116         {
3117           MalformedGeomsDialog dlg;
3118           dlg.Create(MainFrame, obj->GetName(), obj->GetColumn(), list);
3119           dlg.ShowModal();
3120         }
3121     }
3122 }
3123 
OnCmdRepairPolygons(wxCommandEvent & WXUNUSED (event))3124 void MyTableTree::OnCmdRepairPolygons(wxCommandEvent & WXUNUSED(event))
3125 {
3126 //
3127 // menu event - attempting to repair malformed polygons
3128 //
3129   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
3130   if (obj == NULL)
3131     return;
3132   if (obj->GetType() == MY_GEOMETRY || obj->GetType() == MY_GEOMETRY_INDEX
3133       || obj->GetType() == MY_GEOMETRY_CACHED)
3134     {
3135       int count;
3136       ::wxBeginBusyCursor();
3137       MainFrame->PreRepairPolygons(obj->GetName(), obj->GetColumn(), &count);
3138       if (count == 0)
3139         {
3140           wxString msg = wxT("No Polygon to be repaired found in ");
3141           msg += obj->GetName();
3142           msg += wxT(".");
3143           msg += obj->GetColumn();
3144           wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_INFORMATION,
3145                        this);
3146           ::wxEndBusyCursor();
3147           return;
3148         }
3149       MainFrame->RepairPolygons(obj->GetName(), obj->GetColumn(), &count);
3150       if (count > 0)
3151         {
3152           char str[256];
3153           sprintf(str, "%d Geometries were succesfully updated", count);
3154           wxMessageBox(wxString::FromUTF8(str), wxT("spatialite_gui"),
3155                        wxOK | wxICON_INFORMATION, this);
3156           ::wxEndBusyCursor();
3157           return;
3158         }
3159       ::wxEndBusyCursor();
3160     }
3161 }
3162 
OnCmdSetSrid(wxCommandEvent & WXUNUSED (event))3163 void MyTableTree::OnCmdSetSrid(wxCommandEvent & WXUNUSED(event))
3164 {
3165 //
3166 // menu event - setting SRID for geometries
3167 //
3168   SetSridDialog dlg;
3169   wxString sql;
3170   int srid;
3171   int oldSrid;
3172   int ret;
3173   char dummy[128];
3174   char xname[1024];
3175   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
3176   if (obj == NULL)
3177     return;
3178   if (obj->GetType() == MY_COLUMN)
3179     {
3180       dlg.Create(MainFrame, obj->GetName(), obj->GetColumn());
3181       ret = dlg.ShowModal();
3182       if (ret == wxID_OK)
3183         {
3184           srid = dlg.GetSrid();
3185           oldSrid = dlg.GetOldSrid();
3186           sql = wxT("UPDATE ");
3187           strcpy(xname, obj->GetName().ToUTF8());
3188           MainFrame->DoubleQuotedSql(xname);
3189           sql += wxString::FromUTF8(xname);
3190           sql += wxT(" SET ");
3191           strcpy(xname, obj->GetColumn().ToUTF8());
3192           MainFrame->DoubleQuotedSql(xname);
3193           sql += wxString::FromUTF8(xname);
3194           sql += wxT(" = SetSrid(");
3195           strcpy(xname, obj->GetColumn().ToUTF8());
3196           MainFrame->DoubleQuotedSql(xname);
3197           sql += wxString::FromUTF8(xname);
3198           sprintf(dummy, ", %d)", srid);
3199           sql += wxString::FromUTF8(dummy);
3200           sql += wxT("\nWHERE Srid(");
3201           strcpy(xname, obj->GetColumn().ToUTF8());
3202           MainFrame->DoubleQuotedSql(xname);
3203           sql += wxString::FromUTF8(xname);
3204           sprintf(dummy, ") = %d", oldSrid);
3205           sql += wxString::FromUTF8(dummy);
3206           MainFrame->SetSql(sql, true);
3207         }
3208     }
3209 }
3210 
OnCmdDumpShp(wxCommandEvent & WXUNUSED (event))3211 void MyTableTree::OnCmdDumpShp(wxCommandEvent & WXUNUSED(event))
3212 {
3213 //
3214 // menu event - dumping as Shapefile
3215 //
3216   int ret;
3217   wxString path;
3218   wxString lastDir;
3219   bool isView = false;
3220   int metadata_type = MainFrame->GetMetaDataType();
3221   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
3222   if (obj == NULL)
3223     return;
3224   if (obj->GetType() == MY_VIEW_GEOMETRY
3225       || obj->GetType() == MY_VIEW_GEOMETRY_INDEX
3226       || obj->GetType() == MY_VIEW_GEOMETRY_CACHED)
3227     isView = true;
3228   if (obj->GetType() == MY_GEOMETRY || obj->GetType() == MY_GEOMETRY_INDEX
3229       || obj->GetType() == MY_GEOMETRY_CACHED || isView == true)
3230     {
3231       wxFileDialog fileDialog(this, wxT("Dump Shapefile"),
3232                               wxT(""), wxT("shapefile.shp"),
3233                               wxT
3234                               ("Shapefile (*.shp)|*.shp|All files (*.*)|*.*"),
3235                               wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
3236                               wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
3237       lastDir = MainFrame->GetLastDirectory();
3238       if (lastDir.Len() >= 1)
3239         fileDialog.SetDirectory(lastDir);
3240       ret = fileDialog.ShowModal();
3241       if (ret == wxID_OK)
3242         {
3243           char x_path[1024];
3244           char x_table[1024];
3245           char x_column[1024];
3246           char x_type[1024];
3247           char x_charset[1024];
3248           char err_msg[1024];
3249           int rt;
3250           char **results;
3251           int rows;
3252           int columns;
3253           int i;
3254           char *errMsg = NULL;
3255           *x_type = '\0';
3256           wxFileName file(fileDialog.GetPath());
3257           path = file.GetPath();
3258           path += file.GetPathSeparator();
3259           path += file.GetName();
3260           lastDir = file.GetPath();
3261           strcpy(x_path, path.ToUTF8());
3262           strcpy(x_table, obj->GetName().ToUTF8());
3263           strcpy(x_column, obj->GetColumn().ToUTF8());
3264           if (isView == true)
3265             {
3266               wxString sql;
3267               if (metadata_type == METADATA_CURRENT)
3268                 sql =
3269                   wxT("SELECT geometry_type FROM views_geometry_columns AS a ");
3270               else if (metadata_type == METADATA_LEGACY)
3271                 sql = wxT("SELECT type FROM views_geometry_columns AS a ");
3272               sql += wxT("JOIN geometry_columns AS b ON (");
3273               sql += wxT("Lower(a.f_table_name) = Lower(b.f_table_name) AND ");
3274               sql +=
3275                 wxT
3276                 ("Lower(a.f_geometry_column) = Lower(b.f_geometry_column)) ");
3277               sql += wxT("WHERE Lower(view_name) = Lower('");
3278               sql += obj->GetName();
3279               sql += wxT("') AND Lower(view_geometry) = Lower('");
3280               sql += obj->GetColumn();
3281               sql += wxT("')");
3282               ret =
3283                 sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(),
3284                                   &results, &rows, &columns, &errMsg);
3285               if (ret != SQLITE_OK)
3286                 {
3287                   wxMessageBox(wxT("dump shapefile error:") +
3288                                wxString::FromUTF8(errMsg),
3289                                wxT("spatialite_gui"), wxOK | wxICON_ERROR,
3290                                this);
3291                   sqlite3_free(errMsg);
3292                   return;
3293                 }
3294               if (rows < 1)
3295                 ;
3296               else
3297                 {
3298                   for (i = 1; i <= rows; i++)
3299                     {
3300                       if (metadata_type == METADATA_LEGACY)
3301                         strcpy(x_type, results[(i * columns) + 0]);
3302                       else if (metadata_type == METADATA_CURRENT)
3303                         {
3304                           switch (atoi(results[(i * columns) + 0]))
3305                             {
3306                               case 0:
3307                               case 1000:
3308                               case 2000:
3309                               case 3000:
3310                                 strcpy(x_type, "GEOMETRY");
3311                                 break;
3312                               case 1:
3313                               case 1001:
3314                               case 2001:
3315                               case 3001:
3316                                 strcpy(x_type, "POINT");
3317                                 break;
3318                               case 2:
3319                               case 1002:
3320                               case 2002:
3321                               case 3002:
3322                                 strcpy(x_type, "LINESTRING");
3323                                 break;
3324                               case 3:
3325                               case 1003:
3326                               case 2003:
3327                               case 3003:
3328                                 strcpy(x_type, "POLYGON");
3329                                 break;
3330                               case 4:
3331                               case 1004:
3332                               case 2004:
3333                               case 3004:
3334                                 strcpy(x_type, "MULTIPOINT");
3335                                 break;
3336                               case 5:
3337                               case 1005:
3338                               case 2005:
3339                               case 3005:
3340                                 strcpy(x_type, "MULTILINESTRING");
3341                                 break;
3342                               case 6:
3343                               case 1006:
3344                               case 2006:
3345                               case 3006:
3346                                 strcpy(x_type, "MULTIPOLYGON");
3347                                 break;
3348                               case 7:
3349                               case 1007:
3350                               case 2007:
3351                               case 3007:
3352                                 strcpy(x_type, "GEOMETRYCOLLECTION");
3353                                 break;
3354                             };
3355                         }
3356                     }
3357                 }
3358               sqlite3_free_table(results);
3359           } else
3360             {
3361               wxString sql;
3362               if (metadata_type == METADATA_CURRENT)
3363                 sql =
3364                   wxT
3365                   ("SELECT geometry_type FROM geometry_columns WHERE Lower(f_table_name) = Lower('");
3366               else if (metadata_type == METADATA_LEGACY)
3367                 sql =
3368                   wxT
3369                   ("SELECT type FROM geometry_columns WHERE Lower(f_table_name) = Lower('");
3370               sql += obj->GetName();
3371               sql += wxT("') AND Lower(f_geometry_column) = Lower('");
3372               sql += obj->GetColumn();
3373               sql += wxT("')");
3374               ret =
3375                 sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(),
3376                                   &results, &rows, &columns, &errMsg);
3377               if (ret != SQLITE_OK)
3378                 {
3379                   wxMessageBox(wxT("dump shapefile error:") +
3380                                wxString::FromUTF8(errMsg),
3381                                wxT("spatialite_gui"), wxOK | wxICON_ERROR,
3382                                this);
3383                   sqlite3_free(errMsg);
3384                   return;
3385                 }
3386               if (rows < 1)
3387                 ;
3388               else
3389                 {
3390                   for (i = 1; i <= rows; i++)
3391                     {
3392                       if (metadata_type == METADATA_LEGACY)
3393                         strcpy(x_type, results[(i * columns) + 0]);
3394                       else if (metadata_type == METADATA_CURRENT)
3395                         {
3396                           switch (atoi(results[(i * columns) + 0]))
3397                             {
3398                               case 0:
3399                               case 1000:
3400                               case 2000:
3401                               case 3000:
3402                                 strcpy(x_type, "GEOMETRY");
3403                                 break;
3404                               case 1:
3405                               case 1001:
3406                               case 2001:
3407                               case 3001:
3408                                 strcpy(x_type, "POINT");
3409                                 break;
3410                               case 2:
3411                               case 1002:
3412                               case 2002:
3413                               case 3002:
3414                                 strcpy(x_type, "LINESTRING");
3415                                 break;
3416                               case 3:
3417                               case 1003:
3418                               case 2003:
3419                               case 3003:
3420                                 strcpy(x_type, "POLYGON");
3421                                 break;
3422                               case 4:
3423                               case 1004:
3424                               case 2004:
3425                               case 3004:
3426                                 strcpy(x_type, "MULTIPOINT");
3427                                 break;
3428                               case 5:
3429                               case 1005:
3430                               case 2005:
3431                               case 3005:
3432                                 strcpy(x_type, "MULTILINESTRING");
3433                                 break;
3434                               case 6:
3435                               case 1006:
3436                               case 2006:
3437                               case 3006:
3438                                 strcpy(x_type, "MULTIPOLYGON");
3439                                 break;
3440                               case 7:
3441                               case 1007:
3442                               case 2007:
3443                               case 3007:
3444                                 strcpy(x_type, "GEOMETRYCOLLECTION");
3445                                 break;
3446                             };
3447                         }
3448                     }
3449                 }
3450               sqlite3_free_table(results);
3451             }
3452           if (MainFrame->IsSetAskCharset() == false)
3453             {
3454               // using the default output charset
3455               MainFrame->SetLastDirectory(lastDir);
3456               ::wxBeginBusyCursor();
3457               strcpy(x_charset, MainFrame->GetDefaultCharset().ToUTF8());
3458               rt =
3459                 dump_shapefile(MainFrame->GetSqlite(), x_table, x_column,
3460                                x_path, x_charset, x_type, 0, &rows, err_msg);
3461               ::wxEndBusyCursor();
3462               if (rt)
3463                 wxMessageBox(wxT("dump shp:") +
3464                              wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
3465                              wxOK | wxICON_INFORMATION, this);
3466               else
3467                 wxMessageBox(wxT("dump shp error:") +
3468                              wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
3469                              wxOK | wxICON_ERROR, this);
3470           } else
3471             {
3472               // asking the charset to be used
3473               DumpShpDialog dlg;
3474               dlg.Create(MainFrame, path, obj->GetName(), obj->GetColumn(),
3475                          MainFrame->GetDefaultCharset());
3476               ret = dlg.ShowModal();
3477               if (ret == wxID_OK)
3478                 {
3479                   MainFrame->SetLastDirectory(lastDir);
3480                   ::wxBeginBusyCursor();
3481                   strcpy(x_charset, dlg.GetCharset().ToUTF8());
3482                   rt =
3483                     dump_shapefile(MainFrame->GetSqlite(), x_table, x_column,
3484                                    x_path, x_charset, x_type, 0, &rows,
3485                                    err_msg);
3486                   ::wxEndBusyCursor();
3487                   if (rt)
3488                     wxMessageBox(wxT("dump shp:") +
3489                                  wxString::FromUTF8(err_msg),
3490                                  wxT("spatialite_gui"),
3491                                  wxOK | wxICON_INFORMATION, this);
3492                   else
3493                     wxMessageBox(wxT("dump shp error:") +
3494                                  wxString::FromUTF8(err_msg),
3495                                  wxT("spatialite_gui"), wxOK | wxICON_ERROR,
3496                                  this);
3497                 }
3498             }
3499         }
3500     }
3501 }
3502 
OnCmdDumpKml(wxCommandEvent & WXUNUSED (event))3503 void MyTableTree::OnCmdDumpKml(wxCommandEvent & WXUNUSED(event))
3504 {
3505 //
3506 // menu event - dumping as KML
3507 //
3508   int ret;
3509   wxString path;
3510   wxString lastDir;
3511   bool isView = false;
3512   bool isVirtual = false;
3513   bool isNameConst = false;
3514   bool isDescConst = false;
3515   wxString Name;
3516   wxString Desc;
3517   int precision = -1;
3518   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
3519   if (obj == NULL)
3520     return;
3521   if (obj->GetType() == MY_VIEW_GEOMETRY
3522       || obj->GetType() == MY_VIEW_GEOMETRY_INDEX
3523       || obj->GetType() == MY_VIEW_GEOMETRY_CACHED)
3524     isView = true;
3525   if (obj->GetType() == MY_VIRTUAL_GEOMETRY)
3526     isVirtual = true;
3527   if (obj->GetType() == MY_GEOMETRY || obj->GetType() == MY_GEOMETRY_INDEX
3528       || obj->GetType() == MY_GEOMETRY_CACHED || isView == true
3529       || isVirtual == true)
3530     {
3531       DumpKmlDialog dlg;
3532       dlg.Create(MainFrame, obj->GetName(), obj->GetColumn());
3533       ret = dlg.ShowModal();
3534       if (ret == wxID_OK)
3535         {
3536           isNameConst = dlg.IsNameConst();
3537           Name = dlg.GetName();
3538           isDescConst = dlg.IsDescConst();
3539           Desc = dlg.GetDesc();
3540           precision = dlg.GetPrecision();
3541       } else
3542         return;
3543       wxFileDialog fileDialog(this, wxT("Dump KML"),
3544                               wxT(""), wxT("export_file.kml"),
3545                               wxT
3546                               ("KML file (*.kml)|*.kml|All files (*.*)|*.*"),
3547                               wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
3548                               wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
3549       lastDir = MainFrame->GetLastDirectory();
3550       if (lastDir.Len() >= 1)
3551         fileDialog.SetDirectory(lastDir);
3552       ret = fileDialog.ShowModal();
3553       if (ret == wxID_OK)
3554         {
3555 
3556           wxFileName file(fileDialog.GetPath());
3557           path = file.GetPath();
3558           path += file.GetPathSeparator();
3559           path += file.GetName();
3560           path += wxT(".kml");
3561           lastDir = file.GetPath();
3562           MainFrame->SetLastDirectory(lastDir);
3563           ::wxBeginBusyCursor();
3564           MainFrame->DumpKml(path, obj->GetName(), obj->GetColumn(), precision,
3565                              Name, isNameConst, Desc, isDescConst);
3566           ::wxEndBusyCursor();
3567         }
3568     }
3569 }
3570 
OnCmdDumpTxtTab(wxCommandEvent & WXUNUSED (event))3571 void MyTableTree::OnCmdDumpTxtTab(wxCommandEvent & WXUNUSED(event))
3572 {
3573 //
3574 // menu event - dumping as TxtTab
3575 //
3576   int ret;
3577   wxString path;
3578   wxString lastDir;
3579   wxString target;
3580   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
3581   if (obj == NULL)
3582     return;
3583   wxFileDialog fileDialog(this, wxT("Dump Txt/Tab file"),
3584                           wxT(""), wxT("table.txt"),
3585                           wxT("Txt/Tab file (*.txt)|*.txt|All files (*.*)|*.*"),
3586                           wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
3587                           wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
3588   lastDir = MainFrame->GetLastDirectory();
3589   if (lastDir.Len() >= 1)
3590     fileDialog.SetDirectory(lastDir);
3591   ret = fileDialog.ShowModal();
3592   if (ret == wxID_OK)
3593     {
3594       wxFileName file(fileDialog.GetPath());
3595       path = file.GetPath();
3596       path += file.GetPathSeparator();
3597       path += file.GetName();
3598       path += wxT(".txt");
3599       lastDir = file.GetPath();
3600       if (MainFrame->IsSetAskCharset() == false)
3601         {
3602           // using the default output charset
3603           MainFrame->SetLastDirectory(lastDir);
3604           ::wxBeginBusyCursor();
3605           MainFrame->DumpTxtTab(path, obj->GetName(),
3606                                 MainFrame->GetDefaultCharset());
3607           ::wxEndBusyCursor();
3608       } else
3609         {
3610           // asking the charset to be used
3611           DumpTxtDialog dlg;
3612           target = wxT("TXT / TAB");
3613           dlg.Create(MainFrame, path, target, MainFrame->GetDefaultCharset());
3614           ret = dlg.ShowModal();
3615           if (ret == wxID_OK)
3616             {
3617               MainFrame->SetLastDirectory(lastDir);
3618               ::wxBeginBusyCursor();
3619               MainFrame->DumpTxtTab(path, obj->GetName(), dlg.GetCharset());
3620               ::wxEndBusyCursor();
3621             }
3622         }
3623     }
3624 }
3625 
OnCmdDumpCsv(wxCommandEvent & WXUNUSED (event))3626 void MyTableTree::OnCmdDumpCsv(wxCommandEvent & WXUNUSED(event))
3627 {
3628 //
3629 // menu event - dumping as CSV
3630 //
3631   int ret;
3632   wxString path;
3633   wxString lastDir;
3634   wxString target;
3635   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
3636   if (obj == NULL)
3637     return;
3638   wxFileDialog fileDialog(this, wxT("Dump CSV file"),
3639                           wxT(""), wxT("table.csv"),
3640                           wxT("CSV file (*.csv)|*.csv|All files (*.*)|*.*"),
3641                           wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
3642                           wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
3643   lastDir = MainFrame->GetLastDirectory();
3644   if (lastDir.Len() >= 1)
3645     fileDialog.SetDirectory(lastDir);
3646   ret = fileDialog.ShowModal();
3647   if (ret == wxID_OK)
3648     {
3649       wxFileName file(fileDialog.GetPath());
3650       path = file.GetPath();
3651       path += file.GetPathSeparator();
3652       path += file.GetName();
3653       path += wxT(".csv");
3654       lastDir = file.GetPath();
3655       if (MainFrame->IsSetAskCharset() == false)
3656         {
3657           // using the default output charset
3658           MainFrame->SetLastDirectory(lastDir);
3659           ::wxBeginBusyCursor();
3660           MainFrame->DumpCsv(path, obj->GetName(),
3661                              MainFrame->GetDefaultCharset());
3662           ::wxEndBusyCursor();
3663       } else
3664         {
3665           // asking the charset to be used
3666           DumpTxtDialog dlg;
3667           target = wxT("CSV");
3668           dlg.Create(MainFrame, path, target, MainFrame->GetDefaultCharset());
3669           ret = dlg.ShowModal();
3670           if (ret == wxID_OK)
3671             {
3672               MainFrame->SetLastDirectory(lastDir);
3673               ::wxBeginBusyCursor();
3674               MainFrame->DumpCsv(path, obj->GetName(), dlg.GetCharset());
3675               ::wxEndBusyCursor();
3676             }
3677         }
3678     }
3679 }
3680 
OnCmdDumpHtml(wxCommandEvent & WXUNUSED (event))3681 void MyTableTree::OnCmdDumpHtml(wxCommandEvent & WXUNUSED(event))
3682 {
3683 //
3684 // menu event - dumping as Html
3685 //
3686   int ret;
3687   wxString path;
3688   wxString lastDir;
3689   wxString target;
3690   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
3691   if (obj == NULL)
3692     return;
3693   wxFileDialog fileDialog(this, wxT("Dump HTML file"),
3694                           wxT(""), wxT("table.html"),
3695                           wxT
3696                           ("HTML web page (*.html)|*.html|All files (*.*)|*.*"),
3697                           wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
3698                           wxDefaultSize, wxT("filedlg"));
3699   lastDir = MainFrame->GetLastDirectory();
3700   if (lastDir.Len() >= 1)
3701     fileDialog.SetDirectory(lastDir);
3702   ret = fileDialog.ShowModal();
3703   if (ret == wxID_OK)
3704     {
3705       wxFileName file(fileDialog.GetPath());
3706       path = file.GetPath();
3707       path += file.GetPathSeparator();
3708       path += file.GetName();
3709       path += wxT(".html");
3710       lastDir = file.GetPath();
3711       if (MainFrame->IsSetAskCharset() == false)
3712         {
3713           // using the default output charset
3714           MainFrame->SetLastDirectory(lastDir);
3715           ::wxBeginBusyCursor();
3716           MainFrame->DumpHtml(path, obj->GetName(), MainFrame->GetSqlitePath(),
3717                               MainFrame->GetDefaultCharset());
3718           ::wxEndBusyCursor();
3719       } else
3720         {
3721           // asking the charset to be used
3722           DumpTxtDialog dlg;
3723           target = wxT("HTML");
3724           dlg.Create(MainFrame, path, target, MainFrame->GetDefaultCharset());
3725           ret = dlg.ShowModal();
3726           if (ret == wxID_OK)
3727             {
3728               MainFrame->SetLastDirectory(lastDir);
3729               ::wxBeginBusyCursor();
3730               MainFrame->DumpHtml(path, obj->GetName(),
3731                                   MainFrame->GetSqlitePath(), dlg.GetCharset());
3732               ::wxEndBusyCursor();
3733             }
3734         }
3735     }
3736 }
3737 
OnCmdDumpDif(wxCommandEvent & WXUNUSED (event))3738 void MyTableTree::OnCmdDumpDif(wxCommandEvent & WXUNUSED(event))
3739 {
3740 //
3741 // menu event - dumping as DIF
3742 //
3743   int ret;
3744   wxString path;
3745   wxString lastDir;
3746   wxString target;
3747   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
3748   if (obj == NULL)
3749     return;
3750 // asking Decimal Point / Date-Times params
3751   DumpSpreadsheetDialog sheet_dlg;
3752   char decimal_point;
3753   bool date_times;
3754   sheet_dlg.Create(MainFrame);
3755   ret = sheet_dlg.ShowModal();
3756   if (ret == wxID_OK)
3757     {
3758       decimal_point = sheet_dlg.GetDecimalPoint();
3759       date_times = sheet_dlg.IsDateTimes();
3760   } else
3761     return;
3762   wxFileDialog fileDialog(this, wxT("Dump DIF file"),
3763                           wxT(""), wxT("table.dif"),
3764                           wxT
3765                           ("DIF spreadsheet document (*.dif)|*.dif|All files (*.*)|*.*"),
3766                           wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
3767                           wxDefaultSize, wxT("filedlg"));
3768   lastDir = MainFrame->GetLastDirectory();
3769   if (lastDir.Len() >= 1)
3770     fileDialog.SetDirectory(lastDir);
3771   ret = fileDialog.ShowModal();
3772   if (ret == wxID_OK)
3773     {
3774       wxFileName file(fileDialog.GetPath());
3775       path = file.GetPath();
3776       path += file.GetPathSeparator();
3777       path += file.GetName();
3778       path += wxT(".dif");
3779       lastDir = file.GetPath();
3780       if (MainFrame->IsSetAskCharset() == false)
3781         {
3782           // using the default output charset
3783           MainFrame->SetLastDirectory(lastDir);
3784           ::wxBeginBusyCursor();
3785           MainFrame->DumpDif(path, obj->GetName(),
3786                              MainFrame->GetDefaultCharset(), decimal_point,
3787                              date_times);
3788           ::wxEndBusyCursor();
3789       } else
3790         {
3791           // asking the charset to be used
3792           DumpTxtDialog dlg;
3793           target = wxT("DIF spreadsheet");
3794           dlg.Create(MainFrame, path, target, MainFrame->GetDefaultCharset());
3795           ret = dlg.ShowModal();
3796           if (ret == wxID_OK)
3797             {
3798               MainFrame->SetLastDirectory(lastDir);
3799               ::wxBeginBusyCursor();
3800               MainFrame->DumpDif(path, obj->GetName(), dlg.GetCharset(),
3801                                  decimal_point, date_times);
3802               ::wxEndBusyCursor();
3803             }
3804         }
3805     }
3806 }
3807 
OnCmdDumpSylk(wxCommandEvent & WXUNUSED (event))3808 void MyTableTree::OnCmdDumpSylk(wxCommandEvent & WXUNUSED(event))
3809 {
3810 //
3811 // menu event - dumping as SYLK
3812 //
3813   int ret;
3814   wxString path;
3815   wxString lastDir;
3816   wxString target;
3817   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
3818   if (obj == NULL)
3819     return;
3820 // asking Decimal Point / Date-Times params
3821   DumpSpreadsheetDialog sheet_dlg;
3822   bool date_times;
3823   sheet_dlg.Create(MainFrame);
3824   ret = sheet_dlg.ShowModal();
3825   if (ret == wxID_OK)
3826     date_times = sheet_dlg.IsDateTimes();
3827   else
3828     return;
3829   wxFileDialog fileDialog(this, wxT("Dump SYLK file"),
3830                           wxT(""), wxT("table.slk"),
3831                           wxT
3832                           ("SYLK spreadsheet document (*.slk)|*.slk|All files (*.*)|*.*"),
3833                           wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
3834                           wxDefaultSize, wxT("filedlg"));
3835   lastDir = MainFrame->GetLastDirectory();
3836   if (lastDir.Len() >= 1)
3837     fileDialog.SetDirectory(lastDir);
3838   ret = fileDialog.ShowModal();
3839   if (ret == wxID_OK)
3840     {
3841       wxFileName file(fileDialog.GetPath());
3842       path = file.GetPath();
3843       path += file.GetPathSeparator();
3844       path += file.GetName();
3845       path += wxT(".slk");
3846       lastDir = file.GetPath();
3847       if (MainFrame->IsSetAskCharset() == false)
3848         {
3849           // using the default output charset
3850           MainFrame->SetLastDirectory(lastDir);
3851           ::wxBeginBusyCursor();
3852           MainFrame->DumpSylk(path, obj->GetName(),
3853                               MainFrame->GetDefaultCharset(), date_times);
3854           ::wxEndBusyCursor();
3855       } else
3856         {
3857           // asking the charset to be used
3858           DumpTxtDialog dlg;
3859           target = wxT("SYLK spreadsheet");
3860           dlg.Create(MainFrame, path, target, MainFrame->GetDefaultCharset());
3861           ret = dlg.ShowModal();
3862           if (ret == wxID_OK)
3863             {
3864               MainFrame->SetLastDirectory(lastDir);
3865               ::wxBeginBusyCursor();
3866               MainFrame->DumpSylk(path, obj->GetName(), dlg.GetCharset(),
3867                                   date_times);
3868               ::wxEndBusyCursor();
3869             }
3870         }
3871     }
3872 }
3873 
OnCmdDumpDbf(wxCommandEvent & WXUNUSED (event))3874 void MyTableTree::OnCmdDumpDbf(wxCommandEvent & WXUNUSED(event))
3875 {
3876 //
3877 // menu event - dumping as DBF
3878 //
3879   int ret;
3880   wxString path;
3881   wxString lastDir;
3882   wxString target;
3883   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
3884   if (obj == NULL)
3885     return;
3886   wxFileDialog fileDialog(this, wxT("Dump DBF file"),
3887                           wxT(""), wxT("table.dbf"),
3888                           wxT
3889                           ("DBF archive (*.dbf)|*.dbf|All files (*.*)|*.*"),
3890                           wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
3891                           wxDefaultSize, wxT("filedlg"));
3892   lastDir = MainFrame->GetLastDirectory();
3893   if (lastDir.Len() >= 1)
3894     fileDialog.SetDirectory(lastDir);
3895   ret = fileDialog.ShowModal();
3896   if (ret == wxID_OK)
3897     {
3898       char x_path[1024];
3899       char x_table[1024];
3900       char x_charset[1024];
3901       char err_msg[1024];
3902       int rt;
3903       wxFileName file(fileDialog.GetPath());
3904       path = file.GetPath();
3905       path += file.GetPathSeparator();
3906       path += file.GetName();
3907       path += wxT(".dbf");
3908       lastDir = file.GetPath();
3909       strcpy(x_path, path.ToUTF8());
3910       strcpy(x_table, obj->GetName().ToUTF8());
3911       if (MainFrame->IsSetAskCharset() == false)
3912         {
3913           // using the default output charset
3914           MainFrame->SetLastDirectory(lastDir);
3915           ::wxBeginBusyCursor();
3916           strcpy(x_charset, MainFrame->GetDefaultCharset().ToUTF8());
3917           rt =
3918             dump_dbf(MainFrame->GetSqlite(), x_table, x_path, x_charset,
3919                      err_msg);
3920           ::wxEndBusyCursor();
3921           if (rt)
3922             wxMessageBox(wxT("dump dbf:") +
3923                          wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
3924                          wxOK | wxICON_INFORMATION, this);
3925           else
3926             wxMessageBox(wxT("dump dbf error:") +
3927                          wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
3928                          wxOK | wxICON_ERROR, this);
3929       } else
3930         {
3931           // asking the charset to be used
3932           DumpTxtDialog dlg;
3933           target = wxT("DBF archive");
3934           dlg.Create(MainFrame, path, obj->GetName(),
3935                      MainFrame->GetDefaultCharset());
3936           ret = dlg.ShowModal();
3937           if (ret == wxID_OK)
3938             {
3939               MainFrame->SetLastDirectory(lastDir);
3940               strcpy(x_charset, dlg.GetCharset().ToUTF8());
3941               ::wxBeginBusyCursor();
3942               rt =
3943                 dump_dbf(MainFrame->GetSqlite(), x_table, x_path, x_charset,
3944                          err_msg);
3945               ::wxEndBusyCursor();
3946               if (rt)
3947                 wxMessageBox(wxT("dump dbf:") +
3948                              wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
3949                              wxOK | wxICON_INFORMATION, this);
3950               else
3951                 wxMessageBox(wxT("dump dbf error:") +
3952                              wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
3953                              wxOK | wxICON_ERROR, this);
3954             }
3955         }
3956     }
3957 }
3958 
OnCmdDumpPostGIS(wxCommandEvent & WXUNUSED (event))3959 void MyTableTree::OnCmdDumpPostGIS(wxCommandEvent & WXUNUSED(event))
3960 {
3961 //
3962 // menu event - SQL dump for PostGIS
3963 //
3964   wxString sql;
3965   sqlite3_stmt *stmt;
3966   char xname[1024];
3967   wxString lastDir;
3968   int ret;
3969   DumpPostGISDialog postgis_dlg;
3970   bool lowercase;
3971   bool create_table;
3972   bool spatial_index;
3973   wxString schema_name;
3974   wxString table_name;
3975   int rows = 0;
3976   int n_cols;
3977   int i;
3978   gaiaGeomCollPtr geom;
3979   PostGISHelper postgis;
3980   wxFileDialog fileDialog(this, wxT("SQL Dump for PostGIS"),
3981                           wxT(""), wxT("postgis.sql"),
3982                           wxT
3983                           ("SQL dump (*.sql)|*.sql|All files (*.*)|*.*"),
3984                           wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
3985                           wxDefaultSize, wxT("filedlg"));
3986   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
3987   if (obj == NULL)
3988     return;
3989 
3990 // asking PostGIS options
3991   postgis_dlg.Create(MainFrame, obj->GetName());
3992   ret = postgis_dlg.ShowModal();
3993   if (ret == wxID_OK)
3994     {
3995       lowercase = postgis_dlg.IsLowercase();
3996       create_table = postgis_dlg.IsCreateTable();
3997       spatial_index = postgis_dlg.IsSpatialIndex();
3998       schema_name = postgis_dlg.GetSchemaName();
3999       table_name = postgis_dlg.GetTableName();
4000   } else
4001     return;
4002 
4003 //
4004 // preparing SQL statement
4005 //
4006   sql = wxT("SELECT * FROM ");
4007   strcpy(xname, obj->GetName().ToUTF8());
4008   MainFrame->DoubleQuotedSql(xname);
4009   sql += wxString::FromUTF8(xname);
4010 //
4011 // compiling SQL prepared statement
4012 //
4013   ret =
4014     sqlite3_prepare_v2(MainFrame->GetSqlite(), sql.ToUTF8(), sql.Len(), &stmt,
4015                        NULL);
4016   if (ret != SQLITE_OK)
4017     goto sql_error;
4018 
4019   ::wxBeginBusyCursor();
4020   while (1)
4021     {
4022       ret = sqlite3_step(stmt);
4023       if (ret == SQLITE_DONE)
4024         break;                  // end of result set
4025       if (ret == SQLITE_ROW)
4026         {
4027           n_cols = sqlite3_column_count(stmt);
4028           if (rows == 0)
4029             {
4030               // setting the column names
4031               postgis.Alloc(n_cols);
4032               for (i = 0; i < n_cols; i++)
4033                 postgis.SetName(i, (const char *) sqlite3_column_name(stmt, i));
4034             }
4035           rows++;
4036           for (i = 0; i < n_cols; i++)
4037             {
4038               if (sqlite3_column_type(stmt, i) == SQLITE_INTEGER)
4039                 postgis.Eval(i, sqlite3_column_int64(stmt, i));
4040               else if (sqlite3_column_type(stmt, i) == SQLITE_FLOAT)
4041                 postgis.Eval(i, sqlite3_column_double(stmt, i));
4042               else if (sqlite3_column_type(stmt, i) == SQLITE_TEXT)
4043                 postgis.Eval(i, (const char *) sqlite3_column_text(stmt, i));
4044               else if (sqlite3_column_type(stmt, i) == SQLITE_BLOB)
4045                 {
4046                   const void *blob_value = sqlite3_column_blob(stmt, i);
4047                   int len = sqlite3_column_bytes(stmt, i);
4048                   geom =
4049                     gaiaFromSpatiaLiteBlobWkb((unsigned char *) blob_value,
4050                                               len);
4051                   if (geom)
4052                     {
4053                       postgis.Eval(i, geom);
4054                       gaiaFreeGeomColl(geom);
4055                   } else
4056                     postgis.EvalBlob(i);
4057               } else
4058                 postgis.Eval(i);
4059             }
4060       } else
4061         {
4062           sqlite3_finalize(stmt);
4063           goto sql_error;
4064         }
4065     }
4066   postgis.GetKeys(MainFrame, obj->GetName());
4067   postgis.Prepare();
4068   ::wxEndBusyCursor();
4069 
4070 // rewinding the result-set
4071   ret = sqlite3_reset(stmt);
4072   if (ret != SQLITE_OK)
4073     {
4074       sqlite3_finalize(stmt);
4075       goto sql_error;
4076     }
4077 
4078   lastDir = MainFrame->GetLastDirectory();
4079   if (lastDir.Len() >= 1)
4080     fileDialog.SetDirectory(lastDir);
4081   ret = fileDialog.ShowModal();
4082   if (ret == wxID_OK)
4083     {
4084       wxString path;
4085       wxFileName file(fileDialog.GetPath());
4086       path = file.GetPath();
4087       path += file.GetPathSeparator();
4088       path += file.GetName();
4089       path += wxT(".sql");
4090       lastDir = file.GetPath();
4091       char x_path[1024];
4092       strcpy(x_path, path.ToUTF8());
4093       FILE *out = fopen(x_path, "wb");
4094       if (out == NULL)
4095         {
4096           wxMessageBox(wxT
4097                        ("PostGIS SQL dump error: unable to create output file"),
4098                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4099           goto stop;
4100         }
4101       ::wxBeginBusyCursor();
4102       fprintf(out,
4103               "--\n-- SQL dump automatically generated by \"spatialite_gui\" [GPLv3]\n");
4104       wxDateTime now = wxDateTime::Now();
4105       fprintf(out, "-- created on: %04d-%02d-%02d %02d:%02d:%02d\n--\n",
4106               now.GetYear(), now.GetMonth() + 1, now.GetDay(), now.GetHour(),
4107               now.GetMinute(), now.GetSecond());
4108       strcpy(x_path, MainFrame->GetSqlitePath().ToUTF8());
4109       fprintf(out, "-- DB-file origin: %s\n", x_path);
4110       fprintf(out, "-- Table origin: %s\n--\n", xname);
4111       fprintf(out, "-- intended target is: PostgreSQL + PostGIS\n--\n\n");
4112       if (create_table)
4113         {
4114           fprintf(out, "CREATE TABLE ");
4115           if (schema_name.Len() > 0)
4116             {
4117               strcpy(xname, schema_name.ToUTF8());
4118               MainFrame->DoubleQuotedSql(xname);
4119               fprintf(out, "%s.", xname);
4120             }
4121           strcpy(xname, table_name.ToUTF8());
4122           MainFrame->DoubleQuotedSql(xname);
4123           fprintf(out, "%s (\n", xname);
4124           for (i = 0; i < postgis.GetCount(); i++)
4125             {
4126               if (postgis.IsGeometry(i) == true)
4127                 {
4128                   // skipping any Geometry column
4129                   continue;
4130                 }
4131               if (postgis.GetDataType(i) == postgis.DATA_TYPE_UNDEFINED)
4132                 {
4133                   // skipping any invalid column
4134                   continue;
4135                 }
4136               strcpy(xname, postgis.GetName(i, lowercase).ToUTF8());
4137               MainFrame->DoubleQuotedSql(xname);
4138               char data_type[128];
4139               postgis.GetDataType(i, data_type);
4140               if (i == 0)
4141                 fprintf(out, "\t%s %s", xname, data_type);
4142               else
4143                 fprintf(out, ",\n\t%s %s", xname, data_type);
4144             }
4145 // definining any Primary Key Constraint (if any)
4146           PostGISIndex *idx = postgis.GetFirstIndex();
4147           while (idx)
4148             {
4149               if (idx->IsPrimaryKey() != true)
4150                 {
4151                   idx = idx->GetNext();
4152                   continue;
4153                 }
4154               if (postgis.IsSingleFieldPrimaryKey() == true)
4155                 {
4156                   idx = idx->GetNext();
4157                   continue;
4158                 }
4159               fprintf(out, "m\nCONSTRAINT ");
4160               strcpy(xname, idx->GetName().ToUTF8());
4161               MyFrame::DoubleQuotedSql(xname);
4162               fprintf(out, "%s PRIMARY KEY (", xname);
4163               PostGISIndexField *idx_fld = idx->GetFirst();
4164               while (idx_fld)
4165                 {
4166                   if (idx_fld == idx->GetFirst())
4167                     ;
4168                   else
4169                     fprintf(out, ", ");
4170                   strcpy(xname, idx_fld->GetColumnRef()->GetName().ToUTF8());
4171                   MyFrame::DoubleQuotedSql(xname);
4172                   fprintf(out, "%s", xname);
4173                   idx_fld = idx_fld->GetNext();
4174                 }
4175               fprintf(out, ")");
4176               idx = idx->GetNext();
4177             }
4178           fprintf(out, ");\n\n");
4179           for (i = 0; i < postgis.GetCount(); i++)
4180             {
4181               if (postgis.IsGeometry(i) != true)
4182                 {
4183                   // skipping any not-Geometry column
4184                   continue;
4185                 }
4186               fprintf(out, "SELECT AddGeometryColumn(");
4187               if (schema_name.Len() > 0)
4188                 {
4189                   strcpy(xname, schema_name.ToUTF8());
4190                   MyFrame::CleanSqlString(xname);
4191                   fprintf(out, "'%s', ", xname);
4192                 }
4193               strcpy(xname, table_name.ToUTF8());
4194               MyFrame::CleanSqlString(xname);
4195               fprintf(out, "'%s', ", xname);
4196               strcpy(xname, postgis.GetName(i, lowercase).ToUTF8());
4197               MyFrame::CleanSqlString(xname);
4198               fprintf(out, "'%s', %d, ", xname, postgis.GetSrid(i));
4199               switch (postgis.GetDataType(i))
4200                 {
4201                   case PostGISHelper::DATA_TYPE_POINT:
4202                     fprintf(out, "'POINT");
4203                     break;
4204                   case PostGISHelper::DATA_TYPE_MULTIPOINT:
4205                     fprintf(out, "'MULTIPOINT");
4206                     break;
4207                   case PostGISHelper::DATA_TYPE_LINESTRING:
4208                     fprintf(out, "'LINESTRING");
4209                     break;
4210                   case PostGISHelper::DATA_TYPE_MULTILINESTRING:
4211                     fprintf(out, "'MULTILINESTRING");
4212                     break;
4213                   case PostGISHelper::DATA_TYPE_POLYGON:
4214                     fprintf(out, "'POLYGON");
4215                     break;
4216                   case PostGISHelper::DATA_TYPE_MULTIPOLYGON:
4217                     fprintf(out, "'MULTIPOLYGON");
4218                     break;
4219                   case PostGISHelper::DATA_TYPE_GEOMETRYCOLLECTION:
4220                     fprintf(out, "'GEOMETRYCOLLECTION");
4221                     break;
4222                   default:
4223                     fprintf(out, "'GEOMETRY");
4224                     break;
4225                 };
4226               switch (postgis.GetCoordDims(i))
4227                 {
4228                   case GAIA_XY_Z_M:
4229                     fprintf(out, "', 4");
4230                     break;
4231                   case GAIA_XY_Z:
4232                     fprintf(out, "', 3");
4233                     break;
4234                   case GAIA_XY_M:
4235                     fprintf(out, "M', 3");
4236                     break;
4237                   default:
4238                     fprintf(out, "', 2");
4239                     break;
4240                 }
4241               fprintf(out, ");\n");
4242               if (spatial_index)
4243                 {
4244                   fprintf(out, "CREATE INDEX ");
4245                   wxString idx_name = wxT("idx_");
4246                   idx_name += table_name;
4247                   idx_name += wxT("_");
4248                   idx_name += postgis.GetName(i, lowercase);
4249                   strcpy(xname, idx_name.ToUTF8());
4250                   MainFrame->DoubleQuotedSql(xname);
4251                   fprintf(out, "%s ON ", xname);
4252                   if (schema_name.Len() > 0)
4253                     {
4254                       strcpy(xname, schema_name.ToUTF8());
4255                       MyFrame::DoubleQuotedSql(xname);
4256                       fprintf(out, "%s.", xname);
4257                     }
4258                   strcpy(xname, table_name.ToUTF8());
4259                   MainFrame->DoubleQuotedSql(xname);
4260                   fprintf(out, "%s USING GIST (", xname);
4261                   strcpy(xname, postgis.GetName(i, lowercase).ToUTF8());
4262                   MainFrame->DoubleQuotedSql(xname);
4263                   fprintf(out, "%s);\n", xname);
4264                 }
4265             }
4266 
4267           idx = postgis.GetFirstIndex();
4268           while (idx)
4269             {
4270               if (idx->IsPrimaryKey() == true)
4271                 {
4272                   idx = idx->GetNext();
4273                   continue;
4274                 }
4275               if (idx->IsUnique() == true)
4276                 fprintf(out, "CREATE UNIQUE INDEX ");
4277               else
4278                 fprintf(out, "CREATE INDEX ");
4279               strcpy(xname, idx->GetName().ToUTF8());
4280               MainFrame->DoubleQuotedSql(xname);
4281               fprintf(out, "%s ON ", xname);
4282               if (schema_name.Len() > 0)
4283                 {
4284                   strcpy(xname, schema_name.ToUTF8());
4285                   MainFrame->DoubleQuotedSql(xname);
4286                   fprintf(out, "%s.", xname);
4287                 }
4288               strcpy(xname, table_name.ToUTF8());
4289               MainFrame->DoubleQuotedSql(xname);
4290               fprintf(out, "%s (", xname);
4291               PostGISIndexField *idx_fld = idx->GetFirst();
4292               while (idx_fld)
4293                 {
4294                   if (idx_fld != idx->GetFirst())
4295                     fprintf(out, ", ");
4296                   strcpy(xname, idx_fld->GetColumnRef()->GetName().ToUTF8());
4297                   MainFrame->DoubleQuotedSql(xname);
4298                   fprintf(out, "%s", xname);
4299                   idx_fld = idx_fld->GetNext();
4300                 }
4301               fprintf(out, ");\n");
4302               idx = idx->GetNext();
4303             }
4304           fprintf(out, "\n");
4305 
4306           rows = 0;
4307           fprintf(out, "BEGIN;\n");
4308           while (1)
4309             {
4310               ret = sqlite3_step(stmt);
4311               if (ret == SQLITE_DONE)
4312                 break;          // end of result set
4313               if (ret == SQLITE_ROW)
4314                 {
4315                   if (rows > 0)
4316                     {
4317                       if ((rows % 1000) == 0)
4318                         {
4319                           // COMMIT and then restarts a new Transaction
4320                           fprintf(out, "COMMIT;\n\n");
4321                           fprintf(out, "-- %d rows\n\nBEGIN;\n", rows);
4322                         }
4323                     }
4324                   rows++;
4325                   fprintf(out, "INSERT INTO ");
4326                   if (schema_name.Len() > 0)
4327                     {
4328                       strcpy(xname, schema_name.ToUTF8());
4329                       MyFrame::DoubleQuotedSql(xname);
4330                       fprintf(out, "%s.", xname);
4331                     }
4332                   strcpy(xname, table_name.ToUTF8());
4333                   MyFrame::DoubleQuotedSql(xname);
4334                   fprintf(out, "%s (", xname);
4335                   for (i = 0; i < postgis.GetCount(); i++)
4336                     {
4337                       if (postgis.GetDataType(i) == postgis.DATA_TYPE_UNDEFINED)
4338                         {
4339                           // skipping any invalid column
4340                           continue;
4341                         }
4342                       strcpy(xname, postgis.GetName(i, lowercase).ToUTF8());
4343                       MainFrame->DoubleQuotedSql(xname);
4344                       if (i == 0)
4345                         fprintf(out, "%s", xname);
4346                       else
4347                         fprintf(out, ", %s", xname);
4348                     }
4349                   fprintf(out, ") VALUES (");
4350                   for (i = 0; i < n_cols; i++)
4351                     {
4352                       if (i > 0)
4353                         fprintf(out, ", ");
4354                       int type = sqlite3_column_type(stmt, i);
4355                       int data_type = postgis.GetDataType(i);
4356                       switch (type)
4357                         {
4358                           case SQLITE_NULL:
4359                             fprintf(out, "NULL");
4360                             break;
4361                           case SQLITE_INTEGER:
4362                             if (data_type == PostGISHelper::DATA_TYPE_BOOLEAN)
4363                               postgis.OutputBooleanValue(out,
4364                                                          sqlite3_column_int64
4365                                                          (stmt, i));
4366                             else
4367                               postgis.OutputValue(out,
4368                                                   sqlite3_column_int64(stmt,
4369                                                                        i));
4370                             break;
4371                           case SQLITE_FLOAT:
4372                             postgis.OutputValue(out,
4373                                                 sqlite3_column_double(stmt, i));
4374                             break;
4375                           case SQLITE_TEXT:
4376                             postgis.OutputValue(out,
4377                                                 (const char *)
4378                                                 sqlite3_column_text(stmt, i));
4379                             break;
4380                           case SQLITE_BLOB:
4381                             if (postgis.IsGeometry(i))
4382                               {
4383                                 const void *blob_value;
4384                                 blob_value = sqlite3_column_blob(stmt, i);
4385                                 int len = sqlite3_column_bytes(stmt, i);
4386                                 geom =
4387                                   gaiaFromSpatiaLiteBlobWkb((unsigned char *)
4388                                                             blob_value, len);
4389                                 if (geom == NULL)
4390                                   fprintf(out, "NULL");
4391                                 else
4392                                   {
4393                                     postgis.OutputValue(out, geom);
4394                                     gaiaFreeGeomColl(geom);
4395                                   }
4396                             } else
4397                               {
4398                                 int len = sqlite3_column_bytes(stmt, i);
4399                                 postgis.OutputValue(out,
4400                                                     (unsigned char *)
4401                                                     sqlite3_column_blob(stmt,
4402                                                                         i),
4403                                                     len);
4404                               }
4405                             break;
4406                         };
4407                     }
4408                   fprintf(out, ");\n");
4409               } else
4410                 {
4411                   sqlite3_finalize(stmt);
4412                   goto sql_error;
4413                 }
4414             }
4415           fprintf(out, "COMMIT;\n");
4416         }
4417 
4418 
4419       fprintf(out, "\n--\n-- end SQL dump\n");
4420       fprintf(out, "--\n");
4421       ::wxEndBusyCursor();
4422       fclose(out);
4423     }
4424 
4425 stop:
4426   sqlite3_finalize(stmt);
4427   return;
4428 
4429 sql_error:
4430 //
4431 // some SQL error occurred
4432 //
4433   sqlite3_finalize(stmt);
4434   ::wxEndBusyCursor();
4435   wxMessageBox(wxT("PostGIS SQL dump error:") +
4436                wxString::FromUTF8(sqlite3_errmsg(MainFrame->GetSqlite())),
4437                wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4438   return;
4439 }
4440 
OnCmdMapPreview(wxCommandEvent & WXUNUSED (event))4441 void MyTableTree::OnCmdMapPreview(wxCommandEvent & WXUNUSED(event))
4442 {
4443 //
4444 // menu event - Map Preview
4445 //
4446   char table_name[1024];
4447   char column_name[1024];
4448   char sql[4192];
4449   char sql2[2048];
4450   int ret;
4451   char err_msg[2048];
4452   sqlite3_stmt *stmt;
4453   double minx = DBL_MAX;
4454   double miny = DBL_MAX;
4455   double maxx = DBL_MAX;
4456   double maxy = DBL_MAX;
4457 
4458   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
4459   if (obj == NULL)
4460     return;
4461 
4462   ::wxBeginBusyCursor();
4463   strcpy(table_name, obj->GetName().ToUTF8());
4464   strcpy(column_name, obj->GetColumn().ToUTF8());
4465   MainFrame->DoubleQuotedSql(table_name);
4466   MainFrame->DoubleQuotedSql(column_name);
4467   sprintf(sql, "SELECT Min(MbrMinX(%s)), Min(MbrMinY(%s)), ", column_name,
4468           column_name);
4469   sprintf(sql2, "Max(MbrMaxX(%s)), Max(MbrMaxY(%s)) ", column_name,
4470           column_name);
4471   strcat(sql, sql2);
4472   sprintf(sql2, "FROM %s", table_name);
4473   strcat(sql, sql2);
4474 
4475   ret =
4476     sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt, NULL);
4477   if (ret != SQLITE_OK)
4478     {
4479       sprintf(err_msg, "SQL error: %s", sqlite3_errmsg(MainFrame->GetSqlite()));
4480       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
4481                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4482       ::wxEndBusyCursor();
4483       return;
4484     }
4485   while (1)
4486     {
4487       //
4488       // fetching the result set rows
4489       //
4490       ret = sqlite3_step(stmt);
4491       if (ret == SQLITE_DONE)
4492         break;                  // end of result set
4493       if (ret == SQLITE_ROW)
4494         {
4495           //
4496           // fetching a row
4497           //
4498           if (sqlite3_column_type(stmt, 0) == SQLITE_FLOAT)
4499             minx = sqlite3_column_double(stmt, 0);
4500           if (sqlite3_column_type(stmt, 1) == SQLITE_FLOAT)
4501             miny = sqlite3_column_double(stmt, 1);
4502           if (sqlite3_column_type(stmt, 2) == SQLITE_FLOAT)
4503             maxx = sqlite3_column_double(stmt, 2);
4504           if (sqlite3_column_type(stmt, 3) == SQLITE_FLOAT)
4505             maxy = sqlite3_column_double(stmt, 3);
4506       } else
4507         {
4508           sqlite3_finalize(stmt);
4509           sprintf(err_msg, "SQL error: %s",
4510                   sqlite3_errmsg(MainFrame->GetSqlite()));
4511           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
4512                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4513           ::wxEndBusyCursor();
4514           return;
4515         }
4516     }
4517   sqlite3_finalize(stmt);
4518   ::wxEndBusyCursor();
4519 
4520   if (minx == DBL_MAX || miny == DBL_MAX || maxx == DBL_MAX || maxy == DBL_MAX)
4521     {
4522       wxMessageBox(wxT("This Column doesn't contains any Geometry: sorry ..."),
4523                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4524       return;
4525     }
4526 
4527   MapPreviewDialog dlg;
4528   dlg.Create(MainFrame, obj->GetName(), obj->GetColumn(), minx, miny, maxx,
4529              maxy);
4530   dlg.ShowModal();
4531 }
4532 
OnCmdColumnStats(wxCommandEvent & WXUNUSED (event))4533 void MyTableTree::OnCmdColumnStats(wxCommandEvent & WXUNUSED(event))
4534 {
4535 //
4536 // menu event - column stats
4537 //
4538   char table_name[1024];
4539   char column_name[1024];
4540   char sql[4192];
4541   char sql2[4192];
4542   int ret;
4543   char **results;
4544   int rows;
4545   int columns;
4546   int i;
4547   char *errMsg = NULL;
4548   const char *value;
4549   char err_msg[2048];
4550   sqlite3_stmt *stmt;
4551   int count;
4552   int null_count = 0;
4553   int text_count = 0;
4554   int integer_count = 0;
4555   int real_count = 0;
4556   int blob_count = 0;
4557   double min;
4558   double max;
4559   double avg;
4560   double stddev_pop;
4561   double stddev_samp;
4562   double var_pop;
4563   double var_samp;
4564   int distinct_values = 0;
4565 
4566   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
4567   if (obj == NULL)
4568     return;
4569 
4570   ::wxBeginBusyCursor();
4571   strcpy(table_name, obj->GetName().ToUTF8());
4572   strcpy(column_name, obj->GetColumn().ToUTF8());
4573   MainFrame->DoubleQuotedSql(table_name);
4574   MainFrame->DoubleQuotedSql(column_name);
4575   sprintf(sql, "SELECT Typeof(%s), Count(*) FROM %s GROUP BY Typeof(%s)",
4576           column_name, table_name, column_name);
4577 
4578   ret = sqlite3_get_table(MainFrame->GetSqlite(), sql, &results,
4579                           &rows, &columns, &errMsg);
4580   if (ret != SQLITE_OK)
4581     {
4582       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
4583                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4584       sqlite3_free(errMsg);
4585       ::wxEndBusyCursor();
4586       return;
4587     }
4588   if (rows < 1)
4589     ;
4590   else
4591     {
4592       for (i = 1; i <= rows; i++)
4593         {
4594           value = results[(i * columns) + 0];
4595           count = atoi(results[(i * columns) + 1]);
4596           if (strcasecmp(value, "null") == 0)
4597             null_count += count;
4598           if (strcasecmp(value, "text") == 0)
4599             text_count += count;
4600           if (strcasecmp(value, "integer") == 0)
4601             integer_count += count;
4602           if (strcasecmp(value, "real") == 0)
4603             real_count += count;
4604           if (strcasecmp(value, "blob") == 0)
4605             blob_count += count;
4606         }
4607     }
4608   sqlite3_free_table(results);
4609 
4610   if ((real_count + integer_count) > 0)
4611     {
4612       // computing statistic analysis
4613       sprintf(sql, "SELECT Min(%s), Max(%s), Avg(%s), ", column_name,
4614               column_name, column_name);
4615       sprintf(sql2, "StdDev_pop(%s), StdDev_samp(%s), ", column_name,
4616               column_name);
4617       strcat(sql, sql2);
4618       sprintf(sql2, "Var_pop(%s), Var_samp(%s) FROM %s", column_name,
4619               column_name, table_name);
4620       strcat(sql, sql2);
4621 
4622       ret = sqlite3_get_table(MainFrame->GetSqlite(), sql, &results,
4623                               &rows, &columns, &errMsg);
4624       if (ret != SQLITE_OK)
4625         {
4626           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
4627                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4628           sqlite3_free(errMsg);
4629           ::wxEndBusyCursor();
4630           return;
4631         }
4632       if (rows < 1)
4633         ;
4634       else
4635         {
4636           for (i = 1; i <= rows; i++)
4637             {
4638               min = atof(results[(i * columns) + 0]);
4639               max = atof(results[(i * columns) + 1]);
4640               avg = atof(results[(i * columns) + 2]);
4641               stddev_pop = atof(results[(i * columns) + 3]);
4642               stddev_samp = atof(results[(i * columns) + 4]);
4643               var_pop = atof(results[(i * columns) + 5]);
4644               var_samp = atof(results[(i * columns) + 6]);
4645             }
4646         }
4647       sqlite3_free_table(results);
4648     }
4649 // computing DISTINCT values
4650   sprintf(sql, "SELECT DISTINCT %s FROM %s", column_name, table_name);
4651   ret =
4652     sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt, NULL);
4653   if (ret != SQLITE_OK)
4654     {
4655       sprintf(err_msg, "SQL error: %s", sqlite3_errmsg(MainFrame->GetSqlite()));
4656       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
4657                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4658       ::wxEndBusyCursor();
4659       return;
4660     }
4661   while (1)
4662     {
4663       //
4664       // fetching the result set rows
4665       //
4666       ret = sqlite3_step(stmt);
4667       if (ret == SQLITE_DONE)
4668         break;                  // end of result set
4669       if (ret == SQLITE_ROW)
4670         {
4671           //
4672           // fetching a row
4673           //
4674           distinct_values++;
4675       } else
4676         {
4677           sqlite3_finalize(stmt);
4678           sprintf(err_msg, "SQL error: %s",
4679                   sqlite3_errmsg(MainFrame->GetSqlite()));
4680           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
4681                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4682           ::wxEndBusyCursor();
4683           return;
4684         }
4685     }
4686   sqlite3_finalize(stmt);
4687 
4688   ::wxEndBusyCursor();
4689 
4690   ColumnStatsDialog dlg;
4691   dlg.Create(MainFrame, obj->GetName(), obj->GetColumn(), null_count,
4692              text_count, integer_count, real_count, blob_count, min, max, avg,
4693              stddev_pop, stddev_samp, var_pop, var_samp, distinct_values);
4694   dlg.ShowModal();
4695 }
4696 
DropRenameAux1(MyObject * obj,GeomColsList * Geometries,bool * autoincrement)4697 bool MyTableTree::DropRenameAux1(MyObject * obj, GeomColsList * Geometries,
4698                                  bool * autoincrement)
4699 {
4700 //
4701 // common tasks: drop/rename column auxiliaries
4702 //
4703   int ret;
4704   char **results;
4705   int rows;
4706   int columns;
4707   int i;
4708   char *errMsg = NULL;
4709   wxString sql;
4710   bool check_autoincrement = false;
4711   wxString geomColumn;
4712   wxString geomType;
4713   wxString coordDims;
4714   int geomSrid;
4715   int indexType;
4716   wxString indexName;
4717   char xname[1024];
4718   char *value;
4719   int metadata_type;
4720 
4721 // checking if the SQLITE_SEQUENCE table exists
4722   sql = wxT("PRAGMA table_info(sqlite_sequence)");
4723   ret = sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(), &results,
4724                           &rows, &columns, &errMsg);
4725   if (ret != SQLITE_OK)
4726     {
4727       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
4728                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4729       sqlite3_free(errMsg);
4730       return false;
4731     }
4732   if (rows < 1)
4733     ;
4734   else
4735     {
4736       for (i = 1; i <= rows; i++)
4737         {
4738           check_autoincrement = true;
4739         }
4740     }
4741   sqlite3_free_table(results);
4742   if (check_autoincrement == true)
4743     {
4744 // checking if there is an AUTOINCREMENT Primary Key
4745       sql = wxT("SELECT name FROM sqlite_sequence WHERE Lower(name) = Lower('");
4746       strcpy(xname, obj->GetName().ToUTF8());
4747       MainFrame->CleanSqlString(xname);
4748       sql += wxString::FromUTF8(xname);
4749       sql += wxT("')");
4750       ret = sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(), &results,
4751                               &rows, &columns, &errMsg);
4752       if (ret != SQLITE_OK)
4753         {
4754           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
4755                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4756           sqlite3_free(errMsg);
4757           return false;
4758         }
4759       if (rows < 1)
4760         ;
4761       else
4762         {
4763           for (i = 1; i <= rows; i++)
4764             {
4765               *autoincrement = true;
4766             }
4767         }
4768       sqlite3_free_table(results);
4769     }
4770 // checking if there is some Spatial Index already defined
4771   metadata_type = MainFrame->GetMetaDataType();
4772   if (metadata_type == METADATA_LEGACY)
4773     sql =
4774       wxT
4775       ("SELECT f_geometry_column, type, coord_dimension, srid, spatial_index_enabled ");
4776   else if (metadata_type == METADATA_CURRENT)
4777     sql =
4778       wxT
4779       ("SELECT f_geometry_column, geometry_type, srid, spatial_index_enabled ");
4780   else
4781     return false;
4782   sql += wxT("FROM geometry_columns WHERE Lower(f_table_name) = Lower('");
4783   strcpy(xname, obj->GetName().ToUTF8());
4784   MainFrame->CleanSqlString(xname);
4785   sql += wxString::FromUTF8(xname);
4786   sql += wxT("')");
4787   ret = sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(), &results,
4788                           &rows, &columns, &errMsg);
4789   if (ret != SQLITE_OK)
4790     {
4791       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
4792                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
4793       sqlite3_free(errMsg);
4794       return false;
4795     }
4796   if (rows < 1)
4797     ;
4798   else
4799     {
4800       for (i = 1; i <= rows; i++)
4801         {
4802           if (metadata_type == METADATA_LEGACY)
4803             {
4804               /* legacy Spatial MetaData layout */
4805               value = results[(i * columns) + 0];
4806               geomColumn = wxString::FromUTF8(value);
4807               value = results[(i * columns) + 1];
4808               geomType = wxString::FromUTF8(value);
4809               value = results[(i * columns) + 2];
4810               coordDims = wxString::FromUTF8(value);
4811               value = results[(i * columns) + 3];
4812               geomSrid = atoi(value);
4813               value = results[(i * columns) + 4];
4814               indexType = atoi(value);
4815           } else
4816             {
4817               /* current Spatial MetaData layout */
4818               value = results[(i * columns) + 0];
4819               geomColumn = wxString::FromUTF8(value);
4820               switch (atoi(results[(i * columns) + 1]))
4821                 {
4822                   case 0:
4823                     geomType = wxT("GEOMETRY");
4824                     coordDims = wxT("XY");
4825                     break;
4826                   case 1000:
4827                     geomType = wxT("GEOMETRY");
4828                     coordDims = wxT("XYZ");
4829                     break;
4830                   case 2000:
4831                     geomType = wxT("GEOMETRY");
4832                     coordDims = wxT("XYM");
4833                     break;
4834                   case 3000:
4835                     geomType = wxT("GEOMETRY");
4836                     coordDims = wxT("XYZM");
4837                     break;
4838                   case 1:
4839                     geomType = wxT("POINT");
4840                     coordDims = wxT("XY");
4841                     break;
4842                   case 1001:
4843                     geomType = wxT("POINT");
4844                     coordDims = wxT("XYZ");
4845                     break;
4846                   case 2001:
4847                     geomType = wxT("POINT");
4848                     coordDims = wxT("XYM");
4849                     break;
4850                   case 3001:
4851                     geomType = wxT("POINT");
4852                     coordDims = wxT("XYZM");
4853                     break;
4854                   case 2:
4855                     geomType = wxT("LINESTRING");
4856                     coordDims = wxT("XY");
4857                     break;
4858                   case 1002:
4859                     geomType = wxT("LINESTRING");
4860                     coordDims = wxT("XYZ");
4861                     break;
4862                   case 2002:
4863                     geomType = wxT("LINESTRING");
4864                     coordDims = wxT("XYM");
4865                     break;
4866                   case 3002:
4867                     geomType = wxT("LINESTRING");
4868                     coordDims = wxT("XYZM");
4869                     break;
4870                   case 3:
4871                     geomType = wxT("POLYGON");
4872                     coordDims = wxT("XY");
4873                     break;
4874                   case 1003:
4875                     geomType = wxT("POLYGON");
4876                     coordDims = wxT("XYZ");
4877                     break;
4878                   case 2003:
4879                     geomType = wxT("POLYGON");
4880                     coordDims = wxT("XYM");
4881                     break;
4882                   case 3003:
4883                     geomType = wxT("POLYGON");
4884                     coordDims = wxT("XYZM");
4885                     break;
4886                   case 4:
4887                     geomType = wxT("MULTIPOINT");
4888                     coordDims = wxT("XY");
4889                     break;
4890                   case 1004:
4891                     geomType = wxT("MULTIPOINT");
4892                     coordDims = wxT("XYZ");
4893                     break;
4894                   case 2004:
4895                     geomType = wxT("MULTIPOINT");
4896                     coordDims = wxT("XYM");
4897                     break;
4898                   case 3004:
4899                     geomType = wxT("MULTIPOINT");
4900                     coordDims = wxT("XYZM");
4901                     break;
4902                   case 5:
4903                     geomType = wxT("MULTILINESTRING");
4904                     coordDims = wxT("XY");
4905                     break;
4906                   case 1005:
4907                     geomType = wxT("MULTILINESTRING");
4908                     coordDims = wxT("XYZ");
4909                     break;
4910                   case 2005:
4911                     geomType = wxT("MULTILINESTRING");
4912                     coordDims = wxT("XYM");
4913                     break;
4914                   case 3005:
4915                     geomType = wxT("MULTILINESTRING");
4916                     coordDims = wxT("XYZM");
4917                     break;
4918                   case 6:
4919                     geomType = wxT("MULTIPOLYGON");
4920                     coordDims = wxT("XY");
4921                     break;
4922                   case 1006:
4923                     geomType = wxT("MULTIPOLYGON");
4924                     coordDims = wxT("XYZ");
4925                     break;
4926                   case 2006:
4927                     geomType = wxT("MULTIPOLYGON");
4928                     coordDims = wxT("XYM");
4929                     break;
4930                   case 3006:
4931                     geomType = wxT("MULTIPOLYGON");
4932                     coordDims = wxT("XYZM");
4933                     break;
4934                   case 7:
4935                     geomType = wxT("GEOMETRYCOLLECTION");
4936                     coordDims = wxT("XY");
4937                     break;
4938                   case 1007:
4939                     geomType = wxT("GEOMETRYCOLLECTION");
4940                     coordDims = wxT("XYZ");
4941                     break;
4942                   case 2007:
4943                     geomType = wxT("GEOMETRYCOLLECTION");
4944                     coordDims = wxT("XYM");
4945                     break;
4946                   case 3007:
4947                     geomType = wxT("GEOMETRYCOLLECTION");
4948                     coordDims = wxT("XYZM");
4949                     break;
4950                 };
4951               value = results[(i * columns) + 2];
4952               geomSrid = atoi(value);
4953               value = results[(i * columns) + 3];
4954               indexType = atoi(value);
4955             }
4956           Geometries->Add(geomColumn, geomType, coordDims, geomSrid, indexType);
4957         }
4958     }
4959   sqlite3_free_table(results);
4960   return true;
4961 }
4962 
DropRenameAux2(MyObject * obj,GeomColsList * Geometries,wxString & aliasTable,wxString & renameSql,wxString & dropSql,wxString & disableSpatialIdxSql,wxString & dropSpatialIdxSql,wxString & createSpatialIdxSql,wxString & discardGeometrySql)4963 void MyTableTree::DropRenameAux2(MyObject * obj, GeomColsList * Geometries,
4964                                  wxString & aliasTable, wxString & renameSql,
4965                                  wxString & dropSql,
4966                                  wxString & disableSpatialIdxSql,
4967                                  wxString & dropSpatialIdxSql,
4968                                  wxString & createSpatialIdxSql,
4969                                  wxString & discardGeometrySql)
4970 {
4971 //
4972 // common tasks: drop/rename column auxiliaries
4973 //
4974   GeomColumn *pG;
4975   wxString name;
4976   char xname[1024];
4977   char column[1024];
4978 
4979 // creating the SQL fragments
4980   aliasTable = wxT("tmp_alias ");
4981   aliasTable += obj->GetName();
4982   aliasTable += wxT(" tmp_alias");
4983   strcpy(xname, aliasTable.ToUTF8());
4984   MainFrame->DoubleQuotedSql(xname);
4985   aliasTable = wxString::FromUTF8(xname);
4986   renameSql = wxT("ALTER TABLE ");
4987   strcpy(xname, obj->GetName().ToUTF8());
4988   MainFrame->DoubleQuotedSql(xname);
4989   renameSql += wxString::FromUTF8(xname);
4990   renameSql += wxT(" RENAME TO ");
4991   renameSql += aliasTable;
4992   renameSql += wxT(";\n");
4993 
4994   dropSql = wxT("DROP TABLE ");
4995   dropSql += aliasTable;
4996   dropSql += wxT(";\n");
4997   strcpy(column, obj->GetColumn().ToUTF8());
4998   pG = Geometries->GetFirst();
4999   while (pG)
5000     {
5001       if (pG->IsRTree() == true || pG->IsMbrCache() == true)
5002         {
5003           // disabling a Spatial Index
5004           disableSpatialIdxSql += wxT("SELECT DisableSpatialIndex('");
5005           strcpy(xname, obj->GetName().ToUTF8());
5006           MainFrame->CleanSqlString(xname);
5007           disableSpatialIdxSql += wxString::FromUTF8(xname);
5008           disableSpatialIdxSql += wxT("', '");
5009           strcpy(xname, pG->GetGeometryName().ToUTF8());
5010           MainFrame->CleanSqlString(xname);
5011           disableSpatialIdxSql += wxString::FromUTF8(xname);
5012           disableSpatialIdxSql += wxT("');\n");
5013           dropSpatialIdxSql += wxT("DROP TABLE IF EXISTS ");
5014           name = wxT("idx_");
5015           name += obj->GetName();
5016           name += wxT("_");
5017           name += pG->GetGeometryName();
5018           strcpy(xname, name.ToUTF8());
5019           MainFrame->DoubleQuotedSql(xname);
5020           dropSpatialIdxSql += wxString::FromUTF8(xname);
5021           dropSpatialIdxSql += wxT(";\n");
5022           if (pG->IsRTree() == true)
5023             {
5024               // creating an RTree Spatial Index
5025               createSpatialIdxSql += wxT("SELECT CreateSpatialIndex('");
5026               strcpy(xname, obj->GetName().ToUTF8());
5027               MainFrame->CleanSqlString(xname);
5028               createSpatialIdxSql += wxString::FromUTF8(xname);
5029               createSpatialIdxSql += wxT("', '");
5030               strcpy(xname, pG->GetGeometryName().ToUTF8());
5031               MainFrame->CleanSqlString(xname);
5032               createSpatialIdxSql += wxString::FromUTF8(xname);
5033               createSpatialIdxSql += wxT("');\n");
5034           } else
5035             {
5036               // creating an MbrCache Spatial Index
5037               createSpatialIdxSql += wxT("SELECT CreateMbrCache('");
5038               strcpy(xname, obj->GetName().ToUTF8());
5039               MainFrame->CleanSqlString(xname);
5040               createSpatialIdxSql += wxString::FromUTF8(xname);
5041               createSpatialIdxSql += wxT("', '");
5042               strcpy(xname, pG->GetGeometryName().ToUTF8());
5043               MainFrame->CleanSqlString(xname);
5044               createSpatialIdxSql += wxString::FromUTF8(xname);
5045               createSpatialIdxSql += wxT("');\n");
5046             }
5047         }
5048       // discarding a Geometry Column
5049       discardGeometrySql += wxT("SELECT DiscardGeometryColumn('");
5050       strcpy(xname, obj->GetName().ToUTF8());
5051       MainFrame->CleanSqlString(xname);
5052       discardGeometrySql += wxString::FromUTF8(xname);
5053       discardGeometrySql += wxT("', '");
5054       strcpy(xname, pG->GetGeometryName().ToUTF8());
5055       MainFrame->CleanSqlString(xname);
5056       discardGeometrySql += wxString::FromUTF8(xname);
5057       discardGeometrySql += wxT("');\n");
5058       pG = pG->GetNext();
5059     }
5060 }
5061 
DropRenameAux3(MyObject * obj,GeomColsList * Geometries,TblIndexList * Index,wxString & addGeometrySql)5062 void MyTableTree::DropRenameAux3(MyObject * obj, GeomColsList * Geometries,
5063                                  TblIndexList * Index,
5064                                  wxString & addGeometrySql)
5065 {
5066 //
5067 // common tasks: drop/rename column auxiliaries
5068 //
5069   GeomColumn *pG;
5070   TblIndex *pI;
5071   char xname[1024];
5072   char dummy[64];
5073   int ret;
5074   char **results;
5075   int rows;
5076   int columns;
5077   int i;
5078   char *errMsg = NULL;
5079   wxString sql;
5080   char *value;
5081   wxString indexName;
5082   bool uniqueIndex;
5083 
5084   pG = Geometries->GetFirst();
5085   while (pG)
5086     {
5087       // adding a Geometry Column
5088       addGeometrySql += wxT("SELECT AddGeometryColumn('");
5089       strcpy(xname, obj->GetName().ToUTF8());
5090       MainFrame->CleanSqlString(xname);
5091       addGeometrySql += wxString::FromUTF8(xname);
5092       addGeometrySql += wxT("', '");
5093       strcpy(xname, pG->GetGeometryName().ToUTF8());
5094       MainFrame->CleanSqlString(xname);
5095       addGeometrySql += wxString::FromUTF8(xname);
5096       sprintf(dummy, "', %d", pG->GetSrid());
5097       addGeometrySql += wxString::FromUTF8(dummy);
5098       addGeometrySql += wxT(", '");
5099       addGeometrySql += pG->GetGeometryType();
5100       if (pG->GetCoordDims() == wxT('2') || pG->GetCoordDims() == wxT('3'))
5101         {
5102           addGeometrySql += wxT("', ");
5103           addGeometrySql += pG->GetCoordDims();
5104       } else
5105         {
5106           addGeometrySql += wxT("', '");
5107           addGeometrySql += pG->GetCoordDims();
5108           addGeometrySql += wxT("'");
5109         }
5110       if (pG->IsNotNull() == false)
5111         addGeometrySql += wxT(");\n");
5112       else
5113         addGeometrySql += wxT(", 1);\n");
5114       pG = pG->GetNext();
5115     }
5116 
5117 // retrieving any related Index
5118   sql = wxT("PRAGMA index_list(");
5119   strcpy(xname, obj->GetName().ToUTF8());
5120   MainFrame->DoubleQuotedSql(xname);
5121   sql += wxString::FromUTF8(xname);
5122   sql += wxT(")");
5123   ret = sqlite3_get_table(MainFrame->GetSqlite(), 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       for (i = 1; i <= rows; i++)
5137         {
5138           value = results[(i * columns) + 1];
5139           if (strncmp(value, "sqlite_autoindex_", 17) == 0)
5140             {
5141               // sandro 2011-01-03: discarding any Primary Key Index
5142               continue;
5143             }
5144           indexName = wxString::FromUTF8(value);
5145           value = results[(i * columns) + 2];
5146           if (atoi(value) == 0)
5147             uniqueIndex = false;
5148           else
5149             uniqueIndex = true;
5150           Index->Add(indexName, uniqueIndex);
5151         }
5152     }
5153   sqlite3_free_table(results);
5154   pI = Index->GetFirst();
5155   while (pI)
5156     {
5157       // retrieving any Index Column
5158       sql = wxT("PRAGMA index_info(");
5159       strcpy(xname, pI->GetIndexName().ToUTF8());
5160       MainFrame->DoubleQuotedSql(xname);
5161       sql += wxString::FromUTF8(xname);
5162       sql += wxT(")");
5163       ret = sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(), &results,
5164                               &rows, &columns, &errMsg);
5165       if (ret != SQLITE_OK)
5166         {
5167           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5168                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5169           sqlite3_free(errMsg);
5170           return;
5171         }
5172       if (rows < 1)
5173         ;
5174       else
5175         {
5176           for (i = 1; i <= rows; i++)
5177             {
5178               value = results[(i * columns) + 2];
5179               indexName = wxString::FromUTF8(value);
5180               pI->Add(indexName);
5181             }
5182         }
5183       sqlite3_free_table(results);
5184       pI = pI->GetNext();
5185     }
5186 
5187 }
5188 
OnCmdDropColumn(wxCommandEvent & WXUNUSED (event))5189 void MyTableTree::OnCmdDropColumn(wxCommandEvent & WXUNUSED(event))
5190 {
5191 //
5192 // menu event - drop column
5193 //
5194   char column[1024];
5195   int ret;
5196   char **results;
5197   int rows;
5198   int columns;
5199   int i;
5200   char *errMsg = NULL;
5201   wxString sql;
5202   wxString createSql;
5203   wxString insertSql;
5204   wxString insertFromSql;
5205   wxString renameSql;
5206   wxString dropSql;
5207   wxString dropIndexSql;
5208   wxString createIndexSql;
5209   wxString disableSpatialIdxSql;
5210   wxString dropSpatialIdxSql;
5211   wxString createSpatialIdxSql;
5212   wxString discardGeometrySql;
5213   wxString addGeometrySql;
5214   wxString geomColumn;
5215   bool comma = false;
5216   char *value;
5217   bool autoincrement = false;
5218   wxString aliasTable;
5219   bool isGeom;
5220   wxString msg;
5221   GeomColsList Geometries;
5222   GeomColumn *pG;
5223   TblIndexList Index;
5224   TblIndex *pI;
5225   IndexColumn *pC;
5226   wxString name;
5227   char xname[1024];
5228   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
5229   if (obj == NULL)
5230     return;
5231 
5232   strcpy(column, obj->GetColumn().ToUTF8());
5233   if (DropRenameAux1(obj, &Geometries, &autoincrement) == false)
5234     return;
5235   DropRenameAux2(obj, &Geometries, aliasTable, renameSql, dropSql,
5236                  disableSpatialIdxSql, dropSpatialIdxSql, createSpatialIdxSql,
5237                  discardGeometrySql);
5238 
5239 // retrieving the Column names
5240   sql = wxT("PRAGMA table_info(");
5241   strcpy(xname, obj->GetName().ToUTF8());
5242   MainFrame->DoubleQuotedSql(xname);
5243   sql += wxString::FromUTF8(xname);
5244   sql += wxT(")");
5245   ret = sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(), &results,
5246                           &rows, &columns, &errMsg);
5247   if (ret != SQLITE_OK)
5248     {
5249       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5250                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5251       sqlite3_free(errMsg);
5252       return;
5253     }
5254   if (rows < 1)
5255     ;
5256   else
5257     {
5258       createSql = wxT("CREATE TABLE ");
5259       strcpy(xname, obj->GetName().ToUTF8());
5260       MainFrame->DoubleQuotedSql(xname);
5261       createSql += wxString::FromUTF8(xname);
5262       createSql += wxT(" (\n");
5263       insertSql = wxT("INSERT INTO ");
5264       strcpy(xname, obj->GetName().ToUTF8());
5265       MainFrame->DoubleQuotedSql(xname);
5266       insertSql += wxString::FromUTF8(xname);
5267       insertSql += wxT(" (");
5268       insertFromSql = wxT("SELECT ");
5269       for (i = 1; i <= rows; i++)
5270         {
5271           value = results[(i * columns) + 1];
5272           if (strcasecmp(value, column) == 0)
5273             continue;
5274           isGeom = false;
5275           pG = Geometries.GetFirst();
5276           while (pG)
5277             {
5278               char geom[1024];
5279               strcpy(geom, pG->GetGeometryName().ToUTF8());
5280               if (strcasecmp(geom, value) == 0)
5281                 {
5282                   isGeom = true;
5283                   geomColumn = pG->GetGeometryName();
5284                   break;
5285                 }
5286               pG = pG->GetNext();
5287             }
5288           if (comma == true)
5289             {
5290               if (isGeom == false)
5291                 createSql += wxT(",\n");
5292               insertSql += wxT(", ");
5293               insertFromSql += wxT(", ");
5294             }
5295           if (isGeom == false)
5296             {
5297               strcpy(xname, value);
5298               MainFrame->DoubleQuotedSql(xname);
5299               createSql += wxString::FromUTF8(xname);
5300               createSql += wxT(" ");
5301             }
5302           strcpy(xname, value);
5303           MainFrame->DoubleQuotedSql(xname);
5304           insertSql += wxString::FromUTF8(xname);
5305           strcpy(xname, value);
5306           MainFrame->DoubleQuotedSql(xname);
5307           insertFromSql += wxString::FromUTF8(xname);
5308           value = results[(i * columns) + 2];
5309           if (isGeom == false)
5310             createSql += wxString::FromUTF8(value);
5311           value = results[(i * columns) + 5];
5312           if (value)
5313             {
5314               if (atoi(value) != 0)
5315                 {
5316                   if (isGeom == false)
5317                     {
5318                       createSql += wxT(" PRIMARY KEY");
5319                       if (autoincrement == true)
5320                         createSql += wxT(" AUTOINCREMENT");
5321                     }
5322                 }
5323             }
5324           value = results[(i * columns) + 3];
5325           if (value)
5326             {
5327               if (atoi(value) != 0)
5328                 {
5329                   if (isGeom == true)
5330                     Geometries.SetNotNull(geomColumn);
5331                   else
5332                     createSql += wxT(" NOT NULL");
5333                 }
5334             }
5335           value = results[(i * columns) + 4];
5336           if (value && isGeom == false)
5337             {
5338               createSql += wxT(" DEFAULT ");
5339               createSql += wxString::FromUTF8(value);
5340             }
5341           comma = true;
5342         }
5343       createSql += wxT(");\n");
5344       insertSql += wxT(")\n");
5345       insertFromSql += wxT("\nFROM ");
5346       insertFromSql += aliasTable;
5347       insertFromSql += wxT(";\n");
5348       insertSql += insertFromSql;
5349     }
5350   sqlite3_free_table(results);
5351 
5352   DropRenameAux3(obj, &Geometries, &Index, addGeometrySql);
5353 
5354 // setting up the Index SQL fragments
5355   Index.Invalidate(obj->GetColumn());
5356   pI = Index.GetFirst();
5357   while (pI)
5358     {
5359       dropIndexSql += wxT("DROP INDEX ");
5360       strcpy(xname, pI->GetIndexName().ToUTF8());
5361       MainFrame->DoubleQuotedSql(xname);
5362       dropIndexSql += wxString::FromUTF8(xname);
5363       dropIndexSql += wxT(";\n");
5364       if (pI->IsValid() == true)
5365         {
5366           if (pI->GetFirst())
5367             {
5368               if (pI->IsUnique() == true)
5369                 createIndexSql += wxT("CREATE UNIQUE INDEX ");
5370               else
5371                 createIndexSql += wxT("CREATE INDEX ");
5372               strcpy(xname, pI->GetIndexName().ToUTF8());
5373               MainFrame->DoubleQuotedSql(xname);
5374               createIndexSql += wxString::FromUTF8(xname);
5375               createIndexSql += wxT(" ON ");
5376               strcpy(xname, obj->GetName().ToUTF8());
5377               MainFrame->DoubleQuotedSql(xname);
5378               createIndexSql += wxString::FromUTF8(xname);
5379               createIndexSql += wxT(" (");
5380             }
5381           comma = false;
5382           pC = pI->GetFirst();
5383           while (pC)
5384             {
5385               if (comma == true)
5386                 createIndexSql += wxT(", ");
5387               strcpy(xname, pC->GetColumnName().ToUTF8());
5388               MainFrame->DoubleQuotedSql(xname);
5389               createIndexSql += wxString::FromUTF8(xname);
5390               comma = true;
5391               pC = pC->GetNext();
5392             }
5393           if (pI->GetFirst())
5394             createIndexSql += wxT(");\n");
5395         }
5396       pI = pI->GetNext();
5397     }
5398 
5399 // setting up the SQL complex statement
5400   sql = wxT("BEGIN;\n");
5401   sql += disableSpatialIdxSql;
5402   sql += discardGeometrySql;
5403   sql += dropSpatialIdxSql;
5404   sql += dropIndexSql;
5405   sql += renameSql;
5406   sql += createSql;
5407   sql += addGeometrySql;
5408   sql += createSpatialIdxSql;
5409   sql += createIndexSql;
5410   sql += insertSql;
5411   sql += dropSql;
5412   sql += wxT("COMMIT;");
5413   if (sql.Len() < 1)
5414     return;
5415   msg = wxT("Do you really intend to drop the Column ");
5416   msg += obj->GetColumn();
5417   msg += wxT("\nfrom the Table ");
5418   msg += obj->GetName();
5419   msg += wxT(" ?");
5420   wxMessageDialog confirm(this, msg, wxT("Confirming DROP COLUMN"),
5421                           wxOK | wxCANCEL | wxICON_QUESTION);
5422   ret = confirm.ShowModal();
5423   if (ret != wxID_OK)
5424     return;
5425 
5426 // executing
5427   ::wxBeginBusyCursor();
5428   ret = sqlite3_exec(MainFrame->GetSqlite(), sql.ToUTF8(), NULL, NULL, &errMsg);
5429   if (ret != SQLITE_OK)
5430     {
5431       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5432                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5433       sqlite3_free(errMsg);
5434       ::wxEndBusyCursor();
5435       goto rollback;
5436     }
5437   ::wxEndBusyCursor();
5438   wxMessageBox(wxT("The column ") + obj->GetColumn() +
5439                wxT("\nwas successfully removed\nfrom the Table ") +
5440                obj->GetName(), wxT("spatialite_gui"),
5441                wxOK | wxICON_INFORMATION, this);
5442   MainFrame->InitTableTree();
5443   return;
5444 rollback:
5445   ret = sqlite3_exec(MainFrame->GetSqlite(), "ROLLBACK", NULL, NULL, &errMsg);
5446   if (ret != SQLITE_OK)
5447     {
5448       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5449                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5450       sqlite3_free(errMsg);
5451       ::wxEndBusyCursor();
5452       return;
5453     }
5454   ::wxEndBusyCursor();
5455   wxMessageBox(wxT
5456                ("An error occurred\n\na ROLLBACK was automatically performed"),
5457                wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
5458 }
5459 
OnCmdRenameColumn(wxCommandEvent & WXUNUSED (event))5460 void MyTableTree::OnCmdRenameColumn(wxCommandEvent & WXUNUSED(event))
5461 {
5462 //
5463 // menu event - rename column
5464 //
5465   char column[1024];
5466   int ret;
5467   char **results;
5468   int rows;
5469   int columns;
5470   int i;
5471   char *errMsg = NULL;
5472   wxString sql;
5473   wxString createSql;
5474   wxString insertSql;
5475   wxString insertFromSql;
5476   wxString renameSql;
5477   wxString dropSql;
5478   wxString dropIndexSql;
5479   wxString createIndexSql;
5480   wxString disableSpatialIdxSql;
5481   wxString dropSpatialIdxSql;
5482   wxString createSpatialIdxSql;
5483   wxString discardGeometrySql;
5484   wxString addGeometrySql;
5485   wxString geomColumn;
5486   bool comma = false;
5487   char *value;
5488   bool autoincrement = false;
5489   wxString aliasTable;
5490   bool isGeom;
5491   wxString msg;
5492   GeomColsList Geometries;
5493   GeomColumn *pG;
5494   TblIndexList Index;
5495   TblIndex *pI;
5496   IndexColumn *pC;
5497   wxString name;
5498   char xname[1024];
5499   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
5500   if (obj == NULL)
5501     return;
5502 
5503 // asking the new column name
5504   wxString newColumn =
5505     wxGetTextFromUser(wxT("Please, insert the new Column Name"),
5506                       wxT("Rename Column"), obj->GetColumn(),
5507                       MainFrame, wxDefaultCoord, wxDefaultCoord, false);
5508 
5509   strcpy(column, obj->GetColumn().ToUTF8());
5510   if (DropRenameAux1(obj, &Geometries, &autoincrement) == false)
5511     return;
5512   DropRenameAux2(obj, &Geometries, aliasTable, renameSql, dropSql,
5513                  disableSpatialIdxSql, dropSpatialIdxSql, createSpatialIdxSql,
5514                  discardGeometrySql);
5515 
5516 // retrieving the Column names
5517   sql = wxT("PRAGMA table_info(");
5518   strcpy(xname, obj->GetName().ToUTF8());
5519   MainFrame->DoubleQuotedSql(xname);
5520   sql += wxString::FromUTF8(xname);
5521   sql += wxT(")");
5522   ret = sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(), &results,
5523                           &rows, &columns, &errMsg);
5524   if (ret != SQLITE_OK)
5525     {
5526       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5527                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5528       sqlite3_free(errMsg);
5529       return;
5530     }
5531   if (rows < 1)
5532     ;
5533   else
5534     {
5535       createSql = wxT("CREATE TABLE ");
5536       strcpy(xname, obj->GetName().ToUTF8());
5537       MainFrame->DoubleQuotedSql(xname);
5538       createSql += wxString::FromUTF8(xname);
5539       createSql += wxT(" (\n");
5540       insertSql = wxT("INSERT INTO ");
5541       strcpy(xname, obj->GetName().ToUTF8());
5542       MainFrame->DoubleQuotedSql(xname);
5543       insertSql += wxString::FromUTF8(xname);
5544       insertSql += wxT(" (");
5545       insertFromSql = wxT("SELECT ");
5546       for (i = 1; i <= rows; i++)
5547         {
5548           value = results[(i * columns) + 1];
5549           isGeom = false;
5550           pG = Geometries.GetFirst();
5551           while (pG)
5552             {
5553               char geom[1024];
5554               strcpy(geom, pG->GetGeometryName().ToUTF8());
5555               if (strcasecmp(geom, value) == 0)
5556                 {
5557                   isGeom = true;
5558                   geomColumn = pG->GetGeometryName();
5559                   break;
5560                 }
5561               pG = pG->GetNext();
5562             }
5563           if (comma == true)
5564             {
5565               if (isGeom == false)
5566                 createSql += wxT(",\n");
5567               insertSql += wxT(", ");
5568               insertFromSql += wxT(", ");
5569             }
5570           if (isGeom == false)
5571             {
5572               if (strcasecmp(value, column) == 0)
5573                 {
5574                   strcpy(xname, newColumn.ToUTF8());
5575                   MainFrame->DoubleQuotedSql(xname);
5576                   createSql += wxString::FromUTF8(xname);
5577               } else
5578                 {
5579                   strcpy(xname, value);
5580                   MainFrame->DoubleQuotedSql(xname);
5581                   createSql += wxString::FromUTF8(xname);
5582                 }
5583               createSql += wxT(" ");
5584             }
5585           if (strcasecmp(value, column) == 0)
5586             {
5587               strcpy(xname, newColumn.ToUTF8());
5588               MainFrame->DoubleQuotedSql(xname);
5589               insertSql += wxString::FromUTF8(xname);
5590           } else
5591             {
5592               strcpy(xname, value);
5593               MainFrame->DoubleQuotedSql(xname);
5594               insertSql += wxString::FromUTF8(xname);
5595             }
5596           strcpy(xname, value);
5597           MainFrame->DoubleQuotedSql(xname);
5598           insertFromSql += wxString::FromUTF8(xname);
5599           value = results[(i * columns) + 2];
5600           if (isGeom == false)
5601             createSql += wxString::FromUTF8(value);
5602           value = results[(i * columns) + 5];
5603           if (value)
5604             {
5605               if (atoi(value) != 0)
5606                 {
5607                   if (isGeom == false)
5608                     {
5609                       createSql += wxT(" PRIMARY KEY");
5610                       if (autoincrement == true)
5611                         createSql += wxT(" AUTOINCREMENT");
5612                     }
5613                 }
5614             }
5615           value = results[(i * columns) + 3];
5616           if (value)
5617             {
5618               if (atoi(value) != 0)
5619                 {
5620                   if (isGeom == true)
5621                     Geometries.SetNotNull(geomColumn);
5622                   else
5623                     createSql += wxT(" NOT NULL");
5624                 }
5625             }
5626           value = results[(i * columns) + 4];
5627           if (value && isGeom == false)
5628             {
5629               createSql += wxT(" DEFAULT ");
5630               createSql += wxString::FromUTF8(value);
5631             }
5632           comma = true;
5633         }
5634       createSql += wxT(");\n");
5635       insertSql += wxT(")\n");
5636       insertFromSql += wxT("\nFROM ");
5637       insertFromSql += aliasTable;
5638       insertFromSql += wxT(";\n");
5639       insertSql += insertFromSql;
5640     }
5641   sqlite3_free_table(results);
5642 
5643   DropRenameAux3(obj, &Geometries, &Index, addGeometrySql);
5644 
5645 // setting up the Index SQL fragments
5646   pI = Index.GetFirst();
5647   while (pI)
5648     {
5649       dropIndexSql += wxT("DROP INDEX ");
5650       strcpy(xname, pI->GetIndexName().ToUTF8());
5651       MainFrame->DoubleQuotedSql(xname);
5652       dropIndexSql += wxString::FromUTF8(xname);
5653       dropIndexSql += wxT(";\n");
5654       if (pI->IsValid() == true)
5655         {
5656           if (pI->GetFirst())
5657             {
5658               if (pI->IsUnique() == true)
5659                 createIndexSql += wxT("CREATE UNIQUE INDEX ");
5660               else
5661                 createIndexSql += wxT("CREATE INDEX ");
5662               strcpy(xname, pI->GetIndexName().ToUTF8());
5663               MainFrame->DoubleQuotedSql(xname);
5664               createIndexSql += wxString::FromUTF8(xname);
5665               createIndexSql += wxT(" ON ");
5666               strcpy(xname, obj->GetName().ToUTF8());
5667               MainFrame->DoubleQuotedSql(xname);
5668               createIndexSql += wxString::FromUTF8(xname);
5669               createIndexSql += wxT(" (");
5670             }
5671           comma = false;
5672           pC = pI->GetFirst();
5673           while (pC)
5674             {
5675               char xvalue[1024];
5676               strcpy(xvalue, pC->GetColumnName().ToUTF8());
5677               if (comma == true)
5678                 createIndexSql += wxT(", ");
5679               if (strcasecmp(xvalue, column) == 0)
5680                 {
5681                   strcpy(xname, newColumn.ToUTF8());
5682                   MainFrame->DoubleQuotedSql(xname);
5683                   createIndexSql += wxString::FromUTF8(xname);
5684               } else
5685                 {
5686                   strcpy(xname, pC->GetColumnName().ToUTF8());
5687                   MainFrame->DoubleQuotedSql(xname);
5688                   createIndexSql += wxString::FromUTF8(xname);
5689                 }
5690               comma = true;
5691               pC = pC->GetNext();
5692             }
5693           if (pI->GetFirst())
5694             createIndexSql += wxT(");\n");
5695         }
5696       pI = pI->GetNext();
5697     }
5698 
5699 // setting up the SQL complex statement
5700   sql = wxT("BEGIN;\n");
5701   sql += disableSpatialIdxSql;
5702   sql += discardGeometrySql;
5703   sql += dropSpatialIdxSql;
5704   sql += dropIndexSql;
5705   sql += renameSql;
5706   sql += createSql;
5707   sql += addGeometrySql;
5708   sql += createSpatialIdxSql;
5709   sql += createIndexSql;
5710   sql += insertSql;
5711   sql += dropSql;
5712   sql += wxT("COMMIT;");
5713   if (sql.Len() < 1)
5714     return;
5715   char cazzo[8192];
5716   strcpy(cazzo, sql.ToUTF8());
5717   msg = wxT("Do you really intend to rename the Column ");
5718   msg += obj->GetColumn();
5719   msg += wxT(" as ");
5720   msg += newColumn;
5721   msg += wxT("\ninto the Table ");
5722   msg += obj->GetName();
5723   msg += wxT(" ?");
5724   wxMessageDialog confirm(this, msg, wxT("Confirming RENAME COLUMN"),
5725                           wxOK | wxCANCEL | wxICON_QUESTION);
5726   ret = confirm.ShowModal();
5727   if (ret != wxID_OK)
5728     return;
5729 
5730 // executing
5731   ::wxBeginBusyCursor();
5732   ret = sqlite3_exec(MainFrame->GetSqlite(), sql.ToUTF8(), NULL, NULL, &errMsg);
5733   if (ret != SQLITE_OK)
5734     {
5735       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5736                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5737       sqlite3_free(errMsg);
5738       ::wxEndBusyCursor();
5739       goto rollback;
5740     }
5741   ::wxEndBusyCursor();
5742   wxMessageBox(wxT("The column ") + obj->GetColumn() +
5743                wxT("\nwas successfully renamed as ") + newColumn +
5744                wxT("\ninto the Table ") + obj->GetName(),
5745                wxT("spatialite_gui"), wxOK | wxICON_INFORMATION, this);
5746   MainFrame->InitTableTree();
5747   return;
5748 rollback:
5749   ret = sqlite3_exec(MainFrame->GetSqlite(), "ROLLBACK", NULL, NULL, &errMsg);
5750   if (ret != SQLITE_OK)
5751     {
5752       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5753                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5754       sqlite3_free(errMsg);
5755       ::wxEndBusyCursor();
5756       return;
5757     }
5758   ::wxEndBusyCursor();
5759   wxMessageBox(wxT
5760                ("An error occurred\n\na ROLLBACK was automatically performed"),
5761                wxT("spatialite_gui"), wxOK | wxICON_WARNING, this);
5762 }
5763 
OnCmdEdit(wxCommandEvent & WXUNUSED (event))5764 void MyTableTree::OnCmdEdit(wxCommandEvent & WXUNUSED(event))
5765 {
5766 //
5767 // menu event - editing row values
5768 //
5769   char **results;
5770   int rows;
5771   int columns;
5772   int i;
5773   char *errMsg = NULL;
5774   wxString sql;
5775   char *column;
5776   char *type;
5777   int pk = 0;
5778   int pb = 0;
5779   int primaryKeys[1024];
5780   int blobCols[1024];
5781   char xname[1024];
5782   for (i = 0; i < 1024; i++)
5783     {
5784       primaryKeys[i] = -1;
5785       blobCols[i] = -1;
5786     }
5787   primaryKeys[pk++] = 0;
5788   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
5789   if (obj == NULL)
5790     return;
5791   sql = wxT("PRAGMA table_info(");
5792   strcpy(xname, obj->GetName().ToUTF8());
5793   MainFrame->DoubleQuotedSql(xname);
5794   sql += wxString::FromUTF8(xname);
5795   sql += wxT(")");
5796   int ret = sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(), &results,
5797                               &rows, &columns, &errMsg);
5798   if (ret != SQLITE_OK)
5799     {
5800       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5801                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5802       sqlite3_free(errMsg);
5803       return;
5804     }
5805   if (rows < 1)
5806     ;
5807   else
5808     {
5809       sql = wxT("SELECT ROWID");
5810       for (i = 1; i <= rows; i++)
5811         {
5812           column = results[(i * columns) + 1];
5813           sql += wxT(", ");
5814           strcpy(xname, column);
5815           MainFrame->DoubleQuotedSql(xname);
5816           sql += wxString::FromUTF8(xname);
5817           type = results[(i * columns) + 2];
5818           if (strcasecmp(type, "BLOB") == 0)
5819             blobCols[pb++] = i;
5820           if (atoi(results[(i * columns) + 5]) == 0)
5821             ;
5822           else
5823             primaryKeys[pk++] = i;
5824         }
5825     }
5826   sqlite3_free_table(results);
5827   if (sql.Len() < 1)
5828     return;
5829   sql += wxT("\nFROM ");
5830   strcpy(xname, obj->GetName().ToUTF8());
5831   MainFrame->DoubleQuotedSql(xname);
5832   sql += wxString::FromUTF8(xname);
5833   sql += wxT("\nORDER BY ROWID");
5834   MainFrame->EditTable(sql, primaryKeys, blobCols, obj->GetName());
5835 }
5836 
OnCmdCheckDuplicates(wxCommandEvent & WXUNUSED (event))5837 void MyTableTree::OnCmdCheckDuplicates(wxCommandEvent & WXUNUSED(event))
5838 {
5839 //
5840 // menu event - Checking for Duplicate rows
5841 //
5842   wxString sql;
5843   wxString col_list;
5844   bool first = true;
5845   char xname[1024];
5846   int pk;
5847   int ret;
5848   char **results;
5849   int rows;
5850   int columns;
5851   int i;
5852   char *errMsg = NULL;
5853   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
5854   if (obj == NULL)
5855     return;
5856   if (obj->GetType() == MY_TABLE)
5857     {
5858       // extracting the column names (excluding any Primary Key)
5859       sql = wxT("PRAGMA table_info(");
5860       strcpy(xname, obj->GetName().ToUTF8());
5861       MainFrame->DoubleQuotedSql(xname);
5862       sql += wxString::FromUTF8(xname);
5863       sql += wxT(")");
5864       ret = sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(), &results,
5865                               &rows, &columns, &errMsg);
5866       if (ret != SQLITE_OK)
5867         {
5868           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5869                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5870           sqlite3_free(errMsg);
5871           return;
5872         }
5873       if (rows < 1)
5874         ;
5875       else
5876         {
5877           for (i = 1; i <= rows; i++)
5878             {
5879               strcpy(xname, results[(i * columns) + 1]);
5880               pk = atoi(results[(i * columns) + 5]);
5881               if (!pk)
5882                 {
5883                   if (first)
5884                     first = false;
5885                   else
5886                     col_list += wxT(", ");
5887                   MainFrame->DoubleQuotedSql(xname);
5888                   col_list += wxString::FromUTF8(xname);
5889                 }
5890             }
5891         }
5892       sqlite3_free_table(results);
5893       // preparing the SQL statement
5894       sql = wxT("SELECT Count(*) AS \"[dupl-count]\", ");
5895       sql += col_list;
5896       sql += wxT("\nFROM ");
5897       strcpy(xname, obj->GetName().ToUTF8());
5898       MainFrame->DoubleQuotedSql(xname);
5899       sql += wxString::FromUTF8(xname);
5900       sql += wxT("\nGROUP BY ");
5901       sql += col_list;
5902       sql += wxT("\nHAVING \"[dupl-count]\" > 1");
5903       sql += wxT("\nORDER BY \"[dupl-count]\" DESC");
5904       MainFrame->SetSql(sql, true);
5905     }
5906 }
5907 
OnCmdRemoveDuplicates(wxCommandEvent & WXUNUSED (event))5908 void MyTableTree::OnCmdRemoveDuplicates(wxCommandEvent & WXUNUSED(event))
5909 {
5910 //
5911 // menu event - Removing Duplicate rows
5912 //
5913   DuplRow value_list;
5914   wxString sql;
5915   wxString sql2;
5916   wxString col_list;
5917   wxString params_list;
5918   bool first = true;
5919   char xname[1024];
5920   int count;
5921   int pk;
5922   int ret;
5923   char **results;
5924   int rows;
5925   int columns;
5926   int i;
5927   char *errMsg = NULL;
5928   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
5929   if (obj == NULL)
5930     return;
5931   if (obj->GetType() == MY_TABLE)
5932     {
5933       // extracting the column names (excluding any Primary Key)
5934       value_list.SetTable(obj->GetName());
5935       sql = wxT("PRAGMA table_info(");
5936       strcpy(xname, obj->GetName().ToUTF8());
5937       MainFrame->DoubleQuotedSql(xname);
5938       sql += wxString::FromUTF8(xname);
5939       sql += wxT(")");
5940       ret = sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(), &results,
5941                               &rows, &columns, &errMsg);
5942       if (ret != SQLITE_OK)
5943         {
5944           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
5945                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
5946           sqlite3_free(errMsg);
5947           return;
5948         }
5949       if (rows < 1)
5950         ;
5951       else
5952         {
5953           for (i = 1; i <= rows; i++)
5954             {
5955               strcpy(xname, results[(i * columns) + 1]);
5956               pk = atoi(results[(i * columns) + 5]);
5957               if (!pk)
5958                 {
5959                   if (first)
5960                     first = false;
5961                   else
5962                     col_list += wxT(", ");
5963                   MainFrame->DoubleQuotedSql(xname);
5964                   wxString col_name = wxString::FromUTF8(xname);
5965                   col_list += col_name;
5966                   value_list.Add(col_name);
5967                 }
5968             }
5969         }
5970       sqlite3_free_table(results);
5971       // preparing the SQL statement (identifying duplicated rows)
5972       sql = wxT("SELECT Count(*) AS \"[dupl-count]\", ");
5973       sql += col_list;
5974       sql += wxT("\nFROM ");
5975       strcpy(xname, obj->GetName().ToUTF8());
5976       MainFrame->DoubleQuotedSql(xname);
5977       sql += wxString::FromUTF8(xname);
5978       sql += wxT("\nGROUP BY ");
5979       sql += col_list;
5980       sql += wxT("\nHAVING \"[dupl-count]\" > 1");
5981       // preparing the SQL statement [delete]
5982       sql2 = wxT("DELETE FROM ");
5983       strcpy(xname, obj->GetName().ToUTF8());
5984       MainFrame->DoubleQuotedSql(xname);
5985       sql2 += wxString::FromUTF8(xname);
5986       sql2 += wxT(" WHERE ROWID = ?");
5987 
5988       if (doDeleteDuplicates(sql, sql2, &value_list, &count) == true)
5989         {
5990           if (!count)
5991             {
5992               strcpy(xname, "No duplicated rows have been identified on ");
5993               sql = wxString::FromUTF8(xname);
5994               strcpy(xname, obj->GetName().ToUTF8());
5995               MainFrame->DoubleQuotedSql(xname);
5996               sql += wxString::FromUTF8(xname);
5997               wxMessageBox(sql, wxT("spatialite_gui"),
5998                            wxOK | wxICON_INFORMATION, this);
5999           } else
6000             {
6001               sprintf(xname, "%d duplicated rows deleted from ", count);
6002               sql = wxString::FromUTF8(xname);
6003               strcpy(xname, obj->GetName().ToUTF8());
6004               MainFrame->DoubleQuotedSql(xname);
6005               sql += wxString::FromUTF8(xname);
6006               wxMessageBox(sql, wxT("spatialite_gui"),
6007                            wxOK | wxICON_INFORMATION, this);
6008             }
6009         }
6010     }
6011 }
6012 
OnCmdCheckGeometries(wxCommandEvent & WXUNUSED (event))6013 void MyTableTree::OnCmdCheckGeometries(wxCommandEvent & WXUNUSED(event))
6014 {
6015 //
6016 // menu event - Checking a Geometry Column
6017 //
6018   int ret;
6019   wxString table;
6020   wxString geom;
6021   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
6022   if (obj == NULL)
6023     return;
6024   if (obj->GetType() == MY_GEOMETRY
6025       || obj->GetType() == MY_GEOMETRY_INDEX
6026       || obj->GetType() == MY_GEOMETRY_CACHED)
6027     {
6028       table = obj->GetName();
6029       geom = obj->GetColumn();
6030   } else
6031     return;
6032   CheckGeometryDialog dlg;
6033   dlg.Create(MainFrame, table, geom);
6034   ret = dlg.ShowModal();
6035   if (ret != wxYES)
6036     return;
6037 
6038   char xtable[1024];
6039   char xgeometry[1024];
6040   char *err_msg = NULL;
6041   char report_path[1024];
6042   wxString msg;
6043   strcpy(xtable, table.ToUTF8());
6044   strcpy(xgeometry, geom.ToUTF8());
6045 
6046   wxFileDialog fileDialog(this, wxT("Diagnostic Report"),
6047                           wxT(""), wxT("report.html"),
6048                           wxT
6049                           ("HTML document (*.html)|*.html|All files (*.*)|*.*"),
6050                           wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
6051                           wxDefaultSize, wxT("filedlg"));
6052   ret = fileDialog.ShowModal();
6053   if (ret == wxID_OK)
6054     {
6055       strcpy(report_path, fileDialog.GetPath().ToUTF8());
6056       ::wxBeginBusyCursor();
6057       int n_invalids;
6058       ret =
6059         check_geometry_column(MainFrame->GetSqlite(), xtable, xgeometry,
6060                               report_path, NULL, &n_invalids, &err_msg);
6061       ::wxEndBusyCursor();
6062       if (ret == 0)
6063         {
6064           // reporting some error condition
6065           msg = wxT("Some unexpected error occurred:\n\n");
6066           if (err_msg != NULL)
6067             {
6068               msg += wxString::FromUTF8(err_msg);
6069               free(err_msg);
6070           } else
6071             msg += wxT("Sorry, no further details are available");
6072           wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6073       } else
6074         {
6075           int mode;
6076           if (n_invalids > 0)
6077             {
6078               msg =
6079                 wxT
6080                 ("ATTENTION: some invalid Geometries have been detected !!!\n\n");
6081               mode = wxICON_WARNING;
6082           } else
6083             {
6084               msg =
6085                 wxT
6086                 ("No invalid Geometries have been detected; this layer is full valid\n\n");
6087               mode = wxICON_INFORMATION;
6088             }
6089           msg += wxT("A full diagnostic report has been created.\n");
6090           msg +=
6091             wxT
6092             ("Please point your WEB Browser at the following HTML document containing the report:\n\n");
6093           msg += fileDialog.GetPath();
6094           wxMessageBox(msg, wxT("spatialite_gui"), wxOK | mode, this);
6095         }
6096     }
6097 }
6098 
OnCmdSanitizeGeometries(wxCommandEvent & WXUNUSED (event))6099 void MyTableTree::OnCmdSanitizeGeometries(wxCommandEvent & WXUNUSED(event))
6100 {
6101 //
6102 // menu event - Attempting to sanitize a Geometry Column
6103 //
6104   int ret;
6105   wxString table;
6106   wxString geom;
6107   MyObject *obj = (MyObject *) GetItemData(CurrentItem);
6108   if (obj == NULL)
6109     return;
6110   if (obj->GetType() == MY_GEOMETRY
6111       || obj->GetType() == MY_GEOMETRY_INDEX
6112       || obj->GetType() == MY_GEOMETRY_CACHED)
6113     {
6114       table = obj->GetName();
6115       geom = obj->GetColumn();
6116   } else
6117     return;
6118   SanitizeGeometryDialog dlg;
6119   dlg.Create(MainFrame, table, geom);
6120   ret = dlg.ShowModal();
6121   if (ret != wxYES)
6122     return;
6123 
6124   char tmp_prefix[1024];
6125   char xtable[1024];
6126   char xgeometry[1024];
6127   char *err_msg = NULL;
6128   char report_path[1024];
6129   wxString msg;
6130   strcpy(tmp_prefix, dlg.GetTmpPrefix().ToUTF8());
6131   strcpy(xtable, table.ToUTF8());
6132   strcpy(xgeometry, geom.ToUTF8());
6133 
6134   wxFileDialog fileDialog(this, wxT("Diagnostic Report"),
6135                           wxT(""), wxT("report.html"),
6136                           wxT
6137                           ("HTML document (*.html)|*.html|All files (*.*)|*.*"),
6138                           wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
6139                           wxDefaultSize, wxT("filedlg"));
6140   ret = fileDialog.ShowModal();
6141   if (ret == wxID_OK)
6142     {
6143       strcpy(report_path, fileDialog.GetPath().ToUTF8());
6144       ::wxBeginBusyCursor();
6145       int n_failures;
6146       ret =
6147         sanitize_geometry_column(MainFrame->GetSqlite(), xtable, xgeometry,
6148                                  tmp_prefix, report_path, NULL, NULL, NULL,
6149                                  &n_failures, &err_msg);
6150       ::wxEndBusyCursor();
6151       if (ret == 0)
6152         {
6153           // reporting some error condition
6154           msg = wxT("Some unexpected error occurred:\n\n");
6155           if (err_msg != NULL)
6156             {
6157               msg += wxString::FromUTF8(err_msg);
6158               free(err_msg);
6159           } else
6160             msg += wxT("Sorry, no further details are available");
6161           wxMessageBox(msg, wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6162       } else
6163         {
6164           int mode;
6165           if (n_failures > 0)
6166             {
6167               msg =
6168                 wxT
6169                 ("ATTENTION: some invalid Geometries still remain invalid !!!\n\n");
6170               mode = wxICON_WARNING;
6171           } else
6172             {
6173               msg =
6174                 wxT
6175                 ("All invalid Geometries have been saned; this layer is now full valid\n\n");
6176               mode = wxICON_INFORMATION;
6177             }
6178           msg += wxT("A full diagnostic report has been created.\n");
6179           msg +=
6180             wxT
6181             ("Please point your WEB Browser at the following HTML document containing the report:\n\n");
6182           msg += fileDialog.GetPath();
6183           wxMessageBox(msg, wxT("spatialite_gui"), wxOK | mode, this);
6184         }
6185     }
6186 }
6187 
doDeleteDuplicates(wxString & sql1,wxString & sql2,DuplRow * value_list,int * count)6188 bool MyTableTree::doDeleteDuplicates(wxString & sql1, wxString & sql2,
6189                                      DuplRow * value_list, int *count)
6190 {
6191 // deleting duplicate rows
6192   char xsql[8192];
6193   sqlite3_stmt *stmt1 = NULL;
6194   sqlite3_stmt *stmt2 = NULL;
6195   int ret;
6196   int xcnt;
6197   int cnt = 0;
6198   int n_cols;
6199   int col_no;
6200   char *sql_err = NULL;
6201 
6202   *count = 0;
6203   ::wxBeginBusyCursor();
6204 
6205 // the complete operation is handled as an unique SQL Transaction
6206   ret = sqlite3_exec(MainFrame->GetSqlite(), "BEGIN", NULL, NULL, &sql_err);
6207   if (ret != SQLITE_OK)
6208     {
6209       sqlite3_free(sql_err);
6210       return false;
6211     }
6212 // preparing the main SELECT statement
6213   strcpy(xsql, sql1.ToUTF8());
6214   ret =
6215     sqlite3_prepare_v2(MainFrame->GetSqlite(), xsql, strlen(xsql), &stmt1,
6216                        NULL);
6217   if (ret != SQLITE_OK)
6218     {
6219       sprintf(xsql, "SQL error: %s", sqlite3_errmsg(MainFrame->GetSqlite()));
6220       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(xsql),
6221                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6222       return false;
6223     }
6224 // preparing the DELETE statement
6225   strcpy(xsql, sql2.ToUTF8());
6226   ret =
6227     sqlite3_prepare_v2(MainFrame->GetSqlite(), xsql, strlen(xsql), &stmt2,
6228                        NULL);
6229   if (ret != SQLITE_OK)
6230     {
6231       sprintf(xsql, "SQL error: %s", sqlite3_errmsg(MainFrame->GetSqlite()));
6232       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(xsql),
6233                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6234       goto error;
6235     }
6236 
6237   while (1)
6238     {
6239       //
6240       // fetching the result set rows
6241       //
6242       ret = sqlite3_step(stmt1);
6243       if (ret == SQLITE_DONE)
6244         break;                  // end of result set
6245       if (ret == SQLITE_ROW)
6246         {
6247           //
6248           // fetching a row
6249           //
6250           sqlite3_reset(stmt2);
6251           sqlite3_clear_bindings(stmt2);
6252           n_cols = sqlite3_column_count(stmt1);
6253           for (col_no = 1; col_no < n_cols; col_no++)
6254             {
6255               // saving column values
6256               if (sqlite3_column_type(stmt1, col_no) == SQLITE_INTEGER)
6257                 value_list->SetValue(col_no - 1,
6258                                      sqlite3_column_int64(stmt1, col_no));
6259               if (sqlite3_column_type(stmt1, col_no) == SQLITE_FLOAT)
6260                 value_list->SetValue(col_no - 1,
6261                                      sqlite3_column_double(stmt1, col_no));
6262               if (sqlite3_column_type(stmt1, col_no) == SQLITE_TEXT)
6263                 {
6264                   const char *xtext =
6265                     (const char *) sqlite3_column_text(stmt1, col_no);
6266                   value_list->SetValue(col_no - 1, xtext);
6267                 }
6268               if (sqlite3_column_type(stmt1, col_no) == SQLITE_BLOB)
6269                 {
6270                   const void *blob = sqlite3_column_blob(stmt1, col_no);
6271                   int blob_size = sqlite3_column_bytes(stmt1, col_no);
6272                   value_list->SetValue(col_no - 1, blob, blob_size);
6273                 }
6274               if (sqlite3_column_type(stmt1, col_no) == SQLITE_NULL)
6275                 value_list->SetValue(col_no - 1);
6276             }
6277           if (doDeleteDuplicates2(stmt2, value_list, &xcnt) == true)
6278             cnt += xcnt;
6279           else
6280             goto error;
6281       } else
6282         {
6283           sprintf(xsql, "SQL error: %s",
6284                   sqlite3_errmsg(MainFrame->GetSqlite()));
6285           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(xsql),
6286                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6287           goto error;
6288         }
6289     }
6290 
6291   sqlite3_finalize(stmt1);
6292   sqlite3_finalize(stmt2);
6293 
6294 // confirm the still pending Transaction
6295   ret = sqlite3_exec(MainFrame->GetSqlite(), "COMMIT", NULL, NULL, &sql_err);
6296   if (ret != SQLITE_OK)
6297     {
6298       sprintf(xsql, "COMMIT TRANSACTION error: %s\n", sql_err);
6299       wxMessageBox(wxString::FromUTF8(xsql),
6300                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6301       sqlite3_free(sql_err);
6302       return false;
6303     }
6304 
6305   ::wxEndBusyCursor();
6306   *count = cnt;
6307   return true;
6308 
6309 error:
6310   *count = 0;
6311   if (stmt1)
6312     sqlite3_finalize(stmt1);
6313   if (stmt2)
6314     sqlite3_finalize(stmt2);
6315 
6316 // performing a ROLLBACK anyway
6317   ret = sqlite3_exec(MainFrame->GetSqlite(), "ROLLBACK", NULL, NULL, &sql_err);
6318   if (ret != SQLITE_OK)
6319     {
6320       sprintf(xsql, "ROLLBACK TRANSACTION error: %s\n", sql_err);
6321       wxMessageBox(wxString::FromUTF8(xsql),
6322                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6323       sqlite3_free(sql_err);
6324       return false;
6325     }
6326 
6327   ::wxEndBusyCursor();
6328   return false;
6329 }
6330 
doDeleteDuplicates2(sqlite3_stmt * stmt1,DuplRow * value_list,int * count)6331 bool MyTableTree::doDeleteDuplicates2(sqlite3_stmt * stmt1,
6332                                       DuplRow * value_list, int *count)
6333 {
6334 // deleting duplicate rows [actual delete]
6335   int cnt = 0;
6336   int row_no = 0;
6337   char xsql[8192];
6338   char xname[1024];
6339   int ret;
6340   sqlite3_stmt *stmt2 = NULL;
6341   DuplColumn *col;
6342   wxString sql;
6343   wxString where;
6344   wxString condition;
6345   bool first = true;
6346   int qcnt = 0;
6347   int param = 1;
6348   bool match;
6349   int n_cols;
6350   int col_no;
6351 
6352   *count = 0;
6353   value_list->ResetQueryPos();
6354 
6355 // preparing the query statement
6356   sql = wxT("SELECT ROWID");
6357   where = wxT("\nWHERE ");
6358   col = value_list->GetFirst();
6359   while (col)
6360     {
6361       if (col->GetType() == SQLITE_BLOB)
6362         {
6363           sql += wxT(", ");
6364           sql += col->GetName();
6365           col->SetQueryPos(qcnt++);
6366       } else if (col->GetType() == SQLITE_NULL)
6367         {
6368           if (first == true)
6369             {
6370               first = false;
6371               condition = col->GetName();
6372           } else
6373             {
6374               condition = wxT(" AND ");
6375               condition += col->GetName();
6376             }
6377           condition += wxT(" IS NULL");
6378           where += condition;
6379       } else
6380         {
6381           if (first == true)
6382             {
6383               first = false;
6384               condition = col->GetName();
6385           } else
6386             {
6387               condition = wxT(" AND ");
6388               condition += col->GetName();
6389             }
6390           condition += wxT(" = ?");
6391           where += condition;
6392           col->SetQueryPos(param++);
6393         }
6394       col = col->GetNext();
6395     }
6396   sql += wxT("\nFROM ");
6397   strcpy(xname, value_list->GetTable().ToUTF8());
6398   MainFrame->DoubleQuotedSql(xname);
6399   sql += wxString::FromUTF8(xname);
6400   sql += where;
6401 
6402   strcpy(xsql, sql.ToUTF8());
6403   ret =
6404     sqlite3_prepare_v2(MainFrame->GetSqlite(), xsql, strlen(xsql), &stmt2,
6405                        NULL);
6406   if (ret != SQLITE_OK)
6407     {
6408       sprintf(xsql, "SQL error: %s", sqlite3_errmsg(MainFrame->GetSqlite()));
6409       wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(xsql),
6410                    wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6411       goto error;
6412     }
6413 
6414   sqlite3_reset(stmt2);
6415   sqlite3_clear_bindings(stmt2);
6416   col = value_list->GetFirst();
6417   while (col)
6418     {
6419       // binding query params
6420       if (col->GetType() == SQLITE_INTEGER)
6421         sqlite3_bind_int64(stmt2, col->GetQueryPos(), col->GetIntValue());
6422       if (col->GetType() == SQLITE_FLOAT)
6423         sqlite3_bind_double(stmt2, col->GetQueryPos(), col->GetDblValue());
6424       if (col->GetType() == SQLITE_TEXT)
6425         sqlite3_bind_text(stmt2, col->GetQueryPos(), col->GetTxtValue(),
6426                           strlen(col->GetTxtValue()), SQLITE_STATIC);
6427       col = col->GetNext();
6428     }
6429 
6430   while (1)
6431     {
6432       //
6433       // fetching the result set rows
6434       //
6435       ret = sqlite3_step(stmt2);
6436       if (ret == SQLITE_DONE)
6437         break;                  // end of result set
6438       if (ret == SQLITE_ROW)
6439         {
6440           //
6441           // fetching a row
6442           //
6443           match = true;
6444           n_cols = sqlite3_column_count(stmt2);
6445           for (col_no = 1; col_no < n_cols; col_no++)
6446             {
6447               // checking blob columns
6448               if (sqlite3_column_type(stmt2, col_no) == SQLITE_BLOB)
6449                 {
6450                   const void *blob = sqlite3_column_blob(stmt2, col_no);
6451                   int blob_size = sqlite3_column_bytes(stmt2, col_no);
6452                   if (value_list->CheckBlob(col_no - 1, blob, blob_size) ==
6453                       false)
6454                     match = false;
6455               } else
6456                 match = false;
6457               if (match == false)
6458                 break;
6459             }
6460           if (match == false)
6461             continue;
6462           row_no++;
6463           if (row_no > 1)
6464             {
6465               // deleting any duplicated row except the first one
6466               sqlite3_reset(stmt1);
6467               sqlite3_clear_bindings(stmt1);
6468               sqlite3_bind_int64(stmt1, 1, sqlite3_column_int64(stmt2, 0));
6469               ret = sqlite3_step(stmt1);
6470               if (ret == SQLITE_DONE || ret == SQLITE_ROW)
6471                 cnt++;
6472               else
6473                 {
6474                   sprintf(xsql, "SQL error: %s",
6475                           sqlite3_errmsg(MainFrame->GetSqlite()));
6476                   wxMessageBox(wxT("SQLite SQL error: ") +
6477                                wxString::FromUTF8(xsql), wxT("spatialite_gui"),
6478                                wxOK | wxICON_ERROR, this);
6479                   goto error;
6480                 }
6481             }
6482       } else
6483         {
6484           sprintf(xsql, "SQL error: %s",
6485                   sqlite3_errmsg(MainFrame->GetSqlite()));
6486           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(xsql),
6487                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
6488           goto error;
6489         }
6490     }
6491   if (stmt2)
6492     sqlite3_finalize(stmt2);
6493   *count = cnt;
6494   return true;
6495 
6496 error:
6497   if (stmt2)
6498     sqlite3_finalize(stmt2);
6499   *count = 0;
6500 
6501   return false;
6502 }
6503 
~DuplRow()6504 DuplRow::~DuplRow()
6505 {
6506 // destructor
6507   DuplColumn *p;
6508   DuplColumn *pn;
6509   p = First;
6510   while (p)
6511     {
6512       pn = p->GetNext();
6513       delete p;
6514       p = pn;
6515     }
6516 }
6517 
Add(wxString & name)6518 void DuplRow::Add(wxString & name)
6519 {
6520 // adding a column
6521   DuplColumn *p = new DuplColumn(Count, name);
6522   Count++;
6523   if (First == NULL)
6524     First = p;
6525   if (Last)
6526     Last->SetNext(p);
6527   Last = p;
6528 }
6529 
SetValue(int pos,sqlite3_int64 value)6530 void DuplRow::SetValue(int pos, sqlite3_int64 value)
6531 {
6532 // setting up an integer value
6533   DuplColumn *p = First;
6534   while (p)
6535     {
6536       if (p->GetPos() == pos)
6537         {
6538           p->SetValue(value);
6539           return;
6540         }
6541       p = p->GetNext();
6542     }
6543 }
6544 
SetValue(int pos,double value)6545 void DuplRow::SetValue(int pos, double value)
6546 {
6547 // setting up a double value
6548   DuplColumn *p = First;
6549   while (p)
6550     {
6551       if (p->GetPos() == pos)
6552         {
6553           p->SetValue(value);
6554           return;
6555         }
6556       p = p->GetNext();
6557     }
6558 }
6559 
SetValue(int pos,const char * value)6560 void DuplRow::SetValue(int pos, const char *value)
6561 {
6562 // setting up a text value
6563   DuplColumn *p = First;
6564   while (p)
6565     {
6566       if (p->GetPos() == pos)
6567         {
6568           p->SetValue(value);
6569           return;
6570         }
6571       p = p->GetNext();
6572     }
6573 }
6574 
SetValue(int pos,const void * blob,int size)6575 void DuplRow::SetValue(int pos, const void *blob, int size)
6576 {
6577 // setting up a blob value
6578   DuplColumn *p = First;
6579   while (p)
6580     {
6581       if (p->GetPos() == pos)
6582         {
6583           p->SetValue(blob, size);
6584           return;
6585         }
6586       p = p->GetNext();
6587     }
6588 }
6589 
SetValue(int pos)6590 void DuplRow::SetValue(int pos)
6591 {
6592 // setting up a NULL value
6593   DuplColumn *p = First;
6594   while (p)
6595     {
6596       if (p->GetPos() == pos)
6597         {
6598           p->SetValue();
6599           return;
6600         }
6601       p = p->GetNext();
6602     }
6603 }
6604 
ResetQueryPos()6605 void DuplRow::ResetQueryPos()
6606 {
6607 // resetting QueryPos for BLOBs
6608   DuplColumn *p = First;
6609   while (p)
6610     {
6611       p->SetQueryPos(-1);
6612       p = p->GetNext();
6613     }
6614 }
6615 
CheckBlob(int pos,const void * blob,int size)6616 bool DuplRow::CheckBlob(int pos, const void *blob, int size)
6617 {
6618 // checking a BLOB value
6619   DuplColumn *p = First;
6620   while (p)
6621     {
6622       if (p->GetQueryPos() == pos)
6623         {
6624           return p->CheckBlob(blob, size);
6625         }
6626       p = p->GetNext();
6627     }
6628   return false;
6629 }
6630 
CheckBlob(const void * blob,int size)6631 bool DuplColumn::CheckBlob(const void *blob, int size)
6632 {
6633 // checking a BLOB value
6634   if (Type != SQLITE_BLOB)
6635     return false;
6636   if (Size != size)
6637     return false;
6638   if (memcmp(Blob, blob, size) != 0)
6639     return false;
6640   return true;
6641 }
6642