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 "constraint.h"
20
Constraint()21 Constraint::Constraint()
22 {
23 ref_table=nullptr;
24 obj_type=ObjectType::Constraint;
25 deferrable=false;
26 no_inherit=false;
27 fill_factor=0;
28 index_type=BaseType::Null;
29
30 attributes[Attributes::PkConstr]="";
31 attributes[Attributes::FkConstr]="";
32 attributes[Attributes::CkConstr]="";
33 attributes[Attributes::UqConstr]="";
34 attributes[Attributes::ExConstr]="";
35 attributes[Attributes::RefTable]="";
36 attributes[Attributes::SrcColumns]="";
37 attributes[Attributes::DstColumns]="";
38 attributes[Attributes::DelAction]="";
39 attributes[Attributes::UpdAction]="";
40 attributes[Attributes::Expression]="";
41 attributes[Attributes::Type]="";
42 attributes[Attributes::ComparisonType]="";
43 attributes[Attributes::DeferType]="";
44 attributes[Attributes::IndexType]="";
45 attributes[Attributes::Deferrable]="";
46 attributes[Attributes::Table]="";
47 attributes[Attributes::DeclInTable]="";
48 attributes[Attributes::Factor]="";
49 attributes[Attributes::NoInherit]="";
50 attributes[Attributes::Elements]="";
51 }
52
~Constraint()53 Constraint::~Constraint()
54 {
55 columns.clear();
56 ref_columns.clear();
57 }
58
setConstraintType(ConstraintType constr_type)59 void Constraint::setConstraintType(ConstraintType constr_type)
60 {
61 this->constr_type=constr_type;
62 }
63
setActionType(ActionType action_type,unsigned act_id)64 void Constraint::setActionType(ActionType action_type, unsigned act_id)
65 {
66 if(act_id==DeleteAction)
67 {
68 setCodeInvalidated(this->del_action != action_type);
69 this->del_action=action_type;
70 }
71 else
72 {
73 setCodeInvalidated(this->upd_action != action_type);
74 this->upd_action=action_type;
75 }
76 }
77
setExpression(const QString & expr)78 void Constraint::setExpression(const QString &expr)
79 {
80 setCodeInvalidated(expression != expr);
81 expression=expr;
82 }
83
isColumnExists(Column * column,unsigned col_type)84 bool Constraint::isColumnExists(Column *column, unsigned col_type)
85 {
86 vector<Column *>::iterator itr, itr_end;
87 bool found=false;
88
89 //Raises an error if the column is not allocated
90 if(!column)
91 throw Exception(ErrorCode::OprNotAllocatedObject,__PRETTY_FUNCTION__,__FILE__,__LINE__);
92
93 //Gets the iterators from the specified internal list
94 if(col_type==SourceCols)
95 {
96 itr=columns.begin();
97 itr_end=columns.end();
98 }
99 else
100 {
101 itr=ref_columns.begin();
102 itr_end=ref_columns.end();
103 }
104
105 //Tries to find the column on the internal list
106 while(itr!=itr_end && !found)
107 {
108 found=((*itr)==column);
109 itr++;
110 }
111
112 return found;
113 }
114
isColumnsExist(vector<Column * > columns,unsigned col_type)115 bool Constraint::isColumnsExist(vector<Column *> columns, unsigned col_type)
116 {
117 bool is_ref = false;
118
119 for(auto &col : columns)
120 {
121 is_ref = isColumnExists(col, col_type);
122 if(!is_ref) break;
123 }
124
125 return is_ref;
126 }
127
isColumnReferenced(Column * column,bool search_only_ref_cols)128 bool Constraint::isColumnReferenced(Column *column, bool search_only_ref_cols)
129 {
130 bool found=false;
131 vector<ExcludeElement>::iterator itr, itr_end;
132
133 if(constr_type == ConstraintType::PrimaryKey ||
134 constr_type == ConstraintType::Unique ||
135 constr_type == ConstraintType::ForeignKey)
136 {
137 if(!search_only_ref_cols)
138 found=isColumnExists(column, SourceCols);
139
140 if(!found && constr_type==ConstraintType::ForeignKey)
141 found=isColumnExists(column, ReferencedCols);
142 }
143 else if(constr_type==ConstraintType::Exclude)
144 {
145 //Iterates over the exclude elements
146 itr=excl_elements.begin();
147 itr_end=excl_elements.end();
148
149 while(itr!=itr_end && !found)
150 {
151 found=((*itr).getColumn() == column);
152 itr++;
153 }
154 }
155
156 return found;
157 }
158
addColumn(Column * column,unsigned col_type)159 void Constraint::addColumn(Column *column, unsigned col_type)
160 {
161 //Raises an error if the column is not allocated
162 if(!column)
163 throw Exception(Exception::getErrorMessage(ErrorCode::AsgNotAllocatedColumn)
164 .arg(this->getName())
165 .arg(BaseObject::getTypeName(ObjectType::Constraint)),
166 ErrorCode::AsgNotAllocatedColumn,__PRETTY_FUNCTION__,__FILE__,__LINE__);
167 else if(constr_type!=ConstraintType::Check)
168 {
169 //Adds the column only if the column doesn't exists on the internal list
170 if(!isColumnExists(column,col_type))
171 {
172 if(col_type==ReferencedCols)
173 ref_columns.push_back(column);
174 else
175 {
176 columns.push_back(column);
177 setColumnsNotNull(true);
178 }
179
180 setCodeInvalidated(true);
181 }
182 }
183 }
184
setTablespace(BaseObject * tabspc)185 void Constraint::setTablespace(BaseObject *tabspc)
186 {
187 try
188 {
189 if(tabspc &&
190 constr_type!=ConstraintType::PrimaryKey &&
191 constr_type!=ConstraintType::Unique)
192 throw Exception(ErrorCode::AsgTablespaceInvalidConstraintType,__PRETTY_FUNCTION__,__FILE__,__LINE__);
193
194 BaseObject::setTablespace(tabspc);
195 }
196 catch(Exception &e)
197 {
198 throw Exception(e.getErrorMessage(),e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__,&e);
199 }
200 }
201
setColumnsAttribute(unsigned col_type,unsigned def_type,bool inc_addedbyrel)202 void Constraint::setColumnsAttribute(unsigned col_type, unsigned def_type, bool inc_addedbyrel)
203 {
204 vector<Column *> *col_vector=nullptr;
205 Column *col=nullptr;
206 QString str_cols, attrib;
207 unsigned i, count;
208 bool format=(def_type==SchemaParser::SqlDefinition);
209
210 if(col_type==ReferencedCols)
211 {
212 col_vector=&ref_columns;
213 attrib=Attributes::DstColumns;
214 }
215 else
216 {
217 col_vector=&columns;
218 attrib=Attributes::SrcColumns;
219 }
220
221 count=col_vector->size();
222 for(i=0; i < count; i++)
223 {
224 col=col_vector->at(i);
225
226 /* For XML definition the columns added to the constraint
227 through relationship can not be included because they are inserted
228 to the restriction on the time of creation of the relationship from its XML
229 so the parameter 'inc_addedbyrel' can be used to solve this case. */
230 if((def_type==SchemaParser::SqlDefinition) ||
231 ((def_type==SchemaParser::XmlDefinition) &&
232 ((inc_addedbyrel && col->isAddedByRelationship()) ||
233 (inc_addedbyrel && !col->isAddedByRelationship()) ||
234 (!inc_addedbyrel && !col->isAddedByRelationship()))))
235 {
236 str_cols+=col->getName(format);
237 str_cols+=',';
238 }
239 }
240
241 str_cols.remove(str_cols.size()-1,1);
242 attributes[attrib]=str_cols;
243 }
244
setReferencedTable(BaseTable * tab_ref)245 void Constraint::setReferencedTable(BaseTable *tab_ref)
246 {
247 this->ref_table=tab_ref;
248 }
249
setDeferralType(DeferralType deferral_type)250 void Constraint::setDeferralType(DeferralType deferral_type)
251 {
252 this->deferral_type=deferral_type;
253 }
254
setDeferrable(bool value)255 void Constraint::setDeferrable(bool value)
256 {
257 deferrable=value;
258 }
259
setMatchType(MatchType match_type)260 void Constraint::setMatchType(MatchType match_type)
261 {
262 this->match_type=match_type;
263 }
264
setFillFactor(unsigned factor)265 void Constraint::setFillFactor(unsigned factor)
266 {
267 if(factor!=0 && factor < 10) factor=10;
268 else if(factor > 100) factor=100;
269 fill_factor=factor;
270 }
271
setNoInherit(bool value)272 void Constraint::setNoInherit(bool value)
273 {
274 no_inherit=value;
275 }
276
getFillFactor()277 unsigned Constraint::getFillFactor()
278 {
279 return fill_factor;
280 }
281
getConstraintType()282 ConstraintType Constraint::getConstraintType()
283 {
284 return constr_type;
285 }
286
getActionType(unsigned act_id)287 ActionType Constraint::getActionType(unsigned act_id)
288 {
289 if(act_id==DeleteAction)
290 return del_action;
291 else
292 return upd_action;
293 }
294
getColumns(unsigned col_type)295 vector<Column *> Constraint::getColumns(unsigned col_type)
296 {
297 return (col_type==SourceCols ? columns : ref_columns);
298 }
299
getExpression()300 QString Constraint::getExpression()
301 {
302 return expression;
303 }
304
getColumn(unsigned col_idx,unsigned col_type)305 Column *Constraint::getColumn(unsigned col_idx, unsigned col_type)
306 {
307 vector<Column *> *col_list=nullptr;
308
309 col_list=(col_type==SourceCols ? &columns : &ref_columns);
310
311 //Raises an error if the column index is invalid (out of bound)
312 if(col_idx>=col_list->size())
313 throw Exception(ErrorCode::RefColumnInvalidIndex,__PRETTY_FUNCTION__,__FILE__,__LINE__);
314
315 return col_list->at(col_idx);
316 }
317
getColumn(const QString & name,unsigned col_type)318 Column *Constraint::getColumn(const QString &name, unsigned col_type)
319 {
320 bool found=false;
321 vector<Column *> *col_list=nullptr;
322 vector<Column *>::iterator itr_col, itr_end_col;
323
324 col_list=(col_type==SourceCols? &columns : &ref_columns);
325
326 itr_col=col_list->begin();
327 itr_end_col=col_list->end();
328
329 while(itr_col!=itr_end_col)
330 {
331 found=((*itr_col)->getName()==name);
332 if(!found) itr_col++;
333 else break;
334 }
335
336 if(found) return *itr_col;
337 else return nullptr;
338 }
339
getReferencedTable()340 BaseTable *Constraint::getReferencedTable()
341 {
342 return ref_table;
343 }
344
getColumnCount(unsigned col_type)345 unsigned Constraint::getColumnCount(unsigned col_type)
346 {
347 if(col_type==ReferencedCols)
348 return ref_columns.size();
349 else
350 return columns.size();
351 }
352
removeColumns()353 void Constraint::removeColumns()
354 {
355 setColumnsNotNull(false);
356 columns.clear();
357 ref_columns.clear();
358 setCodeInvalidated(true);
359 }
360
removeColumn(const QString & name,unsigned col_type)361 void Constraint::removeColumn(const QString &name, unsigned col_type)
362 {
363 vector<Column *>::iterator itr, itr_end;
364 vector<Column *> *cols=nullptr;
365 Column *col=nullptr;
366
367 //Gets the column list using the specified internal list type
368 if(col_type==ReferencedCols)
369 cols=&ref_columns;
370 else
371 cols=&columns;
372
373 itr=cols->begin();
374 itr_end=cols->end();
375
376 while(itr!=itr_end)
377 {
378 col=(*itr);
379
380 //Case the column is found
381 if(col->getName()==name)
382 {
383 if(constr_type==ConstraintType::PrimaryKey)
384 col->setNotNull(false);
385
386 //Remove its iterator from the list
387 cols->erase(itr);
388 setCodeInvalidated(true);
389 break;
390 }
391 else itr++;
392 }
393 }
394
getDeferralType()395 DeferralType Constraint::getDeferralType()
396 {
397 return deferral_type;
398 }
399
isDeferrable()400 bool Constraint::isDeferrable()
401 {
402 return deferrable;
403 }
404
isNoInherit()405 bool Constraint::isNoInherit()
406 {
407 return no_inherit;
408 }
409
isReferRelationshipAddedColumn()410 bool Constraint::isReferRelationshipAddedColumn()
411 {
412 vector<Column *>::iterator itr, itr_end;
413 vector<ExcludeElement>::iterator itr1, itr1_end;
414 Column *col=nullptr;
415 bool found=false;
416
417 //First iterates over the source columns list
418 itr=columns.begin();
419 itr_end=columns.end();
420
421 while(itr!=itr_end && !found)
422 {
423 col=(*itr);
424 //Check if the current column were added by relationship
425 found=col->isAddedByRelationship();
426 itr++;
427
428 /* Case the source column list is completely iterated steps to
429 the referenced columns list iteration */
430 if(itr==itr_end && itr_end!=ref_columns.end() && !found)
431 {
432 itr=ref_columns.begin();
433 itr_end=ref_columns.end();
434 }
435 }
436
437 //Iterates over the exclude elements
438 itr1=excl_elements.begin();
439 itr1_end=excl_elements.end();
440
441 while(itr1!=itr1_end && !found)
442 {
443 col=(*itr1).getColumn();
444 found=(col && col->isAddedByRelationship());
445 itr1++;
446 }
447
448 return found;
449 }
450
getRelationshipAddedColumns()451 vector<Column *> Constraint::getRelationshipAddedColumns()
452 {
453 Column *column=nullptr;
454 vector<Column *> cols;
455 vector<vector<Column *> *> lists = { &columns, &ref_columns };
456
457 for(auto &p_lst : lists)
458 {
459 for(auto &col : (*p_lst))
460 {
461 if(col->isAddedByRelationship())
462 cols.push_back(col);
463 }
464 }
465
466 for(auto &excl_elem : excl_elements)
467 {
468 column=excl_elem.getColumn();
469 if(column && column->isAddedByRelationship())
470 cols.push_back(column);
471 }
472
473 return cols;
474 }
475
getMatchType()476 MatchType Constraint::getMatchType()
477 {
478 return match_type;
479 }
480
481
getExcludeElementIndex(ExcludeElement elem)482 int Constraint::getExcludeElementIndex(ExcludeElement elem)
483 {
484 int idx=0;
485 bool found=false;
486
487 while(idx < static_cast<int>(excl_elements.size()) && !found)
488 {
489 found=(excl_elements[idx]==elem);
490 if(!found) idx++;
491 }
492
493 return (found ? idx : -1);
494 }
495
getExcludeElements()496 vector<ExcludeElement> Constraint::getExcludeElements()
497 {
498 return excl_elements;
499 }
500
addExcludeElements(vector<ExcludeElement> & elems)501 void Constraint::addExcludeElements(vector<ExcludeElement> &elems)
502 {
503 vector<ExcludeElement> elems_bkp=excl_elements;
504
505 try
506 {
507 excl_elements.clear();
508
509 for(unsigned i=0; i < elems.size(); i++)
510 addExcludeElement(elems[i]);
511 }
512 catch(Exception &e)
513 {
514 excl_elements = elems_bkp;
515 throw Exception(e.getErrorMessage(), e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
516 }
517 }
518
addExcludeElement(ExcludeElement elem)519 void Constraint::addExcludeElement(ExcludeElement elem)
520 {
521 if(getExcludeElementIndex(elem) >= 0)
522 throw Exception(ErrorCode::InsDuplicatedElement,__PRETTY_FUNCTION__,__FILE__,__LINE__);
523
524 if(elem.getExpression().isEmpty() && !elem.getColumn())
525 throw Exception(ErrorCode::AsgInvalidExpressionObject,__PRETTY_FUNCTION__,__FILE__,__LINE__);
526
527 excl_elements.push_back(elem);
528 setCodeInvalidated(true);
529 }
530
addExcludeElement(const QString & expr,Operator * oper,OperatorClass * op_class,bool use_sorting,bool asc_order,bool nulls_first)531 void Constraint::addExcludeElement(const QString &expr, Operator *oper, OperatorClass *op_class, bool use_sorting, bool asc_order, bool nulls_first)
532 {
533 try
534 {
535 ExcludeElement elem;
536
537 //Raises an error if the expression is empty
538 if(expr.isEmpty())
539 throw Exception(ErrorCode::AsgInvalidExpressionObject,__PRETTY_FUNCTION__,__FILE__,__LINE__);
540
541 //Configures the element
542 elem.setExpression(expr);
543 elem.setOperatorClass(op_class);
544 elem.setOperator(oper);
545 elem.setSortingEnabled(use_sorting);
546 elem.setSortingAttribute(ExcludeElement::NullsFirst, nulls_first);
547 elem.setSortingAttribute(ExcludeElement::AscOrder, asc_order);
548
549 if(getExcludeElementIndex(elem) >= 0)
550 throw Exception(ErrorCode::InsDuplicatedElement,__PRETTY_FUNCTION__,__FILE__,__LINE__);
551
552 excl_elements.push_back(elem);
553 setCodeInvalidated(true);
554 }
555 catch(Exception &e)
556 {
557 throw Exception(e.getErrorMessage(), e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
558 }
559 }
560
addExcludeElement(Column * column,Operator * oper,OperatorClass * op_class,bool use_sorting,bool asc_order,bool nulls_first)561 void Constraint::addExcludeElement(Column *column, Operator *oper, OperatorClass *op_class, bool use_sorting, bool asc_order, bool nulls_first)
562 {
563 try
564 {
565 ExcludeElement elem;
566
567 //Case the column is not allocated raises an error
568 if(!column)
569 throw Exception(Exception::getErrorMessage(ErrorCode::AsgNotAllocatedColumn)
570 .arg(this->getName())
571 .arg(this->getTypeName()),
572 ErrorCode::AsgNotAllocatedColumn,__PRETTY_FUNCTION__,__FILE__,__LINE__);
573
574 //Configures the element
575 elem.setColumn(column);
576 elem.setOperatorClass(op_class);
577 elem.setOperator(oper);
578 elem.setSortingEnabled(use_sorting);
579 elem.setSortingAttribute(ExcludeElement::NullsFirst, nulls_first);
580 elem.setSortingAttribute(ExcludeElement::AscOrder, asc_order);
581
582 if(getExcludeElementIndex(elem) >= 0)
583 throw Exception(ErrorCode::InsDuplicatedElement,__PRETTY_FUNCTION__,__FILE__,__LINE__);
584
585 excl_elements.push_back(elem);
586 setCodeInvalidated(true);
587 }
588 catch(Exception &e)
589 {
590 throw Exception(e.getErrorMessage(), e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
591 }
592 }
593
removeExcludeElement(unsigned elem_idx)594 void Constraint::removeExcludeElement(unsigned elem_idx)
595 {
596 if(elem_idx >= excl_elements.size())
597 throw Exception(ErrorCode::RefElementInvalidIndex,__PRETTY_FUNCTION__,__FILE__,__LINE__);
598
599 excl_elements.erase(excl_elements.begin() + elem_idx);
600 setCodeInvalidated(true);
601 }
602
removeExcludeElements()603 void Constraint::removeExcludeElements()
604 {
605 excl_elements.clear();
606 setCodeInvalidated(true);
607 }
608
setColumnsNotNull(bool value)609 void Constraint::setColumnsNotNull(bool value)
610 {
611 if(constr_type==ConstraintType::PrimaryKey)
612 {
613 for(auto &col : columns)
614 {
615 //if(!col->isAddedByRelationship())
616 col->setNotNull(value);
617 }
618 }
619 }
620
getExcludeElement(unsigned elem_idx)621 ExcludeElement Constraint::getExcludeElement(unsigned elem_idx)
622 {
623 if(elem_idx >= excl_elements.size())
624 throw Exception(ErrorCode::RefElementInvalidIndex,__PRETTY_FUNCTION__,__FILE__,__LINE__);
625
626 return excl_elements[elem_idx];
627 }
628
getExcludeElementCount()629 unsigned Constraint::getExcludeElementCount()
630 {
631 return excl_elements.size();
632 }
633
setExcludeElementsAttribute(unsigned def_type)634 void Constraint::setExcludeElementsAttribute(unsigned def_type)
635 {
636 QString str_elem;
637 unsigned i, count;
638
639 count=excl_elements.size();
640 for(i=0; i < count; i++)
641 {
642 str_elem+=excl_elements[i].getCodeDefinition(def_type);
643 if(i < (count-1) && def_type==SchemaParser::SqlDefinition) str_elem+=',';
644 }
645
646 attributes[Attributes::Elements]=str_elem;
647 }
648
setIndexType(IndexingType index_type)649 void Constraint::setIndexType(IndexingType index_type)
650 {
651 this->index_type=index_type;
652 }
653
getIndexType()654 IndexingType Constraint::getIndexType()
655 {
656 return index_type;
657 }
658
getCodeDefinition(unsigned def_type)659 QString Constraint::getCodeDefinition(unsigned def_type)
660 {
661 return getCodeDefinition(def_type, false);
662 }
663
setDeclInTableAttribute()664 void Constraint::setDeclInTableAttribute()
665 {
666 if(!isDeclaredInTable() || (constr_type==ConstraintType::ForeignKey && !isAddedByLinking()))
667 attributes[Attributes::DeclInTable]="";
668 else if(!isReferRelationshipAddedColumn() || constr_type==ConstraintType::PrimaryKey)
669 attributes[Attributes::DeclInTable]=Attributes::True;
670 }
671
getCodeDefinition(unsigned def_type,bool inc_addedbyrel)672 QString Constraint::getCodeDefinition(unsigned def_type, bool inc_addedbyrel)
673 {
674 QString code_def=getCachedCode(def_type, false);
675 if(!inc_addedbyrel && !code_def.isEmpty()) return code_def;
676
677 QString attrib;
678
679 attributes[Attributes::PkConstr]="";
680 attributes[Attributes::FkConstr]="";
681 attributes[Attributes::CkConstr]="";
682 attributes[Attributes::UqConstr]="";
683 attributes[Attributes::ExConstr]="";
684
685 switch(!constr_type)
686 {
687 case ConstraintType::Check:
688 attrib=Attributes::CkConstr;
689 break;
690 case ConstraintType::PrimaryKey:
691 attrib=Attributes::PkConstr;
692 break;
693 case ConstraintType::ForeignKey:
694 attrib=Attributes::FkConstr;
695 break;
696 case ConstraintType::Unique:
697 attrib=Attributes::UqConstr;
698 break;
699 default:
700 attrib=Attributes::ExConstr;
701 break;
702 }
703 attributes[attrib]=Attributes::True;
704
705 attributes[Attributes::Type]=attrib;
706 attributes[Attributes::UpdAction]=(~upd_action);
707 attributes[Attributes::DelAction]=(~del_action);
708 attributes[Attributes::Expression]=expression;
709
710 if(constr_type!=ConstraintType::Check)
711 {
712 if(constr_type!=ConstraintType::Exclude)
713 setColumnsAttribute(SourceCols, def_type, inc_addedbyrel);
714 else
715 setExcludeElementsAttribute(def_type);
716
717 /* Only generates the definition of the foreign key referenced columns
718 if the number of columns of the source and referenced cols list are equal,
719 this means the constraint is configured correctly, otherwise don't generates
720 the attribute forcing the schema parser to return an error because the foreign key is
721 misconfigured. */
722 if(constr_type==ConstraintType::ForeignKey && columns.size() == ref_columns.size())
723 setColumnsAttribute(ReferencedCols, def_type, inc_addedbyrel);
724 }
725
726 attributes[Attributes::RefTable]=(ref_table ? ref_table->getName(true) : "");
727 attributes[Attributes::Deferrable]=(deferrable ? Attributes::True : "");
728 attributes[Attributes::NoInherit]=(no_inherit ? Attributes::True : "");
729 attributes[Attributes::ComparisonType]=(~match_type);
730 attributes[Attributes::DeferType]=(~deferral_type);
731 attributes[Attributes::IndexType]=(~ index_type);
732
733 if(getParentTable())
734 attributes[Attributes::Table]=getParentTable()->getName(true);
735
736 setDeclInTableAttribute();
737
738 if(fill_factor!=0 && (constr_type==ConstraintType::PrimaryKey || constr_type==ConstraintType::Unique))
739 attributes[Attributes::Factor]=QString("%1").arg(fill_factor);
740 else
741 attributes[Attributes::Factor]="";
742
743 return BaseObject::__getCodeDefinition(def_type);
744 }
745
getDropDefinition(bool cascade)746 QString Constraint::getDropDefinition(bool cascade)
747 {
748 setDeclInTableAttribute();
749 return TableObject::getDropDefinition(cascade);
750 }
751
getSignature(bool format)752 QString Constraint::getSignature(bool format)
753 {
754 if(!getParentTable())
755 return BaseObject::getSignature(format);
756
757 return QString("%1 ON %2 ").arg(this->getName(format)).arg(getParentTable()->getSignature(true));
758 }
759
isCodeDiffersFrom(BaseObject * object,const vector<QString> & ignored_attribs,const vector<QString> & ignored_tags)760 bool Constraint::isCodeDiffersFrom(BaseObject *object, const vector<QString> &ignored_attribs, const vector<QString> &ignored_tags)
761 {
762 if(!object)
763 throw Exception(ErrorCode::OprNotAllocatedObject,__PRETTY_FUNCTION__,__FILE__,__LINE__);
764 else if(object->getObjectType()!=this->getObjectType())
765 throw Exception(ErrorCode::OprObjectInvalidType,__PRETTY_FUNCTION__,__FILE__,__LINE__);
766
767 try
768 {
769 return BaseObject::isCodeDiffersFrom(this->getCodeDefinition(SchemaParser::XmlDefinition, true),
770 object->getCodeDefinition(SchemaParser::XmlDefinition, true),
771 ignored_attribs, ignored_tags);
772 }
773 catch(Exception &e)
774 {
775 throw Exception(e.getErrorMessage(), e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e);
776 }
777 }
778