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