Skip to main content

nexus_common/db/graph/
setup.rs

1use crate::{db::get_neo4j_graph, types::DynError};
2use neo4rs::query;
3use tracing::info;
4
5/// Ensure the Neo4j graph has the required constraints and indexes
6pub async fn setup_graph() -> Result<(), DynError> {
7    // Define unique constraints
8    let constraints = [
9        "CREATE CONSTRAINT uniqueUserId IF NOT EXISTS FOR (u:User) REQUIRE u.id IS UNIQUE",
10        "CREATE CONSTRAINT uniquePostId IF NOT EXISTS FOR (p:Post) REQUIRE p.id IS UNIQUE",
11        "CREATE CONSTRAINT uniqueFileId IF NOT EXISTS FOR (f:File) REQUIRE (f.owner_id, f.id) IS UNIQUE",
12    ];
13
14    // Create indexes
15    let indexes = [
16        "CREATE INDEX userIdIndex IF NOT EXISTS FOR (u:User) ON (u.id)",
17        "CREATE INDEX postIdIndex IF NOT EXISTS FOR (p:Post) ON (p.id)",
18        "CREATE INDEX postTimestampIndex IF NOT EXISTS FOR (p:Post) ON (p.indexed_at)",
19        "CREATE INDEX postKindIndex IF NOT EXISTS FOR (p:Post) ON (p.kind)",
20        "CREATE INDEX taggedLabelIndex IF NOT EXISTS FOR ()-[r:TAGGED]-() ON (r.label)",
21        "CREATE INDEX taggedTimestampIndex IF NOT EXISTS FOR ()-[r:TAGGED]-() ON (r.indexed_at)",
22        "CREATE INDEX fileIdIndex IF NOT EXISTS FOR (f:File) ON (f.owner_id, f.id)",
23    ];
24
25    let queries = constraints.iter().chain(indexes.iter());
26
27    let graph = get_neo4j_graph()?;
28    let graph = graph.lock().await;
29
30    // Start an explicit transaction
31    let txn = graph
32        .start_txn()
33        .await
34        .map_err(|e| format!("Failed to start transaction: {e}"))?;
35
36    for &ddl in queries {
37        if let Err(err) = graph.run(query(ddl)).await {
38            return Err(format!("Failed to apply graph constraints/indexes: {err}").into());
39        }
40    }
41    // Commit everything in one go
42    txn.commit()
43        .await
44        .map_err(|e| format!("Failed to commit the transaction: {e}"))?;
45
46    info!("Neo4j graph constraints and indexes have been applied successfully");
47
48    Ok(())
49}