pub struct EntityGraph { /* private fields */ }Expand description
实体图
描述一组关联关系的抓取计划。
§示例
use sz_orm_core::entity_graph::EntityGraph;
let mut graph = EntityGraph::new();
graph.add_edge("user", "profile");
graph.add_edge("user", "posts");Implementations§
Source§impl EntityGraph
impl EntityGraph
Sourcepub fn add_edge(
&mut self,
parent_field: impl Into<String>,
relation: impl Into<String>,
) -> &mut Self
pub fn add_edge( &mut self, parent_field: impl Into<String>, relation: impl Into<String>, ) -> &mut Self
添加一条边
Sourcepub fn add_edge_with_graph(
&mut self,
parent_field: impl Into<String>,
relation: impl Into<String>,
sub_graph: EntityGraph,
) -> &mut Self
pub fn add_edge_with_graph( &mut self, parent_field: impl Into<String>, relation: impl Into<String>, sub_graph: EntityGraph, ) -> &mut Self
添加一条带子图的边(嵌套抓取)
Sourcepub fn edge_count(&self) -> usize
pub fn edge_count(&self) -> usize
返回边的数量
Sourcepub fn relations_of(&self, parent_field: &str) -> Vec<&GraphEdge>
pub fn relations_of(&self, parent_field: &str) -> Vec<&GraphEdge>
查询某个父字段的所有关联
Sourcepub fn all_relations(&self) -> Vec<String>
pub fn all_relations(&self) -> Vec<String>
收集图中所有关联名(去重)
Sourcepub fn all_parent_fields(&self) -> Vec<String>
pub fn all_parent_fields(&self) -> Vec<String>
收集图中所有父字段(去重)
Sourcepub fn all_relations_recursive(&self) -> Vec<String>
pub fn all_relations_recursive(&self) -> Vec<String>
递归收集图中所有关联(含子图)
Sourcepub fn detect_cycles(&self) -> Result<(), Vec<String>>
pub fn detect_cycles(&self) -> Result<(), Vec<String>>
P2-7:检测实体图中的循环引用
使用 DFS 遍历图(含嵌套子图),检测是否存在循环路径。 循环引用会导致递归 eager load 时栈溢出,必须在加载前检测。
§算法
- 展平:递归收集主图 + 所有子图的边到统一邻接表
- 三色标记 DFS:
- 白色(未访问):节点尚未访问
- 灰色(访问中):节点正在当前 DFS 路径中,若再次遇到则发现回边(循环)
- 黑色(已完成):节点及其所有子节点已访问完毕
§返回
Ok(()):无循环引用Err(cycle_path):检测到循环,cycle_path是循环路径上的节点列表 (如["user", "posts", "user"]表示 user → posts → user 的循环)
§示例
use sz_orm_core::entity_graph::EntityGraph;
// 无循环:user → posts → comments
let mut graph = EntityGraph::new();
graph.add_edge("user", "posts");
graph.add_edge("posts", "comments");
assert!(graph.detect_cycles().is_ok());
// 有循环:user → posts → user
let mut graph = EntityGraph::new();
graph.add_edge_with_graph("user", "posts", {
let mut sub = EntityGraph::new();
sub.add_edge("posts", "user");
sub
});
assert!(graph.detect_cycles().is_err());Trait Implementations§
Source§impl Clone for EntityGraph
impl Clone for EntityGraph
Source§fn clone(&self) -> EntityGraph
fn clone(&self) -> EntityGraph
Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Debug for EntityGraph
impl Debug for EntityGraph
Source§impl Default for EntityGraph
impl Default for EntityGraph
Source§fn default() -> EntityGraph
fn default() -> EntityGraph
Returns the “default value” for a type. Read more
Auto Trait Implementations§
impl Freeze for EntityGraph
impl RefUnwindSafe for EntityGraph
impl Send for EntityGraph
impl Sync for EntityGraph
impl Unpin for EntityGraph
impl UnsafeUnpin for EntityGraph
impl UnwindSafe for EntityGraph
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more