-
Notifications
You must be signed in to change notification settings - Fork 0
⚡ Bolt: [성능 개선] Prisma 내보내기 엣지 관계 O(1) Map 조회 최적화 #977
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
21f2434
3f1c732
7461231
ff83b1a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,7 +59,8 @@ export function exportPrisma( | |
| const fkNodeColumnPairs = new Set<string>(); | ||
| const fkNodesWithoutHandles = new Set<string>(); | ||
| const incomingRelationsByNode = new Map<string, Array<{ relationName: string, sourceModel: string, sourceField: string, isUnique: boolean }>>(); | ||
| const edgesProcessed = new Map<string, { sourceModel: string, targetModel: string, sourceFields: string[], targetFields: string[], relationName: string }>(); | ||
| // ⚡ Bolt: Precompute edge relations by model and field to avoid O(N * C * E) nested loop lookups | ||
| const edgeRelationsByModelAndField = new Map<string, { targetModel: string, targetField: string, relationName: string }>(); | ||
|
|
||
| for (const edge of edges) { | ||
| const sourceNode = nodesById.get(edge.source); | ||
|
|
@@ -93,11 +94,9 @@ export function exportPrisma( | |
| }); | ||
| incomingRelationsByNode.set(edge.target, relList); | ||
|
|
||
| edgesProcessed.set(edge.id, { | ||
| sourceModel: sanitizeName(sourceNode.data.title), | ||
| edgeRelationsByModelAndField.set(`${sanitizeName(sourceNode.data.title)}:${sanitizeName(sourceField)}`, { | ||
| targetModel: sanitizeName(targetNode.data.title), | ||
| sourceFields: [sanitizeName(sourceField)], | ||
| targetFields: [sanitizeName(targetField)], | ||
| targetField: sanitizeName(targetField), | ||
|
Comment on lines
+97
to
+99
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- candidate files ---'
git ls-files | grep -E '(^|/)(prisma\.ts|.*(test|spec).*\.(ts|tsx|js))$' | head -200
printf '%s\n' '--- prisma.ts outline ---'
ast-grep outline frontend/src/erd/prisma.ts --view expanded || true
printf '%s\n' '--- relevant source ---'
sed -n '1,220p' frontend/src/erd/prisma.ts
printf '%s\n' '--- sanitizer and relation references ---'
rg -n -C 3 'sanitize(Name|HandleId)|edgeRelationsByModelAndField|relationName|isFk' frontend/src frontend --glob '*.{ts,tsx}' | head -300
printf '%s\n' '--- diff summary ---'
git diff --stat
git status --shortRepository: ContextualWisdomLab/pg-erd-cloud Length of output: 28034 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- Prisma tests ---'
sed -n '1,320p' frontend/src/erd/__tests__/prisma.test.ts
printf '%s\n' '--- handle utilities ---'
cat -n frontend/src/erd/handleUtils.ts
printf '%s\n' '--- edge construction and source-handle usage ---'
rg -n -C 4 'sourceColumnHandleId|targetColumnHandleId|sourceHandle|targetHandle|addEdge|onConnect|edges:' frontend/src --glob '*.{ts,tsx}' | head -500
printf '%s\n' '--- edge-related types and validation ---'
rg -n -C 4 'Edge\[\]|Edge<|interface .*Edge|foreign key|foreign_key|relationship|relation' frontend/src --glob '*.{ts,tsx}' | head -500Repository: ContextualWisdomLab/pg-erd-cloud Length of output: 50388 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- snapshot conversion ---'
sed -n '1,180p' frontend/src/erd/convert.ts
printf '%s\n' '--- edge edit persistence ---'
rg -n -C 8 'setEdges|editingEdge|onRelSave|relLabel|label:' frontend/src/App.tsx frontend/src/components/modals/EditEdgeModal.tsx
printf '%s\n' '--- direct encoded-handle fixtures ---'
rg -n -C 5 'c-0069|sourceHandle:|targetHandle:' frontend/src/erd/__tests__ frontend/src/erd --glob '*.{ts,tsx}' | head -300
printf '%s\n' '--- package scripts and config ---'
cat frontend/package.jsonRepository: ContextualWisdomLab/pg-erd-cloud Length of output: 45352 🏁 Script executed: #!/bin/bash
set -eu
python3 - <<'PY'
import re
def sanitize_name(name):
value = re.sub(r'[^a-zA-Z0-9_]', '_', name)
return value if re.match(r'^[a-zA-Z]', value) else 'M_' + value
def sanitize_handle_id(name):
encoded = '-'.join(f'{ord(ch):04x}' for ch in name)
return 'c-' + (encoded or 'empty')
column = 'user_id'
encoded_source_handle = 'src-' + sanitize_handle_id(column)
source_field = encoded_source_handle[4:]
lookup_key = f'{sanitize_name("public.posts")}:{sanitize_name(column)}'
stored_key = f'{sanitize_name("public.posts")}:{sanitize_name(source_field)}'
print('actual sourceHandle:', encoded_source_handle)
print('sourceField extracted by prisma.ts:', source_field)
print('lookup key:', lookup_key)
print('stored key:', stored_key)
print('relation lookup matches:', stored_key == lookup_key)
edges = [
('public.posts', 'user_id', 'public.users', 'id', 'fk_posts_users'),
('public.posts', 'user_id', 'public.accounts', 'id', 'fk_posts_accounts'),
]
relation_map = {}
for source_model, source_column, target_model, target_column, relation_name in edges:
key = f'{sanitize_name(source_model)}:{sanitize_name(source_column)}'
relation_map[key] = (target_model, target_column, relation_name)
print('duplicate-key count:', len(edges) - len(relation_map))
print('retained relation for duplicate key:', relation_map.get('public_posts:user_id'))
PYRepository: ContextualWisdomLab/pg-erd-cloud Length of output: 538
동일한 모델·필드에 여러 🤖 Prompt for AI Agents |
||
| relationName: relName | ||
| }); | ||
| } | ||
|
|
@@ -136,13 +135,12 @@ export function exportPrisma( | |
|
|
||
| // Determine if there is a relation defined on this field | ||
| let relationDef = ""; | ||
| for (const [_, edgeInfo] of edgesProcessed) { | ||
| if (edgeInfo.sourceModel === modelName && edgeInfo.sourceFields.includes(fieldName)) { | ||
| // This field is a foreign key, but in Prisma, we typically define the relation object field | ||
| // alongside the scalar field. We will add the relation object field here. | ||
| const relField = sanitizeName(edgeInfo.targetModel) + "_" + fieldName; | ||
| relationDef = `\n ${relField} ${edgeInfo.targetModel}${optional} @relation("${edgeInfo.relationName}", fields: [${fieldName}], references: [${edgeInfo.targetFields[0]}])`; | ||
| } | ||
| const edgeInfo = edgeRelationsByModelAndField.get(`${modelName}:${fieldName}`); | ||
| if (edgeInfo) { | ||
| // This field is a foreign key, but in Prisma, we typically define the relation object field | ||
| // alongside the scalar field. We will add the relation object field here. | ||
| const relField = sanitizeName(edgeInfo.targetModel) + "_" + fieldName; | ||
| relationDef = `\n ${relField} ${edgeInfo.targetModel}${optional} @relation("${edgeInfo.relationName}", fields: [${fieldName}], references: [${edgeInfo.targetField}])`; | ||
| } | ||
|
Comment on lines
135
to
144
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📝 Info: Map refactor preserves last-write-wins semantics The old inner loop over (Refers to this code) Was this helpful? React with 👍 or 👎 to provide feedback. |
||
|
|
||
| output += ` ${fieldName} ${prismaType}${optional}${attributes}${relationDef}\n`; | ||
|
|
||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
최적화 근거에 학술 출처를 추가하세요.
이 항목은 복잡도 개선만 기록하고 학술 인용, 링크, 요약을 제공하지 않습니다. 관련 학술 자료의 전체 인용 정보와 요약을 추가하거나 허용되는 PDF를 첨부하세요.
As per coding guidelines, substantive feature or process pull requests must be grounded in relevant academic literature.
🤖 Prompt for AI Agents
Source: Coding guidelines