mirror of
https://github.com/strapi/strapi.git
synced 2025-09-04 14:23:03 +00:00
add transaction in DB entity manager
This commit is contained in:
parent
76c0ffb791
commit
6e67d82f5f
@ -211,12 +211,24 @@ const createEntityManager = (db) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const dataToInsert = processData(metadata, data, { withDefaults: true });
|
const dataToInsert = processData(metadata, data, { withDefaults: true });
|
||||||
|
let id;
|
||||||
|
|
||||||
const res = await this.createQueryBuilder(uid).insert(dataToInsert).execute();
|
const trx = await strapi.db.transaction();
|
||||||
|
try {
|
||||||
|
const res = await this.createQueryBuilder(uid)
|
||||||
|
.insert(dataToInsert)
|
||||||
|
.transacting(trx)
|
||||||
|
.execute();
|
||||||
|
|
||||||
const id = res[0].id || res[0];
|
id = res[0].id || res[0];
|
||||||
|
|
||||||
await this.attachRelations(uid, id, data);
|
await this.attachRelations(uid, id, data, { transaction: trx });
|
||||||
|
|
||||||
|
await trx.commit();
|
||||||
|
} catch (e) {
|
||||||
|
await trx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: in case there is no select or populate specified return the inserted data ?
|
// TODO: in case there is no select or populate specified return the inserted data ?
|
||||||
// TODO: do not trigger the findOne lifecycles ?
|
// TODO: do not trigger the findOne lifecycles ?
|
||||||
@ -281,14 +293,26 @@ const createEntityManager = (db) => {
|
|||||||
|
|
||||||
const { id } = entity;
|
const { id } = entity;
|
||||||
|
|
||||||
const dataToUpdate = processData(metadata, data);
|
const trx = await strapi.db.transaction();
|
||||||
|
try {
|
||||||
|
const dataToUpdate = processData(metadata, data);
|
||||||
|
|
||||||
if (!isEmpty(dataToUpdate)) {
|
if (!isEmpty(dataToUpdate)) {
|
||||||
await this.createQueryBuilder(uid).where({ id }).update(dataToUpdate).execute();
|
await this.createQueryBuilder(uid)
|
||||||
|
.where({ id })
|
||||||
|
.update(dataToUpdate)
|
||||||
|
.transacting(trx)
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.updateRelations(uid, id, data, { transaction: trx });
|
||||||
|
|
||||||
|
await trx.commit();
|
||||||
|
} catch (e) {
|
||||||
|
await trx.rollback();
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.updateRelations(uid, id, data);
|
|
||||||
|
|
||||||
// TODO: do not trigger the findOne lifecycles ?
|
// TODO: do not trigger the findOne lifecycles ?
|
||||||
const result = await this.findOne(uid, {
|
const result = await this.findOne(uid, {
|
||||||
where: { id },
|
where: { id },
|
||||||
@ -348,9 +372,17 @@ const createEntityManager = (db) => {
|
|||||||
|
|
||||||
const { id } = entity;
|
const { id } = entity;
|
||||||
|
|
||||||
await this.createQueryBuilder(uid).where({ id }).delete().execute();
|
const trx = await strapi.db.transaction();
|
||||||
|
try {
|
||||||
|
await this.createQueryBuilder(uid).where({ id }).delete().transacting(trx).execute();
|
||||||
|
|
||||||
await this.deleteRelations(uid, id);
|
await this.deleteRelations(uid, id, { transaction: trx });
|
||||||
|
|
||||||
|
await trx.commit();
|
||||||
|
} catch (e) {
|
||||||
|
await trx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
await db.lifecycles.run('afterDelete', uid, { params, result: entity }, states);
|
await db.lifecycles.run('afterDelete', uid, { params, result: entity }, states);
|
||||||
|
|
||||||
@ -381,7 +413,7 @@ const createEntityManager = (db) => {
|
|||||||
* @param {object} data - data received for creation
|
* @param {object} data - data received for creation
|
||||||
*/
|
*/
|
||||||
// TODO: wrap Transaction
|
// TODO: wrap Transaction
|
||||||
async attachRelations(uid, id, data) {
|
async attachRelations(uid, id, data, { transaction: trx }) {
|
||||||
const { attributes } = db.metadata.get(uid);
|
const { attributes } = db.metadata.get(uid);
|
||||||
|
|
||||||
for (const attributeName of Object.keys(attributes)) {
|
for (const attributeName of Object.keys(attributes)) {
|
||||||
@ -409,6 +441,7 @@ const createEntityManager = (db) => {
|
|||||||
await this.createQueryBuilder(target)
|
await this.createQueryBuilder(target)
|
||||||
.update({ [idColumn.name]: id, [typeColumn.name]: uid })
|
.update({ [idColumn.name]: id, [typeColumn.name]: uid })
|
||||||
.where({ id: relId })
|
.where({ id: relId })
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
} else if (targetAttribute.relation === 'morphToMany') {
|
} else if (targetAttribute.relation === 'morphToMany') {
|
||||||
const { joinTable } = targetAttribute;
|
const { joinTable } = targetAttribute;
|
||||||
@ -432,7 +465,7 @@ const createEntityManager = (db) => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.createQueryBuilder(joinTable.name).insert(rows).execute();
|
await this.createQueryBuilder(joinTable.name).insert(rows).transacting(trx).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -464,9 +497,10 @@ const createEntityManager = (db) => {
|
|||||||
attributeName,
|
attributeName,
|
||||||
joinTable,
|
joinTable,
|
||||||
db,
|
db,
|
||||||
|
transaction: trx,
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.createQueryBuilder(joinTable.name).insert(rows).execute();
|
await this.createQueryBuilder(joinTable.name).insert(rows).transacting(trx).execute();
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -481,6 +515,7 @@ const createEntityManager = (db) => {
|
|||||||
await this.createQueryBuilder(uid)
|
await this.createQueryBuilder(uid)
|
||||||
.where({ [attribute.joinColumn.name]: relIdsToAdd, id: { $ne: id } })
|
.where({ [attribute.joinColumn.name]: relIdsToAdd, id: { $ne: id } })
|
||||||
.update({ [attribute.joinColumn.name]: null })
|
.update({ [attribute.joinColumn.name]: null })
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,12 +533,14 @@ const createEntityManager = (db) => {
|
|||||||
await this.createQueryBuilder(target)
|
await this.createQueryBuilder(target)
|
||||||
.where({ [attribute.joinColumn.referencedColumn]: id })
|
.where({ [attribute.joinColumn.referencedColumn]: id })
|
||||||
.update({ [attribute.joinColumn.referencedColumn]: null })
|
.update({ [attribute.joinColumn.referencedColumn]: null })
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
await this.createQueryBuilder(target)
|
await this.createQueryBuilder(target)
|
||||||
.update({ [attribute.joinColumn.referencedColumn]: id })
|
.update({ [attribute.joinColumn.referencedColumn]: id })
|
||||||
// NOTE: works if it is an array or a single id
|
// NOTE: works if it is an array or a single id
|
||||||
.where({ id: relIdsToAdd })
|
.where({ id: relIdsToAdd })
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,7 +555,13 @@ const createEntityManager = (db) => {
|
|||||||
const relIdsToadd = toIds(relsToAdd);
|
const relIdsToadd = toIds(relsToAdd);
|
||||||
|
|
||||||
if (isBidirectional(attribute) && isOneToAny(attribute)) {
|
if (isBidirectional(attribute) && isOneToAny(attribute)) {
|
||||||
await deletePreviousOneToAnyRelations({ id, attribute, relIdsToadd, db });
|
await deletePreviousOneToAnyRelations({
|
||||||
|
id,
|
||||||
|
attribute,
|
||||||
|
relIdsToadd,
|
||||||
|
db,
|
||||||
|
transaction: trx,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare new relations to insert
|
// prepare new relations to insert
|
||||||
@ -546,7 +589,8 @@ const createEntityManager = (db) => {
|
|||||||
.whereIn(inverseJoinColumn.name, relIdsToadd)
|
.whereIn(inverseJoinColumn.name, relIdsToadd)
|
||||||
.where(joinTable.on || {})
|
.where(joinTable.on || {})
|
||||||
.groupBy(inverseJoinColumn.name)
|
.groupBy(inverseJoinColumn.name)
|
||||||
.from(joinTable.name);
|
.from(joinTable.name)
|
||||||
|
.transacting(trx);
|
||||||
|
|
||||||
const maxMap = maxResults.reduce(
|
const maxMap = maxResults.reduce(
|
||||||
(acc, res) => Object.assign(acc, { [res[inverseJoinColumn.name]]: res.max }),
|
(acc, res) => Object.assign(acc, { [res[inverseJoinColumn.name]]: res.max }),
|
||||||
@ -563,7 +607,7 @@ const createEntityManager = (db) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// insert new relations
|
// insert new relations
|
||||||
await this.createQueryBuilder(joinTable.name).insert(insert).execute();
|
await this.createQueryBuilder(joinTable.name).insert(insert).transacting(trx).execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -578,7 +622,7 @@ const createEntityManager = (db) => {
|
|||||||
*/
|
*/
|
||||||
// TODO: check relation exists (handled by FKs except for polymorphics)
|
// TODO: check relation exists (handled by FKs except for polymorphics)
|
||||||
// TODO: wrap Transaction
|
// TODO: wrap Transaction
|
||||||
async updateRelations(uid, id, data) {
|
async updateRelations(uid, id, data, { transaction: trx }) {
|
||||||
const { attributes } = db.metadata.get(uid);
|
const { attributes } = db.metadata.get(uid);
|
||||||
|
|
||||||
for (const attributeName of Object.keys(attributes)) {
|
for (const attributeName of Object.keys(attributes)) {
|
||||||
@ -603,6 +647,7 @@ const createEntityManager = (db) => {
|
|||||||
await this.createQueryBuilder(target)
|
await this.createQueryBuilder(target)
|
||||||
.update({ [idColumn.name]: null, [typeColumn.name]: null })
|
.update({ [idColumn.name]: null, [typeColumn.name]: null })
|
||||||
.where({ [idColumn.name]: id, [typeColumn.name]: uid })
|
.where({ [idColumn.name]: id, [typeColumn.name]: uid })
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
if (!isNull(cleanRelationData.set)) {
|
if (!isNull(cleanRelationData.set)) {
|
||||||
@ -610,6 +655,7 @@ const createEntityManager = (db) => {
|
|||||||
await this.createQueryBuilder(target)
|
await this.createQueryBuilder(target)
|
||||||
.update({ [idColumn.name]: id, [typeColumn.name]: uid })
|
.update({ [idColumn.name]: id, [typeColumn.name]: uid })
|
||||||
.where({ id: relId })
|
.where({ id: relId })
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
} else if (targetAttribute.relation === 'morphToMany') {
|
} else if (targetAttribute.relation === 'morphToMany') {
|
||||||
@ -626,6 +672,7 @@ const createEntityManager = (db) => {
|
|||||||
...(joinTable.on || {}),
|
...(joinTable.on || {}),
|
||||||
field: attributeName,
|
field: attributeName,
|
||||||
})
|
})
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
if (isEmpty(cleanRelationData.set)) {
|
if (isEmpty(cleanRelationData.set)) {
|
||||||
@ -642,7 +689,7 @@ const createEntityManager = (db) => {
|
|||||||
field: attributeName,
|
field: attributeName,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await this.createQueryBuilder(joinTable.name).insert(rows).execute();
|
await this.createQueryBuilder(joinTable.name).insert(rows).transacting(trx).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -665,6 +712,7 @@ const createEntityManager = (db) => {
|
|||||||
[joinColumn.name]: id,
|
[joinColumn.name]: id,
|
||||||
...(joinTable.on || {}),
|
...(joinTable.on || {}),
|
||||||
})
|
})
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
if (isEmpty(cleanRelationData.set)) {
|
if (isEmpty(cleanRelationData.set)) {
|
||||||
@ -686,9 +734,10 @@ const createEntityManager = (db) => {
|
|||||||
attributeName,
|
attributeName,
|
||||||
joinTable,
|
joinTable,
|
||||||
db,
|
db,
|
||||||
|
transaction: trx,
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.createQueryBuilder(joinTable.name).insert(rows).execute();
|
await this.createQueryBuilder(joinTable.name).insert(rows).transacting(trx).execute();
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -707,6 +756,7 @@ const createEntityManager = (db) => {
|
|||||||
await this.createQueryBuilder(target)
|
await this.createQueryBuilder(target)
|
||||||
.where({ [attribute.joinColumn.referencedColumn]: id })
|
.where({ [attribute.joinColumn.referencedColumn]: id })
|
||||||
.update({ [attribute.joinColumn.referencedColumn]: null })
|
.update({ [attribute.joinColumn.referencedColumn]: null })
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
if (!isNull(cleanRelationData.set)) {
|
if (!isNull(cleanRelationData.set)) {
|
||||||
@ -714,6 +764,7 @@ const createEntityManager = (db) => {
|
|||||||
await this.createQueryBuilder(target)
|
await this.createQueryBuilder(target)
|
||||||
.where({ id: relIdsToAdd })
|
.where({ id: relIdsToAdd })
|
||||||
.update({ [attribute.joinColumn.referencedColumn]: id })
|
.update({ [attribute.joinColumn.referencedColumn]: id })
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -732,7 +783,7 @@ const createEntityManager = (db) => {
|
|||||||
|
|
||||||
// only delete relations
|
// only delete relations
|
||||||
if (isNull(cleanRelationData.set)) {
|
if (isNull(cleanRelationData.set)) {
|
||||||
await deleteRelations({ id, attribute, db, relIdsToDelete: 'all' });
|
await deleteRelations({ id, attribute, db, relIdsToDelete: 'all', transaction: trx });
|
||||||
} else {
|
} else {
|
||||||
const isPartialUpdate = !has('set', cleanRelationData);
|
const isPartialUpdate = !has('set', cleanRelationData);
|
||||||
let relIdsToaddOrMove;
|
let relIdsToaddOrMove;
|
||||||
@ -747,7 +798,7 @@ const createEntityManager = (db) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!isEmpty(relIdsToDelete)) {
|
if (!isEmpty(relIdsToDelete)) {
|
||||||
await deleteRelations({ id, attribute, db, relIdsToDelete });
|
await deleteRelations({ id, attribute, db, relIdsToDelete, transaction: trx });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEmpty(cleanRelationData.connect)) {
|
if (isEmpty(cleanRelationData.connect)) {
|
||||||
@ -764,6 +815,7 @@ const createEntityManager = (db) => {
|
|||||||
[inverseJoinColumn.name]: { $in: relIdsToaddOrMove },
|
[inverseJoinColumn.name]: { $in: relIdsToaddOrMove },
|
||||||
})
|
})
|
||||||
.where(joinTable.on || {})
|
.where(joinTable.on || {})
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -783,6 +835,7 @@ const createEntityManager = (db) => {
|
|||||||
.where({ [joinColumn.name]: id })
|
.where({ [joinColumn.name]: id })
|
||||||
.where(joinTable.on || {})
|
.where(joinTable.on || {})
|
||||||
.first()
|
.first()
|
||||||
|
.transacting(trx)
|
||||||
.execute()
|
.execute()
|
||||||
).max;
|
).max;
|
||||||
|
|
||||||
@ -805,7 +858,8 @@ const createEntityManager = (db) => {
|
|||||||
.whereIn(inverseJoinColumn.name, nonExistingRelsIds)
|
.whereIn(inverseJoinColumn.name, nonExistingRelsIds)
|
||||||
.where(joinTable.on || {})
|
.where(joinTable.on || {})
|
||||||
.groupBy(inverseJoinColumn.name)
|
.groupBy(inverseJoinColumn.name)
|
||||||
.from(joinTable.name);
|
.from(joinTable.name)
|
||||||
|
.transacting(trx);
|
||||||
|
|
||||||
const maxMap = maxResults.reduce(
|
const maxMap = maxResults.reduce(
|
||||||
(acc, res) => Object.assign(acc, { [res[inverseJoinColumn.name]]: res.max }),
|
(acc, res) => Object.assign(acc, { [res[inverseJoinColumn.name]]: res.max }),
|
||||||
@ -820,7 +874,8 @@ const createEntityManager = (db) => {
|
|||||||
// insert rows
|
// insert rows
|
||||||
const query = this.createQueryBuilder(joinTable.name)
|
const query = this.createQueryBuilder(joinTable.name)
|
||||||
.insert(insert)
|
.insert(insert)
|
||||||
.onConflict(joinTable.pivotColumns);
|
.onConflict(joinTable.pivotColumns)
|
||||||
|
.transacting(trx);
|
||||||
|
|
||||||
if (hasOrderColumn(attribute)) {
|
if (hasOrderColumn(attribute)) {
|
||||||
query.merge([orderColumnName]);
|
query.merge([orderColumnName]);
|
||||||
@ -831,7 +886,7 @@ const createEntityManager = (db) => {
|
|||||||
await query.execute();
|
await query.execute();
|
||||||
|
|
||||||
// remove gap between orders
|
// remove gap between orders
|
||||||
await cleanOrderColumns({ attribute, db, id });
|
await cleanOrderColumns({ attribute, db, id, transaction: trx });
|
||||||
} else {
|
} else {
|
||||||
if (isAnyToOne(attribute)) {
|
if (isAnyToOne(attribute)) {
|
||||||
cleanRelationData.set = cleanRelationData.set.slice(-1);
|
cleanRelationData.set = cleanRelationData.set.slice(-1);
|
||||||
@ -844,6 +899,7 @@ const createEntityManager = (db) => {
|
|||||||
db,
|
db,
|
||||||
relIdsToDelete: 'all',
|
relIdsToDelete: 'all',
|
||||||
relIdsToNotDelete: relIdsToaddOrMove,
|
relIdsToNotDelete: relIdsToaddOrMove,
|
||||||
|
transaction: trx,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isEmpty(cleanRelationData.set)) {
|
if (isEmpty(cleanRelationData.set)) {
|
||||||
@ -873,6 +929,7 @@ const createEntityManager = (db) => {
|
|||||||
[inverseJoinColumn.name]: { $in: relIdsToaddOrMove },
|
[inverseJoinColumn.name]: { $in: relIdsToaddOrMove },
|
||||||
})
|
})
|
||||||
.where(joinTable.on || {})
|
.where(joinTable.on || {})
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
const nonExistingRelsIds = difference(
|
const nonExistingRelsIds = difference(
|
||||||
@ -887,7 +944,8 @@ const createEntityManager = (db) => {
|
|||||||
.whereIn(inverseJoinColumn.name, nonExistingRelsIds)
|
.whereIn(inverseJoinColumn.name, nonExistingRelsIds)
|
||||||
.where(joinTable.on || {})
|
.where(joinTable.on || {})
|
||||||
.groupBy(inverseJoinColumn.name)
|
.groupBy(inverseJoinColumn.name)
|
||||||
.from(joinTable.name);
|
.from(joinTable.name)
|
||||||
|
.transacting(trx);
|
||||||
|
|
||||||
const maxMap = maxResults.reduce(
|
const maxMap = maxResults.reduce(
|
||||||
(acc, res) => Object.assign(acc, { [res[inverseJoinColumn.name]]: res.max }),
|
(acc, res) => Object.assign(acc, { [res[inverseJoinColumn.name]]: res.max }),
|
||||||
@ -902,7 +960,8 @@ const createEntityManager = (db) => {
|
|||||||
// insert rows
|
// insert rows
|
||||||
const query = this.createQueryBuilder(joinTable.name)
|
const query = this.createQueryBuilder(joinTable.name)
|
||||||
.insert(insert)
|
.insert(insert)
|
||||||
.onConflict(joinTable.pivotColumns);
|
.onConflict(joinTable.pivotColumns)
|
||||||
|
.transacting(trx);
|
||||||
|
|
||||||
if (hasOrderColumn(attribute)) {
|
if (hasOrderColumn(attribute)) {
|
||||||
query.merge([orderColumnName]);
|
query.merge([orderColumnName]);
|
||||||
@ -920,6 +979,7 @@ const createEntityManager = (db) => {
|
|||||||
attribute,
|
attribute,
|
||||||
relIdsToadd: relIdsToaddOrMove,
|
relIdsToadd: relIdsToaddOrMove,
|
||||||
db,
|
db,
|
||||||
|
transaction: trx,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -930,6 +990,7 @@ const createEntityManager = (db) => {
|
|||||||
attribute,
|
attribute,
|
||||||
relIdToadd: relIdsToaddOrMove[0],
|
relIdToadd: relIdsToaddOrMove[0],
|
||||||
db,
|
db,
|
||||||
|
transaction: trx,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -947,7 +1008,7 @@ const createEntityManager = (db) => {
|
|||||||
* @param {ID} id - entity ID
|
* @param {ID} id - entity ID
|
||||||
*/
|
*/
|
||||||
// TODO: wrap Transaction
|
// TODO: wrap Transaction
|
||||||
async deleteRelations(uid, id) {
|
async deleteRelations(uid, id, { transaction: trx }) {
|
||||||
const { attributes } = db.metadata.get(uid);
|
const { attributes } = db.metadata.get(uid);
|
||||||
|
|
||||||
for (const attributeName of Object.keys(attributes)) {
|
for (const attributeName of Object.keys(attributes)) {
|
||||||
@ -976,6 +1037,7 @@ const createEntityManager = (db) => {
|
|||||||
await this.createQueryBuilder(target)
|
await this.createQueryBuilder(target)
|
||||||
.update({ [idColumn.name]: null, [typeColumn.name]: null })
|
.update({ [idColumn.name]: null, [typeColumn.name]: null })
|
||||||
.where({ [idColumn.name]: id, [typeColumn.name]: uid })
|
.where({ [idColumn.name]: id, [typeColumn.name]: uid })
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
} else if (targetAttribute.relation === 'morphToMany') {
|
} else if (targetAttribute.relation === 'morphToMany') {
|
||||||
const { joinTable } = targetAttribute;
|
const { joinTable } = targetAttribute;
|
||||||
@ -991,6 +1053,7 @@ const createEntityManager = (db) => {
|
|||||||
...(joinTable.on || {}),
|
...(joinTable.on || {}),
|
||||||
field: attributeName,
|
field: attributeName,
|
||||||
})
|
})
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1019,6 +1082,7 @@ const createEntityManager = (db) => {
|
|||||||
[joinColumn.name]: id,
|
[joinColumn.name]: id,
|
||||||
...(joinTable.on || {}),
|
...(joinTable.on || {}),
|
||||||
})
|
})
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -1043,11 +1107,12 @@ const createEntityManager = (db) => {
|
|||||||
await this.createQueryBuilder(target)
|
await this.createQueryBuilder(target)
|
||||||
.where({ [attribute.joinColumn.referencedColumn]: id })
|
.where({ [attribute.joinColumn.referencedColumn]: id })
|
||||||
.update({ [attribute.joinColumn.referencedColumn]: null })
|
.update({ [attribute.joinColumn.referencedColumn]: null })
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attribute.joinTable) {
|
if (attribute.joinTable) {
|
||||||
await deleteRelations({ id, attribute, db, relIdsToDelete: 'all' });
|
await deleteRelations({ id, attribute, db, relIdsToDelete: 'all', transaction: trx });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -20,7 +20,7 @@ const getMorphToManyRowsLinkedToMorphOne = (rows, { uid, attributeName, typeColu
|
|||||||
|
|
||||||
const deleteRelatedMorphOneRelationsAfterMorphToManyUpdate = async (
|
const deleteRelatedMorphOneRelationsAfterMorphToManyUpdate = async (
|
||||||
rows,
|
rows,
|
||||||
{ uid, attributeName, joinTable, db }
|
{ uid, attributeName, joinTable, db, transaction: trx }
|
||||||
) => {
|
) => {
|
||||||
const { morphColumn } = joinTable;
|
const { morphColumn } = joinTable;
|
||||||
const { idColumn, typeColumn } = morphColumn;
|
const { idColumn, typeColumn } = morphColumn;
|
||||||
@ -50,7 +50,11 @@ const deleteRelatedMorphOneRelationsAfterMorphToManyUpdate = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isEmpty(orWhere)) {
|
if (!isEmpty(orWhere)) {
|
||||||
await createQueryBuilder(joinTable.name, db).delete().where({ $or: orWhere }).execute();
|
await createQueryBuilder(joinTable.name, db)
|
||||||
|
.delete()
|
||||||
|
.where({ $or: orWhere })
|
||||||
|
.transacting(trx)
|
||||||
|
.execute();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -19,7 +19,13 @@ const { createQueryBuilder } = require('../query');
|
|||||||
* @param {string} params.inverseRelIds - entity ids of the inverse side for which the current relations will be deleted
|
* @param {string} params.inverseRelIds - entity ids of the inverse side for which the current relations will be deleted
|
||||||
* @param {string} params.db - database instance
|
* @param {string} params.db - database instance
|
||||||
*/
|
*/
|
||||||
const deletePreviousOneToAnyRelations = async ({ id, attribute, relIdsToadd, db }) => {
|
const deletePreviousOneToAnyRelations = async ({
|
||||||
|
id,
|
||||||
|
attribute,
|
||||||
|
relIdsToadd,
|
||||||
|
db,
|
||||||
|
transaction: trx,
|
||||||
|
}) => {
|
||||||
if (!(isBidirectional(attribute) && isOneToAny(attribute))) {
|
if (!(isBidirectional(attribute) && isOneToAny(attribute))) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'deletePreviousOneToAnyRelations can only be called for bidirectional oneToAny relations'
|
'deletePreviousOneToAnyRelations can only be called for bidirectional oneToAny relations'
|
||||||
@ -35,9 +41,10 @@ const deletePreviousOneToAnyRelations = async ({ id, attribute, relIdsToadd, db
|
|||||||
[joinColumn.name]: { $ne: id },
|
[joinColumn.name]: { $ne: id },
|
||||||
})
|
})
|
||||||
.where(joinTable.on || {})
|
.where(joinTable.on || {})
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
await cleanOrderColumns({ attribute, db, inverseRelIds: relIdsToadd });
|
await cleanOrderColumns({ attribute, db, inverseRelIds: relIdsToadd, transaction: trx });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,7 +55,13 @@ const deletePreviousOneToAnyRelations = async ({ id, attribute, relIdsToadd, db
|
|||||||
* @param {string} params.relIdToadd - entity id of the new relation
|
* @param {string} params.relIdToadd - entity id of the new relation
|
||||||
* @param {string} params.db - database instance
|
* @param {string} params.db - database instance
|
||||||
*/
|
*/
|
||||||
const deletePreviousAnyToOneRelations = async ({ id, attribute, relIdToadd, db }) => {
|
const deletePreviousAnyToOneRelations = async ({
|
||||||
|
id,
|
||||||
|
attribute,
|
||||||
|
relIdToadd,
|
||||||
|
db,
|
||||||
|
transaction: trx,
|
||||||
|
}) => {
|
||||||
const { joinTable } = attribute;
|
const { joinTable } = attribute;
|
||||||
const { joinColumn, inverseJoinColumn } = joinTable;
|
const { joinColumn, inverseJoinColumn } = joinTable;
|
||||||
|
|
||||||
@ -67,6 +80,7 @@ const deletePreviousAnyToOneRelations = async ({ id, attribute, relIdToadd, db }
|
|||||||
[inverseJoinColumn.name]: { $ne: relIdToadd },
|
[inverseJoinColumn.name]: { $ne: relIdToadd },
|
||||||
})
|
})
|
||||||
.where(joinTable.on || {})
|
.where(joinTable.on || {})
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
const relIdsToDelete = map(inverseJoinColumn.name, relsToDelete);
|
const relIdsToDelete = map(inverseJoinColumn.name, relsToDelete);
|
||||||
@ -78,9 +92,10 @@ const deletePreviousAnyToOneRelations = async ({ id, attribute, relIdToadd, db }
|
|||||||
[inverseJoinColumn.name]: { $in: relIdsToDelete },
|
[inverseJoinColumn.name]: { $in: relIdsToDelete },
|
||||||
})
|
})
|
||||||
.where(joinTable.on || {})
|
.where(joinTable.on || {})
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
await cleanOrderColumns({ attribute, db, inverseRelIds: relIdsToDelete });
|
await cleanOrderColumns({ attribute, db, inverseRelIds: relIdsToDelete, transaction: trx });
|
||||||
|
|
||||||
// handling oneToOne
|
// handling oneToOne
|
||||||
} else {
|
} else {
|
||||||
@ -91,6 +106,7 @@ const deletePreviousAnyToOneRelations = async ({ id, attribute, relIdToadd, db }
|
|||||||
[inverseJoinColumn.name]: { $ne: relIdToadd },
|
[inverseJoinColumn.name]: { $ne: relIdToadd },
|
||||||
})
|
})
|
||||||
.where(joinTable.on || {})
|
.where(joinTable.on || {})
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -110,6 +126,7 @@ const deleteRelations = async ({
|
|||||||
db,
|
db,
|
||||||
relIdsToNotDelete = [],
|
relIdsToNotDelete = [],
|
||||||
relIdsToDelete = [],
|
relIdsToDelete = [],
|
||||||
|
transaction: trx,
|
||||||
}) => {
|
}) => {
|
||||||
const { joinTable } = attribute;
|
const { joinTable } = attribute;
|
||||||
const { joinColumn, inverseJoinColumn } = joinTable;
|
const { joinColumn, inverseJoinColumn } = joinTable;
|
||||||
@ -131,6 +148,7 @@ const deleteRelations = async ({
|
|||||||
.where(joinTable.on || {})
|
.where(joinTable.on || {})
|
||||||
.orderBy('id')
|
.orderBy('id')
|
||||||
.limit(batchSize)
|
.limit(batchSize)
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
done = batchToDelete.length < batchSize;
|
done = batchToDelete.length < batchSize;
|
||||||
lastId = batchToDelete[batchToDelete.length - 1]?.id;
|
lastId = batchToDelete[batchToDelete.length - 1]?.id;
|
||||||
@ -144,9 +162,10 @@ const deleteRelations = async ({
|
|||||||
[inverseJoinColumn.name]: { $in: batchIds },
|
[inverseJoinColumn.name]: { $in: batchIds },
|
||||||
})
|
})
|
||||||
.where(joinTable.on || {})
|
.where(joinTable.on || {})
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
await cleanOrderColumns({ attribute, db, id, inverseRelIds: batchIds });
|
await cleanOrderColumns({ attribute, db, id, inverseRelIds: batchIds, transaction: trx });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await createQueryBuilder(joinTable.name, db)
|
await createQueryBuilder(joinTable.name, db)
|
||||||
@ -157,6 +176,7 @@ const deleteRelations = async ({
|
|||||||
...(all ? {} : { [inverseJoinColumn.name]: { $in: relIdsToDelete } }),
|
...(all ? {} : { [inverseJoinColumn.name]: { $in: relIdsToDelete } }),
|
||||||
})
|
})
|
||||||
.where(joinTable.on || {})
|
.where(joinTable.on || {})
|
||||||
|
.transacting(trx)
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -169,7 +189,7 @@ const deleteRelations = async ({
|
|||||||
* @param {string} params.db - database instance
|
* @param {string} params.db - database instance
|
||||||
* @param {string} params.inverseRelIds - entity ids of the inverse side for which the clean will be done
|
* @param {string} params.inverseRelIds - entity ids of the inverse side for which the clean will be done
|
||||||
*/
|
*/
|
||||||
const cleanOrderColumns = async ({ id, attribute, db, inverseRelIds }) => {
|
const cleanOrderColumns = async ({ id, attribute, db, inverseRelIds, transaction: trx }) => {
|
||||||
if (
|
if (
|
||||||
!(hasOrderColumn(attribute) && id) &&
|
!(hasOrderColumn(attribute) && id) &&
|
||||||
!(hasInverseOrderColumn(attribute) && !isEmpty(inverseRelIds))
|
!(hasInverseOrderColumn(attribute) && !isEmpty(inverseRelIds))
|
||||||
@ -208,31 +228,37 @@ const cleanOrderColumns = async ({ id, attribute, db, inverseRelIds }) => {
|
|||||||
// https://github.com/knex/knex/issues/2504
|
// https://github.com/knex/knex/issues/2504
|
||||||
switch (strapi.db.dialect.client) {
|
switch (strapi.db.dialect.client) {
|
||||||
case 'mysql':
|
case 'mysql':
|
||||||
await db.getConnection().raw(
|
await db
|
||||||
`UPDATE
|
.getConnection()
|
||||||
?? as a,
|
.raw(
|
||||||
(
|
`UPDATE
|
||||||
SELECT ${select.join(', ')}
|
?? as a,
|
||||||
FROM ??
|
(
|
||||||
WHERE ${where.join(' OR ')}
|
SELECT ${select.join(', ')}
|
||||||
) AS b
|
FROM ??
|
||||||
SET ${update.join(', ')}
|
WHERE ${where.join(' OR ')}
|
||||||
WHERE b.id = a.id`,
|
) AS b
|
||||||
[joinTable.name, ...selectBinding, joinTable.name, ...whereBinding, ...updateBinding]
|
SET ${update.join(', ')}
|
||||||
);
|
WHERE b.id = a.id`,
|
||||||
|
[joinTable.name, ...selectBinding, joinTable.name, ...whereBinding, ...updateBinding]
|
||||||
|
)
|
||||||
|
.transacting(trx);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
await db.getConnection().raw(
|
await db
|
||||||
`UPDATE ?? as a
|
.getConnection()
|
||||||
SET ${update.join(', ')}
|
.raw(
|
||||||
FROM (
|
`UPDATE ?? as a
|
||||||
SELECT ${select.join(', ')}
|
SET ${update.join(', ')}
|
||||||
FROM ??
|
FROM (
|
||||||
WHERE ${where.join(' OR ')}
|
SELECT ${select.join(', ')}
|
||||||
) AS b
|
FROM ??
|
||||||
WHERE b.id = a.id`,
|
WHERE ${where.join(' OR ')}
|
||||||
[joinTable.name, ...updateBinding, ...selectBinding, joinTable.name, ...whereBinding]
|
) AS b
|
||||||
);
|
WHERE b.id = a.id`,
|
||||||
|
[joinTable.name, ...updateBinding, ...selectBinding, joinTable.name, ...whereBinding]
|
||||||
|
)
|
||||||
|
.transacting(trx);
|
||||||
/*
|
/*
|
||||||
`UPDATE :joinTable: as a
|
`UPDATE :joinTable: as a
|
||||||
SET :orderColumn: = b.src_order, :inverseOrderColumn: = b.inv_order
|
SET :orderColumn: = b.src_order, :inverseOrderColumn: = b.inv_order
|
||||||
|
@ -47,7 +47,6 @@ const createComponents = async (uid, data) => {
|
|||||||
componentValue.map((value) => createComponent(componentUID, value))
|
componentValue.map((value) => createComponent(componentUID, value))
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: add order
|
|
||||||
componentBody[attributeName] = components.map(({ id }) => {
|
componentBody[attributeName] = components.map(({ id }) => {
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user