ChengLei Shao e566d56c2d
fix: destroy through table record referencing collections table (#1611)
* test: destory through table record referencing collections table

* fix: belongs to many fields to reference
2023-03-28 12:26:30 +08:00

77 lines
2.0 KiB
TypeScript

export interface Reference {
sourceCollectionName: string;
sourceField: string;
targetField: string;
targetCollectionName: string;
onDelete: string;
}
class ReferencesMap {
protected map: Map<string, Reference[]> = new Map();
addReference(reference: Reference) {
if (!reference.onDelete) {
reference.onDelete = 'SET NULL';
}
reference.onDelete = reference.onDelete.toUpperCase();
const existReference = this.existReference(reference);
if (existReference && existReference.onDelete !== reference.onDelete) {
if (reference.onDelete === 'SET NULL') {
// using existing reference
return;
} else if (existReference.onDelete === 'SET NULL') {
existReference.onDelete = reference.onDelete;
} else {
throw new Error(
`On Delete Conflict, exist reference ${JSON.stringify(existReference)}, new reference ${JSON.stringify(
reference,
)}`,
);
}
}
if (!existReference) {
this.map.set(reference.targetCollectionName, [
...(this.map.get(reference.targetCollectionName) || []),
reference,
]);
}
}
getReferences(collectionName) {
return this.map.get(collectionName);
}
existReference(reference: Reference) {
const references = this.map.get(reference.targetCollectionName);
if (!references) {
return null;
}
const keys = Object.keys(reference).filter((k) => k !== 'onDelete');
return references.find((ref) => keys.every((key) => ref[key] === reference[key]));
}
removeReference(reference: Reference) {
const references = this.map.get(reference.targetCollectionName);
if (!references) {
return;
}
const keys = ['sourceCollectionName', 'sourceField', 'targetField', 'targetCollectionName'];
this.map.set(
reference.targetCollectionName,
references.filter((ref) => !keys.every((key) => ref[key] === reference[key])),
);
}
}
export default ReferencesMap;