Skip to content

Commit ef11d85

Browse files
committed
chore: use option uid
1 parent 7a9248e commit ef11d85

File tree

17 files changed

+282
-198
lines changed

17 files changed

+282
-198
lines changed

collab/src/folder/folder.rs

Lines changed: 126 additions & 73 deletions
Large diffs are not rendered by default.

collab/src/folder/folder_observe.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub(crate) fn subscribe_view_change(
5252
txn,
5353
&view_relations,
5454
&section_map,
55-
uid,
55+
Some(uid),
5656
mappings,
5757
) {
5858
deletion_cache.insert(view.id, Arc::new(view.clone()));
@@ -78,7 +78,7 @@ pub(crate) fn subscribe_view_change(
7878
txn,
7979
&view_relations,
8080
&section_map,
81-
uid,
81+
Some(uid),
8282
mappings,
8383
) {
8484
// Update deletion cache with the updated view

collab/src/folder/section.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ impl SectionMap {
4545
&self,
4646
txn: &T,
4747
section: Section,
48-
uid: i64,
48+
uid: Option<i64>,
4949
) -> Option<SectionOperation> {
5050
let container = self.get_section(txn, section.as_ref())?;
5151
Some(SectionOperation {
52-
uid: UserId::from(uid),
52+
uid: uid.map(UserId::from),
5353
container,
5454
section,
5555
change_tx: self.change_tx.clone(),
@@ -119,7 +119,7 @@ pub enum TrashSectionChange {
119119
pub type SectionsByUid = HashMap<UserId, Vec<SectionItem>>;
120120

121121
pub struct SectionOperation {
122-
uid: UserId,
122+
uid: Option<UserId>,
123123
container: MapRef,
124124
section: Section,
125125
change_tx: Option<SectionChangeSender>,
@@ -130,8 +130,8 @@ impl SectionOperation {
130130
&self.container
131131
}
132132

133-
fn uid(&self) -> &UserId {
134-
&self.uid
133+
fn uid(&self) -> Option<&UserId> {
134+
self.uid.as_ref()
135135
}
136136

137137
pub fn get_sections<T: ReadTxn>(&self, txn: &T) -> SectionsByUid {
@@ -154,9 +154,12 @@ impl SectionOperation {
154154
}
155155

156156
pub fn contains_with_txn<T: ReadTxn>(&self, txn: &T, view_id: &ViewId) -> bool {
157+
let Some(uid) = self.uid() else {
158+
return false;
159+
};
157160
match self
158161
.container()
159-
.get_with_txn::<_, ArrayRef>(txn, self.uid().as_ref())
162+
.get_with_txn::<_, ArrayRef>(txn, uid.as_ref())
160163
{
161164
None => false,
162165
Some(array) => {
@@ -173,9 +176,12 @@ impl SectionOperation {
173176
}
174177

175178
pub fn get_all_section_item<T: ReadTxn>(&self, txn: &T) -> Vec<SectionItem> {
179+
let Some(uid) = self.uid() else {
180+
return vec![];
181+
};
176182
match self
177183
.container()
178-
.get_with_txn::<_, ArrayRef>(txn, self.uid().as_ref())
184+
.get_with_txn::<_, ArrayRef>(txn, uid.as_ref())
179185
{
180186
None => vec![],
181187
Some(array) => {
@@ -201,6 +207,9 @@ impl SectionOperation {
201207
id: T,
202208
prev_id: Option<T>,
203209
) {
210+
let Some(uid) = self.uid() else {
211+
return;
212+
};
204213
let section_items = self.get_all_section_item(txn);
205214
let id = id.as_ref();
206215
let old_pos = section_items
@@ -217,7 +226,7 @@ impl SectionOperation {
217226
.unwrap_or(0);
218227
let section_array = self
219228
.container()
220-
.get_with_txn::<_, ArrayRef>(txn, self.uid().as_ref());
229+
.get_with_txn::<_, ArrayRef>(txn, uid.as_ref());
221230
// If the new position index is greater than the length of the section, yrs will panic
222231
if new_pos > section_items.len() as u32 {
223232
return;
@@ -233,9 +242,12 @@ impl SectionOperation {
233242
txn: &mut TransactionMut,
234243
ids: Vec<T>,
235244
) {
245+
let Some(uid) = self.uid() else {
246+
return;
247+
};
236248
if let Some(fav_array) = self
237249
.container()
238-
.get_with_txn::<_, ArrayRef>(txn, self.uid().as_ref())
250+
.get_with_txn::<_, ArrayRef>(txn, uid.as_ref())
239251
{
240252
for id in &ids {
241253
if let Some(pos) = self
@@ -267,8 +279,11 @@ impl SectionOperation {
267279
}
268280

269281
pub fn add_sections_item(&self, txn: &mut TransactionMut, items: Vec<SectionItem>) {
282+
let Some(uid) = self.uid() else {
283+
return;
284+
};
270285
let item_ids = items.iter().map(|item| item.id).collect::<Vec<_>>();
271-
self.add_sections_for_user_with_txn(txn, self.uid(), items);
286+
self.add_sections_for_user_with_txn(txn, uid, items);
272287
if let Some(change_tx) = self.change_tx.as_ref() {
273288
match self.section {
274289
Section::Favorite => {},
@@ -298,9 +313,12 @@ impl SectionOperation {
298313
}
299314

300315
pub fn clear(&self, txn: &mut TransactionMut) {
316+
let Some(uid) = self.uid() else {
317+
return;
318+
};
301319
if let Some(array) = self
302320
.container()
303-
.get_with_txn::<_, ArrayRef>(txn, self.uid().as_ref())
321+
.get_with_txn::<_, ArrayRef>(txn, uid.as_ref())
304322
{
305323
let len = array.iter(txn).count();
306324
array.remove_range(txn, 0, len as u32);

collab/src/folder/view.rs

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,11 @@ impl ViewsMap {
7272
}
7373
}
7474

75-
pub async fn observe_view_change(&self, uid: i64, views: HashMap<ViewId, Arc<View>>) {
75+
/// Observe view changes for a specific user. Requires uid to properly track user-specific changes.
76+
pub async fn observe_view_change(&self, uid: Option<i64>, views: HashMap<ViewId, Arc<View>>) {
77+
let Some(uid) = uid else {
78+
return; // Cannot observe changes without uid
79+
};
7680
for (k, v) in views {
7781
self.deletion_cache.insert(k, v);
7882
}
@@ -157,11 +161,12 @@ impl ViewsMap {
157161
}
158162
}
159163

164+
/// Get views belonging to a parent. When uid is provided, includes user-specific enrichment.
160165
pub fn get_views_belong_to<T: ReadTxn>(
161166
&self,
162167
txn: &T,
163168
parent_view_id: &ViewId,
164-
uid: i64,
169+
uid: Option<i64>,
165170
) -> Vec<Arc<View>> {
166171
match self.get_view_with_txn(txn, parent_view_id, uid) {
167172
Some(root_view) => root_view
@@ -205,14 +210,16 @@ impl ViewsMap {
205210
}
206211
}
207212

208-
pub fn get_views<T: ReadTxn>(&self, txn: &T, view_ids: &[ViewId], uid: i64) -> Vec<Arc<View>> {
213+
/// Get multiple views by ids. When uid is provided, includes user-specific enrichment.
214+
pub fn get_views<T: ReadTxn>(&self, txn: &T, view_ids: &[ViewId], uid: Option<i64>) -> Vec<Arc<View>> {
209215
view_ids
210216
.iter()
211217
.flat_map(|view_id| self.get_view_with_txn(txn, view_id, uid))
212218
.collect::<Vec<_>>()
213219
}
214220

215-
pub fn get_all_views<T: ReadTxn>(&self, txn: &T, uid: i64) -> Vec<Arc<View>> {
221+
/// Get all views. When uid is provided, includes user-specific enrichment like is_favorite.
222+
pub fn get_all_views<T: ReadTxn>(&self, txn: &T, uid: Option<i64>) -> Vec<Arc<View>> {
216223
// since views can be mapped through revisions, we need a map of final_view_id and its predecessors
217224

218225
// first split the keys into ones that have existing mappings (roots) and ones that have not more mapping (leafs)
@@ -252,14 +259,16 @@ impl ViewsMap {
252259
.collect()
253260
}
254261

262+
/// Get a view by id. When uid is provided, includes user-specific enrichment like is_favorite.
255263
#[instrument(level = "trace", skip_all)]
256-
pub fn get_view<T: ReadTxn>(&self, txn: &T, view_id: &ViewId, uid: i64) -> Option<Arc<View>> {
264+
pub fn get_view<T: ReadTxn>(&self, txn: &T, view_id: &ViewId, uid: Option<i64>) -> Option<Arc<View>> {
257265
self.get_view_with_txn(txn, view_id, uid)
258266
}
259267

260-
/// Return the orphan views.d
268+
/// Return the orphan views.
261269
/// The orphan views are the views that its parent_view_id equal to its view_id.
262-
pub fn get_orphan_views_with_txn<T: ReadTxn>(&self, txn: &T, uid: i64) -> Vec<Arc<View>> {
270+
/// When uid is provided, includes user-specific enrichment.
271+
pub fn get_orphan_views_with_txn<T: ReadTxn>(&self, txn: &T, uid: Option<i64>) -> Vec<Arc<View>> {
263272
self
264273
.container
265274
.keys(txn)
@@ -279,7 +288,7 @@ impl ViewsMap {
279288
&self,
280289
txn: &T,
281290
view_id: &ViewId,
282-
uid: i64,
291+
uid: Option<i64>,
283292
) -> Option<Arc<View>> {
284293
let (view_id, mappings) = self.revision_map.mappings(txn, *view_id);
285294
let map_ref = self.container.get_with_txn(txn, &view_id.to_string())?;
@@ -297,11 +306,12 @@ impl ViewsMap {
297306
/// Gets a view with stronger consistency guarantees, bypassing cache when needed
298307
/// Use this during transactions that might have uncommitted changes
299308
/// Note: Since we removed the cache, this is now identical to get_view_with_txn
309+
/// When uid is provided, includes user-specific enrichment like is_favorite.
300310
pub fn get_view_with_strong_consistency<T: ReadTxn>(
301311
&self,
302312
txn: &T,
303313
view_id: &ViewId,
304-
uid: i64,
314+
uid: Option<i64>,
305315
) -> Option<Arc<View>> {
306316
self.get_view_with_txn(txn, view_id, uid)
307317
}
@@ -493,7 +503,7 @@ impl ViewsMap {
493503
new_view_id: &ViewId,
494504
uid: i64,
495505
) -> bool {
496-
if let Some(old_view) = self.get_view(txn, old_view_id, uid) {
506+
if let Some(old_view) = self.get_view(txn, old_view_id, Some(uid)) {
497507
let mut new_view = (*old_view).clone();
498508
new_view.id = *new_view_id;
499509
new_view.last_edited_by = Some(uid);
@@ -517,7 +527,7 @@ pub(crate) fn view_from_map_ref<T: ReadTxn>(
517527
txn: &T,
518528
view_relations: &Arc<ParentChildRelations>,
519529
section_map: &SectionMap,
520-
uid: i64,
530+
uid: Option<i64>,
521531
mappings: impl IntoIterator<Item = ViewId>,
522532
) -> Option<View> {
523533
let parent_view_id: String = map_ref.get_with_txn(txn, VIEW_PARENT_ID)?;
@@ -556,9 +566,12 @@ pub(crate) fn view_from_map_ref<T: ReadTxn>(
556566
}
557567

558568
let icon = get_icon_from_view_map(map_ref, txn);
559-
let is_favorite = section_map
560-
.section_op(txn, Section::Favorite, uid)
561-
.map(|op| op.contains_with_txn(txn, &id))
569+
let is_favorite = uid
570+
.and_then(|uid| {
571+
section_map
572+
.section_op(txn, Section::Favorite, Some(uid))
573+
.map(|op| op.contains_with_txn(txn, &id))
574+
})
562575
.unwrap_or(false);
563576

564577
let created_by = map_ref.get_with_txn(txn, VIEW_CREATED_BY);
@@ -821,7 +834,7 @@ impl<'a, 'b, 'c> ViewUpdate<'a, 'b, 'c> {
821834
if let Some(private_section) =
822835
self
823836
.section_map
824-
.section_op(self.txn, Section::Private, self.uid.as_i64())
837+
.section_op(self.txn, Section::Private, Some(self.uid.as_i64()))
825838
{
826839
if is_private {
827840
private_section.add_sections_item(self.txn, vec![SectionItem::new(*self.view_id)]);
@@ -837,7 +850,7 @@ impl<'a, 'b, 'c> ViewUpdate<'a, 'b, 'c> {
837850
if let Some(fav_section) =
838851
self
839852
.section_map
840-
.section_op(self.txn, Section::Favorite, self.uid.as_i64())
853+
.section_op(self.txn, Section::Favorite, Some(self.uid.as_i64()))
841854
{
842855
if is_favorite {
843856
fav_section.add_sections_item(self.txn, vec![SectionItem::new(*self.view_id)]);
@@ -861,7 +874,7 @@ impl<'a, 'b, 'c> ViewUpdate<'a, 'b, 'c> {
861874
if let Some(trash_section) =
862875
self
863876
.section_map
864-
.section_op(self.txn, Section::Trash, self.uid.as_i64())
877+
.section_op(self.txn, Section::Trash, Some(self.uid.as_i64()))
865878
{
866879
if is_trash {
867880
trash_section.add_sections_item(self.txn, vec![SectionItem::new(*self.view_id)]);
@@ -891,7 +904,7 @@ impl<'a, 'b, 'c> ViewUpdate<'a, 'b, 'c> {
891904
self.txn,
892905
&self.children_map,
893906
self.section_map,
894-
self.uid.as_i64(),
907+
Some(self.uid.as_i64()),
895908
[],
896909
)
897910
}

collab/tests/document/conversions/plain_text_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ fn plain_text_mentions_custom_resolver() {
139139
let options = PlainTextExportOptions::from_default_resolver(resolver);
140140

141141
let plain = document
142-
.to_plain_text_with_options(options)
142+
.to_plain_text_with_options(&options)
143143
.into_iter()
144144
.filter(|line| !line.trim().is_empty())
145145
.collect::<Vec<_>>();

collab/tests/folder/child_views_test.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,19 @@ fn create_child_views_test() {
4848
let v_1_child_views = folder
4949
.body
5050
.views
51-
.get_views_belong_to(&txn, &v_1.id, uid.as_i64());
51+
.get_views_belong_to(&txn, &v_1.id, Some(uid.as_i64()));
5252
assert_eq!(v_1_child_views.len(), 3);
5353

5454
let v_1_2_child_views = folder
5555
.body
5656
.views
57-
.get_views_belong_to(&txn, &v_1_2.id, uid.as_i64());
57+
.get_views_belong_to(&txn, &v_1_2.id, Some(uid.as_i64()));
5858
assert_eq!(v_1_2_child_views.len(), 2);
5959

6060
let workspace_uuid_str = workspace_id.to_string();
6161
let folder_data = folder
6262
.body
63-
.get_folder_data(&txn, &workspace_uuid_str, uid.as_i64())
63+
.get_folder_data(&txn, &workspace_uuid_str, Some(uid.as_i64()))
6464
.unwrap();
6565
let value = serde_json::to_value(folder_data).unwrap();
6666
let fake_w_1_uuid = workspace_uuid_str.clone();
@@ -217,7 +217,7 @@ fn move_child_views_test() {
217217
let v_1_child_views = folder
218218
.body
219219
.views
220-
.get_views_belong_to(&txn, &v_1.id, uid.as_i64());
220+
.get_views_belong_to(&txn, &v_1.id, Some(uid.as_i64()));
221221
assert_eq!(
222222
v_1_child_views[0].id.to_string(),
223223
uuid::Uuid::new_v5(&uuid::Uuid::NAMESPACE_OID, "1_1".as_bytes()).to_string()
@@ -237,7 +237,7 @@ fn move_child_views_test() {
237237
let v_1_child_views = folder
238238
.body
239239
.views
240-
.get_view(&txn, &v_1.id, uid.as_i64())
240+
.get_view(&txn, &v_1.id, Some(uid.as_i64()))
241241
.unwrap();
242242
assert_eq!(
243243
v_1_child_views.children[0].id.to_string(),
@@ -283,7 +283,7 @@ fn delete_view_test() {
283283
let w_1_child_views = folder
284284
.body
285285
.views
286-
.get_views_belong_to(&txn, &workspace_id, uid.as_i64());
286+
.get_views_belong_to(&txn, &workspace_id, Some(uid.as_i64()));
287287
assert_eq!(
288288
w_1_child_views[0].id.to_string(),
289289
uuid::Uuid::new_v5(&uuid::Uuid::NAMESPACE_OID, "1_1".as_bytes()).to_string()
@@ -324,14 +324,14 @@ fn delete_child_view_test() {
324324
let views = folder
325325
.body
326326
.views
327-
.get_views_belong_to(&txn, &parse_view_id(&view_1_id), uid.as_i64());
327+
.get_views_belong_to(&txn, &parse_view_id(&view_1_id), Some(uid.as_i64()));
328328
assert_eq!(views.len(), 1);
329329

330330
folder.body.views.delete_views(&mut txn, vec![view_1_1_id]);
331331
let views = folder
332332
.body
333333
.views
334-
.get_views_belong_to(&txn, &parse_view_id(&view_1_id), uid.as_i64());
334+
.get_views_belong_to(&txn, &parse_view_id(&view_1_id), Some(uid.as_i64()));
335335
assert!(views.is_empty());
336336
}
337337

@@ -361,19 +361,19 @@ fn create_orphan_child_views_test() {
361361
let child_views = folder
362362
.body
363363
.views
364-
.get_views_belong_to(&txn, &workspace_id, uid.as_i64());
364+
.get_views_belong_to(&txn, &workspace_id, Some(uid.as_i64()));
365365
assert_eq!(child_views.len(), 1);
366366

367367
let orphan_views = folder
368368
.body
369369
.views
370-
.get_orphan_views_with_txn(&txn, uid.as_i64());
370+
.get_orphan_views_with_txn(&txn, Some(uid.as_i64()));
371371
assert_eq!(orphan_views.len(), 1);
372372

373373
// The folder data should contains the orphan view
374374
let folder_data = folder
375375
.body
376-
.get_folder_data(&txn, &workspace_uuid_str, uid.as_i64())
376+
.get_folder_data(&txn, &workspace_uuid_str, Some(uid.as_i64()))
377377
.unwrap();
378378
let fake_w_1_uuid = workspace_uuid_str.clone();
379379
let id_1_uuid = uuid::Uuid::new_v5(&uuid::Uuid::NAMESPACE_OID, "1".as_bytes()).to_string();

0 commit comments

Comments
 (0)