Skip to content

Commit

Permalink
Fixed the relationship conversion feature to preserve layer information
Browse files Browse the repository at this point in the history
(issue #1856)

Moved the (set|get)ParentRelationship from Column to TableObject

Minor fix in Relationship class to set the parent relationship attribute
on all generated constraints
  • Loading branch information
rkhaotix committed Feb 28, 2024
1 parent 0cfa8db commit 64f6d0d
Show file tree
Hide file tree
Showing 13 changed files with 111 additions and 99 deletions.
17 changes: 2 additions & 15 deletions libs/libcore/src/column.cpp
Expand Up @@ -40,7 +40,7 @@ Column::Column()
attributes[Attributes::Cache]="";
attributes[Attributes::Cycle]="";

parent_rel=sequence=nullptr;
sequence=nullptr;
identity_type = IdentityType::Null;
}

Expand Down Expand Up @@ -168,19 +168,6 @@ QString Column::getOldName(bool format)
return old_name;
}

void Column::setParentRelationship(BaseObject *parent_rel)
{
if(parent_rel && parent_rel->getObjectType()!=ObjectType::Relationship)
throw Exception(ErrorCode::AsgObjectInvalidType,__PRETTY_FUNCTION__,__FILE__,__LINE__);

this->parent_rel=parent_rel;
}

BaseObject *Column::getParentRelationship()
{
return parent_rel;
}

void Column::setSequence(BaseObject *seq)
{
if(seq)
Expand Down Expand Up @@ -429,7 +416,6 @@ void Column::operator = (Column &col)

this->not_null=col.not_null;
this->generated=col.generated;
this->parent_rel=col.parent_rel;
this->sequence=col.sequence;
this->identity_type=col.identity_type;

Expand All @@ -445,6 +431,7 @@ void Column::operator = (Column &col)
this->setAddedByGeneralization(false);
this->setAddedByLinking(false);
this->setCodeInvalidated(true);
this->setParentRelationship(col.getParentRelationship());
}

