# WebDAV MarkBase Backend集成计划

## 当前状态

**现有WebDAV实现：**
- src/webdav/handler.rs (26 lines)
- 使用 `dav-server` 库
- 使用 `LocalFs`（本地文件系统backend）
- 使用 `FakeLs`（简单lock system）

**问题：**
- ❌ LocalFs只是本地目录映射，不是SQLite backend
- ❌ 无法直接访问warren.sqlite（12659 nodes）
- ❌ 无法使用MarkBaseFS的query_node/read_file功能

---

## 需要实现：MarkBaseFs backend

**目标：**
- 实现dav-server的filesystem trait
- 使用MarkBaseFS（SQLite backend）
- 支持warren.sqlite的12659 nodes
- 实现PROPFIND、GET、PUT操作

---

## dav-server filesystem trait分析

**dav-server库的filesystem trait需要实现：**

```rust
pub trait DavFileSystem: Send + Sync {
    // 必须实现的方法
    fn read_dir(&self, path: &str, meta: bool) -> io::Result<Vec<DavDirItem>>;
    fn get_file(&self, path: &str) -> io::Result<Box<dyn DavFile>>;
    fn metadata(&self, path: &str) -> io::Result<DavMetaData>;
    
    // 可选方法（PUT写入）
    fn put_file(&self, path: &str) -> io::Result<Box<dyn DavFile>>;
    fn create_dir(&self, path: &str) -> io::Result<()>;
    fn remove_file(&self, path: &str) -> io::Result<()>;
    fn remove_dir(&self, path: &str) -> io::Result<()>;
}
```

---

## 实现方案

### 方案A：直接实现filesystem trait（推荐）

**优势：**
- 完全控制
- 直接使用MarkBaseFS
- 性能最优

**步骤：**
1. 创建 `MarkBaseFs` struct，实现 `DavFileSystem` trait
2. 使用 `MarkBaseFS::query_node()` 获取文件节点
3. 使用 `MarkBaseFS::query_children()` 实现read_dir
4. 使用 `MarkBaseFS::read_file()` 实现get_file
5. 集成到DavHandler

**预估时间：** 3-4小时

---

### 方案B：修改handler.rs，使用SQLite backend（简化）

**优势：**
- 快速实现
- 不需要自定义filesystem trait
- 利用现有handler结构

**步骤：**
1. 修改 `MarkBaseWebDAV::create_handler()`
2. 使用 `data/users/warren.sqlite` 作为数据源
3. 创建虚拟文件映射
4. 保留LocalFs，但映射到SQLite虚拟目录

**预估时间：** 1-2小时

---

### 方案C：使用WebDAV handler + HTTP server（最简单）

**优势：**
- 最快实现
- 不需要自定义filesystem
- 使用现有的localfs

**步骤：**
1. 创建 `data/webdav/warren/` 目录
2. 使用 `MarkBaseFS::read_file()` 将warren.sqlite文件复制到该目录
3. LocalFs自动映射目录结构
4. Finder可通过HTTP访问

**缺点：**
- 不是真正的SQLite backend
- 需要文件复制（占用磁盘空间）
- 性能较差

**预估时间：** 30分钟

---

## 推荐方案：方案A（完整实现）

**理由：**
- 完全使用SQLite backend
- 真正的虚拟文件系统
- 性能最优
- 可扩展（未来可添加PUT写入）

---

## 实现步骤（方案A）

### 步骤1：创建MarkBaseFs struct

**文件：** `src/webdav/markbase_fs.rs`

```rust
use dav_server::{DavFileSystem, DavDirItem, DavMetaData, DavFile};
use crate::fskit::filesystem::MarkBaseFS;
use std::io;

pub struct MarkBaseFs {
    markbase_fs: MarkBaseFS,
    user_id: String,
}

impl MarkBaseFs {
    pub fn new(user_id: String, db_path: &str) -> Self {
        let markbase_fs = MarkBaseFS::new(&user_id, db_path);
        Self { markbase_fs, user_id }
    }
}

impl DavFileSystem for MarkBaseFs {
    fn read_dir(&self, path: &str, meta: bool) -> io::Result<Vec<DavDirItem>> {
        // 使用MarkBaseFS::query_children()
        // 返回目录内容
    }
    
    fn get_file(&self, path: &str) -> io::Result<Box<dyn DavFile>> {
        // 使用MarkBaseFS::read_file()
        // 返回文件内容
    }
    
    fn metadata(&self, path: &str) -> io::Result<DavMetaData> {
        // 使用MarkBaseFS::query_node()
        // 返回文件元数据
    }
}
```

---

### 步骤2：实现DavDirItem和DavMetaData

**DavDirItem结构：**
```rust
pub struct MarkBaseDavDirItem {
    name: String,
    is_dir: bool,
    size: u64,
}

impl DavDirItem for MarkBaseDavDirItem {
    fn name(&self) -> &str { &self.name }
    fn is_dir(&self) -> bool { self.is_dir }
}
```

**DavMetaData结构：**
```rust
pub struct MarkBaseMetaData {
    is_dir: bool,
    size: u64,
    modified: SystemTime,
}

impl DavMetaData for MarkBaseMetaData {
    fn is_dir(&self) -> bool { self.is_dir }
    fn len(&self) -> u64 { self.size }
    fn modified(&self) -> SystemTime { self.modified }
}
```

---

### 步骤3：修改handler.rs

**文件：** `src/webdav/handler.rs`

```rust
use crate::webdav::markbase_fs::MarkBaseFs;

impl MarkBaseWebDAV {
    pub fn create_handler(&self) -> DavHandler {
        let db_path = format!("data/users/{}/{}.sqlite", self.user_id, self.user_id);
        
        DavHandler::builder()
            .filesystem(MarkBaseFs::new(self.user_id.clone(), &db_path))
            .locksystem(FakeLs::new())
            .strip_prefix("/webdav")
            .build_handler()
    }
}
```

---

### 步骤4：启动HTTP server

**文件：** `src/bin/webdav_server.rs`

```rust
use axum::Router;
use markbase::webdav::handler::MarkBaseWebDAV;

fn main() {
    let webdav = MarkBaseWebDAV::new("warren", PathBuf::from("data/users/warren.sqlite"));
    let handler = webdav.create_handler();
    
    let app = Router::new()
        .route("/webdav/*path", get(handler.handle_get))
        .route("/webdav/*path", put(handler.handle_put));
    
    // 启动server
    let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
    axum::Server::bind(&addr).serve(app.into_make_service()).await;
}
```

---

### 步骤5：Finder连接测试

**Finder操作：**
- Connect to Server → `http://localhost:8080/webdav`
- 验证warren.sqlite的12659 nodes显示
- 验证文件读取功能

---

## 预估时间

|步骤 |时间 |
|------|------|
| 步骤1：MarkBaseFs struct | 1小时 |
| 步骤2：DavDirItem/DavMetaData | 1小时 |
| 步骤3：修改handler.rs | 30分钟 |
| 步骤4：HTTP server启动 | 30分钟 |
| 步骤5：Finder测试 | 30分钟 |
| **总计** | **3.5小时** |

---

## 快速开始

**立即可执行：**
1. 创建 `src/webdav/markbase_fs.rs`
2. 实现 `DavFileSystem` trait
3. 修改 `src/webdav/handler.rs`
4. 启动HTTP server
5. Finder连接测试

---

**最后更新：** 2026-05-18 20:50
