Skip to main content

gitcortex_store/
schema.rs

1use gitcortex_core::error::{GitCortexError, Result};
2use kuzu::Connection;
3
4use crate::branch;
5
6// ── Table name helpers ────────────────────────────────────────────────────────
7
8/// Node table name for a branch: `{sanitized_branch}_nodes`
9pub fn node_table(branch: &str) -> String {
10    format!("{}_nodes", branch::sanitize(branch))
11}
12
13/// Relationship table name for a branch: `{sanitized_branch}_edges`
14pub fn edge_table(branch: &str) -> String {
15    format!("{}_edges", branch::sanitize(branch))
16}
17
18// ── DDL ───────────────────────────────────────────────────────────────────────
19
20/// Create the node and edge tables for `branch` if they don't already exist.
21/// Safe to call on every operation — idempotent.
22pub fn ensure_branch(conn: &mut Connection, branch: &str) -> Result<()> {
23    let nt = node_table(branch);
24    let et = edge_table(branch);
25
26    conn.query(&format!(
27        "CREATE NODE TABLE IF NOT EXISTS {nt} (\
28            id             STRING, \
29            kind           STRING, \
30            name           STRING, \
31            qualified_name STRING, \
32            file           STRING, \
33            start_line     INT64,  \
34            end_line       INT64,  \
35            loc            INT64,  \
36            visibility     STRING, \
37            is_async       BOOL,   \
38            is_unsafe      BOOL,   \
39            is_static      BOOL,   \
40            is_abstract    BOOL,   \
41            is_final       BOOL,   \
42            is_property    BOOL,   \
43            is_generator   BOOL,   \
44            is_const       BOOL,   \
45            generic_bounds STRING, \
46            def_signature  STRING, \
47            def_body       STRING, \
48            def_doc        STRING, \
49            def_start_byte INT64,  \
50            def_end_byte   INT64,  \
51            complexity     INT64,  \
52            annotations    STRING, \
53            PRIMARY KEY(id)\
54        )"
55    ))
56    .map_err(|e| GitCortexError::Store(format!("create node table: {e}")))?;
57
58    conn.query(&format!(
59        "CREATE REL TABLE IF NOT EXISTS {et} (\
60            FROM {nt} TO {nt},\
61            kind STRING,\
62            line INT64,\
63            confidence STRING\
64        )"
65    ))
66    .map_err(|e| GitCortexError::Store(format!("create edge table: {e}")))?;
67
68    // Secondary indexes on columns hit by every deferred-resolution WHERE clause.
69    // Best-effort: KuzuDB auto-indexes PKs; secondary index support depends on
70    // the runtime version. Warn and continue rather than fail init.
71    for (idx, col) in [
72        (format!("{nt}_name_idx"), "name"),
73        (format!("{nt}_qname_idx"), "qualified_name"),
74        (format!("{nt}_file_idx"), "file"),
75    ] {
76        if let Err(e) = conn.query(&format!("CREATE INDEX IF NOT EXISTS {idx} ON {nt}({col})")) {
77            tracing::debug!("secondary index {idx} skipped: {e}");
78        }
79    }
80
81    Ok(())
82}