@optave/codegraph 3.1.2 → 3.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -21
- package/package.json +10 -7
- package/src/analysis/context.js +408 -0
- package/src/analysis/dependencies.js +341 -0
- package/src/analysis/exports.js +130 -0
- package/src/analysis/impact.js +463 -0
- package/src/analysis/module-map.js +322 -0
- package/src/analysis/roles.js +45 -0
- package/src/analysis/symbol-lookup.js +232 -0
- package/src/ast-analysis/shared.js +5 -4
- package/src/batch.js +2 -1
- package/src/builder/context.js +85 -0
- package/src/builder/helpers.js +218 -0
- package/src/builder/incremental.js +178 -0
- package/src/builder/pipeline.js +130 -0
- package/src/builder/stages/build-edges.js +297 -0
- package/src/builder/stages/build-structure.js +113 -0
- package/src/builder/stages/collect-files.js +44 -0
- package/src/builder/stages/detect-changes.js +413 -0
- package/src/builder/stages/finalize.js +139 -0
- package/src/builder/stages/insert-nodes.js +195 -0
- package/src/builder/stages/parse-files.js +28 -0
- package/src/builder/stages/resolve-imports.js +143 -0
- package/src/builder/stages/run-analyses.js +44 -0
- package/src/builder.js +10 -1472
- package/src/cfg.js +1 -2
- package/src/cli/commands/ast.js +26 -0
- package/src/cli/commands/audit.js +46 -0
- package/src/cli/commands/batch.js +68 -0
- package/src/cli/commands/branch-compare.js +21 -0
- package/src/cli/commands/build.js +26 -0
- package/src/cli/commands/cfg.js +30 -0
- package/src/cli/commands/check.js +79 -0
- package/src/cli/commands/children.js +31 -0
- package/src/cli/commands/co-change.js +65 -0
- package/src/cli/commands/communities.js +23 -0
- package/src/cli/commands/complexity.js +45 -0
- package/src/cli/commands/context.js +34 -0
- package/src/cli/commands/cycles.js +28 -0
- package/src/cli/commands/dataflow.js +32 -0
- package/src/cli/commands/deps.js +16 -0
- package/src/cli/commands/diff-impact.js +30 -0
- package/src/cli/commands/embed.js +30 -0
- package/src/cli/commands/export.js +75 -0
- package/src/cli/commands/exports.js +18 -0
- package/src/cli/commands/flow.js +36 -0
- package/src/cli/commands/fn-impact.js +30 -0
- package/src/cli/commands/impact.js +16 -0
- package/src/cli/commands/info.js +76 -0
- package/src/cli/commands/map.js +19 -0
- package/src/cli/commands/mcp.js +18 -0
- package/src/cli/commands/models.js +19 -0
- package/src/cli/commands/owners.js +25 -0
- package/src/cli/commands/path.js +36 -0
- package/src/cli/commands/plot.js +80 -0
- package/src/cli/commands/query.js +49 -0
- package/src/cli/commands/registry.js +100 -0
- package/src/cli/commands/roles.js +34 -0
- package/src/cli/commands/search.js +42 -0
- package/src/cli/commands/sequence.js +32 -0
- package/src/cli/commands/snapshot.js +61 -0
- package/src/cli/commands/stats.js +15 -0
- package/src/cli/commands/structure.js +32 -0
- package/src/cli/commands/triage.js +78 -0
- package/src/cli/commands/watch.js +12 -0
- package/src/cli/commands/where.js +24 -0
- package/src/cli/index.js +118 -0
- package/src/cli/shared/options.js +39 -0
- package/src/cli/shared/output.js +1 -0
- package/src/cli.js +11 -1514
- package/src/commands/check.js +5 -5
- package/src/commands/manifesto.js +3 -3
- package/src/commands/structure.js +1 -1
- package/src/communities.js +15 -87
- package/src/complexity.js +1 -1
- package/src/cycles.js +30 -85
- package/src/dataflow.js +1 -2
- package/src/db/connection.js +4 -4
- package/src/db/migrations.js +41 -0
- package/src/db/query-builder.js +6 -5
- package/src/db/repository/base.js +201 -0
- package/src/db/repository/cached-stmt.js +19 -0
- package/src/db/repository/cfg.js +27 -38
- package/src/db/repository/cochange.js +16 -3
- package/src/db/repository/complexity.js +11 -6
- package/src/db/repository/dataflow.js +6 -1
- package/src/db/repository/edges.js +120 -98
- package/src/db/repository/embeddings.js +14 -3
- package/src/db/repository/graph-read.js +32 -9
- package/src/db/repository/in-memory-repository.js +584 -0
- package/src/db/repository/index.js +6 -1
- package/src/db/repository/nodes.js +110 -40
- package/src/db/repository/sqlite-repository.js +219 -0
- package/src/db.js +5 -0
- package/src/embeddings/generator.js +163 -0
- package/src/embeddings/index.js +13 -0
- package/src/embeddings/models.js +218 -0
- package/src/embeddings/search/cli-formatter.js +151 -0
- package/src/embeddings/search/filters.js +46 -0
- package/src/embeddings/search/hybrid.js +121 -0
- package/src/embeddings/search/keyword.js +68 -0
- package/src/embeddings/search/prepare.js +66 -0
- package/src/embeddings/search/semantic.js +145 -0
- package/src/embeddings/stores/fts5.js +27 -0
- package/src/embeddings/stores/sqlite-blob.js +24 -0
- package/src/embeddings/strategies/source.js +14 -0
- package/src/embeddings/strategies/structured.js +43 -0
- package/src/embeddings/strategies/text-utils.js +43 -0
- package/src/errors.js +78 -0
- package/src/export.js +217 -520
- package/src/extractors/csharp.js +10 -2
- package/src/extractors/go.js +3 -1
- package/src/extractors/helpers.js +71 -0
- package/src/extractors/java.js +9 -2
- package/src/extractors/javascript.js +38 -1
- package/src/extractors/php.js +3 -1
- package/src/extractors/python.js +14 -3
- package/src/extractors/rust.js +3 -1
- package/src/graph/algorithms/bfs.js +49 -0
- package/src/graph/algorithms/centrality.js +16 -0
- package/src/graph/algorithms/index.js +5 -0
- package/src/graph/algorithms/louvain.js +26 -0
- package/src/graph/algorithms/shortest-path.js +41 -0
- package/src/graph/algorithms/tarjan.js +49 -0
- package/src/graph/builders/dependency.js +91 -0
- package/src/graph/builders/index.js +3 -0
- package/src/graph/builders/structure.js +40 -0
- package/src/graph/builders/temporal.js +33 -0
- package/src/graph/classifiers/index.js +2 -0
- package/src/graph/classifiers/risk.js +85 -0
- package/src/graph/classifiers/roles.js +64 -0
- package/src/graph/index.js +13 -0
- package/src/graph/model.js +230 -0
- package/src/index.js +33 -204
- package/src/infrastructure/result-formatter.js +2 -21
- package/src/mcp/index.js +2 -0
- package/src/mcp/middleware.js +26 -0
- package/src/mcp/server.js +128 -0
- package/src/mcp/tool-registry.js +801 -0
- package/src/mcp/tools/ast-query.js +14 -0
- package/src/mcp/tools/audit.js +21 -0
- package/src/mcp/tools/batch-query.js +11 -0
- package/src/mcp/tools/branch-compare.js +10 -0
- package/src/mcp/tools/cfg.js +21 -0
- package/src/mcp/tools/check.js +43 -0
- package/src/mcp/tools/co-changes.js +20 -0
- package/src/mcp/tools/code-owners.js +12 -0
- package/src/mcp/tools/communities.js +15 -0
- package/src/mcp/tools/complexity.js +18 -0
- package/src/mcp/tools/context.js +17 -0
- package/src/mcp/tools/dataflow.js +26 -0
- package/src/mcp/tools/diff-impact.js +24 -0
- package/src/mcp/tools/execution-flow.js +26 -0
- package/src/mcp/tools/export-graph.js +57 -0
- package/src/mcp/tools/file-deps.js +12 -0
- package/src/mcp/tools/file-exports.js +13 -0
- package/src/mcp/tools/find-cycles.js +15 -0
- package/src/mcp/tools/fn-impact.js +15 -0
- package/src/mcp/tools/impact-analysis.js +12 -0
- package/src/mcp/tools/index.js +71 -0
- package/src/mcp/tools/list-functions.js +14 -0
- package/src/mcp/tools/list-repos.js +11 -0
- package/src/mcp/tools/module-map.js +6 -0
- package/src/mcp/tools/node-roles.js +14 -0
- package/src/mcp/tools/path.js +12 -0
- package/src/mcp/tools/query.js +30 -0
- package/src/mcp/tools/semantic-search.js +65 -0
- package/src/mcp/tools/sequence.js +17 -0
- package/src/mcp/tools/structure.js +15 -0
- package/src/mcp/tools/symbol-children.js +14 -0
- package/src/mcp/tools/triage.js +35 -0
- package/src/mcp/tools/where.js +13 -0
- package/src/mcp.js +2 -1470
- package/src/native.js +34 -10
- package/src/parser.js +53 -2
- package/src/presentation/colors.js +44 -0
- package/src/presentation/export.js +444 -0
- package/src/presentation/result-formatter.js +21 -0
- package/src/presentation/sequence-renderer.js +43 -0
- package/src/presentation/table.js +47 -0
- package/src/presentation/viewer.js +634 -0
- package/src/queries.js +35 -2276
- package/src/resolve.js +1 -1
- package/src/sequence.js +2 -38
- package/src/shared/file-utils.js +153 -0
- package/src/shared/generators.js +125 -0
- package/src/shared/hierarchy.js +27 -0
- package/src/shared/normalize.js +59 -0
- package/src/snapshot.js +6 -5
- package/src/structure.js +15 -40
- package/src/triage.js +20 -72
- package/src/viewer.js +35 -656
- package/src/watcher.js +8 -148
- package/src/embedder.js +0 -1097
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract Repository base class.
|
|
3
|
+
*
|
|
4
|
+
* Defines the contract for all graph data access. Every method throws
|
|
5
|
+
* "not implemented" by default — concrete subclasses override what they support.
|
|
6
|
+
*/
|
|
7
|
+
export class Repository {
|
|
8
|
+
// ── Node lookups ────────────────────────────────────────────────────
|
|
9
|
+
/** @param {number} id @returns {object|undefined} */
|
|
10
|
+
findNodeById(_id) {
|
|
11
|
+
throw new Error('not implemented');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** @param {string} file @returns {object[]} */
|
|
15
|
+
findNodesByFile(_file) {
|
|
16
|
+
throw new Error('not implemented');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** @param {string} fileLike @returns {object[]} */
|
|
20
|
+
findFileNodes(_fileLike) {
|
|
21
|
+
throw new Error('not implemented');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** @param {string} namePattern @param {object} [opts] @returns {object[]} */
|
|
25
|
+
findNodesWithFanIn(_namePattern, _opts) {
|
|
26
|
+
throw new Error('not implemented');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** @returns {number} */
|
|
30
|
+
countNodes() {
|
|
31
|
+
throw new Error('not implemented');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** @returns {number} */
|
|
35
|
+
countEdges() {
|
|
36
|
+
throw new Error('not implemented');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** @returns {number} */
|
|
40
|
+
countFiles() {
|
|
41
|
+
throw new Error('not implemented');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** @param {string} name @param {string} kind @param {string} file @param {number} line @returns {number|undefined} */
|
|
45
|
+
getNodeId(_name, _kind, _file, _line) {
|
|
46
|
+
throw new Error('not implemented');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** @param {string} name @param {string} file @param {number} line @returns {number|undefined} */
|
|
50
|
+
getFunctionNodeId(_name, _file, _line) {
|
|
51
|
+
throw new Error('not implemented');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** @param {string} file @returns {{ id: number, name: string, kind: string, line: number }[]} */
|
|
55
|
+
bulkNodeIdsByFile(_file) {
|
|
56
|
+
throw new Error('not implemented');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** @param {number} parentId @returns {object[]} */
|
|
60
|
+
findNodeChildren(_parentId) {
|
|
61
|
+
throw new Error('not implemented');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** @param {string} scopeName @param {object} [opts] @returns {object[]} */
|
|
65
|
+
findNodesByScope(_scopeName, _opts) {
|
|
66
|
+
throw new Error('not implemented');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** @param {string} qualifiedName @param {object} [opts] @returns {object[]} */
|
|
70
|
+
findNodeByQualifiedName(_qualifiedName, _opts) {
|
|
71
|
+
throw new Error('not implemented');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** @param {object} [opts] @returns {object[]} */
|
|
75
|
+
listFunctionNodes(_opts) {
|
|
76
|
+
throw new Error('not implemented');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** @param {object} [opts] @returns {IterableIterator} */
|
|
80
|
+
iterateFunctionNodes(_opts) {
|
|
81
|
+
throw new Error('not implemented');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** @param {object} [opts] @returns {object[]} */
|
|
85
|
+
findNodesForTriage(_opts) {
|
|
86
|
+
throw new Error('not implemented');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ── Edge queries ────────────────────────────────────────────────────
|
|
90
|
+
/** @param {number} nodeId @returns {object[]} */
|
|
91
|
+
findCallees(_nodeId) {
|
|
92
|
+
throw new Error('not implemented');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** @param {number} nodeId @returns {object[]} */
|
|
96
|
+
findCallers(_nodeId) {
|
|
97
|
+
throw new Error('not implemented');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** @param {number} nodeId @returns {object[]} */
|
|
101
|
+
findDistinctCallers(_nodeId) {
|
|
102
|
+
throw new Error('not implemented');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** @param {number} nodeId @returns {object[]} */
|
|
106
|
+
findAllOutgoingEdges(_nodeId) {
|
|
107
|
+
throw new Error('not implemented');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** @param {number} nodeId @returns {object[]} */
|
|
111
|
+
findAllIncomingEdges(_nodeId) {
|
|
112
|
+
throw new Error('not implemented');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** @param {number} nodeId @returns {string[]} */
|
|
116
|
+
findCalleeNames(_nodeId) {
|
|
117
|
+
throw new Error('not implemented');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** @param {number} nodeId @returns {string[]} */
|
|
121
|
+
findCallerNames(_nodeId) {
|
|
122
|
+
throw new Error('not implemented');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** @param {number} nodeId @returns {{ file: string, edge_kind: string }[]} */
|
|
126
|
+
findImportTargets(_nodeId) {
|
|
127
|
+
throw new Error('not implemented');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** @param {number} nodeId @returns {{ file: string, edge_kind: string }[]} */
|
|
131
|
+
findImportSources(_nodeId) {
|
|
132
|
+
throw new Error('not implemented');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** @param {number} nodeId @returns {object[]} */
|
|
136
|
+
findImportDependents(_nodeId) {
|
|
137
|
+
throw new Error('not implemented');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** @param {string} file @returns {Set<number>} */
|
|
141
|
+
findCrossFileCallTargets(_file) {
|
|
142
|
+
throw new Error('not implemented');
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** @param {number} nodeId @param {string} file @returns {number} */
|
|
146
|
+
countCrossFileCallers(_nodeId, _file) {
|
|
147
|
+
throw new Error('not implemented');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** @param {number} classNodeId @returns {Set<number>} */
|
|
151
|
+
getClassHierarchy(_classNodeId) {
|
|
152
|
+
throw new Error('not implemented');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** @param {string} file @returns {{ caller_name: string, callee_name: string }[]} */
|
|
156
|
+
findIntraFileCallEdges(_file) {
|
|
157
|
+
throw new Error('not implemented');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// ── Graph-read queries ──────────────────────────────────────────────
|
|
161
|
+
/** @returns {{ id: number, name: string, kind: string, file: string }[]} */
|
|
162
|
+
getCallableNodes() {
|
|
163
|
+
throw new Error('not implemented');
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** @returns {{ source_id: number, target_id: number }[]} */
|
|
167
|
+
getCallEdges() {
|
|
168
|
+
throw new Error('not implemented');
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** @returns {{ id: number, name: string, file: string }[]} */
|
|
172
|
+
getFileNodesAll() {
|
|
173
|
+
throw new Error('not implemented');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** @returns {{ source_id: number, target_id: number }[]} */
|
|
177
|
+
getImportEdges() {
|
|
178
|
+
throw new Error('not implemented');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ── Optional table checks (default: false/undefined) ────────────────
|
|
182
|
+
/** @returns {boolean} */
|
|
183
|
+
hasCfgTables() {
|
|
184
|
+
throw new Error('not implemented');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** @returns {boolean} */
|
|
188
|
+
hasEmbeddings() {
|
|
189
|
+
throw new Error('not implemented');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** @returns {boolean} */
|
|
193
|
+
hasDataflowTable() {
|
|
194
|
+
throw new Error('not implemented');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** @param {number} nodeId @returns {object|undefined} */
|
|
198
|
+
getComplexityForNode(_nodeId) {
|
|
199
|
+
throw new Error('not implemented');
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve a cached prepared statement, compiling on first use per db.
|
|
3
|
+
* Each `cache` WeakMap must always be called with the same `sql` —
|
|
4
|
+
* the sql argument is only used on the first compile; subsequent calls
|
|
5
|
+
* return the cached statement regardless of the sql passed.
|
|
6
|
+
*
|
|
7
|
+
* @param {WeakMap} cache - WeakMap keyed by db instance
|
|
8
|
+
* @param {object} db - better-sqlite3 database instance
|
|
9
|
+
* @param {string} sql - SQL to compile on first use
|
|
10
|
+
* @returns {object} prepared statement
|
|
11
|
+
*/
|
|
12
|
+
export function cachedStmt(cache, db, sql) {
|
|
13
|
+
let stmt = cache.get(db);
|
|
14
|
+
if (!stmt) {
|
|
15
|
+
stmt = db.prepare(sql);
|
|
16
|
+
cache.set(db, stmt);
|
|
17
|
+
}
|
|
18
|
+
return stmt;
|
|
19
|
+
}
|
package/src/db/repository/cfg.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { cachedStmt } from './cached-stmt.js';
|
|
2
|
+
|
|
1
3
|
// ─── Statement caches (one prepared statement per db instance) ────────────
|
|
2
|
-
// WeakMap keys on the db object so statements are GC'd when the db closes.
|
|
3
4
|
const _getCfgBlocksStmt = new WeakMap();
|
|
4
5
|
const _getCfgEdgesStmt = new WeakMap();
|
|
5
6
|
const _deleteCfgEdgesStmt = new WeakMap();
|
|
@@ -26,16 +27,13 @@ export function hasCfgTables(db) {
|
|
|
26
27
|
* @returns {object[]}
|
|
27
28
|
*/
|
|
28
29
|
export function getCfgBlocks(db, functionNodeId) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
_getCfgBlocksStmt.set(db, stmt);
|
|
37
|
-
}
|
|
38
|
-
return stmt.all(functionNodeId);
|
|
30
|
+
return cachedStmt(
|
|
31
|
+
_getCfgBlocksStmt,
|
|
32
|
+
db,
|
|
33
|
+
`SELECT id, block_index, block_type, start_line, end_line, label
|
|
34
|
+
FROM cfg_blocks WHERE function_node_id = ?
|
|
35
|
+
ORDER BY block_index`,
|
|
36
|
+
).all(functionNodeId);
|
|
39
37
|
}
|
|
40
38
|
|
|
41
39
|
/**
|
|
@@ -45,21 +43,18 @@ export function getCfgBlocks(db, functionNodeId) {
|
|
|
45
43
|
* @returns {object[]}
|
|
46
44
|
*/
|
|
47
45
|
export function getCfgEdges(db, functionNodeId) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
_getCfgEdgesStmt.set(db, stmt);
|
|
61
|
-
}
|
|
62
|
-
return stmt.all(functionNodeId);
|
|
46
|
+
return cachedStmt(
|
|
47
|
+
_getCfgEdgesStmt,
|
|
48
|
+
db,
|
|
49
|
+
`SELECT e.kind,
|
|
50
|
+
sb.block_index AS source_index, sb.block_type AS source_type,
|
|
51
|
+
tb.block_index AS target_index, tb.block_type AS target_type
|
|
52
|
+
FROM cfg_edges e
|
|
53
|
+
JOIN cfg_blocks sb ON e.source_block_id = sb.id
|
|
54
|
+
JOIN cfg_blocks tb ON e.target_block_id = tb.id
|
|
55
|
+
WHERE e.function_node_id = ?
|
|
56
|
+
ORDER BY sb.block_index, tb.block_index`,
|
|
57
|
+
).all(functionNodeId);
|
|
63
58
|
}
|
|
64
59
|
|
|
65
60
|
/**
|
|
@@ -68,16 +63,10 @@ export function getCfgEdges(db, functionNodeId) {
|
|
|
68
63
|
* @param {number} functionNodeId
|
|
69
64
|
*/
|
|
70
65
|
export function deleteCfgForNode(db, functionNodeId) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (!delBlocks) {
|
|
78
|
-
delBlocks = db.prepare('DELETE FROM cfg_blocks WHERE function_node_id = ?');
|
|
79
|
-
_deleteCfgBlocksStmt.set(db, delBlocks);
|
|
80
|
-
}
|
|
81
|
-
delEdges.run(functionNodeId);
|
|
82
|
-
delBlocks.run(functionNodeId);
|
|
66
|
+
cachedStmt(_deleteCfgEdgesStmt, db, 'DELETE FROM cfg_edges WHERE function_node_id = ?').run(
|
|
67
|
+
functionNodeId,
|
|
68
|
+
);
|
|
69
|
+
cachedStmt(_deleteCfgBlocksStmt, db, 'DELETE FROM cfg_blocks WHERE function_node_id = ?').run(
|
|
70
|
+
functionNodeId,
|
|
71
|
+
);
|
|
83
72
|
}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import { cachedStmt } from './cached-stmt.js';
|
|
2
|
+
|
|
3
|
+
// ─── Statement caches (one prepared statement per db instance) ────────────
|
|
4
|
+
const _hasCoChangesStmt = new WeakMap();
|
|
5
|
+
const _getCoChangeMetaStmt = new WeakMap();
|
|
6
|
+
const _upsertCoChangeMetaStmt = new WeakMap();
|
|
7
|
+
|
|
1
8
|
/**
|
|
2
9
|
* Check whether the co_changes table has data.
|
|
3
10
|
* @param {object} db
|
|
@@ -5,7 +12,7 @@
|
|
|
5
12
|
*/
|
|
6
13
|
export function hasCoChanges(db) {
|
|
7
14
|
try {
|
|
8
|
-
return !!db
|
|
15
|
+
return !!cachedStmt(_hasCoChangesStmt, db, 'SELECT 1 FROM co_changes LIMIT 1').get();
|
|
9
16
|
} catch {
|
|
10
17
|
return false;
|
|
11
18
|
}
|
|
@@ -19,7 +26,11 @@ export function hasCoChanges(db) {
|
|
|
19
26
|
export function getCoChangeMeta(db) {
|
|
20
27
|
const meta = {};
|
|
21
28
|
try {
|
|
22
|
-
for (const row of
|
|
29
|
+
for (const row of cachedStmt(
|
|
30
|
+
_getCoChangeMetaStmt,
|
|
31
|
+
db,
|
|
32
|
+
'SELECT key, value FROM co_change_meta',
|
|
33
|
+
).all()) {
|
|
23
34
|
meta[row.key] = row.value;
|
|
24
35
|
}
|
|
25
36
|
} catch {
|
|
@@ -35,7 +46,9 @@ export function getCoChangeMeta(db) {
|
|
|
35
46
|
* @param {string} value
|
|
36
47
|
*/
|
|
37
48
|
export function upsertCoChangeMeta(db, key, value) {
|
|
38
|
-
|
|
49
|
+
cachedStmt(
|
|
50
|
+
_upsertCoChangeMetaStmt,
|
|
51
|
+
db,
|
|
39
52
|
'INSERT INTO co_change_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value',
|
|
40
53
|
).run(key, value);
|
|
41
54
|
}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { cachedStmt } from './cached-stmt.js';
|
|
2
|
+
|
|
3
|
+
// ─── Statement caches (one prepared statement per db instance) ────────────
|
|
4
|
+
const _getComplexityForNodeStmt = new WeakMap();
|
|
5
|
+
|
|
1
6
|
/**
|
|
2
7
|
* Get complexity metrics for a node.
|
|
3
8
|
* Used by contextData and explainFunctionImpl in queries.js.
|
|
@@ -6,10 +11,10 @@
|
|
|
6
11
|
* @returns {{ cognitive: number, cyclomatic: number, max_nesting: number, maintainability_index: number, halstead_volume: number }|undefined}
|
|
7
12
|
*/
|
|
8
13
|
export function getComplexityForNode(db, nodeId) {
|
|
9
|
-
return
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
return cachedStmt(
|
|
15
|
+
_getComplexityForNodeStmt,
|
|
16
|
+
db,
|
|
17
|
+
`SELECT cognitive, cyclomatic, max_nesting, maintainability_index, halstead_volume
|
|
18
|
+
FROM function_complexity WHERE node_id = ?`,
|
|
19
|
+
).get(nodeId);
|
|
15
20
|
}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import { cachedStmt } from './cached-stmt.js';
|
|
2
|
+
|
|
3
|
+
// ─── Statement caches (one prepared statement per db instance) ────────────
|
|
4
|
+
const _hasDataflowTableStmt = new WeakMap();
|
|
5
|
+
|
|
1
6
|
/**
|
|
2
7
|
* Check whether the dataflow table exists and has data.
|
|
3
8
|
* @param {object} db
|
|
@@ -5,7 +10,7 @@
|
|
|
5
10
|
*/
|
|
6
11
|
export function hasDataflowTable(db) {
|
|
7
12
|
try {
|
|
8
|
-
return db
|
|
13
|
+
return cachedStmt(_hasDataflowTableStmt, db, 'SELECT COUNT(*) AS c FROM dataflow').get().c > 0;
|
|
9
14
|
} catch {
|
|
10
15
|
return false;
|
|
11
16
|
}
|