How to Load Existing Graph Data into the Store Module in Codebase Memory MCP

Yes, you can load existing graph data by opening the SQLite database file using cbm_store_open_path() for read-write access or cbm_store_open_path_query() for read-only analysis, then querying via the high-level CRUD API.

The store module in DeusData/codebase-memory-mcp serves as a thin abstraction layer over SQLite, persisting code-knowledge graphs in database files containing tables like projects, nodes, edges, and file_hashes. Loading existing graph data requires understanding how to initialize the store handle and validate the underlying database schema.

Understanding the Store Module Architecture

The SQLite Database Structure

Graphs are stored as standard SQLite files (.db) located in the cache directory ($CBM_CACHE_DIR) or custom paths you specify. These files contain relational tables representing the code-knowledge graph, including projects, nodes, edges, and file_hashes. When you load existing graph data, you are simply opening this SQLite file through the store API.

The cbm_store_t Handle

The opaque type cbm_store_t (defined in src/store/store.h) encapsulates a sqlite3 *db handle alongside cached prepared statements (stmt_*). This abstraction keeps the rest of the codebase independent of SQLite specifics while ensuring safety-related pragmas remain active.

Opening Methods for Loading Graph Data

The module provides three entry points for opening a database, depending on your access requirements:

  • cbm_store_open_path(const char *db_path): Opens or creates a read-write store. Use this when loading existing graph data for modification, such as adding new nodes or updating edges.
  • cbm_store_open_path_query(const char *db_path): Opens a read-only store without SQLITE_OPEN_CREATE or write pragmas. Ideal for analysis-only workflows like search or graph traversal.
  • cbm_store_open_memory(void): Creates an in-memory store for testing scenarios where persistence is unnecessary.

The Internal Opening Process

When you call cbm_store_open_path or cbm_store_open_path_query, the internal function store_open_internal (in src/store/store.c) executes the following steps:

  1. Allocates the handle and opens the SQLite file with sqlite3_open_v2.
  2. Registers safety-critical SQLite functions including regexp, iregexp, cbm_cosine_i8, and cbm_camel_split.
  3. Applies pragmas (foreign keys, mmap size, WAL mode) via configure_pragmas.
  4. Initializes the schema (init_schema) if the file is new, or verifies compatibility otherwise.
  5. Creates default user indexes via create_user_indexes.

Step-by-Step Workflow to Load an Existing Graph

Follow this sequence to load and query existing graph data:

  1. Locate the database file – typically stored under $CBM_CACHE_DIR or your specified path.
  2. Open the store using cbm_store_open_path() for modifications or cbm_store_open_path_query() for read-only access.
  3. Execute queries using high-level functions like cbm_store_find_node_by_qn() or cbm_store_search().
  4. Close the store with cbm_store_close() when finished.

Handling Edge Cases and Validation

Schema Version Mismatches

The store checks for the presence of the local_name_gen column (used by the IMPORTS edge type). If this column is missing, store_open_internal aborts, forcing you to rebuild the database.

Read-Only Filesystems

cbm_store_open_path_query handles read-only filesystems by first attempting SQLITE_OPEN_READONLY. If this fails due to WAL-shm file creation issues, it falls back to an immutable URI (file://…?immutable=1) as implemented in lines 733-889 of src/store/store.c.

Corruption Detection

Call cbm_store_check_integrity() to validate the projects table row count and root_path format. A false return indicates the database should be deleted and re-indexed.

Importing from Checkpoints

To import an entire dump from another store (such as a checkpoint file), use cbm_store_restore_from(dst, src). This function copies all pages via SQLite's backup API, declared in src/store/store.h and implemented in src/store/store.c.

Code Examples

Loading for Read-Write Access

#include <stdio.h>
#include "store/store.h"

/* Load an existing graph for read-write access */
cbm_store_t *store = cbm_store_open_path("/path/to/project.db");
if (!store) {
    fprintf(stderr, "Failed to open graph: %s\n", cbm_store_error(store));
    exit(1);
}

/* Find a node by qualified name */
cbm_node_t node;
int rc = cbm_store_find_node_by_qn(store, "myproject", "my.module.Class.method", &node);
if (rc == CBM_STORE_OK) {
    printf("Found node id=%lld label=%s\n", node.id, node.label);
    cbm_node_free_fields(&node);
} else {
    printf("Node not found (rc=%d)\n", rc);
}

/* Perform a regex search */
cbm_search_params_t params = {0};
params.project      = "myproject";
params.name_pattern = ".*Service$";
params.limit        = 20;
cbm_search_output_t out;
rc = cbm_store_search(store, &params, &out);
if (rc == CBM_STORE_OK) {
    for (int i = 0; i < out.count; ++i) {
        printf("- %s (%s)\n", out.results[i].node.qualified_name,
               out.results[i].node.label);
    }
    cbm_store_search_free(&out);
}

cbm_store_close(store);

Loading for Read-Only Analysis

#include <stdio.h>
#include "store/store.h"

/* Open existing graph read-only */
cbm_store_t *store = cbm_store_open_path_query("/path/to/project.db");
if (!store) {
    fprintf(stderr, "Graph file not found or unreadable.\n");
    exit(1);
}

/* Run vector search */
const char *keywords[] = {"auth", "token"};
cbm_vector_result_t *vec_res;
int vec_cnt;
int rc = cbm_store_vector_search(store,
                                 "myproject",
                                 keywords, 2,
                                 10,
                                 &vec_res, &vec_cnt);
if (rc == CBM_STORE_OK) {
    for (int i = 0; i < vec_cnt; ++i) {
        printf("%s (score %.2f)\n", vec_res[i].qualified_name, vec_res[i].score);
    }
    cbm_store_free_vector_results(vec_res, vec_cnt);
}
cbm_store_close(store);

Summary

  • Use cbm_store_open_path() to load existing graph data for modifications or cbm_store_open_path_query() for read-only analysis.
  • The store module in src/store/store.c handles SQLite initialization, schema validation, and safety pragmas automatically.
  • Validate database integrity with cbm_store_check_integrity() before operations to detect corruption.
  • Import complete graph dumps using cbm_store_restore_from() via the SQLite backup API.
  • All high-level operations (cbm_store_search, cbm_store_find_node_by_qn) work directly on the loaded graph without requiring raw SQL.

Frequently Asked Questions

Can I load a graph database from a read-only filesystem?

Yes. When using cbm_store_open_path_query(), the function automatically falls back to an immutable URI (file://…?immutable=1) if the standard read-only open fails due to WAL-shm file restrictions. This logic is implemented in lines 733-889 of src/store/store.c.

What happens if the database schema is outdated?

The store_open_internal function checks for the local_name_gen column presence. If this column is missing (indicating an older schema version), the function aborts the opening process, forcing you to delete the old database and rebuild it from source.

Is it possible to import data from another graph file?

Yes. Use cbm_store_restore_from(dst, src) to copy all pages from a source database to a destination database using SQLite's backup API. This is useful for restoring from checkpoint files or merging graph data.

Why should I use the store API instead of raw SQL?

All direct SQL execution is funneled through cbm_store_exec(), which validates the store's state and maintains the ATTACH/DETACH authorizer. This design prevents unsafe operations and ensures that SQLite-specific details remain abstracted from the rest of the codebase.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →