hedl_neo4j/lib.rs
1// Dweve HEDL - Hierarchical Entity Data Language
2//
3// Copyright (c) 2025 Dweve IP B.V. and individual contributors.
4//
5// SPDX-License-Identifier: Apache-2.0
6//
7// Licensed under the Apache License, Version 2.0 (the "License");
8// you may not use this file except in compliance with the License.
9// You may obtain a copy of the License in the LICENSE file at the
10// root of this repository or at: http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Bidirectional conversion between HEDL documents and Neo4j graph databases.
19//!
20//! This crate provides functionality to:
21//! - Export HEDL documents to Cypher queries for Neo4j import
22//! - Import Neo4j graph data back to HEDL documents
23//!
24//! # Mapping Strategy
25//!
26//! ## HEDL → Neo4j
27//!
28//! | HEDL Concept | Neo4j Representation |
29//! |--------------|---------------------|
30//! | `MatrixList` type | Node label |
31//! | Node ID | `_hedl_id` property (configurable) |
32//! | Node fields | Node properties |
33//! | Reference (`@Type:id`) | Relationship to target node |
34//! | NEST hierarchy | `HAS_<CHILDTYPE>` relationships |
35//! | Tensor | JSON string property |
36//! | Expression | String property with `$()` preserved |
37//!
38//! ## Neo4j → HEDL
39//!
40//! | Neo4j Concept | HEDL Representation |
41//! |---------------|---------------------|
42//! | Node label | Struct type / `MatrixList` type |
43//! | Node properties | Field values |
44//! | Relationship | Reference field or NEST hierarchy |
45//! | `HAS_*` relationship | Inferred NEST |
46//!
47//! # Example: Export to Cypher
48//!
49//! ```rust
50//! use hedl_core::Document;
51//! use hedl_neo4j::{to_cypher, ToCypherConfig};
52//!
53//! fn example(doc: &Document) -> Result<(), hedl_neo4j::Neo4jError> {
54//! // Using default configuration
55//! let cypher = hedl_neo4j::hedl_to_cypher(doc)?;
56//! println!("{}", cypher);
57//!
58//! // With fluent configuration API
59//! let config = ToCypherConfig::new()
60//! .with_create() // Use CREATE instead of MERGE
61//! .with_id_property("nodeId")
62//! .without_constraints();
63//!
64//! let cypher = to_cypher(doc, &config)?;
65//! println!("{}", cypher);
66//!
67//! // With builder pattern
68//! let config = ToCypherConfig::builder()
69//! .use_merge(false)
70//! .create_constraints(false)
71//! .id_property("nodeId")
72//! .batch_size(500)
73//! .build();
74//!
75//! let cypher = to_cypher(doc, &config)?;
76//! println!("{}", cypher);
77//!
78//! Ok(())
79//! }
80//! ```
81//!
82//! # Example: Import from Neo4j
83//!
84//! ```rust
85//! use hedl_neo4j::{Neo4jRecord, Neo4jNode, Neo4jRelationship, neo4j_to_hedl};
86//!
87//! fn example() -> Result<(), hedl_neo4j::Neo4jError> {
88//! // Build records from Neo4j query results
89//! let records = vec![
90//! Neo4jRecord::new(
91//! Neo4jNode::new("User", "alice")
92//! .with_property("name", "Alice Smith")
93//! ).with_relationship(
94//! Neo4jRelationship::new("User", "alice", "HAS_POST", "Post", "p1")
95//! ),
96//! Neo4jRecord::new(
97//! Neo4jNode::new("Post", "p1")
98//! .with_property("content", "Hello World")
99//! ),
100//! ];
101//!
102//! let doc = neo4j_to_hedl(&records)?;
103//! println!("Imported {} structs", doc.structs.len());
104//!
105//! Ok(())
106//! }
107//! ```
108//!
109//! # Generated Cypher Format
110//!
111//! The generated Cypher uses best practices for Neo4j imports:
112//!
113//! - **Constraints**: Creates uniqueness constraints for ID properties
114//! - **UNWIND batching**: Uses `UNWIND` for efficient bulk operations
115//! - **MERGE by default**: Uses `MERGE` for idempotent imports
116//! - **Parameterized queries**: Returns statements with parameters for security
117//!
118//! Example output:
119//!
120//! ```cypher
121//! // Ensure unique User IDs
122//! CREATE CONSTRAINT user__hedl_id IF NOT EXISTS FOR (n:User) REQUIRE n._hedl_id IS UNIQUE;
123//!
124//! // Create User nodes from users
125//! UNWIND $rows AS row
126//! MERGE (n:User {_hedl_id: row._hedl_id})
127//! SET n.name = row.name;
128//!
129//! // Create AUTHOR relationships from Post to User
130//! UNWIND $rows AS row
131//! MATCH (from:Post {_hedl_id: row.from_id})
132//! MATCH (to:User {_hedl_id: row.to_id})
133//! MERGE (from)-[rel:AUTHOR]->(to);
134//! ```
135
136#![cfg_attr(not(test), warn(missing_docs))]
137#![deny(missing_docs)]
138#![deny(rustdoc::broken_intra_doc_links)]
139
140/// Batch execution strategies for Neo4j write operations.
141pub mod batch_executor;
142/// Configuration types for Neo4j conversion operations.
143pub mod config;
144/// Constants used throughout the hedl-neo4j library.
145pub mod constants;
146/// Cypher query building utilities.
147pub mod cypher;
148/// Error types for hedl-neo4j conversions.
149pub mod error;
150/// Convert Neo4j records to HEDL documents.
151pub mod from_neo4j;
152/// Mapping between HEDL types and Neo4j graph structures.
153pub mod mapping;
154/// Safe arithmetic operations for hedl-neo4j.
155pub mod safe_arithmetic;
156/// Convert HEDL documents to Cypher queries.
157pub mod to_cypher;
158
159/// Adaptive batching utilities for optimal memory and performance.
160pub mod batching;
161
162/// Batch read operations for efficient Neo4j queries.
163#[cfg(feature = "async")]
164pub mod batch_read;
165
166/// Async Neo4j client for executing HEDL operations.
167#[cfg(feature = "async")]
168pub mod async_client;
169
170// Re-export main types at crate root for convenience
171pub use config::{
172 BatchSizeStrategy, FromNeo4jConfig, FromNeo4jConfigBuilder, IsolationLevel, ObjectHandling,
173 RelationshipNaming, ToCypherConfig, ToCypherConfigBuilder, TransactionStrategy,
174 DEFAULT_FROM_NEO4J_BATCH_SIZE, DEFAULT_MAX_STRING_LENGTH, DEFAULT_TRANSACTION_BATCH_SIZE,
175 DEFAULT_TRANSACTION_ROW_LIMIT,
176};
177pub use cypher::{CypherScript, CypherStatement, CypherValue, RenderMode, StatementType};
178pub use error::{Neo4jError, Result};
179pub use from_neo4j::{
180 build_record, build_relationship, from_neo4j_records, from_records_iter,
181 from_records_streaming, neo4j_to_hedl, Neo4jRecord,
182};
183
184#[cfg(feature = "async")]
185pub use from_neo4j::{
186 query_multi_label_batch, query_nodes_batch, query_nodes_with_relationships_batch,
187};
188
189#[cfg(feature = "async")]
190pub use batch_read::{BatchQuery, BatchReadConfig};
191
192#[cfg(feature = "async")]
193pub use async_client::AsyncNeo4jClient;
194
195pub use mapping::{Neo4jNode, Neo4jRelationship};
196pub use to_cypher::{
197 hedl_to_cypher, node_to_cypher_inline, to_cypher, to_cypher_statements, to_cypher_stream,
198};
199
200// Re-export batching utilities for transaction optimization
201pub use batching::{batch_statements, TransactionBatch};