Skip to content

Commit 981a955

Browse files
authored
chore: support rollup (#442)
* chore: support rollup * chore: fmt * chore: add test * chore: fmt
1 parent 4875f7d commit 981a955

File tree

5 files changed

+422
-0
lines changed

5 files changed

+422
-0
lines changed

collab/src/database/entity.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::database::fields::media_type_option::MediaTypeOption;
99
use crate::database::fields::number_type_option::NumberTypeOption;
1010
use crate::database::fields::person_type_option::PersonTypeOption;
1111
use crate::database::fields::relation_type_option::RelationTypeOption;
12+
use crate::database::fields::rollup_type_option::RollupTypeOption;
1213
use crate::database::fields::select_type_option::{MultiSelectTypeOption, SingleSelectTypeOption};
1314
use crate::database::fields::summary_type_option::SummarizationTypeOption;
1415
use crate::database::fields::text_type_option::RichTextTypeOption;
@@ -307,6 +308,7 @@ pub enum FieldType {
307308
Time = 13,
308309
Media = 14,
309310
Person = 15,
311+
Rollup = 16,
310312
}
311313

312314
impl FieldType {
@@ -380,6 +382,7 @@ impl FieldType {
380382
FieldType::Time => "Time",
381383
FieldType::Media => "Media",
382384
FieldType::Person => "Person",
385+
FieldType::Rollup => "Rollup",
383386
};
384387
s.to_string()
385388
}
@@ -436,6 +439,10 @@ impl FieldType {
436439
matches!(self, FieldType::Relation)
437440
}
438441

442+
pub fn is_rollup(&self) -> bool {
443+
matches!(self, FieldType::Rollup)
444+
}
445+
439446
pub fn is_time(&self) -> bool {
440447
matches!(self, FieldType::Time)
441448
}
@@ -472,6 +479,7 @@ impl From<i64> for FieldType {
472479
13 => FieldType::Time,
473480
14 => FieldType::Media,
474481
15 => FieldType::Person,
482+
16 => FieldType::Rollup,
475483
_ => {
476484
error!("Unknown field type: {}, fallback to text", index);
477485
FieldType::RichText
@@ -501,6 +509,7 @@ pub fn default_type_option_data_from_type(field_type: FieldType) -> TypeOptionDa
501509
FieldType::Summary => SummarizationTypeOption::default().into(),
502510
FieldType::Translate => TranslateTypeOption::default().into(),
503511
FieldType::Person => PersonTypeOption::default().into(),
512+
FieldType::Rollup => RollupTypeOption::default().into(),
504513
}
505514
}
506515

collab/src/database/fields/type_option/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pub mod media_type_option;
55
pub mod number_type_option;
66
pub mod person_type_option;
77
pub mod relation_type_option;
8+
pub mod rollup_type_option;
89
pub mod select_type_option;
910
pub mod summary_type_option;
1011
pub mod text_type_option;
@@ -22,6 +23,7 @@ use crate::database::fields::media_type_option::MediaTypeOption;
2223
use crate::database::fields::number_type_option::NumberTypeOption;
2324
use crate::database::fields::person_type_option::PersonTypeOption;
2425
use crate::database::fields::relation_type_option::RelationTypeOption;
26+
use crate::database::fields::rollup_type_option::RollupTypeOption;
2527
use crate::database::fields::select_type_option::{MultiSelectTypeOption, SingleSelectTypeOption};
2628
use crate::database::fields::summary_type_option::SummarizationTypeOption;
2729
use crate::database::fields::timestamp_type_option::TimestampTypeOption;
@@ -181,6 +183,7 @@ pub fn type_option_cell_writer(
181183
FieldType::Summary => Box::new(SummarizationTypeOption::from(type_option_data)),
182184
FieldType::Translate => Box::new(TranslateTypeOption::from(type_option_data)),
183185
FieldType::Person => Box::new(PersonTypeOption::from(type_option_data)),
186+
FieldType::Rollup => Box::new(RollupTypeOption::from(type_option_data)),
184187
}
185188
}
186189

