Merge pull request #82 from PR0M3TH3AN/codex/add-to_db_path-function-and-update-usages

Normalize db paths
This commit is contained in:
thePR0M3TH3AN
2025-05-24 21:59:42 -04:00
committed by GitHub
6 changed files with 41 additions and 12 deletions

View File

@@ -18,6 +18,8 @@ use rusqlite::{
use std::result::Result as StdResult;
use tracing::{debug, info, warn};
use crate::utils::to_db_path;
/* ─── schema version ───────────────────────────────────────────────── */
/// Current library schema version.
@@ -394,9 +396,13 @@ pub fn take_dirty(conn: &Connection) -> Result<Vec<i64>> {
/* ─── rename helpers ────────────────────────────────────────────── */
pub fn update_file_path(conn: &Connection, old_path: &str, new_path: &str) -> Result<()> {
let file_id: i64 = conn.query_row("SELECT id FROM files WHERE path = ?1", [old_path], |r| {
r.get(0)
})?;
let old_path = to_db_path(old_path);
let new_path = to_db_path(new_path);
let file_id: i64 =
conn.query_row("SELECT id FROM files WHERE path = ?1", [&old_path], |r| {
r.get(0)
})?;
conn.execute(
"UPDATE files SET path = ?1 WHERE id = ?2",
params![new_path, file_id],
@@ -406,6 +412,8 @@ pub fn update_file_path(conn: &Connection, old_path: &str, new_path: &str) -> Re
}
pub fn rename_directory(conn: &mut Connection, old_dir: &str, new_dir: &str) -> Result<()> {
let old_dir = to_db_path(old_dir);
let new_dir = to_db_path(new_dir);
let like_pattern = format!("{}/%", old_dir.trim_end_matches('/'));
let ids = {
let mut stmt = conn.prepare("SELECT id FROM files WHERE path LIKE ?1")?;

View File

@@ -1,6 +1,7 @@
// libmarlin/src/db_tests.rs
use super::db;
use crate::utils::to_db_path;
use rusqlite::Connection;
use tempfile::tempdir;
@@ -283,7 +284,7 @@ fn tables_exist_and_fts_triggers() {
.unwrap()
.collect::<std::result::Result<Vec<_>, _>>()
.unwrap();
assert!(hits_tag.contains(&file_path.to_string_lossy().into_owned()));
assert!(hits_tag.contains(&to_db_path(&file_path)));
let hits_attr: Vec<String> = marlin
.conn()
@@ -293,5 +294,5 @@ fn tables_exist_and_fts_triggers() {
.unwrap()
.collect::<std::result::Result<Vec<_>, _>>()
.unwrap();
assert!(hits_attr.contains(&file_path.to_string_lossy().into_owned()));
assert!(hits_attr.contains(&to_db_path(&file_path)));
}

View File

@@ -3,6 +3,8 @@
use std::fs;
use std::path::Path;
use crate::utils::to_db_path;
use anyhow::Result;
use rusqlite::{params, Connection};
use tracing::{debug, info};
@@ -51,7 +53,7 @@ pub fn scan_directory(conn: &mut Connection, root: &Path) -> Result<usize> {
.as_secs() as i64;
// Execute the upsert
let path_str = path.to_string_lossy();
let path_str = to_db_path(path);
stmt.execute(params![path_str, size, mtime])?;
count += 1;

View File

@@ -1,6 +1,6 @@
//! Misc shared helpers.
use std::path::PathBuf;
use std::path::{Path, PathBuf};
/// Determine a filesystem root to limit recursive walking on glob scans.
///
@@ -44,3 +44,19 @@ pub fn determine_scan_root(pattern: &str) -> PathBuf {
root
}
}
/// Convert a filesystem path to a normalized database path.
///
/// On Windows this replaces backslashes with forward slashes so that paths
/// stored in the database are consistent across platforms.
pub fn to_db_path<P: AsRef<Path>>(p: P) -> String {
let s = p.as_ref().to_string_lossy();
#[cfg(windows)]
{
s.replace('\\', "/")
}
#[cfg(not(windows))]
{
s.into_owned()
}
}

View File

@@ -6,6 +6,7 @@
//! watcher can be paused, resumed and shut down cleanly.
use crate::db::{self, Database};
use crate::utils::to_db_path;
use anyhow::{anyhow, Context, Result};
use crossbeam_channel::{bounded, Receiver};
use notify::{
@@ -479,8 +480,8 @@ impl FileWatcher {
// update DB for renames
if let EventKind::Modify(ModifyKind::Name(_)) = ev.kind {
if let (Some(old_p), Some(new_p)) = (&ev.old_path, &ev.new_path) {
let old_s = old_p.to_string_lossy();
let new_s = new_p.to_string_lossy();
let old_s = to_db_path(old_p);
let new_s = to_db_path(new_p);
let res =
handle_db_update(db_mutex, &old_s, &new_s, new_p.is_dir());
if let Err(e) = res {

View File

@@ -6,6 +6,7 @@ mod tests {
use crate::backup::BackupManager;
// These are still from the watcher module
use crate::db::open as open_marlin_db;
use crate::utils::to_db_path;
use crate::watcher::{FileWatcher, WatcherConfig, WatcherState}; // Use your project's DB open function
use crate::Marlin;
@@ -29,7 +30,7 @@ mod tests {
.conn()
.query_row(
"SELECT COUNT(*) FROM files WHERE path = ?1",
[path.to_string_lossy()],
[to_db_path(path)],
|r| r.get(0),
)
.unwrap();
@@ -211,7 +212,7 @@ mod tests {
.conn()
.query_row(
"SELECT COUNT(*) FROM files WHERE path = ?1",
[new_file.to_string_lossy()],
[to_db_path(&new_file)],
|r| r.get(0),
)
.unwrap();
@@ -262,7 +263,7 @@ mod tests {
.conn()
.query_row(
"SELECT COUNT(*) FROM files WHERE path = ?1",
[p.to_string_lossy()],
[to_db_path(&p)],
|r| r.get(0),
)
.unwrap();