1 /*
2 # PostgreSQL Database Modeler (pgModeler)
3 #
4 # Copyright 2006-2020 - Raphael Araújo e Silva <raphael@pgmodeler.io>
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation version 3.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # The complete text of GPLv3 is at LICENSE file on source code root directory.
16 # Also, you can get the complete GNU General Public License at <http://www.gnu.org/licenses/>
17 */
18
19 #include "viewwidget.h"
20 #include "rulewidget.h"
21 #include "triggerwidget.h"
22 #include "indexwidget.h"
23 #include "baseform.h"
24 #include "referencewidget.h"
25
ViewWidget(QWidget * parent)26 ViewWidget::ViewWidget(QWidget *parent): BaseObjectWidget(parent, ObjectType::View)
27 {
28 try
29 {
30 ObjectsTableWidget *tab=nullptr;
31 ObjectType types[]={ ObjectType::Trigger, ObjectType::Rule, ObjectType::Index };
32 QGridLayout *grid=nullptr;
33 QVBoxLayout *vbox=nullptr;
34
35 map<QString, vector<QWidget *> > fields_map;
36 QFrame *frame=nullptr;
37
38 Ui_ViewWidget::setupUi(this);
39
40 code_txt=new NumberedTextEditor(this);
41 code_txt->setReadOnly(true);
42 code_hl=new SyntaxHighlighter(code_txt);
43 code_hl->loadConfiguration(GlobalAttributes::getSQLHighlightConfPath());
44 vbox=new QVBoxLayout(code_prev_tab);
45 vbox->setContentsMargins(4,4,4,4);
46 vbox->addWidget(code_txt);
47
48 cte_expression_txt=new NumberedTextEditor(this, true);
49 cte_expression_hl=new SyntaxHighlighter(cte_expression_txt);
50 cte_expression_hl->loadConfiguration(GlobalAttributes::getSQLHighlightConfPath());
51 vbox=new QVBoxLayout(cte_tab);
52 vbox->setContentsMargins(4,4,4,4);
53 vbox->addWidget(cte_expression_txt);
54
55 tag_sel=new ObjectSelectorWidget(ObjectType::Tag, false, this);
56 dynamic_cast<QGridLayout *>(options_gb->layout())->addWidget(tag_sel, 0, 1, 1, 4);
57
58 references_tab=new ObjectsTableWidget(ObjectsTableWidget::AllButtons ^ ObjectsTableWidget::UpdateButton, true, this);
59 references_tab->setColumnCount(5);
60 references_tab->setHeaderLabel(tr("Col./Expr."), 0);
61 references_tab->setHeaderLabel(tr("Table alias"), 1);
62 references_tab->setHeaderLabel(tr("Column alias"), 2);
63 references_tab->setHeaderLabel(tr("Flags: SF FW AW EX VD"), 3);
64 references_tab->setHeaderLabel(tr("Reference alias"), 4);
65
66 vbox=new QVBoxLayout(tabWidget->widget(0));
67 vbox->setContentsMargins(4,4,4,4);
68 vbox->addWidget(references_tab);
69
70 cte_expression_cp=new CodeCompletionWidget(cte_expression_txt, true);
71
72 //Configuring the table objects that stores the triggers and rules
73 for(unsigned i=0, tab_id=1; i < sizeof(types)/sizeof(ObjectType); i++, tab_id++)
74 {
75 tab=new ObjectsTableWidget(ObjectsTableWidget::AllButtons ^
76 (ObjectsTableWidget::UpdateButton | ObjectsTableWidget::MoveButtons), true, this);
77
78 objects_tab_map[types[i]]=tab;
79
80 grid=new QGridLayout;
81 grid->addWidget(tab, 0,0,1,1);
82 grid->setContentsMargins(4,4,4,4);
83 tabWidget->widget(tab_id)->setLayout(grid);
84
85 connect(tab, SIGNAL(s_rowsRemoved()), this, SLOT(removeObjects()));
86 connect(tab, SIGNAL(s_rowRemoved(int)), this, SLOT(removeObject(int)));
87 connect(tab, SIGNAL(s_rowAdded(int)), this, SLOT(handleObject()));
88 connect(tab, SIGNAL(s_rowEdited(int)), this, SLOT(handleObject()));
89 connect(tab, SIGNAL(s_rowDuplicated(int,int)), this, SLOT(duplicateObject(int,int)));
90 }
91
92 objects_tab_map[ObjectType::Trigger]->setColumnCount(6);
93 objects_tab_map[ObjectType::Trigger]->setHeaderLabel(tr("Name"), 0);
94 objects_tab_map[ObjectType::Trigger]->setHeaderIcon(QPixmap(PgModelerUiNs::getIconPath("uid")),0);
95 objects_tab_map[ObjectType::Trigger]->setHeaderLabel(tr("Refer. Table"), 1);
96 objects_tab_map[ObjectType::Trigger]->setHeaderIcon(QPixmap(PgModelerUiNs::getIconPath("table")),1);
97 objects_tab_map[ObjectType::Trigger]->setHeaderLabel(tr("Firing"), 2);
98 objects_tab_map[ObjectType::Trigger]->setHeaderIcon(QPixmap(PgModelerUiNs::getIconPath("trigger")),2);
99 objects_tab_map[ObjectType::Trigger]->setHeaderLabel(tr("Events"), 3);
100 objects_tab_map[ObjectType::Trigger]->setHeaderLabel(tr("Alias"), 4);
101 objects_tab_map[ObjectType::Trigger]->setHeaderLabel(tr("Comment"), 5);
102
103 objects_tab_map[ObjectType::Index]->setColumnCount(4);
104 objects_tab_map[ObjectType::Index]->setHeaderLabel(tr("Name"), 0);
105 objects_tab_map[ObjectType::Index]->setHeaderIcon(QPixmap(PgModelerUiNs::getIconPath("uid")),0);
106 objects_tab_map[ObjectType::Index]->setHeaderLabel(tr("Indexing"), 1);
107 objects_tab_map[ObjectType::Index]->setHeaderLabel(tr("Alias"), 2);
108 objects_tab_map[ObjectType::Index]->setHeaderLabel(tr("Comment"), 3);
109
110 objects_tab_map[ObjectType::Rule]->setColumnCount(5);
111 objects_tab_map[ObjectType::Rule]->setHeaderLabel(tr("Name"), 0);
112 objects_tab_map[ObjectType::Rule]->setHeaderIcon(QPixmap(PgModelerUiNs::getIconPath("uid")),0);
113 objects_tab_map[ObjectType::Rule]->setHeaderLabel(tr("Execution"), 1);
114 objects_tab_map[ObjectType::Rule]->setHeaderLabel(tr("Event"), 2);
115 objects_tab_map[ObjectType::Rule]->setHeaderLabel(tr("Alias"), 3);
116 objects_tab_map[ObjectType::Rule]->setHeaderLabel(tr("Comment"), 4);
117
118
119 tablespace_sel->setEnabled(false);
120 tablespace_lbl->setEnabled(false);
121 configureFormLayout(view_grid, ObjectType::View);
122
123 fields_map[generateVersionsInterval(AfterVersion, PgSqlVersions::PgSqlVersion93)].push_back(recursive_rb);
124 fields_map[generateVersionsInterval(AfterVersion, PgSqlVersions::PgSqlVersion93)].push_back(materialized_rb);
125 fields_map[generateVersionsInterval(AfterVersion, PgSqlVersions::PgSqlVersion93)].push_back(with_no_data_chk);
126 frame=generateVersionWarningFrame(fields_map);
127 view_grid->addWidget(frame, view_grid->count()+1, 0, 1,3);
128 frame->setParent(this);
129
130 connect(references_tab, SIGNAL(s_rowAdded(int)), this, SLOT(addReference(int)));
131 connect(references_tab, SIGNAL(s_rowEdited(int)), this, SLOT(editReference(int)));
132 connect(references_tab, SIGNAL(s_rowDuplicated(int,int)), this, SLOT(duplicateReference(int,int)));
133 connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(updateCodePreview()));
134
135 connect(materialized_rb, SIGNAL(toggled(bool)), with_no_data_chk, SLOT(setEnabled(bool)));
136 connect(materialized_rb, SIGNAL(toggled(bool)), tablespace_sel, SLOT(setEnabled(bool)));
137 connect(materialized_rb, SIGNAL(toggled(bool)), tablespace_lbl, SLOT(setEnabled(bool)));
138
139 connect(materialized_rb, SIGNAL(toggled(bool)), this, SLOT(updateCodePreview()));
140 connect(recursive_rb, SIGNAL(toggled(bool)), this, SLOT(updateCodePreview()));
141 connect(with_no_data_chk, SIGNAL(toggled(bool)), this, SLOT(updateCodePreview()));
142 connect(tablespace_sel, SIGNAL(s_objectSelected()), this, SLOT(updateCodePreview()));
143 connect(tablespace_sel, SIGNAL(s_selectorCleared()), this, SLOT(updateCodePreview()));
144 connect(schema_sel, SIGNAL(s_objectSelected()), this, SLOT(updateCodePreview()));
145 connect(schema_sel, SIGNAL(s_selectorCleared()), this, SLOT(updateCodePreview()));
146
147 configureTabOrder({ tag_sel, ordinary_rb, recursive_rb, with_no_data_chk, tabWidget });
148 setMinimumSize(660, 650);
149 }
150 catch(Exception &e)
151 {
152 throw Exception(e.getErrorMessage(),e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
153 }
154 }
155
getObjectTable(ObjectType obj_type)156 ObjectsTableWidget *ViewWidget::getObjectTable(ObjectType obj_type)
157 {
158 if(objects_tab_map.count(obj_type) > 0)
159 return objects_tab_map[obj_type];
160
161 return nullptr;
162 }
163
164 template<class Class, class WidgetClass>
openEditingForm(TableObject * object)165 int ViewWidget::openEditingForm(TableObject *object)
166 {
167 BaseForm editing_form(this);
168 WidgetClass *object_wgt=new WidgetClass;
169 object_wgt->setAttributes(this->model, this->op_list,
170 dynamic_cast<BaseTable *>(this->object),
171 dynamic_cast<Class *>(object));
172 editing_form.setMainWidget(object_wgt);
173
174 return editing_form.exec();
175 }
176
handleObject()177 void ViewWidget::handleObject()
178 {
179 ObjectType obj_type=ObjectType::BaseObject;
180 TableObject *object=nullptr;
181 ObjectsTableWidget *obj_table=nullptr;
182
183 try
184 {
185 obj_type=getObjectType(sender());
186 obj_table=getObjectTable(obj_type);
187
188 if(obj_table->getSelectedRow()>=0)
189 object=reinterpret_cast<TableObject *>(obj_table->getRowData(obj_table->getSelectedRow()).value<void *>());
190
191 if(obj_type==ObjectType::Trigger)
192 openEditingForm<Trigger,TriggerWidget>(object);
193 else if(obj_type==ObjectType::Index)
194 openEditingForm<Index,IndexWidget>(object);
195 else
196 openEditingForm<Rule,RuleWidget>(object);
197
198 listObjects(obj_type);
199 }
200 catch(Exception &e)
201 {
202 listObjects(obj_type);
203 throw Exception(e.getErrorMessage(),e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
204 }
205 }
206
duplicateObject(int curr_row,int new_row)207 void ViewWidget::duplicateObject(int curr_row, int new_row)
208 {
209 ObjectType obj_type=ObjectType::BaseObject;
210 BaseObject *object=nullptr, *dup_object=nullptr;
211 ObjectsTableWidget *obj_table=nullptr;
212 View *view = dynamic_cast<View *>(this->object);
213 int op_id = -1;
214
215 try
216 {
217 obj_type=getObjectType(sender());
218
219 //Selects the object table based upon the passed object type
220 obj_table=getObjectTable(obj_type);
221
222 //Gets the object reference if there is an item select on table
223 if(curr_row >= 0)
224 object = reinterpret_cast<BaseObject *>(obj_table->getRowData(curr_row).value<void *>());
225
226 PgModelerNs::copyObject(&dup_object, object, obj_type);
227 dup_object->setName(PgModelerNs::generateUniqueName(dup_object, *view->getObjectList(obj_type), false, QString("_cp")));
228
229 op_id=op_list->registerObject(dup_object, Operation::ObjectCreated, new_row, this->object);
230
231 view->addObject(dup_object);
232 view->setModified(true);
233 listObjects(obj_type);
234 }
235 catch(Exception &e)
236 {
237 //If operation was registered
238 if(op_id >= 0)
239 {
240 op_list->ignoreOperationChain(true);
241 op_list->removeLastOperation();
242 op_list->ignoreOperationChain(false);
243 }
244
245 listObjects(obj_type);
246 throw Exception(e.getErrorMessage(),e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
247 }
248 }
249
removeObjects()250 void ViewWidget::removeObjects()
251 {
252 View *view=nullptr;
253 unsigned count, op_count=0, i;
254 BaseObject *object=nullptr;
255 ObjectType obj_type=getObjectType(sender());
256
257 try
258 {
259 view=dynamic_cast<View *>(this->object);
260 op_count=op_list->getCurrentSize();
261
262 while(view->getObjectCount(obj_type) > 0)
263 {
264 object=view->getObject(0, obj_type);
265 view->removeObject(object);
266 op_list->registerObject(object, Operation::ObjectRemoved, 0, this->object);
267 }
268 }
269 catch(Exception &e)
270 {
271 if(op_count < op_list->getCurrentSize())
272 {
273 count=op_list->getCurrentSize()-op_count;
274 op_list->ignoreOperationChain(true);
275
276 for(i=0; i < count; i++)
277 {
278 op_list->undoOperation();
279 op_list->removeLastOperation();
280 }
281
282 op_list->ignoreOperationChain(false);
283 }
284
285 listObjects(obj_type);
286 throw Exception(e.getErrorMessage(),e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
287 }
288 }
289
addReference(int row)290 void ViewWidget::addReference(int row)
291 {
292 openReferenceForm(Reference(), row, false);
293 }
294
duplicateReference(int orig_row,int new_row)295 void ViewWidget::duplicateReference(int orig_row, int new_row)
296 {
297 showReferenceData(references_tab->getRowData(orig_row).value<Reference>(),
298 getReferenceFlag(orig_row), new_row);
299 }
300
removeObject(int row)301 void ViewWidget::removeObject(int row)
302 {
303 View *view=nullptr;
304 BaseObject *object=nullptr;
305 ObjectType obj_type=getObjectType(sender());
306
307 try
308 {
309 view=dynamic_cast<View *>(this->object);
310 object=view->getObject(row, obj_type);
311 view->removeObject(object);
312 op_list->registerObject(object, Operation::ObjectRemoved, row, this->object);
313 }
314 catch(Exception &e)
315 {
316 listObjects(obj_type);
317 throw Exception(e.getErrorMessage(),e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
318 }
319 }
320
getObjectType(QObject * sender)321 ObjectType ViewWidget::getObjectType(QObject *sender)
322 {
323 ObjectType obj_type=ObjectType::BaseObject;
324
325 if(sender)
326 {
327 map<ObjectType, ObjectsTableWidget *>::iterator itr, itr_end;
328
329 itr=objects_tab_map.begin();
330 itr_end=objects_tab_map.end();
331
332 while(itr!=itr_end && obj_type==ObjectType::BaseObject)
333 {
334 if(itr->second==sender)
335 obj_type=itr->first;
336
337 itr++;
338 }
339 }
340
341 return obj_type;
342 }
343
showObjectData(TableObject * object,int row)344 void ViewWidget::showObjectData(TableObject *object, int row)
345 {
346 ObjectsTableWidget *tab=nullptr;
347 Trigger *trigger=nullptr;
348 Rule *rule=nullptr;
349 Index *index=nullptr;
350 ObjectType obj_type;
351 QString str_aux;
352 unsigned i;
353 EventType events[]={ EventType::OnInsert, EventType::OnDelete,
354 EventType::OnTruncate, EventType::OnUpdate };
355
356 obj_type=object->getObjectType();
357 tab=objects_tab_map[obj_type];
358
359 //Column 0: Object name
360 tab->setCellText(object->getName(),row,0);
361
362 if(obj_type==ObjectType::Trigger)
363 {
364 trigger=dynamic_cast<Trigger *>(object);
365
366 //Column 1: Table referenced by the trigger (constraint trigger)
367 tab->clearCellText(row,1);
368 if(trigger->getReferencedTable())
369 tab->setCellText(trigger->getReferencedTable()->getName(true),row,1);
370
371 //Column 2: Trigger firing type
372 tab->setCellText(~trigger->getFiringType(),row,2);
373
374 //Column 3: Events that fires the trigger
375 for(i=0; i < sizeof(events)/sizeof(EventType); i++)
376 {
377 if(trigger->isExecuteOnEvent(events[i]))
378 str_aux+=~events[i] + QString(", ");
379 }
380
381 str_aux.remove(str_aux.size()-2, 2);
382 tab->setCellText(str_aux ,row,3);
383 tab->setCellText(trigger->getAlias(), row, 4);
384 }
385 else if(obj_type==ObjectType::Rule)
386 {
387 rule=dynamic_cast<Rule *>(object);
388
389 //Column 1: Rule execution type
390 tab->setCellText(~rule->getExecutionType(),row,1);
391
392 //Column 2: Rule event type
393 tab->setCellText(~rule->getEventType(),row,2);
394
395 tab->setCellText(rule->getAlias(), row, 3);
396 }
397 else
398 {
399 index=dynamic_cast<Index *>(object);
400
401 //Column 1: Indexing type
402 tab->setCellText(~index->getIndexingType(),row,1);
403 tab->setCellText(index->getAlias(), row, 2);
404 }
405
406 tab->setCellText(object->getComment(), row, tab->getColumnCount() - 1);
407 tab->setRowData(QVariant::fromValue<void *>(object), row);
408 }
409
listObjects(ObjectType obj_type)410 void ViewWidget::listObjects(ObjectType obj_type)
411 {
412 ObjectsTableWidget *tab=nullptr;
413 unsigned count, i;
414 View *view=nullptr;
415
416 try
417 {
418 //Gets the object table related to the object type
419 tab=objects_tab_map[obj_type];
420 view=dynamic_cast<View *>(this->object);
421
422 tab->blockSignals(true);
423 tab->removeRows();
424
425 count=view->getObjectCount(obj_type);
426 for(i=0; i < count; i++)
427 {
428 tab->addRow();
429 showObjectData(dynamic_cast<TableObject*>(view->getObject(i, obj_type)), i);
430 }
431 tab->clearSelection();
432 tab->blockSignals(false);
433 }
434 catch(Exception &e)
435 {
436 throw Exception(e.getErrorMessage(),e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
437 }
438 }
439
openReferenceForm(Reference ref,int row,bool update)440 int ViewWidget::openReferenceForm(Reference ref, int row, bool update)
441 {
442 BaseForm editing_form(this);
443 ReferenceWidget *ref_wgt=new ReferenceWidget;
444 int result = 0;
445
446 editing_form.setMainWidget(ref_wgt);
447 editing_form.setButtonConfiguration(Messagebox::OkCancelButtons);
448
449 disconnect(editing_form.apply_ok_btn, SIGNAL(clicked(bool)), &editing_form, SLOT(accept()));
450 connect(editing_form.apply_ok_btn, SIGNAL(clicked(bool)), ref_wgt, SLOT(applyConfiguration()));
451 connect(ref_wgt, SIGNAL(s_closeRequested()), &editing_form, SLOT(accept()));
452
453 ref_wgt->setAttributes(ref, getReferenceFlag(row), model);
454 result = editing_form.exec();
455 disconnect(ref_wgt, nullptr, &editing_form, nullptr);
456
457 if(result == QDialog::Accepted)
458 showReferenceData(ref_wgt->getReference(), ref_wgt->getReferenceFlags(), row);
459 else if(!update)
460 references_tab->removeRow(row);
461
462 return result;
463 }
464
getReferenceFlag(int row)465 unsigned ViewWidget::getReferenceFlag(int row)
466 {
467 QString flags_str = references_tab->getCellText(row, 3);
468 unsigned ref_flags = 0;
469
470 if(flags_str.isEmpty())
471 return 0;
472
473 if(flags_str[4] == '1')
474 ref_flags = Reference::SqlViewDefinition;
475 else
476 {
477 if(flags_str[0] == '1')
478 ref_flags |= Reference::SqlReferSelect;
479
480 if(flags_str[1] == '1')
481 ref_flags |= Reference::SqlReferFrom;
482
483 if(flags_str[2] == '1')
484 ref_flags |= Reference::SqlReferWhere;
485
486 if(flags_str[3] == '1')
487 ref_flags |= Reference::SqlReferEndExpr;
488 }
489
490 return ref_flags;
491 }
492
editReference(int ref_idx)493 void ViewWidget::editReference(int ref_idx)
494 {
495 openReferenceForm(references_tab->getRowData(ref_idx).value<Reference>(), ref_idx, true);
496 }
497
showReferenceData(Reference refer,unsigned ref_flags,unsigned row)498 void ViewWidget::showReferenceData(Reference refer, unsigned ref_flags, unsigned row)
499 {
500 PhysicalTable *tab=nullptr;
501 Column *col=nullptr;
502 QString str_aux;
503 bool selec_from = (ref_flags & Reference::SqlReferSelect) == Reference::SqlReferSelect,
504 from_where = (ref_flags & Reference::SqlReferFrom) == Reference::SqlReferFrom,
505 after_where = (ref_flags & Reference::SqlReferWhere) == Reference::SqlReferWhere,
506 end_expr = (ref_flags & Reference::SqlReferEndExpr) == Reference::SqlReferEndExpr,
507 view_def = (ref_flags & Reference::SqlViewDefinition) == Reference::SqlViewDefinition;
508
509 if(refer.getReferenceType()==Reference::ReferColumn)
510 {
511 tab=refer.getTable();
512 col=refer.getColumn();
513
514 /* If the table is allocated but not the column indicates that the reference
515 is to all table columns this way shows a string in format: [SCHEMA].[TABLE].* */
516 if(tab && !col)
517 references_tab->setCellText(tab->getName(true) + QString(".*"),row,0);
518 /* If the table and column are allocated indicates that the reference
519 is to a specific column this way shows a string in format: [SCHEMA].[TABLE].[COLUMN] */
520 else
521 references_tab->setCellText(tab->getName(true) + QString(".") + col->getName(true),row,0);
522
523 references_tab->setCellText(refer.getAlias(),row,1);
524
525 if(col)
526 references_tab->setCellText(refer.getColumnAlias(),row,2);
527 }
528 else
529 {
530 references_tab->setCellText(refer.getExpression().simplified(),row,0);
531 references_tab->setCellText(refer.getAlias(),row,1);
532 }
533
534 //Configures the string that denotes the SQL application for the reference
535 str_aux+=(selec_from ? QString("1") : QString("0"));
536 str_aux+=(from_where ? QString("1") : QString("0"));
537 str_aux+=(after_where ? QString("1") : QString("0"));
538 str_aux+=(end_expr ? QString("1") : QString("0"));
539 str_aux+=(view_def ? QString("1") : QString("0"));
540 references_tab->setCellText(str_aux, row, 3);
541
542 references_tab->setCellText(refer.getReferenceAlias(), row, 4);
543
544 refer.setDefinitionExpression(view_def);
545 references_tab->setRowData(QVariant::fromValue<Reference>(refer), row);
546 }
547
updateCodePreview()548 void ViewWidget::updateCodePreview()
549 {
550 try
551 {
552 if(tabWidget->currentIndex()==tabWidget->count()-1)
553 {
554 View aux_view;
555 Reference refer;
556 QString str_aux;
557 TableObject *tab_obj=nullptr;
558 map<ObjectType, ObjectsTableWidget *>::iterator itr, itr_end;
559 unsigned i, count, i1, expr_type[]={
560 Reference::SqlReferSelect,
561 Reference::SqlReferFrom,
562 Reference::SqlReferWhere,
563 Reference::SqlReferEndExpr,
564 Reference::SqlViewDefinition};
565
566 aux_view.BaseObject::setName(name_edt->text().toUtf8());
567 aux_view.BaseObject::setSchema(schema_sel->getSelectedObject());
568 aux_view.setTablespace(tablespace_sel->getSelectedObject());
569
570 aux_view.setCommomTableExpression(cte_expression_txt->toPlainText().toUtf8());
571 aux_view.setMaterialized(materialized_rb->isChecked());
572 aux_view.setRecursive(recursive_rb->isChecked());
573 aux_view.setWithNoData(with_no_data_chk->isChecked());
574
575 count=references_tab->getRowCount();
576 for(i=0; i < count; i++)
577 {
578 refer=references_tab->getRowData(i).value<Reference>();
579
580 //Get the SQL application string for the current reference
581 str_aux=references_tab->getCellText(i,3);
582
583 for(i1=0; i1 < sizeof(expr_type)/sizeof(unsigned); i1++)
584 {
585 if(str_aux[i1]=='1')
586 aux_view.addReference(refer, expr_type[i1]);
587 }
588 }
589
590 itr=objects_tab_map.begin();
591 itr_end=objects_tab_map.end();
592
593 //Inserts the triggers / rules into the auxiliary view
594 while(itr!=itr_end)
595 {
596 count=itr->second->getRowCount();
597
598 //Make a copy of each view objects (rule/trigger) to the auxiliary view
599 for(i=0; i < count; i++)
600 {
601 if(itr->first==ObjectType::Trigger)
602 {
603 tab_obj=new Trigger;
604 (*dynamic_cast<Trigger *>(tab_obj))=
605 (*reinterpret_cast<Trigger *>(itr->second->getRowData(i).value<void *>()));
606 }
607 else
608 {
609 tab_obj=new Rule;
610 (*dynamic_cast<Rule *>(tab_obj))=
611 (*reinterpret_cast<Rule *>(itr->second->getRowData(i).value<void *>()));
612 }
613 aux_view.addObject(tab_obj);
614 }
615
616 itr++;
617 }
618 code_txt->setPlainText(aux_view.getCodeDefinition(SchemaParser::SqlDefinition));
619 }
620 }
621 catch(Exception &e)
622 {
623 QString str_aux;
624 //In case of error no code is outputed, showing a error message in the code preview widget
625 str_aux=tr("/* Could not generate the SQL code. Make sure all attributes are correctly filled! ");
626 str_aux+=QString("\n\n>> Returned error(s): \n\n%1*/").arg(e.getExceptionsText());
627 code_txt->setPlainText(str_aux);
628 }
629 }
630
setAttributes(DatabaseModel * model,OperationList * op_list,Schema * schema,View * view,double px,double py)631 void ViewWidget::setAttributes(DatabaseModel *model, OperationList *op_list, Schema *schema, View *view, double px, double py)
632 {
633 unsigned i, count, ref_flags = 0;
634 Reference refer;
635
636 if(!view)
637 {
638 view=new View;
639
640 if(schema)
641 view->setSchema(schema);
642
643 /* Sets the 'new_object' flag as true indicating that the alocated table must be treated
644 as a recently created object */
645 this->new_object=true;
646 }
647
648 BaseObjectWidget::setAttributes(model,op_list, view, schema, px, py);
649
650 materialized_rb->setChecked(view->isMaterialized());
651 recursive_rb->setChecked(view->isRecursive());
652 with_no_data_chk->setChecked(view->isWithNoData());
653
654 cte_expression_cp->configureCompletion(model, cte_expression_hl);
655
656 op_list->startOperationChain();
657 operation_count=op_list->getCurrentSize();
658
659 tag_sel->setModel(this->model);
660 tag_sel->setSelectedObject(view->getTag());
661
662 cte_expression_txt->setPlainText(view->getCommomTableExpression());
663
664 count=view->getReferenceCount();
665 references_tab->blockSignals(true);
666
667 for(i=0; i < count; i++)
668 {
669 references_tab->addRow();
670
671 ref_flags = 0;
672 refer=view->getReference(i);
673
674 if(view->getReferenceIndex(refer, Reference::SqlViewDefinition) >= 0)
675 ref_flags = Reference::SqlViewDefinition;
676
677 if(view->getReferenceIndex(refer, Reference::SqlReferSelect) >= 0)
678 ref_flags |= Reference::SqlReferSelect;
679
680 if(view->getReferenceIndex(refer, Reference::SqlReferFrom) >= 0)
681 ref_flags |= Reference::SqlReferFrom;
682
683 if(view->getReferenceIndex(refer, Reference::SqlReferWhere) >= 0)
684 ref_flags |= Reference::SqlReferWhere;
685
686 if(view->getReferenceIndex(refer, Reference::SqlReferEndExpr) >= 0)
687 ref_flags |= Reference::SqlReferEndExpr;
688
689 showReferenceData(refer, ref_flags, i);
690 }
691
692 references_tab->blockSignals(false);
693 references_tab->clearSelection();
694
695 listObjects(ObjectType::Trigger);
696 listObjects(ObjectType::Rule);
697 listObjects(ObjectType::Index);
698 }
699
applyConfiguration()700 void ViewWidget::applyConfiguration()
701 {
702 try
703 {
704 View *view=nullptr;
705 ObjectType types[]={ ObjectType::Trigger, ObjectType::Rule, ObjectType::Index };
706 unsigned expr_type[]={ Reference::SqlReferSelect,
707 Reference::SqlReferFrom,
708 Reference::SqlReferWhere,
709 Reference::SqlReferEndExpr,
710 Reference::SqlViewDefinition};
711 Reference refer;
712 QString str_aux;
713
714 if(!this->new_object)
715 op_list->registerObject(this->object, Operation::ObjectModified);
716 else
717 registerNewObject();
718
719 BaseObjectWidget::applyConfiguration();
720
721 view=dynamic_cast<View *>(this->object);
722 view->removeObjects();
723 view->removeReferences();
724 view->setMaterialized(materialized_rb->isChecked());
725 view->setRecursive(recursive_rb->isChecked());
726 view->setWithNoData(with_no_data_chk->isChecked());
727 view->setCommomTableExpression(cte_expression_txt->toPlainText().toUtf8());
728 view->setTag(dynamic_cast<Tag *>(tag_sel->getSelectedObject()));
729
730 for(unsigned i=0; i < references_tab->getRowCount(); i++)
731 {
732 refer=references_tab->getRowData(i).value<Reference>();
733
734 //Get the SQL application string for the current reference
735 str_aux=references_tab->getCellText(i, 3);
736 for(unsigned i=0; i < sizeof(expr_type)/sizeof(unsigned); i++)
737 {
738 if(str_aux[i]=='1')
739 view->addReference(refer, expr_type[i]);
740 }
741 }
742
743 //Adds the auxiliary view objects into configured view
744 for(unsigned type_id=0; type_id < sizeof(types)/sizeof(ObjectType); type_id++)
745 {
746 for(unsigned i=0; i < objects_tab_map[types[type_id]]->getRowCount(); i++)
747 view->addObject(reinterpret_cast<TableObject *>(objects_tab_map[types[type_id]]->getRowData(i).value<void *>()));
748 }
749
750 op_list->finishOperationChain();
751 this->model->updateViewRelationships(view);
752 finishConfiguration();
753 }
754 catch(Exception &e)
755 {
756 throw Exception(e.getErrorMessage(),e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
757 }
758 }
759
cancelConfiguration()760 void ViewWidget::cancelConfiguration()
761 {
762 BaseObjectWidget::cancelChainedOperation();
763 }
764