Repository navigation
β‘ Bolt: Optimize Prisma Export Dictionary Complexity #1301
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
c75a8bf
6967847
8eda59a
1c7663d
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 |
|---|---|---|
|
|
@@ -60,6 +60,8 @@ export function exportPrisma( | |
| 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 lookups by sourceModel+sourceField to avoid O(N*C*E) loops | ||
| const edgesProcessedBySource = new Map<string, Array<{ sourceModel: string, targetModel: string, sourceFields: string[], targetFields: string[], relationName: string }>>(); | ||
|
|
||
| for (const edge of edges) { | ||
| const sourceNode = nodesById.get(edge.source); | ||
|
|
@@ -93,13 +95,19 @@ export function exportPrisma( | |
| }); | ||
| incomingRelationsByNode.set(edge.target, relList); | ||
|
|
||
| edgesProcessed.set(edge.id, { | ||
| const edgeInfo = { | ||
| sourceModel: sanitizeName(sourceNode.data.title), | ||
| targetModel: sanitizeName(targetNode.data.title), | ||
| sourceFields: [sanitizeName(sourceField)], | ||
| targetFields: [sanitizeName(targetField)], | ||
| relationName: relName | ||
| }); | ||
| }; | ||
| edgesProcessed.set(edge.id, edgeInfo); | ||
|
|
||
| const sourceKey = `${edgeInfo.sourceModel}:${edgeInfo.sourceFields[0]}`; | ||
|
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. π΄ Snapshot foreign keys lack forward relations For normal snapshot edges, Learn moreGraph edges created by snapshotToGraph use Example: A Recommended fix: Resolve Was this helpful? React with π or π to provide feedback. |
||
| const fieldEdges = edgesProcessedBySource.get(sourceKey) || []; | ||
| fieldEdges.push(edgeInfo); | ||
| edgesProcessedBySource.set(sourceKey, fieldEdges); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -136,12 +144,11 @@ 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 fieldEdges = edgesProcessedBySource.get(`${modelName}:${fieldName}`); | ||
| if (fieldEdges) { | ||
| for (const edgeInfo of fieldEdges) { | ||
| const relField = sanitizeName(edgeInfo.targetModel) + "_" + fieldName; | ||
| relationDef = `\n ${relField} ${edgeInfo.targetModel}${optional} @relation("${edgeInfo.relationName}", fields: [${fieldName}], references: [${edgeInfo.targetFields[0]}])`; | ||
| relationDef += `\n ${relField} ${edgeInfo.targetModel}${optional} @relation("${edgeInfo.relationName}", fields: [${fieldName}], references: [${edgeInfo.targetFields[0]}])`; | ||
|
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. π‘ Repeated foreign keys invalidate Prisma models When two edges connect one source field to the same target model, Learn moreEach matching edge contributes a Prisma relation field named from its target model and source field. Appending every matching edge creates the same field name twice when edges share both values. The previous exporter overwrote Example: Two edges with different IDs use Recommended fix: Decide how to represent multiple relations on the same scalar field, and ensure generated relation field names are unique and correspond to matching back-relations. Cover two edges with the same source field and target model in the exporter tests. Was this helpful? React with π or π to provide feedback. |
||
| } | ||
| } | ||
|
|
||
|
|
||
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.
π Redundant edge index remains allocated
edgesProcessedhas no readers after this change, but each edge still enters it. Large exports retain two edge indexes instead of one.Was this helpful? React with π or π to provide feedback.