* Get unresolved references scoped to specific file paths. * Uses the idx_unresolved_file_path index for efficient lookup.
(filePaths: string[])
| 1691 | * Uses the idx_unresolved_file_path index for efficient lookup. |
| 1692 | */ |
| 1693 | getUnresolvedReferencesByFiles(filePaths: string[]): UnresolvedReference[] { |
| 1694 | if (filePaths.length === 0) return []; |
| 1695 | |
| 1696 | // Chunk under SQLite's parameter limit: the first sync of a very large repo |
| 1697 | // passes every changed file here, which an unbounded `IN (...)` would bind |
| 1698 | // as one parameter each — exceeding MAX_VARIABLE_NUMBER and aborting with |
| 1699 | // "too many SQL variables". (#540) |
| 1700 | const rows: UnresolvedRefRow[] = []; |
| 1701 | for (let i = 0; i < filePaths.length; i += SQLITE_PARAM_CHUNK_SIZE) { |
| 1702 | const chunk = filePaths.slice(i, i + SQLITE_PARAM_CHUNK_SIZE); |
| 1703 | const placeholders = chunk.map(() => '?').join(','); |
| 1704 | const chunkRows = this.db |
| 1705 | .prepare(`SELECT * FROM unresolved_refs WHERE file_path IN (${placeholders})`) |
| 1706 | .all(...chunk) as UnresolvedRefRow[]; |
| 1707 | rows.push(...chunkRows); |
| 1708 | } |
| 1709 | |
| 1710 | return rows.map((row) => ({ |
| 1711 | fromNodeId: row.from_node_id, |
| 1712 | referenceName: row.reference_name, |
| 1713 | referenceKind: row.reference_kind as EdgeKind, |
| 1714 | line: row.line, |
| 1715 | column: row.col, |
| 1716 | candidates: row.candidates ? safeJsonParse(row.candidates, undefined) : undefined, |
| 1717 | filePath: row.file_path, |
| 1718 | language: row.language as Language, |
| 1719 | })); |
| 1720 | } |
| 1721 | |
| 1722 | /** |
| 1723 | * Delete all unresolved references (after resolution) |
no test coverage detected