@@ -205,5 +208,6 @@ pub fn type_option_cell_reader(
205208
FieldType::Summary => Box::new(SummarizationTypeOption::from(type_option_data)),
206209
FieldType::Translate => Box::new(TranslateTypeOption::from(type_option_data)),
207210
FieldType::Person => Box::new(PersonTypeOption::from(type_option_data)),
211+
FieldType::Rollup => Box::new(RollupTypeOption::from(type_option_data)),
208212
}
209213
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
use super::{TypeOptionData, TypeOptionDataBuilder};
2+
use crate::database::entity::FieldType;
3+
use crate::database::fields::{TypeOptionCellReader, TypeOptionCellWriter};
4+
use crate::database::rows::{Cell, new_cell_builder};
5+
use crate::database::template::entity::CELL_DATA;
6+
use crate::util::AnyMapExt;
7+
use serde::{Deserialize, Serialize};
8+
use serde_json::{Value, json};
9+
use serde_repr::{Deserialize_repr, Serialize_repr};
10+
use yrs::Any;
11+
12+
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize_repr, Deserialize_repr)]
13+
#[repr(i64)]
14+
pub enum RollupDisplayMode {
15+
#[default]
16+
Calculated = 0,
17+
OriginalList = 1,
18+
UniqueList = 2,
19+
}
20+
21+
impl From<i64> for RollupDisplayMode {
22+
fn from(value: i64) -> Self {
23+
match value {
24+
0 => RollupDisplayMode::Calculated,
25+
1 => RollupDisplayMode::OriginalList,
26+
2 => RollupDisplayMode::UniqueList,
27+
_ => RollupDisplayMode::Calculated,
28+
}
29+
}
30+
}
31+
32+
impl From<RollupDisplayMode> for i64 {
33+
fn from(value: RollupDisplayMode) -> Self {
34+
value as i64
35+
}
36+
}
37+
38+
#[derive(Debug, Clone, Serialize, Deserialize)]
39+
pub struct RollupTypeOption {
40+
pub relation_field_id: String,
41+
pub target_field_id: String,
42+
pub calculation_type: i64,
43+
pub show_as: RollupDisplayMode,
44+
#[serde(default)]
45+
pub condition_value: String,
46+
}
47+
48+
impl Default for RollupTypeOption {
49+
fn default() -> Self {
50+
Self {
51+
relation_field_id: String::new(),
52+
target_field_id: String::new(),
53+
// Default to Count, which is applicable across all field types.
54+
calculation_type: 5,
55+
show_as: RollupDisplayMode::Calculated,
56+
condition_value: String::new(),
57+
}
58+
}
59+
}
60+
61+
impl From<TypeOptionData> for RollupTypeOption {
62+
fn from(data: TypeOptionData) -> Self {
63+
let relation_field_id: String = data.get_as("relation_field_id").unwrap_or_default();
64+
let target_field_id: String = data.get_as("target_field_id").unwrap_or_default();
65+
let calculation_type: i64 = data.get_as("calculation_type").unwrap_or(5);
66+
let show_as: i64 = data.get_as("show_as").unwrap_or(0);
67+
let condition_value: String = data.get_as("condition_value").unwrap_or_default();
68+
Self {
69+
relation_field_id,
70+
target_field_id,
71+
calculation_type,
72+
show_as: show_as.into(),
73+
condition_value,
74+
}
75+
}
76+
}
77+
78+
impl From<RollupTypeOption> for TypeOptionData {
79+
fn from(data: RollupTypeOption) -> Self {
80+
TypeOptionDataBuilder::from([
81+
(
82+
"relation_field_id".into(),
83+
Any::String(data.relation_field_id.into()),
84+
),
85+
(
86+
"target_field_id".into(),
87+
Any::String(data.target_field_id.into()),
88+
),
89+
(
90+
"calculation_type".into(),
91+
Any::BigInt(data.calculation_type),
92+
),
93+
("show_as".into(), Any::BigInt(i64::from(data.show_as))),
94+
(
95+
"condition_value".into(),
96+
Any::String(data.condition_value.into()),
97+
),
98+
])
99+
}
100+
}
101+
102+
impl TypeOptionCellReader for RollupTypeOption {
103+
fn json_cell(&self, cell: &Cell) -> Value {
104+
json!(self.stringify_cell(cell))
105+
}
106+
107+
fn numeric_cell(&self, cell: &Cell) -> Option<f64> {
108+
self.stringify_cell(cell).parse().ok()
109+
}
110+
111+
fn convert_raw_cell_data(&self, cell_data: &str) -> String {
112+
cell_data.to_string()
113+
}
114+
}
115+
116+
impl TypeOptionCellWriter for RollupTypeOption {
117+
fn convert_json_to_cell(&self, json_value: Value) -> Cell {
118+
let mut cell = new_cell_builder(FieldType::Rollup);
119+
match json_value {
120+
Value::String(value_str) => {
121+
cell.insert(CELL_DATA.into(), value_str.into());
122+
},
123+
_ => {
124+
cell.insert(CELL_DATA.into(), json_value.to_string().into());
125+
},
126+
}
127+
cell
128+
}
129+
}

collab/tests/database/database_test/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ mod group_test;
1010
pub mod helper;
1111
mod layout_test;
1212
// mod restore_test;
13+
mod rollup_type_option_test;
1314
mod row_observe_test;
1415
mod row_test;
1516
mod sort_test;

0 commit comments

Comments
 (0)