mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-11-12 08:41:34 +00:00
feat(graph): persist multi-language nodes to KuzuDB and add description field
- Add description STRING column to all code element schemas (Function, Class, Interface, Method, CodeElement, and all CODE_ELEMENT_BASE types including Property) - Add generateMultiLangNodeCSV() to write Struct, Enum, Trait, Property, etc. nodes to KuzuDB (previously they existed in-memory only, never reached the DB) - Update generateAllCSVs() to generate CSVs for all 19 multi-language types - Fix getCopyQuery() to use correct column list per table type: - Multi-language tables: id,name,filePath,startLine,endLine,content,description - Core tables: id,name,filePath,startLine,endLine,isExported,content,description - Update batchInsertNodesToKuzu and insertNodeToKuzu to include description field Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
890fedaa09
commit
1c02a06d1b
3 changed files with 62 additions and 9 deletions
|
|
@ -180,16 +180,16 @@ const generateFolderCSV = (nodes: GraphNode[]): string => {
|
|||
|
||||
/**
|
||||
* Generate CSV for code element nodes (Function, Class, Interface, Method, CodeElement)
|
||||
* Headers: id,name,filePath,startLine,endLine,isExported,content
|
||||
* Headers: id,name,filePath,startLine,endLine,isExported,content,description
|
||||
*/
|
||||
const generateCodeElementCSV = (
|
||||
nodes: GraphNode[],
|
||||
label: NodeLabel,
|
||||
fileContents: Map<string, string>
|
||||
): string => {
|
||||
const headers = ['id', 'name', 'filePath', 'startLine', 'endLine', 'isExported', 'content'];
|
||||
const headers = ['id', 'name', 'filePath', 'startLine', 'endLine', 'isExported', 'content', 'description'];
|
||||
const rows: string[] = [headers.join(',')];
|
||||
|
||||
|
||||
for (const node of nodes) {
|
||||
if (node.label !== label) continue;
|
||||
const content = extractContent(node, fileContents);
|
||||
|
|
@ -201,9 +201,10 @@ const generateCodeElementCSV = (
|
|||
escapeCSVNumber(node.properties.endLine, -1),
|
||||
node.properties.isExported ? 'true' : 'false',
|
||||
escapeCSVField(content),
|
||||
escapeCSVField((node.properties as any).description || ''),
|
||||
].join(','));
|
||||
}
|
||||
|
||||
|
||||
return rows.join('\n');
|
||||
};
|
||||
|
||||
|
|
@ -267,6 +268,35 @@ const generateProcessCSV = (nodes: GraphNode[]): string => {
|
|||
return rows.join('\n');
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate CSV for multi-language node tables (Struct, Enum, Trait, Property, etc.)
|
||||
* These use CODE_ELEMENT_BASE schema: id,name,filePath,startLine,endLine,content,description
|
||||
*/
|
||||
const generateMultiLangNodeCSV = (
|
||||
nodes: GraphNode[],
|
||||
label: string,
|
||||
fileContents: Map<string, string>
|
||||
): string => {
|
||||
const headers = ['id', 'name', 'filePath', 'startLine', 'endLine', 'content', 'description'];
|
||||
const rows: string[] = [headers.join(',')];
|
||||
|
||||
for (const node of nodes) {
|
||||
if (node.label !== label) continue;
|
||||
const content = extractContent(node, fileContents);
|
||||
rows.push([
|
||||
escapeCSVField(node.id),
|
||||
escapeCSVField(node.properties.name || ''),
|
||||
escapeCSVField(node.properties.filePath || ''),
|
||||
escapeCSVNumber(node.properties.startLine, -1),
|
||||
escapeCSVNumber(node.properties.endLine, -1),
|
||||
escapeCSVField(content),
|
||||
escapeCSVField((node.properties as any).description || ''),
|
||||
].join(','));
|
||||
}
|
||||
|
||||
return rows.join('\n');
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate CSV for the single CodeRelation table
|
||||
* Headers: from,to,type,confidence,reason
|
||||
|
|
@ -317,7 +347,17 @@ export const generateAllCSVs = (
|
|||
nodeCSVs.set('CodeElement', generateCodeElementCSV(nodes, 'CodeElement', fileContents));
|
||||
nodeCSVs.set('Community', generateCommunityCSV(nodes));
|
||||
nodeCSVs.set('Process', generateProcessCSV(nodes));
|
||||
|
||||
|
||||
// Multi-language node types (CODE_ELEMENT_BASE schema: id,name,filePath,startLine,endLine,content,description)
|
||||
const multiLangTypes = [
|
||||
'Struct', 'Enum', 'Macro', 'Typedef', 'Union', 'Namespace', 'Trait', 'Impl',
|
||||
'TypeAlias', 'Const', 'Static', 'Property', 'Record', 'Delegate', 'Annotation',
|
||||
'Constructor', 'Template', 'Module',
|
||||
] as const;
|
||||
for (const mlType of multiLangTypes) {
|
||||
nodeCSVs.set(mlType, generateMultiLangNodeCSV(nodes, mlType, fileContents));
|
||||
}
|
||||
|
||||
// Generate single relation CSV
|
||||
const relCSV = generateRelationCSV(graph);
|
||||
|
||||
|
|
|
|||
|
|
@ -282,8 +282,12 @@ const getCopyQuery = (table: NodeTableName, filePath: string): string => {
|
|||
if (table === 'Process') {
|
||||
return `COPY ${t}(id, label, heuristicLabel, processType, stepCount, communities, entryPointId, terminalId) FROM "${filePath}" ${COPY_CSV_OPTS}`;
|
||||
}
|
||||
// Code element tables (Function, Class, Interface, Method, CodeElement, and multi-language)
|
||||
return `COPY ${t}(id, name, filePath, startLine, endLine, isExported, content) FROM "${filePath}" ${COPY_CSV_OPTS}`;
|
||||
// Multi-language code element tables (CODE_ELEMENT_BASE: no isExported, has description)
|
||||
if (BACKTICK_TABLES.has(table)) {
|
||||
return `COPY ${t}(id, name, filePath, startLine, endLine, content, description) FROM "${filePath}" ${COPY_CSV_OPTS}`;
|
||||
}
|
||||
// Core code element tables (Function, Class, Interface, Method, CodeElement)
|
||||
return `COPY ${t}(id, name, filePath, startLine, endLine, isExported, content, description) FROM "${filePath}" ${COPY_CSV_OPTS}`;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -320,7 +324,8 @@ export const insertNodeToKuzu = async (
|
|||
query = `CREATE (n:Folder {id: ${escapeValue(properties.id)}, name: ${escapeValue(properties.name)}, filePath: ${escapeValue(properties.filePath)}})`;
|
||||
} else {
|
||||
// Function, Class, Method, Interface, etc. - standard code element schema
|
||||
query = `CREATE (n:${label} {id: ${escapeValue(properties.id)}, name: ${escapeValue(properties.name)}, filePath: ${escapeValue(properties.filePath)}, startLine: ${properties.startLine || 0}, endLine: ${properties.endLine || 0}, content: ${escapeValue(properties.content || '')}})`;
|
||||
const descStr = properties.description ? `, description: ${escapeValue(properties.description)}` : '';
|
||||
query = `CREATE (n:${label} {id: ${escapeValue(properties.id)}, name: ${escapeValue(properties.name)}, filePath: ${escapeValue(properties.filePath)}, startLine: ${properties.startLine || 0}, endLine: ${properties.endLine || 0}, content: ${escapeValue(properties.content || '')}${descStr}})`;
|
||||
}
|
||||
|
||||
// Use per-query connection if dbPath provided (avoids lock conflicts)
|
||||
|
|
@ -385,7 +390,8 @@ export const batchInsertNodesToKuzu = async (
|
|||
} else if (label === 'Folder') {
|
||||
query = `MERGE (n:Folder {id: ${escapeValue(properties.id)}}) SET n.name = ${escapeValue(properties.name)}, n.filePath = ${escapeValue(properties.filePath)}`;
|
||||
} else {
|
||||
query = `MERGE (n:${label} {id: ${escapeValue(properties.id)}}) SET n.name = ${escapeValue(properties.name)}, n.filePath = ${escapeValue(properties.filePath)}, n.startLine = ${properties.startLine || 0}, n.endLine = ${properties.endLine || 0}, n.content = ${escapeValue(properties.content || '')}`;
|
||||
const descPart = properties.description ? `, n.description = ${escapeValue(properties.description)}` : '';
|
||||
query = `MERGE (n:${label} {id: ${escapeValue(properties.id)}}) SET n.name = ${escapeValue(properties.name)}, n.filePath = ${escapeValue(properties.filePath)}, n.startLine = ${properties.startLine || 0}, n.endLine = ${properties.endLine || 0}, n.content = ${escapeValue(properties.content || '')}${descPart}`;
|
||||
}
|
||||
|
||||
await tempConn.query(query);
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ CREATE NODE TABLE Function (
|
|||
endLine INT64,
|
||||
isExported BOOLEAN,
|
||||
content STRING,
|
||||
description STRING,
|
||||
PRIMARY KEY (id)
|
||||
)`;
|
||||
|
||||
|
|
@ -76,6 +77,7 @@ CREATE NODE TABLE Class (
|
|||
endLine INT64,
|
||||
isExported BOOLEAN,
|
||||
content STRING,
|
||||
description STRING,
|
||||
PRIMARY KEY (id)
|
||||
)`;
|
||||
|
||||
|
|
@ -88,6 +90,7 @@ CREATE NODE TABLE Interface (
|
|||
endLine INT64,
|
||||
isExported BOOLEAN,
|
||||
content STRING,
|
||||
description STRING,
|
||||
PRIMARY KEY (id)
|
||||
)`;
|
||||
|
||||
|
|
@ -100,6 +103,7 @@ CREATE NODE TABLE Method (
|
|||
endLine INT64,
|
||||
isExported BOOLEAN,
|
||||
content STRING,
|
||||
description STRING,
|
||||
PRIMARY KEY (id)
|
||||
)`;
|
||||
|
||||
|
|
@ -112,6 +116,7 @@ CREATE NODE TABLE CodeElement (
|
|||
endLine INT64,
|
||||
isExported BOOLEAN,
|
||||
content STRING,
|
||||
description STRING,
|
||||
PRIMARY KEY (id)
|
||||
)`;
|
||||
|
||||
|
|
@ -154,6 +159,7 @@ CREATE NODE TABLE Process (
|
|||
// ============================================================================
|
||||
|
||||
// Generic code element with startLine/endLine for C, C++, Rust, Go, Java, C#
|
||||
// description: optional metadata (e.g. Eloquent $fillable fields, relationship targets)
|
||||
const CODE_ELEMENT_BASE = (name: string) => `
|
||||
CREATE NODE TABLE \`${name}\` (
|
||||
id STRING,
|
||||
|
|
@ -162,6 +168,7 @@ CREATE NODE TABLE \`${name}\` (
|
|||
startLine INT64,
|
||||
endLine INT64,
|
||||
content STRING,
|
||||
description STRING,
|
||||
PRIMARY KEY (id)
|
||||
)`;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue