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 // need to set the column on the target
const { joinTable } = attribute; const { joinTable } = attribute;
const { joinColumn, inverseJoinColumn } = joinTable; const { joinColumn, inverseJoinColumn, orderColumnName, inverseOrderColumnName } =
joinTable;
if (isOneToAny(attribute) && isBidirectional(attribute)) { if (isOneToAny(attribute) && isBidirectional(attribute)) {
await this.createQueryBuilder(joinTable.name) await this.createQueryBuilder(joinTable.name)
.delete() .delete()
.where({ [inverseJoinColumn.name]: castArray(data[attributeName]) }) .where({ [inverseJoinColumn.name]: castArray(data[attributeName]) }) // TODO: would break with connect
.where(joinTable.on || {}) .where(joinTable.on || {})
.execute(); .execute();
} }
const assocs = toAssocs(data[attributeName]); 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) => { const insert = relationsToAdd.map((data, idx) => {
return { return {
[joinColumn.name]: id, [joinColumn.name]: id,
[inverseJoinColumn.name]: data.id, [inverseJoinColumn.name]: data.id,
...(joinTable.on || {}), ...(joinTable.on || {}),
...(data.__pivot || {}), ...(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`); const joinColumnName = _.snakeCase(`${meta.singularName}_id`);
let inverseJoinColumnName = _.snakeCase(`${targetMeta.singularName}_id`); let inverseJoinColumnName = _.snakeCase(`${targetMeta.singularName}_id`);
const orderColumnName = _.snakeCase(`${meta.singularName}_order`);
// if relation is slef referencing // if relation is slef referencing
if (joinColumnName === inverseJoinColumnName) { if (joinColumnName === inverseJoinColumnName) {
inverseJoinColumnName = `inv_${inverseJoinColumnName}`; inverseJoinColumnName = `inv_${inverseJoinColumnName}`;
} }
metadata.add({ const metadataSchema = {
uid: joinTableName, uid: joinTableName,
tableName: joinTableName, tableName: joinTableName,
attributes: { attributes: {
@ -422,7 +424,7 @@ const createJoinTable = (metadata, { attributeName, attribute, meta }) => {
unsigned: true, unsigned: true,
}, },
}, },
order: { [orderColumnName]: {
type: 'integer', type: 'integer',
column: { column: {
unsigned: true, unsigned: true,
@ -440,6 +442,10 @@ const createJoinTable = (metadata, { attributeName, attribute, meta }) => {
name: `${joinTableName}_inv_fk`, name: `${joinTableName}_inv_fk`,
columns: [inverseJoinColumnName], columns: [inverseJoinColumnName],
}, },
{
name: `${joinTableName}_order_fk`,
columns: [orderColumnName],
},
], ],
foreignKeys: [ foreignKeys: [
{ {
@ -457,7 +463,7 @@ const createJoinTable = (metadata, { attributeName, attribute, meta }) => {
onDelete: 'CASCADE', onDelete: 'CASCADE',
}, },
], ],
}); };
const joinTable = { const joinTable = {
name: joinTableName, name: joinTableName,
@ -469,8 +475,35 @@ const createJoinTable = (metadata, { attributeName, attribute, meta }) => {
name: inverseJoinColumnName, name: inverseJoinColumnName,
referencedColumn: 'id', 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; attribute.joinTable = joinTable;
if (isBidirectional(attribute)) { if (isBidirectional(attribute)) {
@ -486,6 +519,8 @@ const createJoinTable = (metadata, { attributeName, attribute, meta }) => {
name: joinTableName, name: joinTableName,
joinColumn: joinTable.inverseJoinColumn, joinColumn: joinTable.inverseJoinColumn,
inverseJoinColumn: joinTable.joinColumn, inverseJoinColumn: joinTable.joinColumn,
orderColumnName: joinTable.inverseOrderColumnName,
inverseOrderColumnName: joinTable.orderColumnName,
}; };
} }
}; };