1 /*
2 / Objects.cpp
3 / miscellaneous ancillary classes implementation
4 /
5 / version 1.7, 2013 May 8
6 /
7 / Author: Sandro Furieri a-furieri@lqt.it
8 /
9 / Copyright (C) 2008-2013 Alessandro Furieri
10 /
11 / This program is free software: you can redistribute it and/or modify
12 / it under the terms of the GNU General Public License as published by
13 / the Free Software Foundation, either version 3 of the License, or
14 / (at your option) any later version.
15 /
16 / This program is distributed in the hope that it will be useful,
17 / but WITHOUT ANY WARRANTY; without even the implied warranty of
18 / MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 / GNU General Public License for more details.
20 /
21 / You should have received a copy of the GNU General Public License
22 / along with this program. If not, see <http://www.gnu.org/licenses/>.
23 /
24 */
25
26 #include "Classdef.h"
27
MyObject(int type,wxString & name)28 MyObject::MyObject(int type, wxString & name)
29 {
30 //
31 // constructor - TreeItemData
32 //
33 Type = type;
34 Name = name;
35 Column = wxT("");
36 DbAlias = wxT("");
37 Temporary = false;
38 }
39
MyObject(int type,wxString & name,bool tmp)40 MyObject::MyObject(int type, wxString & name, bool tmp)
41 {
42 //
43 // constructor - TreeItemData
44 //
45 Type = type;
46 Name = name;
47 Column = wxT("");
48 DbAlias = wxT("");
49 Temporary = tmp;
50 }
51
MyObject(int type,wxString & name,wxString & column)52 MyObject::MyObject(int type, wxString & name, wxString & column)
53 {
54 //
55 // constructor - TreeItemData
56 //
57 Type = type;
58 Name = name;
59 Column = column;
60 DbAlias = wxT("");
61 Temporary = false;
62 }
63
MyObject(int type,bool WXUNUSED (attached),wxString & dbAlias,wxString & name)64 MyObject::MyObject(int type, bool WXUNUSED(attached), wxString & dbAlias,
65 wxString & name)
66 {
67 //
68 // constructor - TreeItemData
69 //
70 Type = type;
71 Name = name;
72 Column = wxT("");
73 DbAlias = dbAlias;
74 Temporary = false;
75 }
76
Copy(MyVariant * other)77 void MyVariant::Copy(MyVariant * other)
78 {
79 //
80 // transfers a BLOB value
81 //
82 if (other->Type != MY_BLOB_VARIANT)
83 return;
84 if (!(other->Blob))
85 return;
86 if (Blob)
87 delete[]Blob;
88 Type = MY_BLOB_VARIANT;
89 BlobSize = other->BlobSize;
90 Blob = other->Blob;
91 other->Type = MY_NULL_VARIANT;
92 other->Blob = NULL;
93 other->BlobSize = 0;
94 }
95
Set(const unsigned char * text)96 void MyVariant::Set(const unsigned char *text)
97 {
98 //
99 // sets a String value for this Variant value
100 //
101 Type = MY_TXT_VARIANT;
102 TxtValue = wxString::FromUTF8((const char *) text);
103 }
104
Set(const void * blob,int size)105 void MyVariant::Set(const void *blob, int size)
106 {
107 //
108 // sets a BLOB value for this Variant value
109 //
110 if (size <= 0)
111 return;
112 Type = MY_BLOB_VARIANT;
113 BlobSize = size;
114 Blob = new unsigned char[size];
115 memcpy(Blob, blob, size);
116 }
117
Create(int cols)118 void MyRowVariant::Create(int cols)
119 {
120 //
121 // creating the row variant
122 //
123 if (ColumnArray)
124 delete[]ColumnArray;
125 NumCols = cols;
126 ColumnArray = new MyVariant[NumCols];
127 }
128
Set(int col,sqlite3_int64 value)129 void MyRowVariant::Set(int col, sqlite3_int64 value)
130 {
131 //
132 // setting an Integer value for the Nth column
133 //
134 MyVariant *var;
135 if (col < 0 || col >= NumCols)
136 return;
137 var = ColumnArray + col;
138 var->Set(value);
139 }
140
Set(int col,double value)141 void MyRowVariant::Set(int col, double value)
142 {
143 //
144 // setting a Double value for the Nth column
145 //
146 MyVariant *var;
147 if (col < 0 || col >= NumCols)
148 return;
149 var = ColumnArray + col;
150 var->Set(value);
151 }
152
Set(int col,const unsigned char * value)153 void MyRowVariant::Set(int col, const unsigned char *value)
154 {
155 //
156 // setting a String value for the Nth column
157 //
158 MyVariant *var;
159 if (col < 0 || col >= NumCols)
160 return;
161 var = ColumnArray + col;
162 var->Set(value);
163 }
164
Set(int col,const void * blob,int size)165 void MyRowVariant::Set(int col, const void *blob, int size)
166 {
167 //
168 // setting a BLOB value for the Nth column
169 //
170 MyVariant *var;
171 if (col < 0 || col >= NumCols)
172 return;
173 var = ColumnArray + col;
174 var->Set(blob, size);
175 }
176
GetColumn(int col)177 MyVariant *MyRowVariant::GetColumn(int col)
178 {
179 //
180 // returns a Column Variant Value
181 //
182 MyVariant *var;
183 if (col < 0 || col >= NumCols)
184 return NULL;
185 var = ColumnArray + col;
186 return var;
187 }
188
MyVariantList()189 MyVariantList::MyVariantList()
190 {
191 //
192 // constructor - result set container
193 //
194 NumCols = 0;
195 ColumnName = NULL;
196 First = NULL;
197 Last = NULL;
198 }
199
~MyVariantList()200 MyVariantList::~MyVariantList()
201 {
202 //
203 // destructor - result set container
204 //
205 Reset();
206 }
207
Reset(void)208 void MyVariantList::Reset(void)
209 {
210 // resetting the list to the initial (empty) state
211 MyRowVariant *el;
212 MyRowVariant *elN;
213 if (ColumnName)
214 delete[]ColumnName;
215 el = First;
216 while (el)
217 {
218 elN = el->GetNext();
219 delete el;
220 el = elN;
221 }
222 NumCols = 0;
223 ColumnName = NULL;
224 First = NULL;
225 Last = NULL;
226 }
227
GetRows()228 int MyVariantList::GetRows()
229 {
230 //
231 // counting how many rows are there
232 //
233 int cnt = 0;
234 MyRowVariant *el = First;
235 while (el)
236 {
237 cnt++;
238 el = el->GetNext();
239 }
240 return cnt;
241 }
242
Add(int columns)243 MyRowVariant *MyVariantList::Add(int columns)
244 {
245 //
246 // adds a row into the result set
247 //
248 if (!NumCols)
249 {
250 NumCols = columns;
251 ColumnName = new wxString[NumCols];
252 }
253 MyRowVariant *el = new MyRowVariant(columns);
254 if (!First)
255 First = el;
256 if (Last)
257 Last->SetNext(el);
258 Last = el;
259 return el;
260 }
261
SetColumnName(int col,const char * name)262 void MyVariantList::SetColumnName(int col, const char *name)
263 {
264 //
265 // storing a column name
266 //
267 if (col < 0 || col >= NumCols)
268 return;
269 ColumnName[col] = wxString::FromUTF8(name);
270 }
271
GetColumnName(int col)272 wxString & MyVariantList::GetColumnName(int col)
273 {
274 //
275 // retrieving a column name
276 //
277 return ColumnName[col];
278 }
279
MyBlobs(int rows,int cols)280 MyBlobs::MyBlobs(int rows, int cols)
281 {
282 //
283 // constructor - a BLOB matrix
284 //
285 int r;
286 MyRowVariant *rowVar;
287 NumRows = 0;
288 NumCols = 0;
289 Rows = NULL;
290 if (rows < 1 || cols < 1)
291 return;
292 NumRows = rows;
293 NumCols = cols;
294 Rows = new MyRowVariant[rows];
295 for (r = 0; r < rows; r++)
296 {
297 rowVar = Rows + r;
298 rowVar->Create(cols);
299 }
300 }
301
~MyBlobs()302 MyBlobs::~MyBlobs()
303 {
304 //
305 // destructor - a BLOB matrix
306 //
307 if (Rows)
308 delete[]Rows;
309 }
310
SetBlob(int row,int col,MyVariant * org)311 void MyBlobs::SetBlob(int row, int col, MyVariant * org)
312 {
313 //
314 // setting a BLOB value
315 //
316 MyRowVariant *rowVar;
317 MyVariant *dest;
318 if (row < 0 || row >= NumRows)
319 return;
320 if (col < 0 || col >= NumCols)
321 return;
322 rowVar = Rows + row;
323 if (!rowVar)
324 return;
325 dest = rowVar->GetColumn(col);
326 if (!dest)
327 return;
328 dest->Copy(org);
329 }
330
GetBlob(int row,int col)331 MyVariant *MyBlobs::GetBlob(int row, int col)
332 {
333 //
334 // return a BLOB value
335 //
336 MyRowVariant *rowVar;
337 MyVariant *dest;
338 if (row < 0 || row >= NumRows)
339 return NULL;
340 if (col < 0 || col >= NumCols)
341 return NULL;
342 rowVar = Rows + row;
343 if (!rowVar)
344 return NULL;
345 dest = rowVar->GetColumn(col);
346 if (!dest)
347 return NULL;
348 if (dest->GetType() != MY_BLOB_VARIANT)
349 return NULL;
350 return dest;
351 }
352
MyValues(int rows,int cols)353 MyValues::MyValues(int rows, int cols)
354 {
355 //
356 // constructor - a generic values matrix
357 //
358 int r;
359 MyRowVariant *rowVar;
360 NumRows = 0;
361 NumCols = 0;
362 Rows = NULL;
363 if (rows < 1 || cols < 1)
364 return;
365 NumRows = rows;
366 NumCols = cols;
367 Rows = new MyRowVariant[rows];
368 for (r = 0; r < rows; r++)
369 {
370 rowVar = Rows + r;
371 rowVar->Create(cols);
372 }
373 }
374
~MyValues()375 MyValues::~MyValues()
376 {
377 //
378 // destructor - a generic values matrix
379 //
380 if (Rows)
381 delete[]Rows;
382 }
383
SetValue(int row,int col,sqlite3_int64 value)384 void MyValues::SetValue(int row, int col, sqlite3_int64 value)
385 {
386 //
387 // setting an integer value
388 //
389 MyRowVariant *rowVar;
390 MyVariant *dest;
391 if (row < 0 || row >= NumRows)
392 return;
393 if (col < 0 || col >= NumCols)
394 return;
395 rowVar = Rows + row;
396 if (!rowVar)
397 return;
398 dest = rowVar->GetColumn(col);
399 if (!dest)
400 return;
401 dest->Set(value);
402 }
403
SetValue(int row,int col,double value)404 void MyValues::SetValue(int row, int col, double value)
405 {
406 //
407 // setting a double value
408 //
409 MyRowVariant *rowVar;
410 MyVariant *dest;
411 if (row < 0 || row >= NumRows)
412 return;
413 if (col < 0 || col >= NumCols)
414 return;
415 rowVar = Rows + row;
416 if (!rowVar)
417 return;
418 dest = rowVar->GetColumn(col);
419 if (!dest)
420 return;
421 dest->Set(value);
422 }
423
SetValue(int row,int col,wxString & value)424 void MyValues::SetValue(int row, int col, wxString & value)
425 {
426 //
427 // setting a string value
428 //
429 MyRowVariant *rowVar;
430 MyVariant *dest;
431 if (row < 0 || row >= NumRows)
432 return;
433 if (col < 0 || col >= NumCols)
434 return;
435 rowVar = Rows + row;
436 if (!rowVar)
437 return;
438 dest = rowVar->GetColumn(col);
439 if (!dest)
440 return;
441 dest->Set(value);
442 }
443
GetValue(int row,int col)444 MyVariant *MyValues::GetValue(int row, int col)
445 {
446 //
447 // return a generic value
448 //
449 MyRowVariant *rowVar;
450 MyVariant *dest;
451 if (row < 0 || row >= NumRows)
452 return NULL;
453 if (col < 0 || col >= NumCols)
454 return NULL;
455 rowVar = Rows + row;
456 if (!rowVar)
457 return NULL;
458 dest = rowVar->GetColumn(col);
459 if (!dest)
460 return NULL;
461 return dest;
462 }
463
GetRow(int row)464 MyRowVariant *MyValues::GetRow(int row)
465 {
466 //
467 // return a row of generic values
468 //
469 MyRowVariant *rowVar;
470 if (row < 0 || row >= NumRows)
471 return NULL;
472 rowVar = Rows + row;
473 return rowVar;
474 }
475
MyColumnInfo(wxString & name,bool pkey)476 MyColumnInfo::MyColumnInfo(wxString & name, bool pkey)
477 {
478 //
479 // constructor - a table column object
480 //
481 Name = name;
482 PrimaryKey = pkey;
483 Geometry = false;
484 GeometryIndex = false;
485 MbrCache = false;
486 Next = NULL;
487 }
488
MyIndexInfo(wxString & name)489 MyIndexInfo::MyIndexInfo(wxString & name)
490 {
491 //
492 // constructor - a table index object
493 //
494 Name = name;
495 Next = NULL;
496 }
497
MyTriggerInfo(wxString & name)498 MyTriggerInfo::MyTriggerInfo(wxString & name)
499 {
500 //
501 // constructor - a table trigger object
502 //
503 Name = name;
504 Next = NULL;
505 }
506
~MyTableInfo()507 MyTableInfo::~MyTableInfo()
508 {
509 //
510 // destructor - a table columns collection
511 //
512 MyColumnInfo *elc;
513 MyColumnInfo *elcN;
514 MyIndexInfo *eli;
515 MyIndexInfo *eliN;
516 MyTriggerInfo *elt;
517 MyTriggerInfo *eltN;
518 elc = FirstColumn;
519 while (elc)
520 {
521 elcN = elc->GetNext();
522 delete elc;
523 elc = elcN;
524 }
525 eli = FirstIndex;
526 while (eli)
527 {
528 eliN = eli->GetNext();
529 delete eli;
530 eli = eliN;
531 }
532 elt = FirstTrigger;
533 while (elt)
534 {
535 eltN = elt->GetNext();
536 delete elt;
537 elt = eltN;
538 }
539 }
540
AddColumn(wxString & name,bool pkey)541 void MyTableInfo::AddColumn(wxString & name, bool pkey)
542 {
543 //
544 // inserting a column def into a table
545 //
546 MyColumnInfo *el = new MyColumnInfo(name, pkey);
547 if (!FirstColumn)
548 FirstColumn = el;
549 if (LastColumn)
550 LastColumn->SetNext(el);
551 LastColumn = el;
552 }
553
SetGeometry(wxString & name,bool index,bool cached)554 void MyTableInfo::SetGeometry(wxString & name, bool index, bool cached)
555 {
556 //
557 //setting a geometry column
558 //
559 MyColumnInfo *elc;
560 elc = FirstColumn;
561 while (elc)
562 {
563 if (name.CmpNoCase(elc->GetName()) == 0)
564 {
565 elc->SetGeometry();
566 if (index == true)
567 elc->SetGeometryIndex();
568 if (cached == true)
569 elc->SetMbrCache();
570 }
571 elc = elc->GetNext();
572 }
573 }
574
AddIndex(wxString & name)575 void MyTableInfo::AddIndex(wxString & name)
576 {
577 //
578 // inserting an index def into a table
579 //
580 MyIndexInfo *el = new MyIndexInfo(name);
581 if (!FirstIndex)
582 FirstIndex = el;
583 if (LastIndex)
584 LastIndex->SetNext(el);
585 LastIndex = el;
586 }
587
AddTrigger(wxString & name)588 void MyTableInfo::AddTrigger(wxString & name)
589 {
590 //
591 // inserting a trigger def into a table
592 //
593 MyTriggerInfo *el = new MyTriggerInfo(name);
594 if (!FirstTrigger)
595 FirstTrigger = el;
596 if (LastTrigger)
597 LastTrigger->SetNext(el);
598 LastTrigger = el;
599 }
600
~MyViewInfo()601 MyViewInfo::~MyViewInfo()
602 {
603 //
604 // destructor - a view columns collection
605 //
606 MyColumnInfo *elc;
607 MyColumnInfo *elcN;
608 MyTriggerInfo *elt;
609 MyTriggerInfo *eltN;
610 elc = First;
611 while (elc)
612 {
613 elcN = elc->GetNext();
614 delete elc;
615 elc = elcN;
616 }
617 elt = FirstTrigger;
618 while (elt)
619 {
620 eltN = elt->GetNext();
621 delete elt;
622 elt = eltN;
623 }
624 }
625
AddColumn(wxString & name)626 void MyViewInfo::AddColumn(wxString & name)
627 {
628 //
629 // inserting a column def into a view
630 //
631 MyColumnInfo *el = new MyColumnInfo(name, false);
632 if (!First)
633 First = el;
634 if (Last)
635 Last->SetNext(el);
636 Last = el;
637 }
638
AddTrigger(wxString & name)639 void MyViewInfo::AddTrigger(wxString & name)
640 {
641 //
642 // inserting a trigger def into a view
643 //
644 MyTriggerInfo *el = new MyTriggerInfo(name);
645 if (!FirstTrigger)
646 FirstTrigger = el;
647 if (LastTrigger)
648 LastTrigger->SetNext(el);
649 LastTrigger = el;
650 }
651
SetGeometry(wxString & name,bool index,bool cached)652 void MyViewInfo::SetGeometry(wxString & name, bool index, bool cached)
653 {
654 //
655 //setting a geometry column
656 //
657 MyColumnInfo *elc;
658 elc = First;
659 while (elc)
660 {
661 if (name.CmpNoCase(elc->GetName()) == 0)
662 {
663 elc->SetGeometry();
664 if (index == true)
665 elc->SetGeometryIndex();
666 if (cached == true)
667 elc->SetMbrCache();
668 }
669 elc = elc->GetNext();
670 }
671 }
672
~MySqlHistory()673 MySqlHistory::~MySqlHistory()
674 {
675 //
676 // destructor - the SQL queries history
677 //
678 MySqlQuery *elq;
679 MySqlQuery *elqN;
680 elq = First;
681 while (elq)
682 {
683 elqN = elq->GetNext();
684 delete elq;
685 elq = elqN;
686 }
687 }
688
Prepend(wxString & sql)689 void MySqlHistory::Prepend(wxString & sql)
690 {
691 //
692 // inserting an SQL query into the history [reverse order]
693 //
694 if (First)
695 {
696 // avoiding stupid duplicates
697 if (First->GetSql() == sql)
698 return;
699 }
700 MySqlQuery *el = new MySqlQuery(sql);
701 el->SetNext(First);
702 if (First)
703 First->SetPrev(el);
704 if (Last == NULL)
705 Last = el;
706 First = el;
707 Current = Last;
708 }
709
Add(wxString & sql)710 void MySqlHistory::Add(wxString & sql)
711 {
712 //
713 // inserting an SQL query into the history
714 //
715 if (Last)
716 {
717 // avoiding stupid duplicates
718 if (Last->GetSql() == sql)
719 return;
720 }
721 MySqlQuery *el = new MySqlQuery(sql);
722 if (!First)
723 First = el;
724 el->SetPrev(Last);
725 if (Last)
726 Last->SetNext(el);
727 Last = el;
728 Current = el;
729 }
730
GetNext()731 MySqlQuery *MySqlHistory::GetNext()
732 {
733 //
734 // return the next SQL query
735 //
736 if (Current)
737 {
738 if (Current->GetNext())
739 {
740 Current = Current->GetNext();
741 return Current;
742 } else
743 return NULL;
744 }
745 return NULL;
746 }
747
GetPrev()748 MySqlQuery *MySqlHistory::GetPrev()
749 {
750 //
751 // return the previous SQL query
752 //
753 if (Current)
754 {
755 if (Current->GetPrev())
756 {
757 Current = Current->GetPrev();
758 return Current;
759 } else
760 return NULL;
761 }
762 return NULL;
763 }
764
TestNext()765 bool MySqlHistory::TestNext()
766 {
767 //
768 // tests if the next SQL query exists
769 //
770 if (Current)
771 {
772 if (Current->GetNext())
773 return true;
774 else
775 return false;
776 }
777 return false;
778 }
779
TestPrev()780 bool MySqlHistory::TestPrev()
781 {
782 //
783 // tests if the previous SQL query exists
784 //
785 if (Current)
786 {
787 if (Current->GetPrev())
788 return true;
789 else
790 return false;
791 }
792 return false;
793 }
794
~AutoFDOTables()795 AutoFDOTables::~AutoFDOTables()
796 {
797 //
798 // destructor - auto FDO-OGR wrapper linked list
799 //
800 AutoFDOTable *el;
801 AutoFDOTable *elN;
802 el = First;
803 while (el)
804 {
805 elN = el->GetNext();
806 delete el;
807 el = elN;
808 }
809 }
810
Add(const char * name,const int len)811 void AutoFDOTables::Add(const char *name, const int len)
812 {
813 //
814 // adding a table name to the auto FDO-OGR wrapper linked list
815 //
816 AutoFDOTable *el = new AutoFDOTable(name, len);
817 if (!First)
818 First = el;
819 if (Last)
820 Last->SetNext(el);
821 Last = el;
822 }
823
GeomColumn(wxString & name,wxString & type,wxString & dims,int srid,int idx)824 GeomColumn::GeomColumn(wxString & name, wxString & type, wxString & dims,
825 int srid, int idx)
826 {
827 // Geometry Column - constructor
828 GeometryName = name;
829 GeometryType = type;
830 CoordDims = dims;
831 Srid = srid;
832 RTree = false;
833 MbrCache = false;
834 if (idx == 1)
835 RTree = true;
836 if (idx == 2)
837 MbrCache = true;
838 NotNull = false;
839 Next = NULL;
840 }
841
GeomColsList()842 GeomColsList::GeomColsList()
843 {
844 // Geometry Columns List - constructor
845 First = NULL;
846 Last = NULL;
847 }
848
~GeomColsList()849 GeomColsList::~GeomColsList()
850 {
851 // Geometry Columns List - destructor
852 GeomColumn *pG;
853 GeomColumn *pGn;
854 pG = First;
855 while (pG)
856 {
857 pGn = pG->GetNext();
858 delete pG;
859 pG = pGn;
860 }
861 }
862
Add(wxString & name,wxString & type,wxString & dims,int srid,int idx)863 void GeomColsList::Add(wxString & name, wxString & type, wxString & dims,
864 int srid, int idx)
865 {
866 // adding a Geometry Column to the list
867 GeomColumn *p = new GeomColumn(name, type, dims, srid, idx);
868 if (!First)
869 First = p;
870 if (Last)
871 Last->SetNext(p);
872 Last = p;
873 }
874
SetNotNull(wxString & name)875 void GeomColsList::SetNotNull(wxString & name)
876 {
877 // setting a NOT NULL geometry
878 GeomColumn *pG = First;
879 while (pG)
880 {
881 if (pG->GetGeometryName() == name)
882 {
883 pG->SetNotNull();
884 return;
885 }
886 pG = pG->GetNext();
887 }
888 }
889
IndexColumn(wxString & name)890 IndexColumn::IndexColumn(wxString & name)
891 {
892 // Index Column - constructor
893 ColumnName = name;
894 Valid = true;
895 Next = NULL;
896 }
897
TblIndex(wxString & name,bool unique)898 TblIndex::TblIndex(wxString & name, bool unique)
899 {
900 // Table Index - constructor
901 IndexName = name;
902 Unique = unique;
903 Valid = true;
904 First = NULL;
905 Last = NULL;
906 Next = NULL;
907 }
908
~TblIndex()909 TblIndex::~TblIndex()
910 {
911 // Table Index - destructor
912 IndexColumn *pC;
913 IndexColumn *pCn;
914 pC = First;
915 while (pC)
916 {
917 pCn = pC->GetNext();
918 delete pC;
919 pC = pCn;
920 }
921 }
922
Add(wxString & name)923 void TblIndex::Add(wxString & name)
924 {
925 // adding a Column to the Index
926 IndexColumn *p = new IndexColumn(name);
927 if (!First)
928 First = p;
929 if (Last)
930 Last->SetNext(p);
931 Last = p;
932 }
933
Invalidate(wxString & name)934 void TblIndex::Invalidate(wxString & name)
935 {
936 // invalidating a column/index
937 IndexColumn *pC = First;
938 while (pC)
939 {
940 if (pC->GetColumnName() == name)
941 {
942 pC->Invalidate();
943 Valid = false;
944 return;
945 }
946 pC = pC->GetNext();
947 }
948 }
949
TblIndexList()950 TblIndexList::TblIndexList()
951 {
952 // Table Index List - constructor
953 First = NULL;
954 Last = NULL;
955 }
956
~TblIndexList()957 TblIndexList::~TblIndexList()
958 {
959 // Table Index List - destructor
960 TblIndex *pI;
961 TblIndex *pIn;
962 pI = First;
963 while (pI)
964 {
965 pIn = pI->GetNext();
966 delete pI;
967 pI = pIn;
968 }
969 }
970
Add(wxString & name,bool unique)971 void TblIndexList::Add(wxString & name, bool unique)
972 {
973 // adding an Index to the List
974 TblIndex *p = new TblIndex(name, unique);
975 if (!First)
976 First = p;
977 if (Last)
978 Last->SetNext(p);
979 Last = p;
980 }
981
Invalidate(wxString & name)982 void TblIndexList::Invalidate(wxString & name)
983 {
984 // invalidating a column/index
985 TblIndex *pI = First;
986 while (pI)
987 {
988 pI->Invalidate(name);
989 pI = pI->GetNext();
990 }
991 }
992
MyChartData()993 MyChartData::MyChartData()
994 {
995 // constructor (unique values)
996 Initialized = false;
997 Array = NULL;
998 First = NULL;
999 Last = NULL;
1000 MaxFreq = INT_MIN;
1001 TotFreq = 0;
1002 MaxClasses = 0;
1003 NumClasses = 0;
1004 OtherUniquesFreq = 0;
1005 OtherUniquesCount = 0;
1006 Valid = false;
1007 ByIntervals = false;
1008 }
1009
~MyChartData()1010 MyChartData::~MyChartData()
1011 {
1012 // destructor
1013 MyChartUniqueClass *p;
1014 MyChartUniqueClass *pN;
1015 if (Array)
1016 delete[]Array;
1017 p = First;
1018 while (p)
1019 {
1020 pN = p->GetNext();
1021 delete p;
1022 p = pN;
1023 }
1024 }
1025
Check(bool by_interval,int classes)1026 bool MyChartData::Check(bool by_interval, int classes)
1027 {
1028 // checking if current Data are still valid
1029 if (Initialized == false)
1030 return false;
1031 if (by_interval == true && Array == NULL)
1032 return false;
1033 if (by_interval == false && First == NULL)
1034 return false;
1035 if (by_interval == true && classes != NumClasses)
1036 return false;
1037 if (by_interval == false && classes != MaxClasses)
1038 return false;
1039 return true;
1040 }
1041
CleanData()1042 void MyChartData::CleanData()
1043 {
1044 // resetting to the initial (not initialized) state
1045
1046 MyChartUniqueClass *p;
1047 MyChartUniqueClass *pN;
1048 if (Array)
1049 delete[]Array;
1050 p = First;
1051 while (p)
1052 {
1053 pN = p->GetNext();
1054 delete p;
1055 p = pN;
1056 }
1057 Initialized = false;
1058 Array = NULL;
1059 First = NULL;
1060 Last = NULL;
1061 MaxFreq = INT_MIN;
1062 TotFreq = 0;
1063 MaxClasses = 0;
1064 NumClasses = 0;
1065 OtherUniquesFreq = 0;
1066 OtherUniquesCount = 0;
1067 Valid = false;
1068 ByIntervals = false;
1069 }
1070
Create(int max_classes)1071 bool MyChartData::Create(int max_classes)
1072 {
1073 // constructor (unique values)
1074 if (Initialized == true)
1075 return false;
1076 MaxClasses = max_classes;
1077 Valid = false;
1078 ByIntervals = false;
1079 return true;
1080 }
1081
Create(double min,double max,int classes)1082 bool MyChartData::Create(double min, double max, int classes)
1083 {
1084 // constructor (interval values)
1085 int ind;
1086 double base = min;
1087 double step;
1088 if (Initialized == true)
1089 return false;
1090 Array = new MyChartIntervalClass[classes];
1091 Min = min;
1092 Max = max;
1093 NumClasses = classes;
1094 Valid = false;
1095 ByIntervals = true;
1096 step = (max - min) / (double) classes;
1097 for (ind = 0; ind < classes; ind++)
1098 {
1099 MyChartIntervalClass *p = GetClass(ind);
1100 p->Create(base, base + step);
1101 base += step;
1102 }
1103 return true;
1104 }
1105
GetClass(int idx)1106 MyChartIntervalClass *MyChartData::GetClass(int idx)
1107 {
1108 // retriving an interval class by index
1109 if (idx >= 0 && idx < NumClasses)
1110 return Array + idx;
1111 return NULL;
1112 }
1113
Add(double value)1114 void MyChartData::Add(double value)
1115 {
1116 // incrementing the frequence count for an interval class
1117 double step = (Max - Min) / (double) NumClasses;
1118 int idx = (int) floor((value - Min) / step);
1119 if (idx >= 0 && idx < NumClasses)
1120 {
1121 MyChartIntervalClass *p = GetClass(idx);
1122 p->Add();
1123 TotFreq++;
1124 if (p->GetCount() > MaxFreq)
1125 MaxFreq = p->GetCount();
1126 }
1127 }
1128
Add(wxString & value,int count)1129 void MyChartData::Add(wxString & value, int count)
1130 {
1131 // appending a new Unique Value (if limit not already reached)
1132 if (NumClasses < MaxClasses)
1133 {
1134 MyChartUniqueClass *p = new MyChartUniqueClass(value, count);
1135 if (First == NULL)
1136 First = p;
1137 if (Last != NULL)
1138 Last->SetNext(p);
1139 Last = p;
1140 NumClasses++;
1141 if (count > MaxFreq)
1142 MaxFreq = count;
1143 } else
1144 {
1145 OtherUniquesFreq += count;
1146 OtherUniquesCount++;
1147 if (OtherUniquesFreq > MaxFreq)
1148 MaxFreq = OtherUniquesFreq;
1149 }
1150 TotFreq += count;
1151 }
1152
~MyChartScaleLabels()1153 MyChartScaleLabels::~MyChartScaleLabels()
1154 {
1155 // destructor
1156 MyChartScaleLabel *p;
1157 MyChartScaleLabel *pN;
1158 p = First;
1159 while (p)
1160 {
1161 pN = p->GetNext();
1162 delete p;
1163 p = pN;
1164 }
1165 }
1166
Initialize(double span,int max_freq)1167 void MyChartScaleLabels::Initialize(double span, int max_freq)
1168 {
1169 // setting the Chart Scale labels
1170 int tic;
1171 int tic2;
1172 char text[128];
1173 double pos;
1174
1175 if (max_freq < 20)
1176 {
1177 tic = 1;
1178 while (tic < max_freq)
1179 {
1180 sprintf(text, "%d", tic);
1181 pos = span * ((double) tic / max_freq);
1182 Add(text, pos);
1183 tic++;
1184 }
1185 } else if (max_freq < 200)
1186 {
1187 tic = 10;
1188 while (tic < max_freq)
1189 {
1190 sprintf(text, "%d", tic);
1191 pos = span * ((double) tic / max_freq);
1192 Add(text, pos);
1193 tic += 10;
1194 }
1195 } else if (max_freq < 2000)
1196 {
1197 tic = 100;
1198 while (tic < max_freq)
1199 {
1200 sprintf(text, "%d", tic);
1201 pos = span * ((double) tic / max_freq);
1202 Add(text, pos);
1203 tic += 100;
1204 }
1205 } else if (max_freq < 20000)
1206 {
1207 tic = 1000;
1208 tic2 = 1;
1209 while (tic < max_freq)
1210 {
1211 sprintf(text, "%dK", tic2);
1212 pos = span * ((double) tic / max_freq);
1213 Add(text, pos);
1214 tic += 1000;
1215 tic2++;
1216 }
1217 } else if (max_freq < 200000)
1218 {
1219 tic = 10000;
1220 tic2 = 1;
1221 while (tic < max_freq)
1222 {
1223 sprintf(text, "%d0K", tic2);
1224 pos = span * ((double) tic / max_freq);
1225 Add(text, pos);
1226 tic += 10000;
1227 tic2++;
1228 }
1229 } else if (max_freq < 2000000)
1230 {
1231 tic = 100000;
1232 tic2 = 1;
1233 while (tic < max_freq)
1234 {
1235 sprintf(text, "%d00K", tic2);
1236 pos = span * ((double) tic / max_freq);
1237 Add(text, pos);
1238 tic += 100000;
1239 tic2++;
1240 }
1241 } else if (max_freq < 20000000)
1242 {
1243 tic = 1000000;
1244 tic2 = 1;
1245 while (tic < max_freq)
1246 {
1247 sprintf(text, "%dM", tic2);
1248 pos = span * ((double) tic / max_freq);
1249 Add(text, pos);
1250 tic += 1000000;
1251 tic2++;
1252 }
1253 } else if (max_freq < 200000000)
1254 {
1255 tic = 10000000;
1256 tic2 = 1;
1257 while (tic < max_freq)
1258 {
1259 sprintf(text, "%d0M", tic2);
1260 pos = span * ((double) tic / max_freq);
1261 Add(text, pos);
1262 tic += 10000000;
1263 tic2++;
1264 }
1265 } else if (max_freq < 200000000)
1266 {
1267 tic = 100000000;
1268 tic2 = 1;
1269 while (tic < max_freq)
1270 {
1271 sprintf(text, "%d00M", tic2);
1272 pos = span * ((double) tic / max_freq);
1273 Add(text, pos);
1274 tic += 100000000;
1275 tic2++;
1276 }
1277 } else
1278 {
1279 tic = 1000000000;
1280 tic2 = 1;
1281 while (tic < max_freq)
1282 {
1283 sprintf(text, "%dG", tic2);
1284 pos = span * ((double) tic / max_freq);
1285 Add(text, pos);
1286 tic += 1000000000;
1287 tic2++;
1288 }
1289 }
1290 }
1291
Add(const char * label,double pos)1292 void MyChartScaleLabels::Add(const char *label, double pos)
1293 {
1294 // adding a Scale Label
1295 wxString text = wxString::FromUTF8(label);
1296 MyChartScaleLabel *p = new MyChartScaleLabel(text, pos);
1297 if (First == NULL)
1298 First = p;
1299 if (Last != NULL)
1300 Last->SetNext(p);
1301 Last = p;
1302 }
1303
MyPieChartLabels()1304 MyPieChartLabels::MyPieChartLabels()
1305 {
1306 // constructor
1307 First = NULL;
1308 Last = NULL;
1309 NumLeftLabels = 0;
1310 LeftLabels = NULL;
1311 NumRightLabels = 0;
1312 RightLabels = NULL;
1313 }
1314
~MyPieChartLabels()1315 MyPieChartLabels::~MyPieChartLabels()
1316 {
1317 // destructor
1318 MyPieChartLabel *p;
1319 MyPieChartLabel *pN;
1320 p = First;
1321 while (p)
1322 {
1323 pN = p->GetNext();
1324 delete p;
1325 p = pN;
1326 }
1327 if (LeftLabels)
1328 delete[]LeftLabels;
1329 if (RightLabels)
1330 delete[]RightLabels;
1331 }
1332
Add(const char * label,double x,double y)1333 void MyPieChartLabels::Add(const char *label, double x, double y)
1334 {
1335 // adding a PieChart Label
1336 wxString text = wxString::FromUTF8(label);
1337 MyPieChartLabel *p = new MyPieChartLabel(text, x, y);
1338 if (First == NULL)
1339 First = p;
1340 if (Last != NULL)
1341 Last->SetNext(p);
1342 Last = p;
1343 }
1344
Sort(double cx)1345 void MyPieChartLabels::Sort(double cx)
1346 {
1347 // sorting the Left/Right arrays
1348 MyPieChartLabel *p;
1349 MyPieChartLabel *p2;
1350 int idx;
1351 bool ok;
1352
1353 if (LeftLabels)
1354 delete[]LeftLabels;
1355 if (RightLabels)
1356 delete[]RightLabels;
1357 NumLeftLabels = 0;
1358 LeftLabels = NULL;
1359 NumRightLabels = 0;
1360 RightLabels = NULL;
1361
1362 p = First;
1363 while (p)
1364 {
1365 // counting how many 'left' labels are there
1366 if (p->GetX() < cx)
1367 NumLeftLabels++;
1368 p = p->GetNext();
1369 }
1370 p = First;
1371 while (p)
1372 {
1373 // counting how many 'right' labels are there
1374 if (p->GetX() >= cx)
1375 NumRightLabels++;
1376 p = p->GetNext();
1377 }
1378 if (NumLeftLabels > 0)
1379 {
1380 // allocating the Left array
1381 LeftLabels = new MyPieChartLabel *[NumLeftLabels];
1382 idx = 0;
1383 p = First;
1384 while (p)
1385 {
1386 // initializing the Left array
1387 if (p->GetX() < cx)
1388 {
1389 *(LeftLabels + idx) = p;
1390 idx++;
1391 }
1392 p = p->GetNext();
1393 }
1394 ok = true;
1395 while (ok)
1396 {
1397 // bubble-sorting the Left array
1398 ok = false;
1399 for (idx = 1; idx < NumLeftLabels; idx++)
1400 {
1401 p = *(LeftLabels + idx - 1);
1402 p2 = *(LeftLabels + idx);
1403 if (p->GetY() > p2->GetY())
1404 {
1405 *(LeftLabels + idx - 1) = p2;
1406 *(LeftLabels + idx) = p;
1407 ok = true;
1408 }
1409 }
1410 }
1411 }
1412 if (NumRightLabels > 0)
1413 {
1414 // allocating the Right array
1415 RightLabels = new MyPieChartLabel *[NumRightLabels];
1416 idx = 0;
1417 p = First;
1418 while (p)
1419 {
1420 // initializing the Right array
1421 if (p->GetX() >= cx)
1422 {
1423 *(RightLabels + idx) = p;
1424 idx++;
1425 }
1426 p = p->GetNext();
1427 }
1428 ok = true;
1429 while (ok)
1430 {
1431 // bubble-sorting the Right array
1432 ok = false;
1433 for (idx = 1; idx < NumRightLabels; idx++)
1434 {
1435 p = *(RightLabels + idx - 1);
1436 p2 = *(RightLabels + idx);
1437 if (p->GetY() > p2->GetY())
1438 {
1439 *(RightLabels + idx - 1) = p2;
1440 *(RightLabels + idx) = p;
1441 ok = true;
1442 }
1443 }
1444 }
1445 }
1446 }
1447
GetLeftLabel(int idx)1448 MyPieChartLabel *MyPieChartLabels::GetLeftLabel(int idx)
1449 {
1450 // return a Left Label pointer by index
1451 if (idx >= 0 && idx < NumLeftLabels)
1452 return *(LeftLabels + idx);
1453 return NULL;
1454 }
1455
GetRightLabel(int idx)1456 MyPieChartLabel *MyPieChartLabels::GetRightLabel(int idx)
1457 {
1458 // return a Right Label pointer by index
1459 if (idx >= 0 && idx < NumRightLabels)
1460 return *(RightLabels + idx);
1461 return NULL;
1462 }
1463
Topology(MyTableTree * tree,wxTreeItemId & root,TopologySet * topology)1464 Topology::Topology(MyTableTree * tree, wxTreeItemId & root,
1465 TopologySet * topology)
1466 {
1467 // constructor: Topology Tree Node
1468 wxString prefix = topology->GetPrefix();
1469 wxString name;
1470 char bufSrid[64];
1471 TopologyItem *pT;
1472 name = prefix;
1473 sprintf(bufSrid, " [SRID=%d]", topology->GetSrid());
1474 name += wxString::FromUTF8(bufSrid);
1475 if (topology->GetCoordDims() == wxT("XYZ"))
1476 name += wxT(" 3D");
1477 else
1478 name += wxT(" 2D");
1479 TopologyNode = tree->AppendItem(root, name);
1480 tree->SetItemImage(TopologyNode, 20);
1481 TopologyItems.SetPrefix(topology->GetPrefix());
1482 TopologyItems.SetSrid(topology->GetSrid());
1483 TopologyItems.SetCoordDims(topology->GetCoordDims());
1484 pT = topology->GetFirst();
1485 while (pT)
1486 {
1487 // copying Topology Items
1488 if (pT->IsTable() == true)
1489 TopologyItems.AddTable(pT->GetName());
1490 else if (pT->IsView() == true)
1491 TopologyItems.AddView(pT->GetName());
1492 pT = pT->GetNext();
1493 }
1494 Next = NULL;
1495 }
1496
Check(wxString & table)1497 wxTreeItemId *Topology::Check(wxString & table)
1498 {
1499 // checking if some table belongs to this Topology
1500 TopologyItem *pT = TopologyItems.GetFirst();
1501 while (pT)
1502 {
1503 // copying Topology Items
1504 if (pT->GetName() == table)
1505 return &TopologyNode;
1506 pT = pT->GetNext();
1507 }
1508 return NULL;
1509 }
1510
Flush()1511 void TopologyList::Flush()
1512 {
1513 // resetting TopologyList to initial empty state
1514 Topology *pT;
1515 Topology *pTn;
1516 pT = First;
1517 while (pT)
1518 {
1519 pTn = pT->GetNext();
1520 delete pT;
1521 pT = pTn;
1522 }
1523 First = NULL;
1524 Last = NULL;
1525 Count = 0;
1526 }
1527
Add(class MyTableTree * tree,wxTreeItemId & root,TopologySet * topology)1528 void TopologyList::Add(class MyTableTree * tree, wxTreeItemId & root,
1529 TopologySet * topology)
1530 {
1531 // inserting a Topology into the list
1532 Topology *pT = new Topology(tree, root, topology);
1533 Count++;
1534 if (First == NULL)
1535 First = pT;
1536 if (Last != NULL)
1537 Last->SetNext(pT);
1538 Last = pT;
1539 }
1540
FindNode(wxString & table)1541 wxTreeItemId *TopologyList::FindNode(wxString & table)
1542 {
1543 // serching corresponding Topology Node (if any)
1544 Topology *pT = First;
1545 while (pT)
1546 {
1547 wxTreeItemId *node = pT->Check(table);
1548 if (node != NULL)
1549 return node;
1550 pT = pT->GetNext();
1551 }
1552 return NULL;
1553 }
1554
PostGISColumn()1555 PostGISColumn::PostGISColumn()
1556 {
1557 // constructor
1558 Nullable = true;
1559 PrimaryKey = false;
1560 Autoincrement = false;
1561 Null = 0;
1562 Boolean = 0;
1563 Int8 = 0;
1564 UInt8 = 0;
1565 Int16 = 0;
1566 UInt16 = 0;
1567 Int32 = 0;
1568 UInt32 = 0;
1569 Int64 = 0;
1570 Double = 0;
1571 Text = 0;
1572 MaxTextLen = 0;
1573 Date = 0;
1574 DateTime = 0;
1575 Blob = 0;
1576 Point = 0;
1577 MultiPoint = 0;
1578 LineString = 0;
1579 MultiLineString = 0;
1580 Polygon = 0;
1581 MultiPolygon = 0;
1582 GeometryCollection = 0;
1583 Srid1 = INT_MIN;
1584 Srid2 = INT_MIN;;
1585 CoordDims1 = GAIA_UNKNOWN;
1586 CoordDims2 = GAIA_UNKNOWN;
1587 DataType = PostGISHelper::DATA_TYPE_UNDEFINED;
1588 }
1589
IncrPoint(int srid,int dims)1590 void PostGISColumn::IncrPoint(int srid, int dims)
1591 {
1592 // increasing POINT statistics
1593 Point++;
1594 if (srid == Srid1 || srid == Srid2)
1595 ;
1596 else
1597 {
1598 if (Srid1 == INT_MIN)
1599 Srid1 = srid;
1600 else if (Srid2 == INT_MIN)
1601 Srid2 = srid;
1602 }
1603 if (dims == CoordDims1 || dims == CoordDims2)
1604 ;
1605 else
1606 {
1607 if (CoordDims1 == GAIA_UNKNOWN)
1608 CoordDims1 = dims;
1609 else if (CoordDims2 == GAIA_UNKNOWN)
1610 CoordDims2 = dims;
1611 }
1612 }
1613
IncrMultiPoint(int srid,int dims)1614 void PostGISColumn::IncrMultiPoint(int srid, int dims)
1615 {
1616 // increasing MULTIPOINT statistics
1617 MultiPoint++;
1618 if (srid == Srid1 || srid == Srid2)
1619 ;
1620 else
1621 {
1622 if (Srid1 == INT_MIN)
1623 Srid1 = srid;
1624 else if (Srid2 == INT_MIN)
1625 Srid2 = srid;
1626 }
1627 if (dims == CoordDims1 || dims == CoordDims2)
1628 ;
1629 else
1630 {
1631 if (CoordDims1 == GAIA_UNKNOWN)
1632 CoordDims1 = dims;
1633 else if (CoordDims2 == GAIA_UNKNOWN)
1634 CoordDims2 = dims;
1635 }
1636 }
1637
IncrLineString(int srid,int dims)1638 void PostGISColumn::IncrLineString(int srid, int dims)
1639 {
1640 // increasing LINESTRING statistics
1641 LineString++;
1642 if (srid == Srid1 || srid == Srid2)
1643 ;
1644 else
1645 {
1646 if (Srid1 == INT_MIN)
1647 Srid1 = srid;
1648 else if (Srid2 == INT_MIN)
1649 Srid2 = srid;
1650 }
1651 if (dims == CoordDims1 || dims == CoordDims2)
1652 ;
1653 else
1654 {
1655 if (CoordDims1 == GAIA_UNKNOWN)
1656 CoordDims1 = dims;
1657 else if (CoordDims2 == GAIA_UNKNOWN)
1658 CoordDims2 = dims;
1659 }
1660 }
1661
IncrMultiLineString(int srid,int dims)1662 void PostGISColumn::IncrMultiLineString(int srid, int dims)
1663 {
1664 // increasing MULTILINESTRING statistics
1665 MultiLineString++;
1666 if (srid == Srid1 || srid == Srid2)
1667 ;
1668 else
1669 {
1670 if (Srid1 == INT_MIN)
1671 Srid1 = srid;
1672 else if (Srid2 == INT_MIN)
1673 Srid2 = srid;
1674 }
1675 if (dims == CoordDims1 || dims == CoordDims2)
1676 ;
1677 else
1678 {
1679 if (CoordDims1 == GAIA_UNKNOWN)
1680 CoordDims1 = dims;
1681 else if (CoordDims2 == GAIA_UNKNOWN)
1682 CoordDims2 = dims;
1683 }
1684 }
1685
IncrPolygon(int srid,int dims)1686 void PostGISColumn::IncrPolygon(int srid, int dims)
1687 {
1688 // increasing POLYGON statistics
1689 Polygon++;
1690 if (srid == Srid1 || srid == Srid2)
1691 ;
1692 else
1693 {
1694 if (Srid1 == INT_MIN)
1695 Srid1 = srid;
1696 else if (Srid2 == INT_MIN)
1697 Srid2 = srid;
1698 }
1699 if (dims == CoordDims1 || dims == CoordDims2)
1700 ;
1701 else
1702 {
1703 if (CoordDims1 == GAIA_UNKNOWN)
1704 CoordDims1 = dims;
1705 else if (CoordDims2 == GAIA_UNKNOWN)
1706 CoordDims2 = dims;
1707 }
1708 }
1709
IncrMultiPolygon(int srid,int dims)1710 void PostGISColumn::IncrMultiPolygon(int srid, int dims)
1711 {
1712 // increasing MULTIPOLYGON statistics
1713 MultiPolygon++;
1714 if (srid == Srid1 || srid == Srid2)
1715 ;
1716 else
1717 {
1718 if (Srid1 == INT_MIN)
1719 Srid1 = srid;
1720 else if (Srid2 == INT_MIN)
1721 Srid2 = srid;
1722 }
1723 if (dims == CoordDims1 || dims == CoordDims2)
1724 ;
1725 else
1726 {
1727 if (CoordDims1 == GAIA_UNKNOWN)
1728 CoordDims1 = dims;
1729 else if (CoordDims2 == GAIA_UNKNOWN)
1730 CoordDims2 = dims;
1731 }
1732 }
1733
IncrGeometryCollection(int srid,int dims)1734 void PostGISColumn::IncrGeometryCollection(int srid, int dims)
1735 {
1736 // increasing GEOMETRYCOLLECTION statistics
1737 GeometryCollection++;
1738 if (srid == Srid1 || srid == Srid2)
1739 ;
1740 else
1741 {
1742 if (Srid1 == INT_MIN)
1743 Srid1 = srid;
1744 else if (Srid2 == INT_MIN)
1745 Srid2 = srid;
1746 }
1747 if (dims == CoordDims1 || dims == CoordDims2)
1748 ;
1749 else
1750 {
1751 if (CoordDims1 == GAIA_UNKNOWN)
1752 CoordDims1 = dims;
1753 else if (CoordDims2 == GAIA_UNKNOWN)
1754 CoordDims2 = dims;
1755 }
1756 }
1757
IsDate(const char * txt)1758 bool PostGISColumn::IsDate(const char *txt)
1759 {
1760 // checking if a text string looks like a DATE
1761 if (txt == NULL)
1762 return false;
1763 if (strlen(txt) != 10)
1764 return false;
1765 if (*(txt + 0) >= '0' && *(txt + 0) <= '9')
1766 ;
1767 else
1768 return false;
1769 if (*(txt + 1) >= '0' && *(txt + 1) <= '9')
1770 ;
1771 else
1772 return false;
1773 if (*(txt + 2) >= '0' && *(txt + 2) <= '9')
1774 ;
1775 else
1776 return false;
1777 if (*(txt + 3) >= '0' && *(txt + 3) <= '9')
1778 ;
1779 else
1780 return false;
1781 if (*(txt + 4) != '-')
1782 return false;
1783 if (*(txt + 5) >= '0' && *(txt + 5) <= '9')
1784 ;
1785 else
1786 return false;
1787 if (*(txt + 6) >= '0' && *(txt + 6) <= '9')
1788 ;
1789 else
1790 return false;
1791 if (*(txt + 7) != '-')
1792 return false;
1793 if (*(txt + 8) >= '0' && *(txt + 8) <= '9')
1794 ;
1795 else
1796 return false;
1797 if (*(txt + 9) >= '0' && *(txt + 9) <= '9')
1798 ;
1799 else
1800 return false;
1801 return true;
1802 }
1803
IsDateTime(const char * txt)1804 bool PostGISColumn::IsDateTime(const char *txt)
1805 {
1806 // checking if a text string looks like a DATETIME
1807 if (txt == NULL)
1808 return false;
1809 if (strlen(txt) != 19)
1810 return false;
1811 if (*(txt + 0) >= '0' && *(txt + 0) <= '9')
1812 ;
1813 else
1814 return false;
1815 if (*(txt + 1) >= '0' && *(txt + 1) <= '9')
1816 ;
1817 else
1818 return false;
1819 if (*(txt + 2) >= '0' && *(txt + 2) <= '9')
1820 ;
1821 else
1822 return false;
1823 if (*(txt + 3) >= '0' && *(txt + 3) <= '9')
1824 ;
1825 else
1826 return false;
1827 if (*(txt + 4) != '-')
1828 return false;
1829 if (*(txt + 5) >= '0' && *(txt + 5) <= '9')
1830 ;
1831 else
1832 return false;
1833 if (*(txt + 6) >= '0' && *(txt + 6) <= '9')
1834 ;
1835 else
1836 return false;
1837 if (*(txt + 7) != '-')
1838 return false;
1839 if (*(txt + 8) >= '0' && *(txt + 8) <= '9')
1840 ;
1841 else
1842 return false;
1843 if (*(txt + 9) >= '0' && *(txt + 9) <= '9')
1844 ;
1845 else
1846 return false;
1847 if (*(txt + 10) != ' ')
1848 return false;
1849 if (*(txt + 11) >= '0' && *(txt + 11) <= '9')
1850 ;
1851 else
1852 return false;
1853 if (*(txt + 12) >= '0' && *(txt + 12) <= '9')
1854 ;
1855 else
1856 return false;
1857 if (*(txt + 13) != ':')
1858 return false;
1859 if (*(txt + 14) >= '0' && *(txt + 14) <= '9')
1860 ;
1861 else
1862 return false;
1863 if (*(txt + 15) >= '0' && *(txt + 15) <= '9')
1864 ;
1865 else
1866 return false;
1867 if (*(txt + 16) != ':')
1868 return false;
1869 if (*(txt + 17) >= '0' && *(txt + 17) <= '9')
1870 ;
1871 else
1872 return false;
1873 if (*(txt + 18) >= '0' && *(txt + 18) <= '9')
1874 ;
1875 else
1876 return false;
1877 return true;
1878 }
1879
Prepare()1880 void PostGISColumn::Prepare()
1881 {
1882 // determining the exact Column Data Type
1883 if (!Boolean && !Int8 && !UInt8 && !Int16 && !UInt16 && !Int32 && !UInt32
1884 && !Int64 && !Double && !Text && !Date && !DateTime && !Blob)
1885 {
1886 // testing for Geometry
1887 int type = PostGISHelper::DATA_TYPE_UNDEFINED;
1888 if ((Point + MultiPoint + LineString + MultiLineString + Polygon +
1889 MultiPolygon + GeometryCollection) > 0)
1890 type = PostGISHelper::DATA_TYPE_GEOMETRY;
1891 else
1892 {
1893 // surely not a Geometry: defaulting to TEXT
1894 DataType = PostGISHelper::DATA_TYPE_TEXT;
1895 return;
1896 }
1897 if (Point > 0 && !MultiPoint && !LineString && !MultiLineString
1898 && !Polygon && !MultiPolygon && !GeometryCollection)
1899 type = PostGISHelper::DATA_TYPE_POINT;
1900 if (MultiPoint > 0 && !LineString && !MultiLineString && !Polygon
1901 && !MultiPolygon && !GeometryCollection)
1902 type = PostGISHelper::DATA_TYPE_MULTIPOINT;
1903 if (!Point && !MultiPoint && LineString > 0 && !MultiLineString
1904 && !Polygon && !MultiPolygon && !GeometryCollection)
1905 type = PostGISHelper::DATA_TYPE_LINESTRING;
1906 if (!Point && !MultiPoint && MultiLineString > 0 && !Polygon
1907 && !MultiPolygon && !GeometryCollection)
1908 type = PostGISHelper::DATA_TYPE_MULTILINESTRING;
1909 if (!Point && !MultiPoint && !LineString && !MultiLineString
1910 && Polygon > 0 && !MultiPolygon && !GeometryCollection)
1911 type = PostGISHelper::DATA_TYPE_POLYGON;
1912 if (!Point && !MultiPoint && !LineString && !MultiLineString
1913 && MultiPolygon > 0 && !GeometryCollection)
1914 type = PostGISHelper::DATA_TYPE_MULTIPOLYGON;
1915 if (!Point && !MultiPoint && !LineString && !MultiLineString && !Polygon
1916 && !MultiPolygon && GeometryCollection > 0)
1917 type = PostGISHelper::DATA_TYPE_GEOMETRYCOLLECTION;
1918 if (type != PostGISHelper::DATA_TYPE_UNDEFINED)
1919 {
1920 if (Srid2 == INT_MIN && CoordDims2 == GAIA_UNKNOWN)
1921 {
1922 // ok, valid Geometry
1923 DataType = type;
1924 return;
1925 } else
1926 {
1927 // no, invalid Geometry
1928 DataType = PostGISHelper::DATA_TYPE_BLOB;
1929 return;
1930 }
1931 }
1932 DataType = PostGISHelper::DATA_TYPE_BLOB;
1933 return;
1934 }
1935
1936 if (Boolean > 0 && !Int8 && !UInt8 && !Int16 && !UInt16 && !Int32 && !UInt32
1937 && !Int64 && !Double && !Text && !Date && !DateTime && !Blob)
1938 {
1939 DataType = PostGISHelper::DATA_TYPE_BOOLEAN;
1940 return;
1941 }
1942 if ((Int8 > 0 && !UInt8) && !Int16 && !UInt16 && !Int32 && !UInt32 && !Int64
1943 && !Double && !Text && !Date && !DateTime && !Blob)
1944 {
1945 DataType = PostGISHelper::DATA_TYPE_INT8;
1946 return;
1947 }
1948 if (UInt8 > 0 && !Int16 && !UInt16 && !Int32 && !UInt32 && !Int64 && !Double
1949 && !Text && !Date && !DateTime && !Blob)
1950 {
1951 DataType = PostGISHelper::DATA_TYPE_UINT8;
1952 return;
1953 }
1954 if ((Int16 > 0 && !UInt16) && !Int32 && !UInt32 && !Int64 && !Double && !Text
1955 && !Date && !DateTime && !Blob)
1956 {
1957 DataType = PostGISHelper::DATA_TYPE_INT16;
1958 return;
1959 }
1960 if (UInt16 > 0 && !Int32 && !UInt32 && !Int64 && !Double && !Text && !Date
1961 && !DateTime && !Blob)
1962 {
1963 DataType = PostGISHelper::DATA_TYPE_UINT16;
1964 return;
1965 }
1966 if ((Int32 > 0 && !UInt32) && !Int64 && !Double && !Text && !Date && !DateTime
1967 && !Blob)
1968 {
1969 DataType = PostGISHelper::DATA_TYPE_INT32;
1970 return;
1971 }
1972 if (UInt32 > 0 && !Int64 && !Double && !Text && !Date && !DateTime && !Blob)
1973 {
1974 DataType = PostGISHelper::DATA_TYPE_UINT32;
1975 return;
1976 }
1977 if (Int64 > 0 && !Double && !Text && !Date && !DateTime && !Blob)
1978 {
1979 DataType = PostGISHelper::DATA_TYPE_INT64;
1980 return;
1981 }
1982 if (Double > 0 && !Text && !Date && !DateTime && !Blob)
1983 {
1984 DataType = PostGISHelper::DATA_TYPE_DOUBLE;
1985 return;
1986 }
1987 if (!Boolean && !Int8 && !UInt8 && !Int16 && !UInt16 && !Int32 && !UInt32
1988 && !Int64 && !Double && Text > 0 && !Date && !DateTime && !Blob)
1989 {
1990 DataType = PostGISHelper::DATA_TYPE_TEXT;
1991 return;
1992 }
1993 if (!Boolean && !Int8 && !UInt8 && !Int16 && !UInt16 && !Int32 && !UInt32
1994 && !Int64 && !Double && !Text && Date > 0 && !DateTime && !Blob)
1995 {
1996 DataType = PostGISHelper::DATA_TYPE_DATE;
1997 return;
1998 }
1999 if (!Boolean && !Int8 && !UInt8 && !Int16 && !UInt16 && !Int32 && !UInt32
2000 && !Int64 && !Double && !Text && DateTime > 0 && !Blob)
2001 {
2002 DataType = PostGISHelper::DATA_TYPE_DATETIME;
2003 return;
2004 }
2005 if (!Boolean && !Int8 && !UInt8 && !Int16 && !UInt16 && !Int32 && !UInt32
2006 && !Int64 && !Double && !Text && !Date && !DateTime && Blob > 0)
2007 {
2008 DataType = PostGISHelper::DATA_TYPE_BLOB;
2009 return;
2010 }
2011 if ((Boolean + Int8 + UInt8 + Int16 + UInt16 + Int32 + UInt32 + Int64 +
2012 Double + Text + Date + DateTime) > 0 && !Blob)
2013 {
2014 DataType = PostGISHelper::DATA_TYPE_TEXT;
2015 return;
2016 }
2017 if (Null > 0)
2018 Nullable = true;
2019 // unable to establish a valid Data Type
2020 DataType = PostGISHelper::DATA_TYPE_UNDEFINED;
2021 }
2022
IsGeometry()2023 bool PostGISColumn::IsGeometry()
2024 {
2025 // does this column corresponds to some Geometry ?
2026 switch (DataType)
2027 {
2028 case PostGISHelper::DATA_TYPE_POINT:
2029 case PostGISHelper::DATA_TYPE_LINESTRING:
2030 case PostGISHelper::DATA_TYPE_POLYGON:
2031 case PostGISHelper::DATA_TYPE_MULTIPOINT:
2032 case PostGISHelper::DATA_TYPE_MULTILINESTRING:
2033 case PostGISHelper::DATA_TYPE_MULTIPOLYGON:
2034 case PostGISHelper::DATA_TYPE_GEOMETRYCOLLECTION:
2035 case PostGISHelper::DATA_TYPE_GEOMETRY:
2036 return true;
2037 }
2038 return false;
2039 }
2040
~PostGISIndex()2041 PostGISIndex::~PostGISIndex()
2042 {
2043 // destructor
2044 PostGISIndexField *pI;
2045 PostGISIndexField *pIn;
2046 pI = First;
2047 while (pI)
2048 {
2049 pIn = pI->GetNext();
2050 delete pI;
2051 pI = pIn;
2052 }
2053 }
2054
AddField(int seq,PostGISColumn * col)2055 void PostGISIndex::AddField(int seq, PostGISColumn * col)
2056 {
2057 // adding a Field into this Index
2058 PostGISIndexField *field = new PostGISIndexField(seq, col);
2059 if (First == NULL)
2060 First = field;
2061 if (Last != NULL)
2062 Last->SetNext(field);
2063 Last = field;
2064 }
2065
PostGISHelper()2066 PostGISHelper::PostGISHelper()
2067 {
2068 // constructor
2069 DumbName = wxT("DumbColumn");
2070 Count = 0;
2071 Columns = NULL;
2072 FirstIdx = NULL;
2073 LastIdx = NULL;
2074 Autoincrement = false;
2075 }
2076
~PostGISHelper()2077 PostGISHelper::~PostGISHelper()
2078 {
2079 // destructor
2080 PostGISIndex *pI;
2081 PostGISIndex *pIn;
2082 if (Columns != NULL)
2083 delete[]Columns;
2084 pI = FirstIdx;
2085 while (pI)
2086 {
2087 pIn = pI->GetNext();
2088 delete pI;
2089 pI = pIn;
2090 }
2091 }
2092
Alloc(int count)2093 void PostGISHelper::Alloc(int count)
2094 {
2095 //
2096 // allocating the Columns array
2097 //
2098 Count = count;
2099 if (Columns != NULL)
2100 delete[]Columns;
2101 Columns = new PostGISColumn[Count];
2102 }
2103
SetName(int pos,const char * name)2104 void PostGISHelper::SetName(int pos, const char *name)
2105 {
2106 //
2107 // setting a Column Name
2108 //
2109 if (pos >= 0 && pos < Count)
2110 {
2111 wxString Name = wxString::FromUTF8(name);
2112 Columns[pos].SetName(Name);
2113 }
2114 }
2115
Eval(int pos,sqlite3_int64 val)2116 void PostGISHelper::Eval(int pos, sqlite3_int64 val)
2117 {
2118 //
2119 // evaluating an INT value
2120 //
2121 if (pos >= 0 && pos < Count)
2122 {
2123 bool skip = false;
2124 if (val == 1 || val == 0)
2125 {
2126 Columns[pos].IncrBoolean();
2127 skip = true;
2128 }
2129 if (!skip)
2130 {
2131 if (val >= SCHAR_MIN && val <= SCHAR_MAX)
2132 {
2133 Columns[pos].IncrInt8();
2134 skip = true;
2135 }
2136 if (val > SCHAR_MAX && val <= UCHAR_MAX)
2137 {
2138 Columns[pos].IncrUInt8();
2139 skip = true;
2140 }
2141 }
2142 if (!skip)
2143 {
2144 if (val >= SHRT_MIN && val <= SHRT_MAX)
2145 {
2146 Columns->IncrInt16();
2147 skip = true;
2148 }
2149 if (val > SHRT_MAX && val <= USHRT_MAX)
2150 {
2151 Columns[pos].IncrUInt16();
2152 skip = true;
2153 }
2154 }
2155 if (!skip)
2156 {
2157 if (val >= INT_MIN && val <= INT_MAX)
2158 {
2159 Columns[pos].IncrInt32();
2160 skip = true;
2161 }
2162 if (val > INT_MAX && val <= UINT_MAX)
2163 {
2164 Columns[pos].IncrUInt32();
2165 skip = true;
2166 }
2167 }
2168 if (!skip)
2169 Columns[pos].IncrInt64();
2170 }
2171 }
2172
Eval(int pos,double val)2173 void PostGISHelper::Eval(int pos, double val)
2174 {
2175 //
2176 // evaluating a DOUBLE value
2177 //
2178 if (val > 0)
2179 val = 0.0; // suppressing stupid warnings
2180 if (pos >= 0 && pos < Count)
2181 Columns[pos].IncrDouble();
2182 }
2183
Eval(int pos,const char * val)2184 void PostGISHelper::Eval(int pos, const char *val)
2185 {
2186 //
2187 // evaluating a TEXT value
2188 //
2189 if (pos >= 0 && pos < Count)
2190 {
2191 int len = strlen(val);
2192 if (Columns[pos].IsDate(val) == true)
2193 Columns[pos].IncrDate();
2194 else if (Columns[pos].IsDateTime(val) == true)
2195 Columns[pos].IncrDateTime();
2196 else
2197 Columns[pos].IncrText(len);
2198 }
2199 }
2200
Eval(int pos,gaiaGeomCollPtr geom)2201 void PostGISHelper::Eval(int pos, gaiaGeomCollPtr geom)
2202 {
2203 //
2204 // evaluating a Geometry value
2205 //
2206 if (pos >= 0 && pos < Count)
2207 {
2208 switch (geom->DeclaredType)
2209 {
2210 case GAIA_POINT:
2211 Columns[pos].IncrPoint(geom->Srid, geom->DimensionModel);
2212 break;
2213 case GAIA_LINESTRING:
2214 Columns[pos].IncrLineString(geom->Srid, geom->DimensionModel);
2215 break;
2216 case GAIA_POLYGON:
2217 Columns[pos].IncrPolygon(geom->Srid, geom->DimensionModel);
2218 break;
2219 case GAIA_MULTIPOINT:
2220 Columns[pos].IncrMultiPoint(geom->Srid, geom->DimensionModel);
2221 break;
2222 case GAIA_MULTILINESTRING:
2223 Columns[pos].IncrMultiLineString(geom->Srid, geom->DimensionModel);
2224 break;
2225 case GAIA_MULTIPOLYGON:
2226 Columns[pos].IncrMultiPolygon(geom->Srid, geom->DimensionModel);
2227 break;
2228 case GAIA_GEOMETRYCOLLECTION:
2229 Columns[pos].IncrGeometryCollection(geom->Srid,
2230 geom->DimensionModel);
2231 break;
2232 };
2233 }
2234 }
2235
EvalBlob(int pos)2236 void PostGISHelper::EvalBlob(int pos)
2237 {
2238 //
2239 // evaluating a BLOB value
2240 //
2241 if (pos >= 0 && pos < Count)
2242 Columns[pos].IncrBlob();
2243 }
2244
Eval(int pos)2245 void PostGISHelper::Eval(int pos)
2246 {
2247 //
2248 // evaluating a NULL value
2249 //
2250 if (pos >= 0 && pos < Count)
2251 Columns[pos].IncrNull();
2252 }
2253
GetName(int pos,bool to_lower)2254 wxString & PostGISHelper::GetName(int pos, bool to_lower)
2255 {
2256 //
2257 // return a Column name [by relative position]
2258 //
2259 wxString name;
2260 if (pos >= 0 && pos < Count)
2261 name = Columns[pos].GetName();
2262 else
2263 name = wxT("DumbColumn");
2264 if (to_lower)
2265 DumbName = name.MakeLower();
2266 else
2267 DumbName = name;
2268 return DumbName;
2269 }
2270
Prepare()2271 void PostGISHelper::Prepare()
2272 {
2273 //
2274 // setting PostGIS data types for each Column
2275 //
2276 int i;
2277 for (i = 0; i < Count; i++)
2278 Columns[i].Prepare();
2279 }
2280
IsSingleFieldPrimaryKey()2281 bool PostGISHelper::IsSingleFieldPrimaryKey()
2282 {
2283 // testing if there is a single column PK
2284 int count = 0;
2285 int i;
2286 for (i = 0; i < Count; i++)
2287 {
2288 if (Columns[i].IsPrimaryKey() == true)
2289 count++;
2290 }
2291 if (count == 1)
2292 return true;
2293 return false;
2294 }
2295
IsGeometry(int pos)2296 bool PostGISHelper::IsGeometry(int pos)
2297 {
2298 //
2299 // checking if a column is of any Geometry type
2300 //
2301 if (pos >= 0 && pos < Count)
2302 return Columns[pos].IsGeometry();
2303 return false;
2304 }
2305
GetDataType(int pos)2306 int PostGISHelper::GetDataType(int pos)
2307 {
2308 //
2309 // return the data type for some column
2310 //
2311 if (pos >= 0 && pos < Count)
2312 return Columns[pos].GetDataType();
2313 return DATA_TYPE_UNDEFINED;
2314 }
2315
GetSrid(int pos)2316 int PostGISHelper::GetSrid(int pos)
2317 {
2318 //
2319 // return the SRID for some Geometry column
2320 //
2321 if (pos >= 0 && pos < Count)
2322 return Columns[pos].GetSrid();
2323 return -1;
2324 }
2325
GetCoordDims(int pos)2326 int PostGISHelper::GetCoordDims(int pos)
2327 {
2328 //
2329 // return the Coord Dimensions for some Geometry column
2330 //
2331 if (pos >= 0 && pos < Count)
2332 return Columns[pos].GetCoordDims();
2333 return GAIA_XY;
2334 }
2335
SetColumn(wxString & name,bool isNull,bool isPKey)2336 void PostGISHelper::SetColumn(wxString & name, bool isNull, bool isPKey)
2337 {
2338 //
2339 // setting up Column params
2340 //
2341 int i;
2342 for (i = 0; i < Count; i++)
2343 {
2344 if (Columns[i].GetName() == name)
2345 {
2346 if (isNull)
2347 Columns[i].SetNotNull();
2348 if (isPKey)
2349 {
2350 Columns[i].SetPrimaryKey();
2351 }
2352 break;
2353 }
2354 }
2355 }
2356
GetDataType(int pos,char * definition)2357 void PostGISHelper::GetDataType(int pos, char *definition)
2358 {
2359 //
2360 // return the data definition for some column
2361 //
2362 if (pos >= 0 && pos < Count)
2363 {
2364 int len;
2365 int data_type = Columns[pos].GetDataType();
2366 switch (data_type)
2367 {
2368 case DATA_TYPE_BOOLEAN:
2369 case DATA_TYPE_INT8:
2370 case DATA_TYPE_UINT8:
2371 case DATA_TYPE_INT16:
2372 strcpy(definition, "smallint");
2373 break;
2374 case DATA_TYPE_UINT16:
2375 case DATA_TYPE_INT32:
2376 strcpy(definition, "integer");
2377 break;
2378 case DATA_TYPE_UINT32:
2379 case DATA_TYPE_INT64:
2380 strcpy(definition, "bigint");
2381 break;
2382 case DATA_TYPE_DOUBLE:
2383 strcpy(definition, "double precision");
2384 break;
2385 case DATA_TYPE_DATE:
2386 strcpy(definition, "date");
2387 break;
2388 case DATA_TYPE_DATETIME:
2389 strcpy(definition, "timestamp");
2390 break;
2391 case DATA_TYPE_TEXT:
2392 len = Columns[pos].GetMaxTextLen();
2393 if (len <= 255)
2394 {
2395 sprintf(definition, "character varying(%d)",
2396 (len == 0) ? 255 : len);
2397 } else
2398 strcpy(definition, "text");
2399 break;
2400 case DATA_TYPE_BLOB:
2401 strcpy(definition, "bytea");
2402 break;
2403 default:
2404 strcpy(definition, "unknownType");
2405 };
2406 if (Columns[pos].IsNotNull() == true)
2407 strcat(definition, " NOT NULL");
2408 if (Columns[pos].IsPrimaryKey() == true
2409 && IsSingleFieldPrimaryKey() == true)
2410 {
2411 if (IsAutoincrement() == true)
2412 strcpy(definition, "SERIAL");
2413 else
2414 {
2415 // attempting to promote any PK as int-4
2416 switch (data_type)
2417 {
2418 case DATA_TYPE_BOOLEAN:
2419 case DATA_TYPE_INT8:
2420 case DATA_TYPE_UINT8:
2421 case DATA_TYPE_INT16:
2422 case DATA_TYPE_UINT16:
2423 case DATA_TYPE_INT32:
2424 strcpy(definition, "integer");
2425 break;
2426 }
2427 }
2428 strcat(definition, " PRIMARY KEY");
2429 }
2430 return;
2431 }
2432 *definition = '\0';
2433 }
2434
OutputBooleanValue(FILE * out,sqlite3_int64 value)2435 void PostGISHelper::OutputBooleanValue(FILE * out, sqlite3_int64 value)
2436 {
2437 // outputting a BOOLEAN value
2438 if (value == 0)
2439 fprintf(out, "0");
2440 else
2441 fprintf(out, "1");
2442 }
2443
OutputValue(FILE * out,sqlite3_int64 value)2444 void PostGISHelper::OutputValue(FILE * out, sqlite3_int64 value)
2445 {
2446 // outputting an INTEGER value
2447 #if defined(_WIN32) || defined(__MINGW32__)
2448 // CAVEAT - M$ runtime doesn't supports %lld for 64 bits
2449 fprintf(out, "%I64d", value);
2450 #else
2451 fprintf(out, "%lld", value);
2452 #endif
2453 }
2454
OutputValue(FILE * out,double value)2455 void PostGISHelper::OutputValue(FILE * out, double value)
2456 {
2457 // outputting a DOUBLE value
2458 fprintf(out, "%1.15f", value);
2459 }
2460
OutputValue(FILE * out,const char * value)2461 void PostGISHelper::OutputValue(FILE * out, const char *value)
2462 {
2463 // outputting a TEXT value
2464 const char *p = value;
2465 fputc('\'', out);
2466 while (*p != '\0')
2467 {
2468 if (*p == '\'')
2469 fputc('\'', out);
2470 fputc(*p++, out);
2471 }
2472 fputc('\'', out);
2473 }
2474
OutputValue(FILE * out,gaiaGeomCollPtr geom)2475 void PostGISHelper::OutputValue(FILE * out, gaiaGeomCollPtr geom)
2476 {
2477 // outputting a GEOMETRY EWKB value
2478 gaiaOutBuffer out_buf;
2479 gaiaOutBufferInitialize(&out_buf);
2480 gaiaToEWKB(&out_buf, geom);
2481 if (out_buf.Error || out_buf.Buffer == NULL)
2482 fprintf(out, "NULL");
2483 else
2484 {
2485 int len = out_buf.WriteOffset;
2486 int i;
2487 fputc('\'', out);
2488 for (i = 0; i < len; i++)
2489 fputc(out_buf.Buffer[i], out);
2490 fputc('\'', out);
2491 }
2492 gaiaOutBufferReset(&out_buf);
2493 }
2494
OutputValue(FILE * out,const unsigned char * value,int len)2495 void PostGISHelper::OutputValue(FILE * out, const unsigned char *value, int len)
2496 {
2497 // outputting a BLOB value as BYTEA
2498 int i;
2499 const char *in = (const char *) value;
2500
2501 // encoding a BLOB as BYTEA [escaped octects]
2502 putc('E', out);
2503 putc('\'', out);
2504 for (i = 0; i < len; i++)
2505 {
2506 if (in[i] <= 31 || in[i] >= 127 || in[i] == '\'' || in[i] == '\\')
2507 fprintf(out, "\\\\%03o", in[i]);
2508 else
2509 putc(in[i], out);
2510 }
2511 putc('\'', out);
2512 }
2513
AddIndex(wxString & Name)2514 PostGISIndex *PostGISHelper::AddIndex(wxString & Name)
2515 {
2516 // adding a Primary Key to this Table
2517 wxString name = wxT("pk_") + Name;
2518 PostGISIndex *idx = new PostGISIndex(name);
2519 if (FirstIdx == NULL)
2520 FirstIdx = idx;
2521 if (LastIdx != NULL)
2522 LastIdx->SetNext(idx);
2523 LastIdx = idx;
2524 return idx;
2525 }
2526
AddIndex(wxString & name,bool unique)2527 PostGISIndex *PostGISHelper::AddIndex(wxString & name, bool unique)
2528 {
2529 // adding an Index to this Table
2530 PostGISIndex *idx = FirstIdx;
2531 while (idx)
2532 {
2533 if (idx->GetName() == name)
2534 {
2535 // already inserted
2536 return idx;
2537 }
2538 idx = idx->GetNext();
2539 }
2540
2541 idx = new PostGISIndex(name, unique);
2542 if (FirstIdx == NULL)
2543 FirstIdx = idx;
2544 if (LastIdx != NULL)
2545 LastIdx->SetNext(idx);
2546 LastIdx = idx;
2547 return idx;
2548 }
2549
Find(wxString & name)2550 PostGISColumn *PostGISHelper::Find(wxString & name)
2551 {
2552 // retrieving a Column by name
2553 int i;
2554 for (i = 0; i < Count; i++)
2555 {
2556 PostGISColumn *pC = Columns + i;
2557 if (pC->GetName() == name)
2558 return pC;
2559 }
2560 return NULL;
2561 }
2562
ExpandIndexFields(MyFrame * MainFrame,PostGISIndex * index,wxString & idxName)2563 void PostGISHelper::ExpandIndexFields(MyFrame * MainFrame, PostGISIndex * index,
2564 wxString & idxName)
2565 {
2566 //
2567 // expanding the Index Fields
2568 //
2569 int i;
2570 char **results;
2571 int rows;
2572 int columns;
2573 char *errMsg = NULL;
2574 char *name;
2575 int seq;
2576 wxString Name;
2577 wxString sql;
2578 char xname[1024];
2579 int ret;
2580
2581 sql = wxT("PRAGMA index_info(");
2582 strcpy(xname, idxName.ToUTF8());
2583 MainFrame->DoubleQuotedSql(xname);
2584 sql += wxString::FromUTF8(xname);
2585 sql += wxT(")");
2586 ret = sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(), &results,
2587 &rows, &columns, &errMsg);
2588 if (ret != SQLITE_OK)
2589 {
2590 wxMessageBox(wxT("PostGIS SQL dump error: ") + wxString::FromUTF8(errMsg),
2591 wxT("spatialite_gui"), wxOK | wxICON_ERROR, MainFrame);
2592 sqlite3_free(errMsg);
2593 return;
2594 }
2595 if (rows < 1)
2596 ;
2597 else
2598 {
2599 for (i = 1; i <= rows; i++)
2600 {
2601 seq = atoi(results[(i * columns) + 0]);
2602 name = results[(i * columns) + 2];
2603 Name = wxString::FromUTF8(name);
2604 PostGISColumn *col = Find(Name);
2605 index->AddField(seq, col);
2606 }
2607 }
2608 sqlite3_free_table(results);
2609 }
2610
GetKeys(MyFrame * MainFrame,wxString & tableName)2611 void PostGISHelper::GetKeys(MyFrame * MainFrame, wxString & tableName)
2612 {
2613 //
2614 // identifying the Primary Key (and any Index)
2615 //
2616 int i;
2617 char **results;
2618 int rows;
2619 int columns;
2620 char *errMsg = NULL;
2621 char *name;
2622 wxString Name;
2623 bool pKey;
2624 bool notNull;
2625 bool unique;
2626 wxString sql;
2627 int ret;
2628 char xname[1024];
2629
2630 // retrieving the Table Columns
2631 sql = wxT("PRAGMA table_info(");
2632 strcpy(xname, tableName.ToUTF8());
2633 MainFrame->DoubleQuotedSql(xname);
2634 sql += wxString::FromUTF8(xname);
2635 sql += wxT(")");
2636 ret = sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(), &results,
2637 &rows, &columns, &errMsg);
2638 if (ret != SQLITE_OK)
2639 {
2640 wxMessageBox(wxT("PostGIS SQL dump error: ") + wxString::FromUTF8(errMsg),
2641 wxT("spatialite_gui"), wxOK | wxICON_ERROR, MainFrame);
2642 sqlite3_free(errMsg);
2643 return;
2644 }
2645 if (rows < 1)
2646 ;
2647 else
2648 {
2649 for (i = 1; i <= rows; i++)
2650 {
2651 name = results[(i * columns) + 1];
2652 if (atoi(results[(i * columns) + 3]) == 0)
2653 notNull = false;
2654 else
2655 notNull = true;
2656 if (atoi(results[(i * columns) + 5]) == 0)
2657 pKey = false;
2658 else
2659 pKey = true;
2660 Name = wxString::FromUTF8(name);
2661 SetColumn(Name, notNull, pKey);
2662 }
2663 }
2664 sqlite3_free_table(results);
2665
2666 // retrieving any Index bounded to this Table
2667 sql = wxT("PRAGMA index_list(");
2668 strcpy(xname, tableName.ToUTF8());
2669 MainFrame->DoubleQuotedSql(xname);
2670 sql += wxString::FromUTF8(xname);
2671 sql += wxT(")");
2672 ret = sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(), &results,
2673 &rows, &columns, &errMsg);
2674 if (ret != SQLITE_OK)
2675 {
2676 wxMessageBox(wxT("PostGIS SQL dump error: ") + wxString::FromUTF8(errMsg),
2677 wxT("spatialite_gui"), wxOK | wxICON_ERROR, MainFrame);
2678 sqlite3_free(errMsg);
2679 return;
2680 }
2681 if (rows < 1)
2682 ;
2683 else
2684 {
2685 for (i = 1; i <= rows; i++)
2686 {
2687 name = results[(i * columns) + 1];
2688 if (atoi(results[(i * columns) + 2]) == 0)
2689 unique = false;
2690 else
2691 unique = true;
2692 Name = wxString::FromUTF8(name);
2693 PostGISIndex *index;
2694 if (Name.StartsWith(wxT("sqlite_autoindex_")) == true)
2695 index = AddIndex(tableName);
2696 else
2697 index = AddIndex(Name, unique);
2698 ExpandIndexFields(MainFrame, index, Name);
2699 }
2700 }
2701 sqlite3_free_table(results);
2702
2703 if (IsSingleFieldPrimaryKey() == true)
2704 {
2705 // checking for AUTOINCREMENT
2706 sql =
2707 wxT("SELECT Count(*) FROM sqlite_sequence WHERE Lower(name) = Lower('");
2708 strcpy(xname, tableName.ToUTF8());
2709 MainFrame->CleanSqlString(xname);
2710 sql += wxString::FromUTF8(xname);
2711 sql += wxT("')");
2712 ret = sqlite3_get_table(MainFrame->GetSqlite(), sql.ToUTF8(), &results,
2713 &rows, &columns, &errMsg);
2714 if (ret != SQLITE_OK)
2715 return;
2716 if (rows < 1)
2717 ;
2718 else
2719 {
2720 int cnt = 0;
2721 for (i = 1; i <= rows; i++)
2722 {
2723 cnt = atoi(results[(i * columns) + 0]);
2724 }
2725 if (cnt)
2726 Autoincrement = true;
2727 }
2728 sqlite3_free_table(results);
2729 }
2730 }
2731
TopologyItem(wxString & name)2732 TopologyItem::TopologyItem(wxString & name)
2733 {
2734 // constructor
2735 Name = name;
2736 Table = false;
2737 View = false;
2738 Next = NULL;
2739 }
2740
TopologySet()2741 TopologySet::TopologySet()
2742 {
2743 // constructor
2744 Srid = 0;
2745 First = NULL;
2746 Last = NULL;
2747 }
2748
~TopologySet()2749 TopologySet::~TopologySet()
2750 {
2751 // destructor
2752 TopologyItem *pT;
2753 TopologyItem *pTn;
2754 pT = First;
2755 while (pT)
2756 {
2757 pTn = pT->GetNext();
2758 delete pT;
2759 pT = pTn;
2760 }
2761 }
2762
SetCoordDims(const char * coords)2763 void TopologySet::SetCoordDims(const char *coords)
2764 {
2765 // setting CoordDims
2766 CoordDims = wxString::FromUTF8(coords);
2767 }
2768
Add(const char * name,bool table,bool view)2769 void TopologySet::Add(const char *name, bool table, bool view)
2770 {
2771 // adding a Table/View
2772 wxString xName = wxString::FromUTF8(name);
2773 TopologyItem *pT = new TopologyItem(xName);
2774 if (table == true)
2775 pT->SetTable();
2776 if (view == true)
2777 pT->SetView();
2778 if (First == NULL)
2779 First = pT;
2780 if (Last != NULL)
2781 Last->SetNext(pT);
2782 Last = pT;
2783 }
2784
AddTable(wxString & name)2785 void TopologySet::AddTable(wxString & name)
2786 {
2787 // adding a Table
2788 TopologyItem *pT = new TopologyItem(name);
2789 pT->SetTable();
2790 if (First == NULL)
2791 First = pT;
2792 if (Last != NULL)
2793 Last->SetNext(pT);
2794 Last = pT;
2795 }
2796
AddView(wxString & name)2797 void TopologySet::AddView(wxString & name)
2798 {
2799 // adding a View
2800 TopologyItem *pT = new TopologyItem(name);
2801 pT->SetView();
2802 if (First == NULL)
2803 First = pT;
2804 if (Last != NULL)
2805 Last->SetNext(pT);
2806 Last = pT;
2807 }
2808
CheckPrefix()2809 bool TopologySet::CheckPrefix()
2810 {
2811 // attempting to check (and validate) Prefix
2812 int count = 0;
2813 int errors = 0;
2814 wxString prefix;
2815 TopologyItem *pT = First;
2816 while (pT != NULL)
2817 {
2818 if (pT->GetName().EndsWith(wxT("nodes"), &prefix) == true)
2819 break;
2820 pT = pT->GetNext();
2821 }
2822 if (prefix.Len() == 0)
2823 return false;
2824 pT = First;
2825 while (pT != NULL)
2826 {
2827 if (pT->GetName().StartsWith(prefix) == true)
2828 count++;
2829 else
2830 errors++;
2831 pT = pT->GetNext();
2832 }
2833 if (count > 1 && errors == 0)
2834 {
2835 Prefix = prefix;
2836 return true;
2837 }
2838 return false;
2839 }
2840