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 /** 20 \ingroup libpgmodeler 21 \class Constraint 22 \brief Implements the operations to manipulate table constraints (primary keys, foreign key, unique and check). 23 \note <strong>Creation date:</strong> 17/09/2006 24 */ 25 26 #ifndef CONSTRAINT_H 27 #define CONSTRAINT_H 28 29 #include "tableobject.h" 30 #include "tablespace.h" 31 #include "column.h" 32 #include "excludeelement.h" 33 #include "pgsqltypes/constrainttype.h" 34 #include "pgsqltypes/deferraltype.h" 35 #include "pgsqltypes/matchtype.h" 36 #include "pgsqltypes/actiontype.h" 37 38 class Constraint: public TableObject{ 39 private: 40 //! \brief Type of the constraint (primary key, foreign key, unique or check) 41 ConstraintType constr_type; 42 43 //! \brief Indicates if the constraint is deferrable (except for check contraints) 44 bool deferrable, 45 46 //! \brief Indicates if the constraint will be copied or not to the child tables of the contraint's table (only for check constraint) 47 no_inherit; 48 49 //! \brief Deferral type for the constraint (except for check contraints) 50 DeferralType deferral_type; 51 52 //! \brief Matching method used by the constraint (only for foreign key) 53 MatchType match_type; 54 55 //! \brief Indexing type used by the constraint (only for exclude constraints) 56 IndexingType index_type; 57 58 /*! \brief This factor is used to indicate the space usage for the index generated by the constraint. 59 Generally there is no need do fill this attribute but for more refined tuning this can be set. 60 This is applicable only on primary keys and unique. */ 61 unsigned fill_factor; 62 63 /*! \brief Actions taken when delete and update event occurs. This is applicable 64 only for foreign keys */ 65 ActionType del_action, upd_action; 66 67 //! \brief Stores the columns that is referenced by the constraint (except for check constraints) 68 vector<Column *> columns; 69 70 //! \brief Stores the referenced columns from the referenced table primary key 71 vector<Column *> ref_columns; 72 73 //! \brief Stores the exclude elements of the exclude constraint 74 vector<ExcludeElement> excl_elements; 75 76 //! \brief Stores the check expression or the exclude predicate (only for check and exclude constraints) 77 QString expression; 78 79 //! \brief Stores the referenced table (only for foreign keys) 80 BaseTable *ref_table; 81 82 //! \brief Formats the string for constraint columns to be used by the SchemaParser 83 void setColumnsAttribute(unsigned col_type, unsigned def_type, bool inc_addedbyrel=false); 84 85 //! \brief Formats the exclude elements string used by the SchemaParser 86 void setExcludeElementsAttribute(unsigned def_type); 87 88 void setDeclInTableAttribute(); 89 90 public: 91 /*! \brief Access the source columns that means the columns that constrais 92 is applied (from the constraint's parent table) */ 93 static constexpr unsigned SourceCols=0, 94 95 /*! \brief Access the referenced columns that means the columns from the 96 referenced table primary key (only for foreign keys) */ 97 ReferencedCols=1; 98 99 static constexpr unsigned DeleteAction=0, 100 UpdateAction=1; 101 102 Constraint(); 103 virtual ~Constraint(); 104 105 /*! \brief Adds one column to the internal column list referenced by the 106 constants SOURCE_COLS or REFERENCED_COLS */ 107 void addColumn(Column *column, unsigned col_type); 108 109 //! \brief Adds several elements to the constraint using a defined vector 110 void addExcludeElements(vector<ExcludeElement> &elems); 111 112 //! \brief Defines the constraint type 113 void setConstraintType(ConstraintType constr_type); 114 115 //! \brief Defines the type of action on foreign keys (ON DELETE and ON UPDATE). (only for foreign key) 116 void setActionType(ActionType action_type, unsigned act_id); 117 118 //! \brief Defines the deferral type for the constraint (except for check contraints) 119 void setDeferralType(DeferralType deferral_type); 120 121 //! \brief Defines whether the constraint is deferrable (except for check contraints) 122 void setDeferrable(bool value); 123 124 //! \brief Defines the matching type used by the constraint (only for foreign key) 125 void setMatchType(MatchType constr_type); 126 127 //! \brief Defines the indexing type used by the constraint (only for exclude) 128 void setIndexType(IndexingType index_type); 129 130 //! \brief Defines the expresion used by the constraint (only for check and exclude constraint) 131 void setExpression(const QString &expr); 132 133 //! \brief Defines the referenced table (only for foreign key) 134 void setReferencedTable(BaseTable *tab_ref); 135 136 //! \brief Defines the tablespace used by the constraint (only for primary keys and unique) 137 void setTablespace(BaseObject *tabspc); 138 139 /*! \brief Defines the constraint fill factor (only for primary keys and unique). 140 Values less than 10 (except 0) or above 100 will be adjusted to accepted values. To use the default 141 settings specify 0 as fill factor */ 142 void setFillFactor(unsigned factor); 143 144 //! \brief Defines if the constraints is propagated to child tables (only for exclude constraints) 145 void setNoInherit(bool value); 146 147 //! \brief Returns the constraint fill factor 148 unsigned getFillFactor(); 149 150 //! \brief Retuns the action type (ON DELETE or ON UPDATE) of a foreign key 151 ActionType getActionType(unsigned act_id); 152 153 //! \brief Returns the list of columns of the specified type SOURCE_COLS or REFERENCED_COLS 154 vector<Column *> getColumns(unsigned col_type); 155 156 /*! \brief Returns one column (using its index) from the internal constraint column lists. 157 Use the constants SOURCE_COLS or REFERENCED_COLS to access the lists */ 158 Column *getColumn(unsigned col_idx, unsigned col_type); 159 160 /*! \brief Returns one column (using its name) from the internal constraint column lists. 161 Use the constants SOURCE_COLS or REFERENCED_COLS to access the lists */ 162 Column *getColumn(const QString &name, unsigned col_type); 163 164 /*! \brief Returns the column count for one internal list. 165 Use the constants SOURCE_COLS or REFERENCED_COLS to access the lists */ 166 unsigned getColumnCount(unsigned col_type); 167 168 //! \brief Returns the exclude constraint element count 169 unsigned getExcludeElementCount(); 170 171 //! \brief Returns a list of exclude elements 172 vector<ExcludeElement> getExcludeElements(); 173 174 /*! \brief Removes one column from internal list using its name. 175 Use the constants SOURCE_COLS or REFERENCED_COLS to access the lists */ 176 void removeColumn(const QString &name, unsigned col_type); 177 178 //! \brief Remove all columns from the internal lists 179 void removeColumns(); 180 181 //! \brief Returns the constraint type 182 ConstraintType getConstraintType(); 183 184 //! \brief Returns the check expression 185 QString getExpression(); 186 187 //! \brief Returns the referenced table 188 BaseTable *getReferencedTable(); 189 190 //! \brief Returns the constraint's deferral type 191 DeferralType getDeferralType(); 192 193 //! \brief Indicates whether the constraint is deferrable 194 bool isDeferrable(); 195 196 //! \brief Returns if the constraints will propagated to child tables 197 bool isNoInherit(); 198 199 /*! \brief Returns whether the constraint references columns added 200 by relationship. This method is used as auxiliary 201 to control which constraints reference columns added by the 202 relationship in order to avoid referece breaking due constants 203 connections and disconnections of relationships */ 204 bool isReferRelationshipAddedColumn(); 205 206 /*! \brief Returns the list of all columns that is created by relationships. 207 This method is slower than isReferRelationshipAddedColumn() so it's not 208 recommended to use it only check if the object is referencing columns 209 added by relationship */ 210 vector<Column *> getRelationshipAddedColumns(); 211 212 //! \brief Returns the matching type adopted by the constraint 213 MatchType getMatchType(); 214 215 //! \brief Returns the indexing type adopted by the constraint 216 IndexingType getIndexType(); 217 218 /*! \brief Returns the SQL / XML definition for the constraint. 219 This method calls getCodeDefintion(unsigned, bool) with the 220 second parameter as false */ 221 virtual QString getCodeDefinition(unsigned def_type) final; 222 223 /*! \brief Returns the SQL / XML definition for the constraint. The boolean parameter indicates 224 whether the columns added by relationship must appear on the code definition */ 225 virtual QString getCodeDefinition(unsigned def_type, bool inc_addedbyrel) final; 226 227 virtual QString getDropDefinition(bool cascade) final; 228 229 //! \brief Indicates whether the column exists on the specified internal column list 230 bool isColumnExists(Column *column, unsigned col_type); 231 232 /*! \brief Indicates whether the column is referenced in internal column list or exclude element list. 233 The second parameter is useful to permit or not the search of column only on referenced columns list. */ 234 bool isColumnReferenced(Column *column, bool search_only_ref_cols = false); 235 236 //! \brief Indicates whether the columns are referenced in internal column list 237 bool isColumnsExist(vector<Column *> columns, unsigned col_type); 238 239 //! \brief Adds an exclude element to the constraint using an column (only exclude constraint) 240 void addExcludeElement(Column *column, Operator *oper, OperatorClass *op_class, bool use_sorting, bool asc_order, bool nulls_first); 241 242 //! \brief Adds an exclude element to the constraint using an expression (only exclude constraint) 243 void addExcludeElement(const QString &expr, Operator *oper, OperatorClass *op_class, bool use_sorting, bool asc_order, bool nulls_first); 244 245 //! \brief Adds an exclude element to the constraint using other pre-configured element (only exclude constraint) 246 void addExcludeElement(ExcludeElement elem); 247 248 //! \brief Returns one exclude element using its index 249 ExcludeElement getExcludeElement(unsigned elem_idx); 250 251 //! \brief Returns the exclude element index 252 int getExcludeElementIndex(ExcludeElement elem); 253 254 //! \brief Remove an exclude element using its index 255 void removeExcludeElement(unsigned idx_elem); 256 257 //! \brief Remove all exclude elements from the constraint 258 void removeExcludeElements(); 259 260 //! \brief Toggles the not-null flag from source columns on primary key constraints. This methods has no effect in other constraint types 261 void setColumnsNotNull(bool value); 262 263 virtual QString getSignature(bool format) final; 264 265 /*! \brief Compares two constratins XML definition and returns if they differs. This methods varies a little from 266 BaseObject::isCodeDiffersFrom() because here we need to generate xml code including relationship added columns */ 267 virtual bool isCodeDiffersFrom(BaseObject *object, const vector<QString> &ignored_attribs={}, const vector<QString> &ignored_tags={}); 268 }; 269 270 #endif 271