QString Column::getDataDictionary(const attribs_map &extra_attribs)
Expand Down
9 changes: 1 addition & 8 deletions libs/libcore/src/column.h
Expand Up @@ -53,11 +53,8 @@ class __libcore Column: public TableObject{
for a date the defaul value should be '2006-09-12 ' and so on. */
QString default_value;

//! \brief Stores a reference to the relationship that generates the column
BaseObject *parent_rel;

/*! \brief Stores a reference to the sequence used to generate the default value.
This attribute is used only the data type is integer, smallint or bigint */
* This attribute is used only the data type is integer, smallint or bigint */
BaseObject *sequence;

//! \brief Identity type of the column (GENERATED BY DEFAULT | ALWAYS)
Expand Down Expand Up @@ -143,10 +140,6 @@ class __libcore Column: public TableObject{
//! \brief Returns the reference to the column type in the form [schema].table.column_name%TYPE
QString getTypeReference();

void setParentRelationship(BaseObject *parent_rel);

BaseObject *getParentRelationship();

//! \brief Set the sequence that will generate the default value for the column
void setSequence(BaseObject *seq);

Expand Down
86 changes: 38 additions & 48 deletions libs/libcore/src/constraint.cpp
Expand Up @@ -429,78 +429,68 @@ bool Constraint::isNoInherit()
return no_inherit;
}

bool Constraint::isReferRelationshipAddedColumn()
bool Constraint::isReferRelationshipAddedColumns(const std::vector<Column *> &cols)
{
std::vector<Column *>::iterator itr, itr_end;
std::vector<ExcludeElement>::iterator itr1, itr1_end;
Column *col=nullptr;
bool found=false;
std::vector<Column *> rel_cols = getRelationshipAddedColumns(cols.empty());

//First iterates over the source columns list
itr=columns.begin();
itr_end=columns.end();

while(itr!=itr_end && !found)
if(!cols.empty())
{
col=(*itr);
//Check if the current column were added by relationship
found=col->isAddedByRelationship();
itr++;

/* Case the source column list is completely iterated steps to
the referenced columns list iteration */
if(itr==itr_end && itr_end!=ref_columns.end() && !found)
{
itr=ref_columns.begin();
itr_end=ref_columns.end();
}
}
auto find_cols = [&rel_cols, &cols]() {
for(auto &col : cols)
{
if(std::find(rel_cols.begin(), rel_cols.end(), col) != rel_cols.end())
return true;
}

//Iterates over the exclude elements
itr1=excl_elements.begin();
itr1_end=excl_elements.end();
return false;
};

while(itr1!=itr1_end && !found)
{
col=(*itr1).getColumn();
found=(col && col->isAddedByRelationship());
itr1++;
return find_cols();
}

return found;
return !rel_cols.empty();
}

std::vector<Column *> Constraint::getRelationshipAddedColumns()
std::vector<Column *> Constraint::getRelationshipAddedColumns(bool first_col_only)
{
Column *column=nullptr;
std::vector<Column *> cols;
std::vector<std::vector<Column *> *> lists = { &columns, &ref_columns };
std::vector<Column *> rel_cols;
Column *col = nullptr;

std::for_each(columns.begin(), columns.end(), [&rel_cols](auto &col) {
if(col->isAddedByRelationship())
rel_cols.push_back(col);
});

for(auto &p_lst : lists)
if(!first_col_only || (first_col_only && rel_cols.empty()))
{
for(auto &col : (*p_lst))
{
std::for_each(ref_columns.begin(), ref_columns.end(), [&rel_cols](auto &col) {
if(col->isAddedByRelationship())
cols.push_back(col);
}
rel_cols.push_back(col);
});
}

for(auto &excl_elem : excl_elements)
if(!first_col_only || (first_col_only && rel_cols.empty()))
{
column=excl_elem.getColumn();
if(column && column->isAddedByRelationship())
cols.push_back(column);
std::for_each(excl_elements.begin(), excl_elements.end(), [&rel_cols, &col](auto &elem) {
col = elem.getColumn();
if(col && col->isAddedByRelationship())
rel_cols.push_back(col);
});
}

return cols;
return rel_cols;
}

std::vector<Column *> Constraint::getRelationshipAddedColumns()
{
return getRelationshipAddedColumns(false);
}

MatchType Constraint::getMatchType()
{
return match_type;
}


int Constraint::getExcludeElementIndex(ExcludeElement elem)
{
int idx=0;
Expand Down Expand Up @@ -627,7 +617,7 @@ void Constraint::setDeclInTableAttribute()
{
if(!isDeclaredInTable() || (constr_type==ConstraintType::ForeignKey && !isAddedByLinking()))
attributes[Attributes::DeclInTable]="";
else if(!isReferRelationshipAddedColumn() || constr_type==ConstraintType::PrimaryKey)
else if(!isReferRelationshipAddedColumns() || constr_type==ConstraintType::PrimaryKey)
attributes[Attributes::DeclInTable]=Attributes::True;
}

Expand Down
21 changes: 13 additions & 8 deletions libs/libcore/src/constraint.h
Expand Up @@ -105,6 +105,11 @@ class __libcore Constraint: public TableObject{

void setDeclInTableAttribute();

/*! \brief Returns the list of all columns that is created by relationships.
* The parameter first_col_only will return as soon as the first column added
* by a relationship is found. */
std::vector<Column *> getRelationshipAddedColumns(bool first_col_only);

protected:
virtual void configureSearchAttributes() override;

Expand Down Expand Up @@ -212,16 +217,16 @@ class __libcore Constraint: public TableObject{
bool isNoInherit();

/*! \brief Returns whether the constraint references columns added
by relationship. This method is used as auxiliary
to control which constraints reference columns added by the
relationship in order to avoid referece breaking due constants
connections and disconnections of relationships */
bool isReferRelationshipAddedColumn();
* by relationship. This method is used as auxiliary to control which
* constraints reference columns added by the relationship in order to
* avoid referece breaking due constants connections and disconnections
* of relationships */
bool isReferRelationshipAddedColumns(const std::vector<Column *> &cols = {});

/*! \brief Returns the list of all columns that is created by relationships.
This method is slower than isReferRelationshipAddedColumn() so it's not
recommended to use it only check if the object is referencing columns
added by relationship */
* this method is slower than isReferRelationshipAddedColumn() so it's not
* recommended to use it only to check if the object is referencing columns
* added by relationship. */
std::vector<Column *> getRelationshipAddedColumns();

//! \brief Returns the matching type adopted by the constraint
Expand Down
8 changes: 4 additions & 4 deletions libs/libcore/src/databasemodel.cpp
Expand Up @@ -2101,7 +2101,7 @@ void DatabaseModel::storeSpecialObjectsXML()
relationship added column and the constraint itself was not added by
relationship (created manually by the user) */
found=(!constr->isAddedByRelationship() &&
constr->isReferRelationshipAddedColumn() &&
constr->isReferRelationshipAddedColumns() &&
constr->getConstraintType()!=ConstraintType::PrimaryKey);

//When found some special object, stores is xml definition
Expand Down Expand Up @@ -7885,7 +7885,7 @@ std::map<unsigned, BaseObject *> DatabaseModel::getCreationOrder(SchemaParser::C
configuration, foreign keys are discarded in this iteration because on the end of the method
they have the definition generated */
if(constr->getConstraintType()!=ConstraintType::ForeignKey && !constr->isAddedByLinking() &&
((constr->getConstraintType()!=ConstraintType::PrimaryKey && constr->isReferRelationshipAddedColumn())))
((constr->getConstraintType()!=ConstraintType::PrimaryKey && constr->isReferRelationshipAddedColumns())))
objects_map[constr->getObjectId()]=constr;
else if(constr->getConstraintType()==ConstraintType::ForeignKey && !constr->isAddedByLinking())
fkeys.push_back(constr);
Expand Down Expand Up @@ -8071,7 +8071,7 @@ std::map<unsigned, BaseObject *> DatabaseModel::getCreationOrder(SchemaParser::C
((constr->getConstraintType()==ConstraintType::ForeignKey) ||
(constr->getConstraintType()!=ConstraintType::ForeignKey &&
constr->getConstraintType()!=ConstraintType::PrimaryKey &&
constr->isReferRelationshipAddedColumn()))))
constr->isReferRelationshipAddedColumns()))))
{
__getObjectDependencies(child, objs);
Expand Down Expand Up @@ -8158,7 +8158,7 @@ std::vector<BaseObject *> DatabaseModel::getCreationOrder(BaseObject *object, bo
((constr->getConstraintType()==ConstraintType::ForeignKey) ||
(constr->getConstraintType()!=ConstraintType::ForeignKey &&
constr->getConstraintType()!=ConstraintType::PrimaryKey &&
constr->isReferRelationshipAddedColumn()))))
constr->isReferRelationshipAddedColumns()))))
{
objs_aux.push_back(child);
}
Expand Down
2 changes: 1 addition & 1 deletion libs/libcore/src/operationlist.cpp
Expand Up @@ -422,7 +422,7 @@ int OperationList::registerObject(BaseObject *object, Operation::OperType op_typ

if(((obj_type==ObjectType::Trigger && dynamic_cast<Trigger *>(tab_obj)->isReferRelationshipAddedColumn()) ||
(obj_type==ObjectType::Index && dynamic_cast<Index *>(tab_obj)->isReferRelationshipAddedColumn()) ||
(obj_type==ObjectType::Constraint && dynamic_cast<Constraint *>(tab_obj)->isReferRelationshipAddedColumn())))
(obj_type==ObjectType::Constraint && dynamic_cast<Constraint *>(tab_obj)->isReferRelationshipAddedColumns())))
{
if(op_type==Operation::ObjRemoved)
tab_obj->setParentTable(parent_tab);
Expand Down
4 changes: 2 additions & 2 deletions libs/libcore/src/physicaltable.cpp
Expand Up @@ -293,12 +293,12 @@ void PhysicalTable::setConstraintsAttribute(SchemaParser::CodeType def_type)
if(constr->getConstraintType()!=ConstraintType::ForeignKey &&

((def_type==SchemaParser::SqlCode &&
((!constr->isReferRelationshipAddedColumn() && constr->getConstraintType()!=ConstraintType::Check) ||
((!constr->isReferRelationshipAddedColumns() && constr->getConstraintType()!=ConstraintType::Check) ||
(constr->getConstraintType()==ConstraintType::Check && !constr->isAddedByGeneralization()) ||
constr->getConstraintType()==ConstraintType::PrimaryKey)) ||

(def_type==SchemaParser::XmlCode && !constr->isAddedByRelationship() &&
((constr->getConstraintType()!=ConstraintType::PrimaryKey && !constr->isReferRelationshipAddedColumn()) ||
((constr->getConstraintType()!=ConstraintType::PrimaryKey && !constr->isReferRelationshipAddedColumns()) ||
(constr->getConstraintType()==ConstraintType::PrimaryKey)))))
{
inc_added_by_rel=(def_type==SchemaParser::SqlCode);
Expand Down
11 changes: 10 additions & 1 deletion libs/libcore/src/relationship.cpp
Expand Up @@ -352,6 +352,7 @@ void Relationship::createSpecialPrimaryKey()
pk_special->setAlias(generateObjectName(PkPattern, nullptr, true));
pk_special->setConstraintType(ConstraintType::PrimaryKey);
pk_special->setAddedByLinking(true);
pk_special->setParentRelationship(this);
pk_special->setProtected(true);
pk_special->setTablespace(dynamic_cast<Tablespace *>(getReceiverTable()->getTablespace()));

Expand Down Expand Up @@ -594,6 +595,7 @@ void Relationship::addObject(TableObject *tab_obj, int obj_idx)

//Defines the parent table for the object only for validation
tab_obj->setParentTable(src_table);
tab_obj->setParentRelationship(this);

//Generates the code for the object only for validation
if(obj_type==ObjectType::Column)
Expand Down Expand Up @@ -909,6 +911,7 @@ void Relationship::addConstraints(PhysicalTable *recv_tab)
{
constr=dynamic_cast<Constraint *>(rel_constraints[constr_id]);
constr->setAddedByLinking(true);
constr->setParentRelationship(this);

//Breaks the iteration if the constraist has a parent
if(constr->getParentTable())
Expand Down Expand Up @@ -1280,6 +1283,7 @@ void Relationship::addCheckConstrsRelGenPart()
ck_constr = createObject<Constraint>();
(*ck_constr)=(*constr);
ck_constr->setParentTable(nullptr);
ck_constr->setParentRelationship(this);
ck_constr->setAddedByGeneralization(true);
child_tab->addConstraint(ck_constr);
ck_constraints.push_back(ck_constr);
Expand Down Expand Up @@ -1485,6 +1489,7 @@ void Relationship::configureIndentifierRel(PhysicalTable *recv_tab)
pk = createObject<Constraint>();
pk->setConstraintType(ConstraintType::PrimaryKey);
pk->setAddedByLinking(true);
pk->setParentRelationship(this);
pk->setDeferrable(this->deferrable);
pk->setDeferralType(this->deferral_type);
this->pk_relident=pk;
Expand Down Expand Up @@ -1547,6 +1552,7 @@ void Relationship::addUniqueKey(PhysicalTable *recv_tab)
uq->setDeferralType(this->deferral_type);
uq->setConstraintType(ConstraintType::Unique);
uq->setAddedByLinking(true);
uq->setParentRelationship(this);
uq_rel11=uq;
}

Expand Down Expand Up @@ -1608,6 +1614,7 @@ void Relationship::addForeignKey(PhysicalTable *ref_tab, PhysicalTable *recv_tab
fk->setDeferralType(this->deferral_type);
fk->setConstraintType(ConstraintType::ForeignKey);
fk->setAddedByLinking(true);
fk->setParentRelationship(this);

//The reference table is the table referenced by the foreign key
fk->setReferencedTable(ref_tab);
Expand Down Expand Up @@ -2075,6 +2082,7 @@ void Relationship::addColumnsRelNn()
pk_col->setAlias(generateObjectName(PkColPattern, nullptr, true));
pk_col->setType(PgSqlType("serial"));
pk_col->setAddedByLinking(true);
pk_col->setParentRelationship(this);
table_relnn->addColumn(pk_col);
}

Expand All @@ -2085,6 +2093,7 @@ void Relationship::addColumnsRelNn()
pk_tabnn->setAlias(generateObjectName(PkPattern, nullptr, true));
pk_tabnn->setConstraintType(ConstraintType::PrimaryKey);
pk_tabnn->setAddedByLinking(true);
pk_tabnn->setParentRelationship(this);

if(!single_pk_column)
{
Expand Down Expand Up @@ -2237,7 +2246,7 @@ void Relationship::removeTableObjectsRefCols(PhysicalTable *table)
constr=table->getConstraint(i);
if(!constr->isAddedByRelationship() &&
constr->getConstraintType()!=ConstraintType::PrimaryKey &&
constr->isReferRelationshipAddedColumn())
constr->isReferRelationshipAddedColumns())
{
table->removeObject(constr);
delete constr;
Expand Down

0 comments on commit 64f6d0d

Please sign in to comment.