Skip to content

Commit ce70661

Browse files
committed
relationship updating
1 parent 060e63b commit ce70661

File tree

3 files changed

+70
-14
lines changed

3 files changed

+70
-14
lines changed

packages/compass-data-modeling/src/components/drawer/field-drawer-content.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@ import {
2525
import { useChangeOnBlur } from './use-change-on-blur';
2626
import { RelationshipsSection } from './relationships-section';
2727
import { getFieldFromSchema } from '../../utils/schema-traversal';
28-
import {
29-
areFieldPathsEqual,
30-
isRelationshipInvolvingField,
31-
} from '../../utils/utils';
28+
import { areFieldPathsEqual, isRelationshipOfAField } from '../../utils/utils';
3229

3330
type FieldDrawerContentProps = {
3431
namespace: string;
@@ -193,7 +190,7 @@ export default connect(
193190
})?.fieldTypes ?? [],
194191
fieldPaths: [], // TODO(COMPASS-9659): get existing field paths
195192
relationships: model.relationships.filter(({ relationship }) =>
196-
isRelationshipInvolvingField(
193+
isRelationshipOfAField(
197194
relationship,
198195
ownProps.namespace,
199196
ownProps.fieldPath

packages/compass-data-modeling/src/store/diagram.ts

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
type StaticModel,
1515
} from '../services/data-model-storage';
1616
import { AnalysisProcessActionTypes } from './analysis-process';
17-
import { memoize } from 'lodash';
17+
import { memoize, update } from 'lodash';
1818
import type { DataModelingState, DataModelingThunkAction } from './reducer';
1919
import {
2020
openToast,
@@ -29,14 +29,12 @@ import type { MongoDBJSONSchema } from 'mongodb-schema';
2929
import { getCoordinatesForNewNode } from '@mongodb-js/diagramming';
3030
import { collectionToDiagramNode } from '../utils/nodes-and-edges';
3131
import toNS from 'mongodb-ns';
32-
import {
33-
removeFieldFromSchema,
34-
traverseSchema,
35-
updateSchema,
36-
} from '../utils/schema-traversal';
32+
import { traverseSchema, updateSchema } from '../utils/schema-traversal';
3733
import {
3834
areFieldPathsEqual,
3935
isRelationshipInvolvingField,
36+
isRelationshipOfAField,
37+
isSameFieldOrChild,
4038
} from '../utils/utils';
4139

4240
function isNonEmptyArray<T>(arr: T[]): arr is [T, ...T[]] {
@@ -755,6 +753,27 @@ export function addCollection(
755753
};
756754
}
757755

756+
function renameFieldInRelationshipSide(
757+
side: Relationship['relationship'][0],
758+
edit: Extract<Edit, { type: 'RenameField' }>
759+
): Relationship['relationship'][0] {
760+
if (
761+
side.ns !== edit.ns ||
762+
!side.fields ||
763+
!isSameFieldOrChild(side.fields, edit.from)
764+
) {
765+
return side;
766+
}
767+
return {
768+
...side,
769+
fields: [
770+
...side.fields.slice(0, edit.from.length - 1),
771+
edit.to,
772+
...side.fields.slice(edit.from.length),
773+
],
774+
};
775+
}
776+
758777
function _applyEdit(edit: Edit, model?: StaticModel): StaticModel {
759778
if (edit.type === 'SetModel') {
760779
return edit.model;
@@ -902,8 +921,18 @@ function _applyEdit(edit: Edit, model?: StaticModel): StaticModel {
902921
...model,
903922
// Update any relationships involving the field being renamed.
904923
relationships: model.relationships.map((r) => {
905-
// TODO
906-
return r;
924+
if (
925+
!isRelationshipInvolvingField(r.relationship, edit.ns, edit.from)
926+
) {
927+
return r;
928+
}
929+
return {
930+
...r,
931+
relationship: [
932+
renameFieldInRelationshipSide(r.relationship[0], edit),
933+
renameFieldInRelationshipSide(r.relationship[1], edit),
934+
] as const,
935+
};
907936
}),
908937
collections: model.collections.map((collection) => {
909938
if (collection.ns !== edit.ns) return collection;

packages/compass-data-modeling/src/utils/utils.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,21 @@ export function areFieldPathsEqual(
77
return JSON.stringify(fieldA) === JSON.stringify(fieldB);
88
}
99

10-
export function isRelationshipInvolvingField(
10+
export function isSameFieldOrChild(
11+
fieldA: FieldPath,
12+
fieldB: FieldPath
13+
): boolean {
14+
if (fieldA.length === fieldB.length)
15+
return areFieldPathsEqual(fieldA, fieldB);
16+
if (fieldA.length < fieldB.length) return false;
17+
// fieldA is shorter than fieldB, check if fieldA is a parent of fieldB
18+
const pathA = JSON.stringify(fieldA);
19+
const pathB = JSON.stringify(fieldB);
20+
// ignore the closing bracket - last character in pathB
21+
return pathA.slice(0, pathB.length - 1) === pathB.slice(0, pathB.length - 1);
22+
}
23+
24+
export function isRelationshipOfAField(
1125
relationship: Relationship['relationship'],
1226
namespace: string,
1327
fieldPath: FieldPath
@@ -22,3 +36,19 @@ export function isRelationshipInvolvingField(
2236
areFieldPathsEqual(foreign.fields, fieldPath))
2337
);
2438
}
39+
40+
export function isRelationshipInvolvingField(
41+
relationship: Relationship['relationship'],
42+
namespace: string,
43+
fieldPath: FieldPath
44+
): boolean {
45+
const [local, foreign] = relationship;
46+
return (
47+
(local.ns === namespace &&
48+
local.fields !== null &&
49+
isSameFieldOrChild(local.fields, fieldPath)) ||
50+
(foreign.ns === namespace &&
51+
foreign.fields !== null &&
52+
isSameFieldOrChild(foreign.fields, fieldPath))
53+
);
54+
}

0 commit comments

Comments
 (0)