MCPcopy Create free account
hub / github.com/mikro-orm/mikro-orm / syncCollections

Function syncCollections

packages/sql/src/AbstractSqlDriver.ts:1697–1822  ·  view source on GitHub ↗
(
    collections: Iterable<Collection<T, O>>,
    options?: DriverMethodOptions,
  )

Source from the content-addressed store, hash-verified

1695 }
1696
1697 override async syncCollections<T extends object, O extends object>(
1698 collections: Iterable<Collection<T, O>>,
1699 options?: DriverMethodOptions,
1700 ): Promise<void> {
1701 const groups = {} as Dictionary<PivotCollectionPersister<any>>;
1702
1703 for (const coll of collections) {
1704 const wrapped = helper(coll.owner);
1705 const meta = wrapped.__meta;
1706 const pks = wrapped.getPrimaryKeys(true)!;
1707 const snap = coll.getSnapshot();
1708 const includes = <T>(arr: T[][], item: T[]) => !!arr.find(i => this.comparePrimaryKeyArrays(i, item));
1709 // For union-target polymorphic M:N, prepend the per-row discriminator value so the pivot
1710 // persister can write it alongside the FK id. Memoized per sync-run because a collection can
1711 // hold hundreds of items of the same few types, and findDiscriminatorValue walks the prototype
1712 // chain + re-scans Object.entries each call.
1713 const isUnionTargetMN = QueryHelper.isUnionTargetPolymorphic(coll.property);
1714 const classToDisc = new Map<Function, Primary<any>>();
1715 const toDiff = (item: AnyEntity) => {
1716 const keys = helper(item).getPrimaryKeys(true)!;
1717 if (!isUnionTargetMN) {
1718 return keys;
1719 }
1720 let disc = classToDisc.get(item.constructor);
1721 if (!classToDisc.has(item.constructor)) {
1722 disc = QueryHelper.findDiscriminatorValue(coll.property.discriminatorMap!, item.constructor) as Primary<any>;
1723
1724 if (disc === undefined) {
1725 throw new Error(
1726 `Cannot resolve discriminator value for ${item.constructor.name} in ${coll.property.name}; the class is not part of the union target list.`,
1727 );
1728 }
1729
1730 classToDisc.set(item.constructor, disc);
1731 }
1732 return [disc as Primary<any>, ...keys];
1733 };
1734 const snapshot = snap ? snap.map(toDiff) : [];
1735 const current = coll.getItems(false).map(toDiff);
1736 const deleteDiff = snap ? snapshot.filter(item => !includes(current, item)) : true;
1737 const insertDiff = current.filter(item => !includes(snapshot, item));
1738 const target = snapshot.filter(item => includes(current, item)).concat(...insertDiff);
1739 const equals = Utils.equals(current, target);
1740
1741 // wrong order if we just delete and insert to the end (only owning sides can have fixed order)
1742 if (coll.property.owner && coll.property.fixedOrder && !equals && Array.isArray(deleteDiff)) {
1743 deleteDiff.length = insertDiff.length = 0;
1744
1745 for (const item of snapshot) {
1746 deleteDiff.push(item);
1747 }
1748
1749 for (const item of current) {
1750 insertDiff.push(item);
1751 }
1752 }
1753
1754 if (coll.property.kind === ReferenceKind.ONE_TO_MANY) {

Callers

nothing calls this directly

Calls 15

helperFunction · 0.90
includesFunction · 0.85
pickAbortOptionsFunction · 0.85
getSnapshotMethod · 0.80
filterMethod · 0.80
pushMethod · 0.80
setAbortOptionsMethod · 0.80
rethrowMethod · 0.80
enqueueUpdateMethod · 0.80
getPrimaryKeysMethod · 0.65
getItemsMethod · 0.65

Tested by

no test coverage detected