implement 2 columns + adapt attachRelations

This commit is contained in:
Pierre Noël 2022-09-07 18:21:54 +02:00
parent a1d1879ffb
commit c4031449fb
2 changed files with 61 additions and 7 deletions

View File

@ -475,26 +475,45 @@ const createEntityManager = (db) => {
// need to set the column on the target
const { joinTable } = attribute;
const { joinColumn, inverseJoinColumn } = joinTable;
const { joinColumn, inverseJoinColumn, orderColumnName, inverseOrderColumnName } =
joinTable;
if (isOneToAny(attribute) && isBidirectional(attribute)) {
await this.createQueryBuilder(joinTable.name)
.delete()
.where({ [inverseJoinColumn.name]: castArray(data[attributeName]) })
.where({ [inverseJoinColumn.name]: castArray(data[attributeName]) }) // TODO: would break with connect
.where(joinTable.on || {})
.execute();
}
const assocs = toAssocs(data[attributeName]);
const relationsToAdd = assocs.connect || assocs;
const relationsToAdd = uniqBy('id', assocs.connect || assocs);
const maxMap = {};
if (inverseOrderColumnName) {
await Promise.all(
relationsToAdd.map(async (rel) => {
const { max } = await this.createQueryBuilder(joinTable.name)
.max(inverseOrderColumnName)
.where({ [inverseJoinColumn.name]: rel.id })
.where(joinTable.on || {})
.first()
.execute();
maxMap[rel.id] = max;
})
);
}
const insert = relationsToAdd.map((data, idx) => {
return {
[joinColumn.name]: id,
[inverseJoinColumn.name]: data.id,
...(joinTable.on || {}),
...(data.__pivot || {}),
order: idx + 1,
[orderColumnName]: idx + 1,
...(inverseOrderColumnName ? { [inverseOrderColumnName]: maxMap[data.id] + 1 } : {}),
};
});

View File

@ -398,12 +398,14 @@ const createJoinTable = (metadata, { attributeName, attribute, meta }) => {
const joinColumnName = _.snakeCase(`${meta.singularName}_id`);
let inverseJoinColumnName = _.snakeCase(`${targetMeta.singularName}_id`);
const orderColumnName = _.snakeCase(`${meta.singularName}_order`);
// if relation is slef referencing
if (joinColumnName === inverseJoinColumnName) {
inverseJoinColumnName = `inv_${inverseJoinColumnName}`;
}
metadata.add({
const metadataSchema = {
uid: joinTableName,
tableName: joinTableName,
attributes: {
@ -422,7 +424,7 @@ const createJoinTable = (metadata, { attributeName, attribute, meta }) => {
unsigned: true,
},
},
order: {
[orderColumnName]: {
type: 'integer',
column: {
unsigned: true,
@ -440,6 +442,10 @@ const createJoinTable = (metadata, { attributeName, attribute, meta }) => {
name: `${joinTableName}_inv_fk`,
columns: [inverseJoinColumnName],
},
{
name: `${joinTableName}_order_fk`,
columns: [orderColumnName],
},
],
foreignKeys: [
{
@ -457,7 +463,7 @@ const createJoinTable = (metadata, { attributeName, attribute, meta }) => {
onDelete: 'CASCADE',
},
],
});
};
const joinTable = {
name: joinTableName,
@ -469,8 +475,35 @@ const createJoinTable = (metadata, { attributeName, attribute, meta }) => {
name: inverseJoinColumnName,
referencedColumn: 'id',
},
orderColumnName,
};
if (isBidirectional(attribute)) {
let inverseOrderColumnName = _.snakeCase(`${targetMeta.singularName}_order`);
// if relation is slef referencing
if (joinColumnName === inverseJoinColumnName) {
inverseOrderColumnName = `inv_${inverseOrderColumnName}`;
}
metadataSchema.attributes[inverseOrderColumnName] = {
type: 'integer',
column: {
unsigned: true,
defaultTo: 0,
},
};
metadataSchema.indexes.push({
name: `${joinTableName}_order_inv_fk`,
columns: [inverseOrderColumnName],
});
joinTable.inverseOrderColumnName = inverseOrderColumnName;
}
metadata.add(metadataSchema);
attribute.joinTable = joinTable;
if (isBidirectional(attribute)) {
@ -486,6 +519,8 @@ const createJoinTable = (metadata, { attributeName, attribute, meta }) => {
name: joinTableName,
joinColumn: joinTable.inverseJoinColumn,
inverseJoinColumn: joinTable.joinColumn,
orderColumnName: joinTable.inverseOrderColumnName,
inverseOrderColumnName: joinTable.orderColumnName,
};
}
};