Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions reverse_engineering/helpers/bigQueryHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,31 @@ const createBigQueryHelper = (client, log) => {
return (
await client.query({
query: `SELECT
CCU.column_name as \`parent_column\`,
KCU.column_name as \`child_column\`,
PK.column_name as \`parent_column\`,
FK.column_name as \`child_column\`,
FK.ordinal_position,
TC.constraint_catalog,
TC.constraint_name,
TC.constraint_schema,
TC.constraint_type,
TC.table_catalog,
CCU.table_schema as \`parent_schema\`,
KCU.table_schema as \`child_schema\`,
CCU.table_name as \`parent_table\`,
KCU.table_name as \`child_table\`
FROM (${projectId}.${datasetId}.INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS CCU
INNER JOIN ${projectId}.${datasetId}.INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU
USING(constraint_name))
REF.table_schema as \`parent_schema\`,
FK.table_schema as \`child_schema\`,
REF.table_name as \`parent_table\`,
FK.table_name as \`child_table\`
FROM ${projectId}.${datasetId}.INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS FK
INNER JOIN ${projectId}.${datasetId}.INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
USING(constraint_name)
INNER JOIN (
SELECT DISTINCT constraint_name, table_schema, table_name
FROM ${projectId}.${datasetId}.INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE
) AS REF
USING(constraint_name)
INNER JOIN ${projectId}.${datasetId}.INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS PK
ON PK.table_schema = REF.table_schema
AND PK.table_name = REF.table_name
AND PK.position_in_unique_constraint IS NULL
AND PK.ordinal_position = FK.position_in_unique_constraint

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose we may want to add sorting by constraint name if the flakiness continues, to ensure we always get the same order.
ORDER BY FK.constraint_name.

WHERE TC.constraint_type = "FOREIGN KEY";`,
})
)[0];
Expand Down
55 changes: 22 additions & 33 deletions reverse_engineering/helpers/constraintsHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,39 +90,28 @@ const getConstraintBusinessName = constraintNameFromCloud => {
};

const reverseForeignKeys = foreignKeyConstraintsData => {
return foreignKeyConstraintsData.reduce((constraints, fkConstraintData) => {
const constraintNameToUse = getConstraintBusinessName(fkConstraintData.constraint_name);
const constraintInList = constraints.find(({ relationshipName }) => relationshipName === constraintNameToUse);
const { parent_column, child_column } = fkConstraintData;
if (constraintInList) {
const isParentAdded = constraintInList.parentField.includes(parent_column);
const isChildAdded = constraintInList.childField.includes(child_column);
const newConstraintData = {
...constraintInList,
childField: isChildAdded ? constraintInList.childField : [...constraintInList.childField, child_column],
parentField: isParentAdded
? constraintInList.parentField
: [...constraintInList.parentField, parent_column],
};
return [
...constraints.filter(({ relationshipName }) => relationshipName !== constraintNameToUse),
newConstraintData,
];
} else {
const newConstraint = {
relationshipName: constraintNameToUse,
relationshipType: 'Foreign Key',
childDbName: fkConstraintData.child_schema,
childCollection: fkConstraintData.child_table,
childField: [fkConstraintData.child_column],
dbName: fkConstraintData.parent_schema,
parentCollection: fkConstraintData.parent_table,
parentField: [fkConstraintData.parent_column],
relationshipInfo: {},
};
return [...constraints, newConstraint];
}
}, []);
const constraintNames = [
...new Set(foreignKeyConstraintsData.map(({ constraint_name }) => getConstraintBusinessName(constraint_name))),
];

return constraintNames.map(constraintName => {
const columns = foreignKeyConstraintsData
.filter(({ constraint_name }) => getConstraintBusinessName(constraint_name) === constraintName)
.toSorted((a, b) => a.ordinal_position - b.ordinal_position);
const [firstColumn] = columns;

return {
relationshipName: constraintName,
relationshipType: 'Foreign Key',
childDbName: firstColumn.child_schema,
childCollection: firstColumn.child_table,
childField: columns.map(({ child_column }) => child_column),
dbName: firstColumn.parent_schema,
parentCollection: firstColumn.parent_table,
parentField: columns.map(({ parent_column }) => parent_column),
relationshipInfo: {},
};
});
};

module.exports = {
Expand Down