reddb_server/application/
ports_impls_tree.rs1use super::*;
2use crate::application::entity::metadata_to_json;
3use crate::storage::query::ast::{
4 CreateTreeQuery, DropTreeQuery, TreeCommand, TreeNodeSpec, TreePosition,
5};
6
7fn api_tree_query(label: &str, collection: &str, tree: &str) -> String {
8 format!("api.{label}({collection}.{tree})")
9}
10
11fn tree_position(position: crate::application::TreePositionInput) -> TreePosition {
12 match position {
13 crate::application::TreePositionInput::First => TreePosition::First,
14 crate::application::TreePositionInput::Last => TreePosition::Last,
15 crate::application::TreePositionInput::Index(index) => TreePosition::Index(index),
16 }
17}
18
19fn tree_node_spec(input: crate::application::TreeNodeInput) -> RedDBResult<TreeNodeSpec> {
20 let metadata = input
21 .metadata
22 .into_iter()
23 .map(|(key, value)| {
24 let json = metadata_to_json(&crate::storage::unified::Metadata::with_fields(
25 [(key.clone(), value)].into_iter().collect(),
26 ));
27 let value = json
28 .get(&key)
29 .ok_or_else(|| {
30 crate::RedDBError::Query(format!(
31 "failed to convert tree metadata field '{}'",
32 key
33 ))
34 })
35 .and_then(crate::application::entity::json_to_storage_value)?;
36 Ok((key, value))
37 })
38 .collect::<RedDBResult<Vec<_>>>()?;
39
40 Ok(TreeNodeSpec {
41 label: input.label,
42 node_type: input.node_type,
43 properties: input.properties,
44 metadata,
45 max_children: input.max_children,
46 })
47}
48
49impl RuntimeTreePort for RedDBRuntime {
50 fn create_tree(&self, input: CreateTreeInput) -> RedDBResult<RuntimeQueryResult> {
51 let raw_query = api_tree_query("create_tree", &input.collection, &input.name);
52 let query = CreateTreeQuery {
53 collection: input.collection,
54 name: input.name,
55 root: tree_node_spec(input.root)?,
56 default_max_children: input.default_max_children,
57 if_not_exists: input.if_not_exists,
58 };
59 RedDBRuntime::execute_create_tree(self, &raw_query, &query)
60 }
61
62 fn drop_tree(&self, input: DropTreeInput) -> RedDBResult<RuntimeQueryResult> {
63 let raw_query = api_tree_query("drop_tree", &input.collection, &input.name);
64 let query = DropTreeQuery {
65 collection: input.collection,
66 name: input.name,
67 if_exists: input.if_exists,
68 };
69 RedDBRuntime::execute_drop_tree(self, &raw_query, &query)
70 }
71
72 fn insert_tree_node(&self, input: InsertTreeNodeInput) -> RedDBResult<RuntimeQueryResult> {
73 let raw_query = api_tree_query("tree_insert", &input.collection, &input.tree_name);
74 let command = TreeCommand::Insert {
75 collection: input.collection,
76 tree_name: input.tree_name,
77 parent_id: input.parent_id,
78 node: tree_node_spec(input.node)?,
79 position: tree_position(input.position),
80 };
81 RedDBRuntime::execute_tree_command(self, &raw_query, &command)
82 }
83
84 fn move_tree_node(&self, input: MoveTreeNodeInput) -> RedDBResult<RuntimeQueryResult> {
85 let raw_query = api_tree_query("tree_move", &input.collection, &input.tree_name);
86 let command = TreeCommand::Move {
87 collection: input.collection,
88 tree_name: input.tree_name,
89 node_id: input.node_id,
90 parent_id: input.parent_id,
91 position: tree_position(input.position),
92 };
93 RedDBRuntime::execute_tree_command(self, &raw_query, &command)
94 }
95
96 fn delete_tree_node(&self, input: DeleteTreeNodeInput) -> RedDBResult<RuntimeQueryResult> {
97 let raw_query = api_tree_query("tree_delete", &input.collection, &input.tree_name);
98 let command = TreeCommand::Delete {
99 collection: input.collection,
100 tree_name: input.tree_name,
101 node_id: input.node_id,
102 };
103 RedDBRuntime::execute_tree_command(self, &raw_query, &command)
104 }
105
106 fn validate_tree(&self, input: ValidateTreeInput) -> RedDBResult<RuntimeQueryResult> {
107 let raw_query = api_tree_query("tree_validate", &input.collection, &input.tree_name);
108 let command = TreeCommand::Validate {
109 collection: input.collection,
110 tree_name: input.tree_name,
111 };
112 RedDBRuntime::execute_tree_command(self, &raw_query, &command)
113 }
114
115 fn rebalance_tree(&self, input: RebalanceTreeInput) -> RedDBResult<RuntimeQueryResult> {
116 let raw_query = api_tree_query("tree_rebalance", &input.collection, &input.tree_name);
117 let command = TreeCommand::Rebalance {
118 collection: input.collection,
119 tree_name: input.tree_name,
120 dry_run: input.dry_run,
121 };
122 RedDBRuntime::execute_tree_command(self, &raw_query, &command)
123 }
124}