# sqlitegraph-core/src/graph/ — Graph Data Structure
Core graph implementation on SQLite. Nodes, edges, properties, traversal.
## Architecture
- `core.rs` — `SqliteGraph` — the main graph struct. Opens DB, manages connections, provides all graph operations.
- `types.rs` — `GraphEntity` (node), `GraphEdge` (edge), property types.
- `mod.rs` — Module exports: `SqliteGraph`, `is_in_memory_connection()`, `GraphEntity`, `GraphEdge`.
- `adjacency.rs` — `ConnectionWrapper`, `StatementWrapper` — prepared statement caching.
- `edge_ops.rs` — Edge CRUD, bulk edge operations.
- `entity_ops.rs` — Node CRUD, bulk node operations.
- `pattern.rs` — Graph pattern matching (find subgraphs matching a template).
- `metrics.rs` — `GraphMetricsSnapshot`, `InstrumentedConnection` — query performance tracking.
- `metrics_schema.rs` — Schema for persisting metrics to SQLite.
## Key Conventions
- Nodes: `id` (i64 autoincrement), `label` (text), `properties` (JSON).
- Edges: `id`, `from_id`, `to_id`, `label`, `weight` (f64), `properties` (JSON).
- `SqliteGraph` uses a connection pool — concurrent reads are fine, writes are serialized.
- `is_in_memory_connection(":memory:")` — use for tests and ephemeral graphs.
- Properties are stored as SQLite JSON columns. Use `serde_json::Value` for typed access.
- The `pool/` submodule manages the connection pool lifecycle.
## When Editing Here
- `core.rs` is 1000+ lines — read the method you need, don't scan the whole file.
- Adding a new property to GraphEntity/GraphEdge requires a DB schema migration in `core.rs` init.
- Always use parameterized queries (the `StatementWrapper` handles this). Never interpolate values into SQL.
- Bulk operations (`entity_ops.rs`, `edge_ops.rs`) use transactions — wrap multi-statement ops in `BEGIN`/`COMMIT`.
- Pattern matching in `pattern.rs` uses a custom DSL — document new pattern features in the struct's doc comment.