dbgraph 0.1.0
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/LICENSE +21 -0
- package/README.md +347 -0
- package/dist/bin/dbgraph.d.ts +8 -0
- package/dist/bin/dbgraph.d.ts.map +1 -0
- package/dist/bin/dbgraph.js +382 -0
- package/dist/bin/dbgraph.js.map +1 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +158 -0
- package/dist/config.js.map +1 -0
- package/dist/context/formatter.d.ts +94 -0
- package/dist/context/formatter.d.ts.map +1 -0
- package/dist/context/formatter.js +288 -0
- package/dist/context/formatter.js.map +1 -0
- package/dist/context/index.d.ts +77 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +458 -0
- package/dist/context/index.js.map +1 -0
- package/dist/db/index.d.ts +26 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +127 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrations.d.ts +8 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +39 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/queries.d.ts +46 -0
- package/dist/db/queries.d.ts.map +1 -0
- package/dist/db/queries.js +436 -0
- package/dist/db/queries.js.map +1 -0
- package/dist/db/schema.sql +113 -0
- package/dist/db/sqlite-adapter.d.ts +30 -0
- package/dist/db/sqlite-adapter.d.ts.map +1 -0
- package/dist/db/sqlite-adapter.js +78 -0
- package/dist/db/sqlite-adapter.js.map +1 -0
- package/dist/directory.d.ts +37 -0
- package/dist/directory.d.ts.map +1 -0
- package/dist/directory.js +160 -0
- package/dist/directory.js.map +1 -0
- package/dist/errors.d.ts +46 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +90 -0
- package/dist/errors.js.map +1 -0
- package/dist/graph/traversal.d.ts +157 -0
- package/dist/graph/traversal.d.ts.map +1 -0
- package/dist/graph/traversal.js +531 -0
- package/dist/graph/traversal.js.map +1 -0
- package/dist/index.d.ts +183 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +435 -0
- package/dist/index.js.map +1 -0
- package/dist/introspect/base.d.ts +62 -0
- package/dist/introspect/base.d.ts.map +1 -0
- package/dist/introspect/base.js +107 -0
- package/dist/introspect/base.js.map +1 -0
- package/dist/introspect/connection.d.ts +30 -0
- package/dist/introspect/connection.d.ts.map +1 -0
- package/dist/introspect/connection.js +232 -0
- package/dist/introspect/connection.js.map +1 -0
- package/dist/introspect/index.d.ts +23 -0
- package/dist/introspect/index.d.ts.map +1 -0
- package/dist/introspect/index.js +46 -0
- package/dist/introspect/index.js.map +1 -0
- package/dist/introspect/mysql.d.ts +64 -0
- package/dist/introspect/mysql.d.ts.map +1 -0
- package/dist/introspect/mysql.js +360 -0
- package/dist/introspect/mysql.js.map +1 -0
- package/dist/introspect/postgres.d.ts +55 -0
- package/dist/introspect/postgres.d.ts.map +1 -0
- package/dist/introspect/postgres.js +372 -0
- package/dist/introspect/postgres.js.map +1 -0
- package/dist/introspect/sqlite.d.ts +33 -0
- package/dist/introspect/sqlite.d.ts.map +1 -0
- package/dist/introspect/sqlite.js +207 -0
- package/dist/introspect/sqlite.js.map +1 -0
- package/dist/mcp/engine.d.ts +92 -0
- package/dist/mcp/engine.d.ts.map +1 -0
- package/dist/mcp/engine.js +261 -0
- package/dist/mcp/engine.js.map +1 -0
- package/dist/mcp/index.d.ts +33 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +119 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server-instructions.d.ts +9 -0
- package/dist/mcp/server-instructions.d.ts.map +1 -0
- package/dist/mcp/server-instructions.js +71 -0
- package/dist/mcp/server-instructions.js.map +1 -0
- package/dist/mcp/session.d.ts +35 -0
- package/dist/mcp/session.d.ts.map +1 -0
- package/dist/mcp/session.js +140 -0
- package/dist/mcp/session.js.map +1 -0
- package/dist/mcp/tools.d.ts +99 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +499 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp/transport.d.ts +78 -0
- package/dist/mcp/transport.d.ts.map +1 -0
- package/dist/mcp/transport.js +182 -0
- package/dist/mcp/transport.js.map +1 -0
- package/dist/search/query-parser.d.ts +66 -0
- package/dist/search/query-parser.d.ts.map +1 -0
- package/dist/search/query-parser.js +163 -0
- package/dist/search/query-parser.js.map +1 -0
- package/dist/search/query-utils.d.ts +78 -0
- package/dist/search/query-utils.d.ts.map +1 -0
- package/dist/search/query-utils.js +203 -0
- package/dist/search/query-utils.js.map +1 -0
- package/dist/types.d.ts +279 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +47 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +40 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +190 -0
- package/dist/utils.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Database Migrations
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CURRENT_SCHEMA_VERSION = void 0;
|
|
7
|
+
exports.getCurrentVersion = getCurrentVersion;
|
|
8
|
+
exports.runMigrations = runMigrations;
|
|
9
|
+
exports.CURRENT_SCHEMA_VERSION = 1;
|
|
10
|
+
const migrations = [
|
|
11
|
+
// Version 1 is the initial schema, handled by schema.sql
|
|
12
|
+
];
|
|
13
|
+
function getCurrentVersion(db) {
|
|
14
|
+
try {
|
|
15
|
+
const row = db
|
|
16
|
+
.prepare('SELECT MAX(version) as version FROM schema_versions')
|
|
17
|
+
.get();
|
|
18
|
+
return row?.version ?? 0;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function recordMigration(db, version, description) {
|
|
25
|
+
db.prepare('INSERT INTO schema_versions (version, applied_at, description) VALUES (?, ?, ?)').run(version, Date.now(), description);
|
|
26
|
+
}
|
|
27
|
+
function runMigrations(db, fromVersion) {
|
|
28
|
+
const pending = migrations.filter((m) => m.version > fromVersion);
|
|
29
|
+
if (pending.length === 0)
|
|
30
|
+
return;
|
|
31
|
+
pending.sort((a, b) => a.version - b.version);
|
|
32
|
+
for (const migration of pending) {
|
|
33
|
+
db.transaction(() => {
|
|
34
|
+
migration.up(db);
|
|
35
|
+
recordMigration(db, migration.version, migration.description);
|
|
36
|
+
})();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/db/migrations.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAgBH,8CASC;AAQD,sCAUC;AAvCY,QAAA,sBAAsB,GAAG,CAAC,CAAC;AAQxC,MAAM,UAAU,GAAgB;AAC9B,yDAAyD;CAC1D,CAAC;AAEF,SAAgB,iBAAiB,CAAC,EAAkB;IAClD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE;aACX,OAAO,CAAC,qDAAqD,CAAC;aAC9D,GAAG,EAA4C,CAAC;QACnD,OAAO,GAAG,EAAE,OAAO,IAAI,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,EAAkB,EAAE,OAAe,EAAE,WAAmB;IAC/E,EAAE,CAAC,OAAO,CACR,iFAAiF,CAClF,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;AAC1C,CAAC;AAED,SAAgB,aAAa,CAAC,EAAkB,EAAE,WAAmB;IACnE,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,WAAW,CAAC,CAAC;IAClE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,MAAM,SAAS,IAAI,OAAO,EAAE,CAAC;QAChC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAClB,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACjB,eAAe,CAAC,EAAE,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;QAChE,CAAC,CAAC,EAAE,CAAC;IACP,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Queries
|
|
3
|
+
*
|
|
4
|
+
* Prepared statements for CRUD operations on the database knowledge graph.
|
|
5
|
+
*/
|
|
6
|
+
import { SqliteDatabase } from './sqlite-adapter';
|
|
7
|
+
import { Node, Edge, NodeKind, EdgeKind, DbSourceRecord, GraphStats, SearchOptions, SearchResult } from '../types';
|
|
8
|
+
export declare class QueryBuilder {
|
|
9
|
+
private db;
|
|
10
|
+
private nodeCache;
|
|
11
|
+
private readonly maxCacheSize;
|
|
12
|
+
private stmts;
|
|
13
|
+
constructor(db: SqliteDatabase);
|
|
14
|
+
insertNode(node: Node): void;
|
|
15
|
+
insertNodes(nodes: Node[]): void;
|
|
16
|
+
deleteNodesBySource(source: string): void;
|
|
17
|
+
getNodeById(id: string): Node | null;
|
|
18
|
+
getNodesByIds(ids: readonly string[]): Map<string, Node>;
|
|
19
|
+
private cacheNode;
|
|
20
|
+
clearCache(): void;
|
|
21
|
+
getNodesByKind(kind: NodeKind): Node[];
|
|
22
|
+
getNodesByName(name: string): Node[];
|
|
23
|
+
getNodesByQualifiedName(qualifiedName: string): Node[];
|
|
24
|
+
searchNodes(query: string, options?: SearchOptions): SearchResult[];
|
|
25
|
+
private searchNodesLike;
|
|
26
|
+
insertEdge(edge: Edge): void;
|
|
27
|
+
insertEdges(edges: Edge[]): void;
|
|
28
|
+
deleteEdgesBySource(sourceId: string): void;
|
|
29
|
+
deleteEdgesByTarget(targetId: string): void;
|
|
30
|
+
getOutgoingEdges(sourceId: string, kinds?: EdgeKind[]): Edge[];
|
|
31
|
+
getIncomingEdges(targetId: string, kinds?: EdgeKind[]): Edge[];
|
|
32
|
+
findEdgesBetweenNodes(nodeIds: string[], kinds?: EdgeKind[]): Edge[];
|
|
33
|
+
upsertDbSource(source: DbSourceRecord): void;
|
|
34
|
+
getDbSource(alias: string): DbSourceRecord | null;
|
|
35
|
+
getAllDbSources(): DbSourceRecord[];
|
|
36
|
+
deleteDbSource(alias: string): void;
|
|
37
|
+
getNodeAndEdgeCount(): {
|
|
38
|
+
nodes: number;
|
|
39
|
+
edges: number;
|
|
40
|
+
};
|
|
41
|
+
getStats(): GraphStats;
|
|
42
|
+
clear(): void;
|
|
43
|
+
getMetadata(key: string): string | null;
|
|
44
|
+
setMetadata(key: string, value: string): void;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/db/queries.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAmB,MAAM,kBAAkB,CAAC;AACnE,OAAO,EACL,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAC9C,UAAU,EAAE,aAAa,EAAE,YAAY,EACxC,MAAM,UAAU,CAAC;AA4FlB,qBAAa,YAAY;IACvB,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IAErC,OAAO,CAAC,KAAK,CAAmD;gBAEpD,EAAE,EAAE,cAAc;IAQ9B,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IA+B5B,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI;IAIhC,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAazC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAiBpC,aAAa,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC;IAiCxD,OAAO,CAAC,SAAS;IAQjB,UAAU,IAAI,IAAI;IAElB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,EAAE;IAOtC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE;IAOpC,uBAAuB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,EAAE;IAStD,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,YAAY,EAAE;IA8CvE,OAAO,CAAC,eAAe;IA6CvB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAgB5B,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI;IAKhC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAO3C,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAO3C,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE;IAW9D,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE;IAW9D,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE;IAgBpE,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAuB5C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAQjD,eAAe,IAAI,cAAc,EAAE;IAOnC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAWnC,mBAAmB,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAMvD,QAAQ,IAAI,UAAU;IAmCtB,KAAK,IAAI,IAAI;IASb,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAMvC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;CAO9C"}
|
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Database Queries
|
|
4
|
+
*
|
|
5
|
+
* Prepared statements for CRUD operations on the database knowledge graph.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.QueryBuilder = void 0;
|
|
9
|
+
const utils_1 = require("../utils");
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// Row converters
|
|
12
|
+
// =============================================================================
|
|
13
|
+
function rowToNode(row) {
|
|
14
|
+
return {
|
|
15
|
+
id: row.id,
|
|
16
|
+
kind: row.kind,
|
|
17
|
+
name: row.name,
|
|
18
|
+
qualifiedName: row.qualified_name,
|
|
19
|
+
filePath: row.file_path,
|
|
20
|
+
language: row.language,
|
|
21
|
+
startLine: row.start_line,
|
|
22
|
+
endLine: row.end_line,
|
|
23
|
+
docstring: row.docstring ?? undefined,
|
|
24
|
+
signature: row.signature ?? undefined,
|
|
25
|
+
metadata: row.metadata ? (0, utils_1.safeJsonParse)(row.metadata, undefined) : undefined,
|
|
26
|
+
updatedAt: row.updated_at,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function rowToEdge(row) {
|
|
30
|
+
return {
|
|
31
|
+
source: row.source,
|
|
32
|
+
target: row.target,
|
|
33
|
+
kind: row.kind,
|
|
34
|
+
metadata: row.metadata ? (0, utils_1.safeJsonParse)(row.metadata, undefined) : undefined,
|
|
35
|
+
provenance: row.provenance,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function rowToDbSource(row) {
|
|
39
|
+
return {
|
|
40
|
+
alias: row.alias,
|
|
41
|
+
engine: row.engine,
|
|
42
|
+
database: row.database,
|
|
43
|
+
host: row.host ?? undefined,
|
|
44
|
+
port: row.port ?? undefined,
|
|
45
|
+
displayUri: row.display_uri,
|
|
46
|
+
indexedAt: row.indexed_at,
|
|
47
|
+
nodeCount: row.node_count,
|
|
48
|
+
errors: row.errors ? (0, utils_1.safeJsonParse)(row.errors, undefined) : undefined,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// =============================================================================
|
|
52
|
+
// QueryBuilder
|
|
53
|
+
// =============================================================================
|
|
54
|
+
class QueryBuilder {
|
|
55
|
+
db;
|
|
56
|
+
nodeCache = new Map();
|
|
57
|
+
maxCacheSize = 1000;
|
|
58
|
+
stmts = {};
|
|
59
|
+
constructor(db) {
|
|
60
|
+
this.db = db;
|
|
61
|
+
}
|
|
62
|
+
// ===========================================================================
|
|
63
|
+
// Node Operations
|
|
64
|
+
// ===========================================================================
|
|
65
|
+
insertNode(node) {
|
|
66
|
+
if (!this.stmts.insertNode) {
|
|
67
|
+
this.stmts.insertNode = this.db.prepare(`
|
|
68
|
+
INSERT OR REPLACE INTO nodes (
|
|
69
|
+
id, kind, name, qualified_name, file_path, language,
|
|
70
|
+
start_line, end_line, docstring, signature, metadata, updated_at
|
|
71
|
+
) VALUES (
|
|
72
|
+
@id, @kind, @name, @qualifiedName, @filePath, @language,
|
|
73
|
+
@startLine, @endLine, @docstring, @signature, @metadata, @updatedAt
|
|
74
|
+
)
|
|
75
|
+
`);
|
|
76
|
+
}
|
|
77
|
+
if (!node.id || !node.kind || !node.name || !node.filePath)
|
|
78
|
+
return;
|
|
79
|
+
this.nodeCache.delete(node.id);
|
|
80
|
+
this.stmts.insertNode.run({
|
|
81
|
+
id: node.id,
|
|
82
|
+
kind: node.kind,
|
|
83
|
+
name: node.name,
|
|
84
|
+
qualifiedName: node.qualifiedName ?? node.name,
|
|
85
|
+
filePath: node.filePath,
|
|
86
|
+
language: node.language ?? 'unknown',
|
|
87
|
+
startLine: node.startLine ?? 0,
|
|
88
|
+
endLine: node.endLine ?? 0,
|
|
89
|
+
docstring: node.docstring ?? null,
|
|
90
|
+
signature: node.signature ?? null,
|
|
91
|
+
metadata: node.metadata ? JSON.stringify(node.metadata) : null,
|
|
92
|
+
updatedAt: node.updatedAt ?? Date.now(),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
insertNodes(nodes) {
|
|
96
|
+
for (const node of nodes)
|
|
97
|
+
this.insertNode(node);
|
|
98
|
+
}
|
|
99
|
+
deleteNodesBySource(source) {
|
|
100
|
+
if (!this.stmts.deleteNodesBySource) {
|
|
101
|
+
this.stmts.deleteNodesBySource = this.db.prepare('DELETE FROM nodes WHERE file_path LIKE ?');
|
|
102
|
+
}
|
|
103
|
+
// Invalidate cache for nodes matching this source
|
|
104
|
+
for (const [id, node] of this.nodeCache) {
|
|
105
|
+
if (node.filePath.startsWith(source))
|
|
106
|
+
this.nodeCache.delete(id);
|
|
107
|
+
}
|
|
108
|
+
this.stmts.deleteNodesBySource.run(`${source}%`);
|
|
109
|
+
}
|
|
110
|
+
getNodeById(id) {
|
|
111
|
+
if (this.nodeCache.has(id)) {
|
|
112
|
+
const cached = this.nodeCache.get(id);
|
|
113
|
+
this.nodeCache.delete(id);
|
|
114
|
+
this.nodeCache.set(id, cached);
|
|
115
|
+
return cached;
|
|
116
|
+
}
|
|
117
|
+
if (!this.stmts.getNodeById) {
|
|
118
|
+
this.stmts.getNodeById = this.db.prepare('SELECT * FROM nodes WHERE id = ?');
|
|
119
|
+
}
|
|
120
|
+
const row = this.stmts.getNodeById.get(id);
|
|
121
|
+
if (!row)
|
|
122
|
+
return null;
|
|
123
|
+
const node = rowToNode(row);
|
|
124
|
+
this.cacheNode(node);
|
|
125
|
+
return node;
|
|
126
|
+
}
|
|
127
|
+
getNodesByIds(ids) {
|
|
128
|
+
const out = new Map();
|
|
129
|
+
if (ids.length === 0)
|
|
130
|
+
return out;
|
|
131
|
+
const misses = [];
|
|
132
|
+
for (const id of ids) {
|
|
133
|
+
const cached = this.nodeCache.get(id);
|
|
134
|
+
if (cached !== undefined) {
|
|
135
|
+
this.nodeCache.delete(id);
|
|
136
|
+
this.nodeCache.set(id, cached);
|
|
137
|
+
out.set(id, cached);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
misses.push(id);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (misses.length === 0)
|
|
144
|
+
return out;
|
|
145
|
+
const CHUNK = 500;
|
|
146
|
+
for (let i = 0; i < misses.length; i += CHUNK) {
|
|
147
|
+
const chunk = misses.slice(i, i + CHUNK);
|
|
148
|
+
const placeholders = chunk.map(() => '?').join(',');
|
|
149
|
+
const rows = this.db
|
|
150
|
+
.prepare(`SELECT * FROM nodes WHERE id IN (${placeholders})`)
|
|
151
|
+
.all(...chunk);
|
|
152
|
+
for (const row of rows) {
|
|
153
|
+
const node = rowToNode(row);
|
|
154
|
+
out.set(node.id, node);
|
|
155
|
+
this.cacheNode(node);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return out;
|
|
159
|
+
}
|
|
160
|
+
cacheNode(node) {
|
|
161
|
+
if (this.nodeCache.size >= this.maxCacheSize) {
|
|
162
|
+
const firstKey = this.nodeCache.keys().next().value;
|
|
163
|
+
if (firstKey)
|
|
164
|
+
this.nodeCache.delete(firstKey);
|
|
165
|
+
}
|
|
166
|
+
this.nodeCache.set(node.id, node);
|
|
167
|
+
}
|
|
168
|
+
clearCache() { this.nodeCache.clear(); }
|
|
169
|
+
getNodesByKind(kind) {
|
|
170
|
+
if (!this.stmts.getNodesByKind) {
|
|
171
|
+
this.stmts.getNodesByKind = this.db.prepare('SELECT * FROM nodes WHERE kind = ?');
|
|
172
|
+
}
|
|
173
|
+
return this.stmts.getNodesByKind.all(kind).map(rowToNode);
|
|
174
|
+
}
|
|
175
|
+
getNodesByName(name) {
|
|
176
|
+
if (!this.stmts.getNodesByName) {
|
|
177
|
+
this.stmts.getNodesByName = this.db.prepare('SELECT * FROM nodes WHERE name = ?');
|
|
178
|
+
}
|
|
179
|
+
return this.stmts.getNodesByName.all(name).map(rowToNode);
|
|
180
|
+
}
|
|
181
|
+
getNodesByQualifiedName(qualifiedName) {
|
|
182
|
+
if (!this.stmts.getNodesByQualifiedName) {
|
|
183
|
+
this.stmts.getNodesByQualifiedName = this.db.prepare('SELECT * FROM nodes WHERE qualified_name = ?');
|
|
184
|
+
}
|
|
185
|
+
return this.stmts.getNodesByQualifiedName.all(qualifiedName).map(rowToNode);
|
|
186
|
+
}
|
|
187
|
+
searchNodes(query, options = {}) {
|
|
188
|
+
const { kinds, source, limit = 100, offset = 0 } = options;
|
|
189
|
+
// FTS5 prefix search
|
|
190
|
+
const ftsQuery = query
|
|
191
|
+
.replace(/['"*():^]/g, '')
|
|
192
|
+
.split(/\s+/)
|
|
193
|
+
.filter(t => t.length > 0)
|
|
194
|
+
.filter(t => !/^(AND|OR|NOT|NEAR)$/i.test(t))
|
|
195
|
+
.map(t => `"${t}"*`)
|
|
196
|
+
.join(' OR ');
|
|
197
|
+
if (!ftsQuery)
|
|
198
|
+
return [];
|
|
199
|
+
const ftsLimit = Math.max(limit * 5, 100);
|
|
200
|
+
let sql = `
|
|
201
|
+
SELECT nodes.*, bm25(nodes_fts, 0, 20, 5, 1) as score
|
|
202
|
+
FROM nodes_fts
|
|
203
|
+
JOIN nodes ON nodes_fts.id = nodes.id
|
|
204
|
+
WHERE nodes_fts MATCH ?
|
|
205
|
+
`;
|
|
206
|
+
const params = [ftsQuery];
|
|
207
|
+
if (kinds && kinds.length > 0) {
|
|
208
|
+
sql += ` AND nodes.kind IN (${kinds.map(() => '?').join(',')})`;
|
|
209
|
+
params.push(...kinds);
|
|
210
|
+
}
|
|
211
|
+
if (source) {
|
|
212
|
+
sql += ` AND nodes.file_path LIKE ?`;
|
|
213
|
+
params.push(`${source}%`);
|
|
214
|
+
}
|
|
215
|
+
sql += ' ORDER BY score LIMIT ? OFFSET ?';
|
|
216
|
+
params.push(ftsLimit, offset);
|
|
217
|
+
try {
|
|
218
|
+
const rows = this.db.prepare(sql).all(...params);
|
|
219
|
+
return rows.map(row => ({ node: rowToNode(row), score: Math.abs(row.score) }));
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
// FTS query failed — try LIKE fallback
|
|
223
|
+
return this.searchNodesLike(query, options);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
searchNodesLike(query, options) {
|
|
227
|
+
const { kinds, source, limit = 100 } = options;
|
|
228
|
+
// Escape LIKE wildcards so `user_id` doesn't match `userXid`
|
|
229
|
+
const esc = (s) => s.replace(/[%_]/g, '\\$&');
|
|
230
|
+
const escaped = esc(query);
|
|
231
|
+
const likeEsc = ` LIKE ? ESCAPE '\\'`;
|
|
232
|
+
let sql = `
|
|
233
|
+
SELECT nodes.*,
|
|
234
|
+
CASE
|
|
235
|
+
WHEN name = ? THEN 1.0
|
|
236
|
+
WHEN name${likeEsc} THEN 0.9
|
|
237
|
+
WHEN name${likeEsc} THEN 0.8
|
|
238
|
+
WHEN qualified_name${likeEsc} THEN 0.7
|
|
239
|
+
ELSE 0.5
|
|
240
|
+
END as score
|
|
241
|
+
FROM nodes
|
|
242
|
+
WHERE (name${likeEsc} OR qualified_name${likeEsc} OR name${likeEsc})
|
|
243
|
+
`;
|
|
244
|
+
const pPrefix = `${escaped}%`;
|
|
245
|
+
const pContain = `%${escaped}%`;
|
|
246
|
+
const params = [
|
|
247
|
+
query, pPrefix, pContain, pContain,
|
|
248
|
+
pContain, pContain, pPrefix,
|
|
249
|
+
];
|
|
250
|
+
if (kinds && kinds.length > 0) {
|
|
251
|
+
sql += ` AND kind IN (${kinds.map(() => '?').join(',')})`;
|
|
252
|
+
params.push(...kinds);
|
|
253
|
+
}
|
|
254
|
+
if (source) {
|
|
255
|
+
sql += ' AND file_path LIKE ?';
|
|
256
|
+
params.push(`${source}%`);
|
|
257
|
+
}
|
|
258
|
+
sql += ' ORDER BY score DESC, length(name) ASC LIMIT ?';
|
|
259
|
+
params.push(limit);
|
|
260
|
+
return this.db.prepare(sql).all(...params)
|
|
261
|
+
.map(row => ({ node: rowToNode(row), score: row.score }));
|
|
262
|
+
}
|
|
263
|
+
// ===========================================================================
|
|
264
|
+
// Edge Operations
|
|
265
|
+
// ===========================================================================
|
|
266
|
+
insertEdge(edge) {
|
|
267
|
+
if (!this.stmts.insertEdge) {
|
|
268
|
+
this.stmts.insertEdge = this.db.prepare(`
|
|
269
|
+
INSERT OR IGNORE INTO edges (source, target, kind, metadata, provenance)
|
|
270
|
+
VALUES (@source, @target, @kind, @metadata, @provenance)
|
|
271
|
+
`);
|
|
272
|
+
}
|
|
273
|
+
this.stmts.insertEdge.run({
|
|
274
|
+
source: edge.source,
|
|
275
|
+
target: edge.target,
|
|
276
|
+
kind: edge.kind,
|
|
277
|
+
metadata: edge.metadata ? JSON.stringify(edge.metadata) : null,
|
|
278
|
+
provenance: edge.provenance ?? null,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
insertEdges(edges) {
|
|
282
|
+
if (edges.length === 0)
|
|
283
|
+
return;
|
|
284
|
+
for (const edge of edges)
|
|
285
|
+
this.insertEdge(edge);
|
|
286
|
+
}
|
|
287
|
+
deleteEdgesBySource(sourceId) {
|
|
288
|
+
if (!this.stmts.deleteEdgesBySource) {
|
|
289
|
+
this.stmts.deleteEdgesBySource = this.db.prepare('DELETE FROM edges WHERE source = ?');
|
|
290
|
+
}
|
|
291
|
+
this.stmts.deleteEdgesBySource.run(sourceId);
|
|
292
|
+
}
|
|
293
|
+
deleteEdgesByTarget(targetId) {
|
|
294
|
+
if (!this.stmts.deleteEdgesByTarget) {
|
|
295
|
+
this.stmts.deleteEdgesByTarget = this.db.prepare('DELETE FROM edges WHERE target = ?');
|
|
296
|
+
}
|
|
297
|
+
this.stmts.deleteEdgesByTarget.run(targetId);
|
|
298
|
+
}
|
|
299
|
+
getOutgoingEdges(sourceId, kinds) {
|
|
300
|
+
if (kinds && kinds.length > 0) {
|
|
301
|
+
const sql = `SELECT * FROM edges WHERE source = ? AND kind IN (${kinds.map(() => '?').join(',')})`;
|
|
302
|
+
return this.db.prepare(sql).all(sourceId, ...kinds).map(rowToEdge);
|
|
303
|
+
}
|
|
304
|
+
if (!this.stmts.getEdgesBySource) {
|
|
305
|
+
this.stmts.getEdgesBySource = this.db.prepare('SELECT * FROM edges WHERE source = ?');
|
|
306
|
+
}
|
|
307
|
+
return this.stmts.getEdgesBySource.all(sourceId).map(rowToEdge);
|
|
308
|
+
}
|
|
309
|
+
getIncomingEdges(targetId, kinds) {
|
|
310
|
+
if (kinds && kinds.length > 0) {
|
|
311
|
+
const sql = `SELECT * FROM edges WHERE target = ? AND kind IN (${kinds.map(() => '?').join(',')})`;
|
|
312
|
+
return this.db.prepare(sql).all(targetId, ...kinds).map(rowToEdge);
|
|
313
|
+
}
|
|
314
|
+
if (!this.stmts.getEdgesByTarget) {
|
|
315
|
+
this.stmts.getEdgesByTarget = this.db.prepare('SELECT * FROM edges WHERE target = ?');
|
|
316
|
+
}
|
|
317
|
+
return this.stmts.getEdgesByTarget.all(targetId).map(rowToEdge);
|
|
318
|
+
}
|
|
319
|
+
findEdgesBetweenNodes(nodeIds, kinds) {
|
|
320
|
+
if (nodeIds.length === 0)
|
|
321
|
+
return [];
|
|
322
|
+
const idsJson = JSON.stringify(nodeIds);
|
|
323
|
+
let sql = `SELECT * FROM edges WHERE source IN (SELECT value FROM json_each(?)) AND target IN (SELECT value FROM json_each(?))`;
|
|
324
|
+
const params = [idsJson, idsJson];
|
|
325
|
+
if (kinds && kinds.length > 0) {
|
|
326
|
+
sql += ` AND kind IN (${kinds.map(() => '?').join(',')})`;
|
|
327
|
+
params.push(...kinds);
|
|
328
|
+
}
|
|
329
|
+
return this.db.prepare(sql).all(...params).map(rowToEdge);
|
|
330
|
+
}
|
|
331
|
+
// ===========================================================================
|
|
332
|
+
// DB Source Operations
|
|
333
|
+
// ===========================================================================
|
|
334
|
+
upsertDbSource(source) {
|
|
335
|
+
if (!this.stmts.upsertDbSource) {
|
|
336
|
+
this.stmts.upsertDbSource = this.db.prepare(`
|
|
337
|
+
INSERT INTO db_sources (alias, engine, database, host, port, display_uri, indexed_at, node_count, errors)
|
|
338
|
+
VALUES (@alias, @engine, @database, @host, @port, @displayUri, @indexedAt, @nodeCount, @errors)
|
|
339
|
+
ON CONFLICT(alias) DO UPDATE SET
|
|
340
|
+
engine = @engine, database = @database, host = @host, port = @port,
|
|
341
|
+
display_uri = @displayUri, indexed_at = @indexedAt, node_count = @nodeCount, errors = @errors
|
|
342
|
+
`);
|
|
343
|
+
}
|
|
344
|
+
this.stmts.upsertDbSource.run({
|
|
345
|
+
alias: source.alias,
|
|
346
|
+
engine: source.engine,
|
|
347
|
+
database: source.database,
|
|
348
|
+
host: source.host ?? null,
|
|
349
|
+
port: source.port ?? null,
|
|
350
|
+
displayUri: source.displayUri,
|
|
351
|
+
indexedAt: source.indexedAt,
|
|
352
|
+
nodeCount: source.nodeCount,
|
|
353
|
+
errors: source.errors ? JSON.stringify(source.errors) : null,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
getDbSource(alias) {
|
|
357
|
+
if (!this.stmts.getDbSource) {
|
|
358
|
+
this.stmts.getDbSource = this.db.prepare('SELECT * FROM db_sources WHERE alias = ?');
|
|
359
|
+
}
|
|
360
|
+
const row = this.stmts.getDbSource.get(alias);
|
|
361
|
+
return row ? rowToDbSource(row) : null;
|
|
362
|
+
}
|
|
363
|
+
getAllDbSources() {
|
|
364
|
+
if (!this.stmts.getAllDbSources) {
|
|
365
|
+
this.stmts.getAllDbSources = this.db.prepare('SELECT * FROM db_sources ORDER BY alias');
|
|
366
|
+
}
|
|
367
|
+
return this.stmts.getAllDbSources.all().map(rowToDbSource);
|
|
368
|
+
}
|
|
369
|
+
deleteDbSource(alias) {
|
|
370
|
+
if (!this.stmts.deleteDbSource) {
|
|
371
|
+
this.stmts.deleteDbSource = this.db.prepare('DELETE FROM db_sources WHERE alias = ?');
|
|
372
|
+
}
|
|
373
|
+
this.stmts.deleteDbSource.run(alias);
|
|
374
|
+
}
|
|
375
|
+
// ===========================================================================
|
|
376
|
+
// Statistics
|
|
377
|
+
// ===========================================================================
|
|
378
|
+
getNodeAndEdgeCount() {
|
|
379
|
+
return this.db
|
|
380
|
+
.prepare('SELECT (SELECT COUNT(*) FROM nodes) AS nodes, (SELECT COUNT(*) FROM edges) AS edges')
|
|
381
|
+
.get();
|
|
382
|
+
}
|
|
383
|
+
getStats() {
|
|
384
|
+
const counts = this.db.prepare(`
|
|
385
|
+
SELECT
|
|
386
|
+
(SELECT COUNT(*) FROM nodes) AS node_count,
|
|
387
|
+
(SELECT COUNT(*) FROM edges) AS edge_count,
|
|
388
|
+
(SELECT COUNT(*) FROM db_sources) AS db_count
|
|
389
|
+
`).get();
|
|
390
|
+
const nodesByKind = {};
|
|
391
|
+
const nodeKindRows = this.db
|
|
392
|
+
.prepare('SELECT kind, COUNT(*) as count FROM nodes GROUP BY kind')
|
|
393
|
+
.all();
|
|
394
|
+
for (const row of nodeKindRows)
|
|
395
|
+
nodesByKind[row.kind] = row.count;
|
|
396
|
+
const edgesByKind = {};
|
|
397
|
+
const edgeKindRows = this.db
|
|
398
|
+
.prepare('SELECT kind, COUNT(*) as count FROM edges GROUP BY kind')
|
|
399
|
+
.all();
|
|
400
|
+
for (const row of edgeKindRows)
|
|
401
|
+
edgesByKind[row.kind] = row.count;
|
|
402
|
+
const lastIndexed = this.db
|
|
403
|
+
.prepare('SELECT MAX(indexed_at) AS ts FROM db_sources')
|
|
404
|
+
.get();
|
|
405
|
+
return {
|
|
406
|
+
nodeCount: counts.node_count,
|
|
407
|
+
edgeCount: counts.edge_count,
|
|
408
|
+
dbCount: counts.db_count ?? 0,
|
|
409
|
+
nodesByKind,
|
|
410
|
+
edgesByKind,
|
|
411
|
+
dbSizeBytes: 0,
|
|
412
|
+
lastUpdated: lastIndexed?.ts ?? 0,
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
clear() {
|
|
416
|
+
this.db.transaction(() => {
|
|
417
|
+
this.db.exec('DELETE FROM edges');
|
|
418
|
+
this.db.exec('DELETE FROM nodes');
|
|
419
|
+
this.db.exec('DELETE FROM db_sources');
|
|
420
|
+
})();
|
|
421
|
+
this.nodeCache.clear();
|
|
422
|
+
}
|
|
423
|
+
getMetadata(key) {
|
|
424
|
+
const row = this.db.prepare('SELECT value FROM project_metadata WHERE key = ?').get(key);
|
|
425
|
+
return row?.value ?? null;
|
|
426
|
+
}
|
|
427
|
+
setMetadata(key, value) {
|
|
428
|
+
this.db.prepare(`
|
|
429
|
+
INSERT INTO project_metadata (key, value, updated_at)
|
|
430
|
+
VALUES (?, ?, ?)
|
|
431
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at
|
|
432
|
+
`).run(key, value, Date.now());
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
exports.QueryBuilder = QueryBuilder;
|
|
436
|
+
//# sourceMappingURL=queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/db/queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
-- DBGraph SQLite Schema
|
|
2
|
+
-- Version 1
|
|
3
|
+
|
|
4
|
+
-- Schema version tracking
|
|
5
|
+
CREATE TABLE IF NOT EXISTS schema_versions (
|
|
6
|
+
version INTEGER PRIMARY KEY,
|
|
7
|
+
applied_at INTEGER NOT NULL,
|
|
8
|
+
description TEXT
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
INSERT INTO schema_versions (version, applied_at, description)
|
|
12
|
+
VALUES (1, strftime('%s', 'now') * 1000, 'Initial schema');
|
|
13
|
+
|
|
14
|
+
-- =============================================================================
|
|
15
|
+
-- Core Tables
|
|
16
|
+
-- =============================================================================
|
|
17
|
+
|
|
18
|
+
-- Nodes: Database schema objects (tables, columns, indexes, etc.)
|
|
19
|
+
CREATE TABLE IF NOT EXISTS nodes (
|
|
20
|
+
id TEXT PRIMARY KEY,
|
|
21
|
+
kind TEXT NOT NULL,
|
|
22
|
+
name TEXT NOT NULL,
|
|
23
|
+
qualified_name TEXT NOT NULL,
|
|
24
|
+
file_path TEXT NOT NULL,
|
|
25
|
+
language TEXT NOT NULL,
|
|
26
|
+
start_line INTEGER NOT NULL DEFAULT 0,
|
|
27
|
+
end_line INTEGER NOT NULL DEFAULT 0,
|
|
28
|
+
docstring TEXT,
|
|
29
|
+
signature TEXT,
|
|
30
|
+
metadata TEXT, -- JSON object for type info, constraints, etc.
|
|
31
|
+
updated_at INTEGER NOT NULL
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
-- Edges: Relationships between schema objects
|
|
35
|
+
CREATE TABLE IF NOT EXISTS edges (
|
|
36
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
37
|
+
source TEXT NOT NULL,
|
|
38
|
+
target TEXT NOT NULL,
|
|
39
|
+
kind TEXT NOT NULL,
|
|
40
|
+
metadata TEXT, -- JSON object
|
|
41
|
+
provenance TEXT DEFAULT NULL,
|
|
42
|
+
FOREIGN KEY (source) REFERENCES nodes(id) ON DELETE CASCADE,
|
|
43
|
+
FOREIGN KEY (target) REFERENCES nodes(id) ON DELETE CASCADE
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
-- Database sources: Tracked database connections
|
|
47
|
+
CREATE TABLE IF NOT EXISTS db_sources (
|
|
48
|
+
alias TEXT PRIMARY KEY,
|
|
49
|
+
engine TEXT NOT NULL,
|
|
50
|
+
database TEXT NOT NULL,
|
|
51
|
+
host TEXT,
|
|
52
|
+
port INTEGER,
|
|
53
|
+
display_uri TEXT NOT NULL,
|
|
54
|
+
indexed_at INTEGER NOT NULL,
|
|
55
|
+
node_count INTEGER DEFAULT 0,
|
|
56
|
+
errors TEXT -- JSON array
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
-- =============================================================================
|
|
60
|
+
-- Indexes
|
|
61
|
+
-- =============================================================================
|
|
62
|
+
|
|
63
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_kind ON nodes(kind);
|
|
64
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_name ON nodes(name);
|
|
65
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_qualified_name ON nodes(qualified_name);
|
|
66
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_file_path ON nodes(file_path);
|
|
67
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_language ON nodes(language);
|
|
68
|
+
|
|
69
|
+
-- Full-text search index
|
|
70
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5(
|
|
71
|
+
id,
|
|
72
|
+
name,
|
|
73
|
+
qualified_name,
|
|
74
|
+
docstring,
|
|
75
|
+
signature,
|
|
76
|
+
content='nodes',
|
|
77
|
+
content_rowid='rowid'
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
-- Triggers to keep FTS index in sync
|
|
81
|
+
CREATE TRIGGER IF NOT EXISTS nodes_ai AFTER INSERT ON nodes BEGIN
|
|
82
|
+
INSERT INTO nodes_fts(rowid, id, name, qualified_name, docstring, signature)
|
|
83
|
+
VALUES (NEW.rowid, NEW.id, NEW.name, NEW.qualified_name, NEW.docstring, NEW.signature);
|
|
84
|
+
END;
|
|
85
|
+
|
|
86
|
+
CREATE TRIGGER IF NOT EXISTS nodes_ad AFTER DELETE ON nodes BEGIN
|
|
87
|
+
INSERT INTO nodes_fts(nodes_fts, rowid, id, name, qualified_name, docstring, signature)
|
|
88
|
+
VALUES ('delete', OLD.rowid, OLD.id, OLD.name, OLD.qualified_name, OLD.docstring, OLD.signature);
|
|
89
|
+
END;
|
|
90
|
+
|
|
91
|
+
CREATE TRIGGER IF NOT EXISTS nodes_au AFTER UPDATE ON nodes BEGIN
|
|
92
|
+
INSERT INTO nodes_fts(nodes_fts, rowid, id, name, qualified_name, docstring, signature)
|
|
93
|
+
VALUES ('delete', OLD.rowid, OLD.id, OLD.name, OLD.qualified_name, OLD.docstring, OLD.signature);
|
|
94
|
+
INSERT INTO nodes_fts(rowid, id, name, qualified_name, docstring, signature)
|
|
95
|
+
VALUES (NEW.rowid, NEW.id, NEW.name, NEW.qualified_name, NEW.docstring, NEW.signature);
|
|
96
|
+
END;
|
|
97
|
+
|
|
98
|
+
-- Edge indexes
|
|
99
|
+
CREATE INDEX IF NOT EXISTS idx_edges_kind ON edges(kind);
|
|
100
|
+
CREATE INDEX IF NOT EXISTS idx_edges_source_kind ON edges(source, kind);
|
|
101
|
+
CREATE INDEX IF NOT EXISTS idx_edges_target_kind ON edges(target, kind);
|
|
102
|
+
CREATE INDEX IF NOT EXISTS idx_edges_provenance ON edges(provenance);
|
|
103
|
+
|
|
104
|
+
-- DB sources index
|
|
105
|
+
CREATE INDEX IF NOT EXISTS idx_db_sources_engine ON db_sources(engine);
|
|
106
|
+
CREATE INDEX IF NOT EXISTS idx_db_sources_indexed_at ON db_sources(indexed_at);
|
|
107
|
+
|
|
108
|
+
-- Project metadata
|
|
109
|
+
CREATE TABLE IF NOT EXISTS project_metadata (
|
|
110
|
+
key TEXT PRIMARY KEY,
|
|
111
|
+
value TEXT NOT NULL,
|
|
112
|
+
updated_at INTEGER NOT NULL
|
|
113
|
+
);
|