Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions app/flowix-core/src/memo_file/media_resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,19 @@ impl MemoFile {
mod tests {
use super::*;

#[test]
fn media_resource_identity_is_notebook_and_normalized_relative_path() {
assert_eq!(
media_resource_id("nb_one", "photos\\summer.png").unwrap(),
"nb_one::photos/summer.png"
);
assert_ne!(
media_resource_id("nb_one", "photos/summer.png").unwrap(),
media_resource_id("nb_two", "photos/summer.png").unwrap()
);
assert!(media_resource_id("nb_one", "../summer.png").is_err());
}

#[test]
fn background_note_preparation_preserves_shared_media_properties() {
let (memo, _temp, root) = fixture();
Expand Down
9 changes: 6 additions & 3 deletions app/flowix-core/src/memo_file/note_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2146,6 +2146,9 @@ mod tests {
INSERT INTO memos VALUES ('legacy-note.md');").unwrap();
drop(conn);

// Legacy projection cleanup is part of startup schema initialization,
// while ordinary reads keep the common connection path lightweight.
store.initialize_note_index_schema("nb_test").unwrap();
let conn = store.open_note_index_connection("nb_test").unwrap();
let note: String = conn.query_row("SELECT relative_path FROM notes", [], |row| row.get(0)).unwrap();
assert_eq!(note, "current.md");
Expand Down Expand Up @@ -2470,9 +2473,9 @@ mod tests {
.unwrap();
assert_eq!(immediate_path, created.relative_path);
drop(conn);
// Creation updates the Note projection immediately; the first full scan records the
// parser version and reparses that row once.
assert_eq!(store.reconcile_note_index("nb_test").unwrap().updated, 1);
// Creation already writes the current parsed projection, so a full scan
// sees it as unchanged.
assert_eq!(store.reconcile_note_index("nb_test").unwrap().unchanged, 1);
let conn = store.open_note_index_connection("nb_test").unwrap();
let memo_path: String = conn
.query_row("SELECT relative_path FROM memos", [], |row| row.get(0))
Expand Down
3 changes: 3 additions & 0 deletions app/flowix-core/src/memo_file/onboarding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,9 @@ mod tests {
mf.write_index(&MemoIndexFile::default()).unwrap();
fs::remove_file(mf.get_memo_base().join("Welcome.md")).unwrap();
fs::remove_file(mf.get_memo_base().join("欢迎文档.md")).unwrap();
// The path projection is authoritative for emptiness. Reconcile the
// externally removed files before asking onboarding to seed again.
mf.reconcile_note_index_blocking("nb_default").unwrap();

assert!(mf.seed_onboarding_docs().unwrap());
assert_eq!(mf.list_note_paths_from_disk("nb_default").unwrap().len(), ONBOARDING_DOCS.len());
Expand Down
8 changes: 8 additions & 0 deletions app/flowix-core/src/memo_file/ops/crud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,11 +480,19 @@ impl MemoFile {
let new_content = existing;
atomic_write_bytes(&new_path, new_content.as_bytes())?;

let old_relative_path = memo.relative_path.clone();
let mut updated = memo;
updated.filename = new_filename;
updated.relative_path = new_relative_path;
updated.updated_at = chrono::Utc::now().timestamp_millis();
apply_derived_memo_fields(&mut updated, &new_content);
if updated.relative_path != old_relative_path {
MemoFile::sync_index_on_delete_for_notebook_id_locked(
self,
&notebook_id,
&old_relative_path,
)?;
}
MemoFile::sync_index_on_write_for_notebook_id_locked(self, &notebook_id, &updated)?;
Ok(updated)
}
Expand Down
2 changes: 2 additions & 0 deletions app/flowix-core/src/memo_file/storage_repair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,8 @@ mod storage_rebuild_tests {
updated_at: 0,
}])
.unwrap();
// Database repair runs during schema initialization before indexing.
memo.initialize_note_index_schema("nb_kept").unwrap();
memo.reconcile_note_index_blocking("nb_kept").unwrap();
assert_eq!(
fs::read(root.join("kept.md")).unwrap(),
Expand Down
Loading
Loading