1 //////////////////////////////////////////////////////////////////////////
2 //
3 // pgAdmin III - PostgreSQL Tools
4 //
5 // Copyright (C) 2002 - 2016, The pgAdmin Development Team
6 // This software is released under the PostgreSQL Licence
7 //
8 // gqbQueryObjs.cpp - All objects used by a model of a query in the MVC Pattern model.
9 //
10 //////////////////////////////////////////////////////////////////////////
11
12 #include "pgAdmin3.h"
13
14 // wxWindows headers
15 #include <wx/wx.h>
16 #include <wx/textctrl.h>
17 #include <wx/regex.h>
18
19 // App headers
20 #include "gqb/gqbTable.h"
21 #include "gqb/gqbColumn.h"
22 #include "gqb/gqbQueryObjs.h"
23 #include "gqb/gqbObjectCollection.h"
24 #include "gqb/gqbViewPanels.h"
25
26 //
27 // Collections of Tables inside a Query, data structured used for query storage & later generation of SQL sentence
28 //
29
gqbQueryObjs()30 gqbQueryObjs::gqbQueryObjs()
31 : gqbObjectCollection(wxT(""), NULL, NULL)
32 {
33 setType(GQB_QUERY);
34 }
35
36
addTable(gqbQueryObject * mtable)37 void gqbQueryObjs::addTable(gqbQueryObject *mtable)
38 {
39 this->addObject(mtable);
40 }
41
42
removeTable(gqbQueryObject * mtable)43 void gqbQueryObjs::removeTable(gqbQueryObject *mtable)
44 {
45 this->removeObject(mtable);
46 }
47
48
createQueryIterator()49 gqbIteratorBase *gqbQueryObjs::createQueryIterator()
50 {
51 return this->createIterator();
52 }
53
createDownQueryIterator()54 gqbIteratorBase *gqbQueryObjs::createDownQueryIterator()
55 {
56 return this->createDownIterator();
57 }
58
59
tablesCount()60 int gqbQueryObjs::tablesCount()
61 {
62 return this->countObjects();
63 }
64
65
removeAllQueryObjs()66 void gqbQueryObjs::removeAllQueryObjs()
67 {
68 this->removeAll();
69 }
70
71
72 //
73 // An Object inside a query (A table object in the query), not equal to gqbTable
74 // Reason: Sometimes a table can be used twice or more times in a query with different columns selected
75 // Because this we can not use directly the base table object
76
gqbQueryObject(gqbTable * table)77 gqbQueryObject::gqbQueryObject(gqbTable *table)
78 : gqbObjectCollection(table->getName(), table, table->getConnection())
79 {
80 selected = false;
81 parent = table;
82
83 //GQB-TODO: Calculate a good initial position
84 position.x = 20;
85 position.y = 20;
86 haveJoins = false;
87 haveRegisteredJoins = false;
88 registeredCollection = NULL;
89 joinsCollection = NULL;
90 setType(GQB_QUERYOBJ);
91 }
92
93
94 // Destructor must empty collection to don't allow deleting of column items from tree
95 // because this collection doesn't owns it, and then shouldn't destroy it.
~gqbQueryObject()96 gqbQueryObject::~gqbQueryObject()
97 {
98 this->removeAll();
99
100 // Remove item registered at this Query Object
101 gqbQueryJoin *tmp;
102 if(registeredCollection)
103 {
104 gqbIteratorBase *r = createRegJoinsIterator();
105 while(r->HasNext())
106 {
107 tmp = (gqbQueryJoin *)r->Next();
108 this->unregisterJoin(tmp, true); // remove and unregister every join in every query object
109 // which have registered at this query object
110
111 // On each iteration the structure of iterator change because
112 // modified his own collection & should be reset
113 r->ResetIterator();
114 }
115 delete r;
116 }
117
118 if(joinsCollection)
119 {
120 gqbIteratorBase *j = createJoinsIterator();
121 while(j->HasNext())
122 {
123 tmp = (gqbQueryJoin *)j->Next();
124 this->removeJoin(tmp, true); // removes & unregister Join which have like origin this
125 // query object
126 // On each iteration the structure of iterator change because
127 // modified his own collection & should be reset
128 j->ResetIterator();
129 }
130 delete j;
131
132 }
133
134 // removeJoin & unregisterJoin delete the collections where there aren't any items inside.
135 }
136
137
setSelected(bool value)138 void gqbQueryObject::setSelected(bool value)
139 {
140 this->selected = value;
141 }
142
143
getSelected()144 bool gqbQueryObject::getSelected()
145 {
146 return this->selected;
147 }
148
149
setWidth(int value)150 void gqbQueryObject::setWidth(int value)
151 {
152 width = value;
153 }
154
155
getWidth()156 int gqbQueryObject::getWidth()
157 {
158 return width;
159 }
160
161
setHeight(int value)162 void gqbQueryObject::setHeight(int value)
163 {
164 height = value;
165 }
166
167
getHeight()168 int gqbQueryObject::getHeight()
169 {
170 return height;
171 }
172
173
addColumn(gqbColumn * column)174 void gqbQueryObject::addColumn(gqbColumn *column)
175 {
176 this->addObject(column);
177 }
178
179
removeColumn(gqbColumn * column)180 void gqbQueryObject::removeColumn(gqbColumn *column)
181 {
182 this->removeObject(column);
183 }
184
185
existsColumn(gqbColumn * column)186 bool gqbQueryObject::existsColumn(gqbColumn *column)
187 {
188 return this->existsObject(column);
189 }
190
191
createQueryTableIterator()192 gqbIteratorBase *gqbQueryObject::createQueryTableIterator()
193 {
194 return this->createIterator();
195 }
196
197
createJoinsIterator()198 gqbIteratorBase *gqbQueryObject::createJoinsIterator()
199 {
200 return joinsCollection->createIterator();
201 }
202
203
createRegJoinsIterator()204 gqbIteratorBase *gqbQueryObject::createRegJoinsIterator()
205 {
206 return registeredCollection->createIterator();
207 }
208
209
210 // Create a Join from this table [owner] column to other table [observable] column
addJoin(gqbQueryObject * owner,gqbQueryObject * observable,gqbColumn * source,gqbColumn * destination,type_Join kind)211 gqbQueryJoin *gqbQueryObject::addJoin(gqbQueryObject *owner, gqbQueryObject *observable, gqbColumn *source, gqbColumn *destination, type_Join kind)
212 {
213 if(!haveJoins)
214 {
215 implementationj = new gqbArrayCollection();
216 joinsCollection = new gqbCollection(implementationj);
217 haveJoins = true;
218 }
219
220 gqbQueryJoin *join = new gqbQueryJoin(owner, observable, source, destination, kind);
221 joinsCollection->addItem(join);
222 observable->registerJoin(join);
223 return join;
224 }
225
226
227 // Remove the join from this query object [source table]
removeJoin(gqbQueryJoin * join,bool unRegister=false)228 void gqbQueryObject::removeJoin(gqbQueryJoin *join, bool unRegister = false)
229 {
230 // Notify to observable that the join this object owns will be removed & then remove the join
231 if(unRegister)
232 join->getDestQTable()->unregisterJoin(join, false);
233 joinsCollection->removeItem(join);
234 if(join)
235 delete join; // Join can be only delete Here by his owner
236
237 if(joinsCollection->count() <= 0)
238 {
239 delete joinsCollection; // implementation it's delete too inside collection.
240 haveJoins = false;
241 joinsCollection = NULL;
242 }
243 }
244
245
246 // Register a Join created from other table [source] to this table [destination]
registerJoin(gqbQueryJoin * join)247 void gqbQueryObject::registerJoin(gqbQueryJoin *join)
248 {
249 if(!haveRegisteredJoins)
250 {
251 implementationr = new gqbArrayCollection();
252 registeredCollection = new gqbCollection(implementationr);
253 haveRegisteredJoins = true;
254 }
255 registeredCollection->addItem(join);
256 }
257
258
259 // Unregister a Join create from other table [source] to this table [destination] delete the join if need it..
unregisterJoin(gqbQueryJoin * join,bool removeIt=false)260 void gqbQueryObject::unregisterJoin(gqbQueryJoin *join, bool removeIt = false)
261 {
262 // Notify to source/owner object of join about join removing & then remove
263 registeredCollection->removeItem(join);
264 if(removeIt)
265 join->getSourceQTable()->removeJoin(join, false);
266 if(registeredCollection->count() <= 0)
267 {
268 delete registeredCollection; //implementation it's delete too inside collection.
269 haveRegisteredJoins = false;
270 registeredCollection = NULL;
271 }
272 }
273
274
getColumnIndex(gqbColumn * column)275 int gqbQueryObject::getColumnIndex(gqbColumn *column)
276 {
277 return parent->indexColumn(column);
278 }
279
280
getHaveJoins()281 bool gqbQueryObject::getHaveJoins()
282 {
283 return haveJoins;
284 }
285
286
getHaveRegJoins()287 bool gqbQueryObject::getHaveRegJoins()
288 {
289 return haveRegisteredJoins;
290 }
291
292 // GQB-TODO if last join it's delete I MUST delete implementation & collection & put haveJoins in false;
293 // Same for registered joins
294
295 //
296 // A Join inside a query Object like Table or view [Stored at source, registered at destination]
297 // I need to store the owner, destination because columns it's share between multiple joins
gqbQueryJoin(gqbQueryObject * _owner,gqbQueryObject * _destination,gqbColumn * sourceCol,gqbColumn * destCol,type_Join joinKind)298 gqbQueryJoin::gqbQueryJoin(gqbQueryObject *_owner, gqbQueryObject *_destination, gqbColumn *sourceCol, gqbColumn *destCol, type_Join joinKind)
299 : gqbObject(wxT(""), _owner, NULL)
300 {
301 kindofJoin = joinKind;
302 sCol = sourceCol;
303 dCol = destCol;
304 owner = _owner;
305 selected = false;
306 destination = _destination;
307 setType(GQB_JOIN);
308 }
309
310
setKindofJoin(type_Join kind)311 void gqbQueryJoin::setKindofJoin(type_Join kind)
312 {
313 kindofJoin = kind;
314 }
315
316
getKindofJoin()317 type_Join gqbQueryJoin::getKindofJoin()
318 {
319 return kindofJoin;
320 }
321
322
323 // Return the object where the join is stored
getSourceQTable()324 gqbQueryObject *gqbQueryJoin::getSourceQTable()
325 {
326 return owner;
327 }
328
329
330 // Return the object where the join point to.
getDestQTable()331 gqbQueryObject *gqbQueryJoin::getDestQTable()
332 {
333 return destination;
334 }
335
336
337 // Return the gqbObject of Destination Column
getDCol()338 gqbColumn *gqbQueryJoin::getDCol()
339 {
340 return dCol;
341 }
342
343
344 // Return the gqbObject of Source Column
getSCol()345 gqbColumn *gqbQueryJoin::getSCol()
346 {
347 return sCol;
348 }
349
350
getSourceTable()351 wxString gqbQueryJoin::getSourceTable()
352 {
353 if (!owner)
354 return wxEmptyString;
355
356 gqbTable *s = (gqbTable *)sCol->getOwner();
357 return s->getName();
358 }
359
360
getDestTable()361 wxString gqbQueryJoin::getDestTable()
362 {
363 if (!destination)
364 return wxEmptyString;
365
366 gqbTable *d = (gqbTable *)dCol->getOwner();
367 return d->getName();
368 }
369
370
getSourceCol()371 wxString gqbQueryJoin::getSourceCol()
372 {
373 if (!sCol)
374 return wxEmptyString;
375
376 return sCol->getName();
377 }
378
379
getDestCol()380 wxString gqbQueryJoin::getDestCol()
381 {
382 if (!dCol)
383 return wxEmptyString;
384
385 return dCol->getName();
386 }
387
388
setSourceAnchor(wxPoint pt)389 void gqbQueryJoin::setSourceAnchor(wxPoint pt)
390 {
391 sAnchor = pt;
392 }
393
394
setDestAnchor(wxPoint pt)395 void gqbQueryJoin::setDestAnchor(wxPoint pt)
396 {
397 dAnchor = pt;
398 }
399
400
getSourceAnchor()401 wxPoint &gqbQueryJoin::getSourceAnchor()
402 {
403 return sAnchor;
404 }
405
406
getDestAnchor()407 wxPoint &gqbQueryJoin::getDestAnchor()
408 {
409 return dAnchor;
410 }
411
412
setSelected(bool value)413 void gqbQueryJoin::setSelected(bool value)
414 {
415 this->selected = value;
416 }
417
418
getSelected()419 bool gqbQueryJoin::getSelected()
420 {
421 return this->selected;
422 }
423
424
setAnchorsUsed(wxPoint pt)425 void gqbQueryJoin::setAnchorsUsed(wxPoint pt)
426 {
427 anchorsUsed = pt;
428 }
429
430
getAnchorsUsed()431 wxPoint &gqbQueryJoin::getAnchorsUsed()
432 {
433 return anchorsUsed;
434 }
435
436
437 //
438 // A query restriction
439 //
440
441 enum
442 {
443 QRButton = 9000,
444 QRValue,
445 QRConnector,
446 QRtype
447 };
448
gqbQueryRestriction()449 gqbQueryRestriction::gqbQueryRestriction()
450 : gqbObject(wxT(""), NULL, NULL)
451 {
452 leftPart = wxT("");
453 value_s = wxT("");
454 connector = wxT("AND");
455 restriction = wxT("=");
456 setType(GQB_RESTRICTION);
457 }
458
459
gqbRestrictions()460 gqbRestrictions::gqbRestrictions()
461 : gqbObjectCollection(wxT(""), NULL, NULL)
462 {
463 setType(GQB_RESTRICTION);
464 }
465
466
~gqbRestrictions()467 gqbRestrictions::~gqbRestrictions()
468 {
469 this->removeAll();
470 }
471
472
addRestriction(gqbQueryRestriction * r)473 void gqbRestrictions::addRestriction(gqbQueryRestriction *r)
474 {
475 this->addObject(r);
476 }
477
478
addRestrictionAt(gqbQueryRestriction * r,int index)479 void gqbRestrictions::addRestrictionAt(gqbQueryRestriction *r, int index)
480 {
481 this->insertObjectAt(r, index);
482 }
483
484
485 // Remove but don't delete restriction
removeRestriction(gqbQueryRestriction * r)486 void gqbRestrictions::removeRestriction(gqbQueryRestriction *r)
487 {
488 this->removeObject(r);
489 }
490
491
deleteAllRestrictions()492 void gqbRestrictions::deleteAllRestrictions()
493 {
494 this->deleteAll();
495 }
496
497
createRestrictionsIterator()498 gqbIteratorBase *gqbRestrictions::createRestrictionsIterator()
499 {
500 return this->createIterator();
501 }
502
503
restrictionsCount()504 int gqbRestrictions::restrictionsCount()
505 {
506 return this->getCount();
507 }
508
509
getRestrictionAt(int index)510 gqbQueryRestriction *gqbRestrictions::getRestrictionAt(int index)
511 {
512 return (gqbQueryRestriction *)this->getObjectAtIndex(index);
513 }
514