refactor(vfs): 重构VFS模块,拆分数据访问逻辑与路径解析逻辑

将原先的 `vfs.go` 文件中的功能进行拆分,创建了独立的 DAO 层文件 `vfs_dao.go`
和路径处理文件 `vfs_path.go`,以提升代码结构清晰度和可维护性。

- 将数据库操作相关方法迁移至 `VfsDAO` 结构体中
- 新增 `vfs_dao.go` 文件用于管理底层数据访问对象
- 新增 `vfs_path.go` 文件专门处理路径解析逻辑
- 移除了原 `vfs.go` 中的数据库初始化、用户及节点操作等冗余代码
This commit is contained in:
zzy
2025-09-29 00:42:45 +08:00
parent 429a863b76
commit 35e79e54f1
13 changed files with 1106 additions and 1005 deletions

View File

@ -0,0 +1,336 @@
// models/vfs_dao.go - 数据访问对象
package models
import (
"database/sql"
"errors"
"fmt"
"strings"
"time"
)
// VfsDAO 处理底层数据库操作
type VfsDAO struct {
DB *sql.DB
}
type VfsDirEntry struct {
ID uint64
Name string
Type VfsNodeType
}
func NewVfsDAO(dbPath string) (*VfsDAO, error) {
db, err := sql.Open("sqlite3", dbPath)
if err != nil {
return nil, err
}
_, err = db.Exec(`
CREATE TABLE IF NOT EXISTS vfs_nodes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
parent_id INTEGER,
type INTEGER NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(parent_id, name)
)`)
if err != nil {
return nil, err
}
_, err = db.Exec(`
CREATE TABLE IF NOT EXISTS vfs_users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
token TEXT NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)`)
if err != nil {
return nil, err
}
vfsdao := VfsDAO{DB: db}
err = vfsdao.createInitialDirectories()
if err != nil {
return nil, err
}
return &vfsdao, nil
}
// 创建初始目录结构
func (dao *VfsDAO) createInitialDirectories() error {
var err error
// 创建 /home 目录
_, err = dao.DB.Exec(`
INSERT OR IGNORE INTO vfs_nodes (name, parent_id, type, created_at, updated_at)
VALUES ('home', 0, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`,
VfsNodeTypeDirectory)
if err != nil {
return err
}
// 创建 /public 目录
_, err = dao.DB.Exec(`
INSERT OR IGNORE INTO vfs_nodes (name, parent_id, type, created_at, updated_at)
VALUES ('public', 0, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`,
VfsNodeTypeDirectory)
if err != nil {
return err
}
return nil
}
// Node 相关操作
func (dao *VfsDAO) CreateNode(node VfsNode) error {
_, err := dao.DB.Exec(`
INSERT INTO vfs_nodes (name, parent_id, type, created_at, updated_at)
VALUES (?, ?, ?, ?, ?)`,
node.Name, node.ParentID, node.Type, time.Now(), time.Now())
return err
}
func (dao *VfsDAO) UpdateNode(node *VfsNode) error {
_, err := dao.DB.Exec(`
UPDATE vfs_nodes
SET name = ?, parent_id = ?, type = ?, updated_at = ?
WHERE id = ?`,
node.Name, node.ParentID, node.Type, time.Now(), node.ID)
return err
}
func (dao *VfsDAO) DeleteNode(id uint64) error {
_, err := dao.DB.Exec("DELETE FROM vfs_nodes WHERE id = ?", id)
return err
}
func (dao *VfsDAO) GetNodeByID(id uint64) (*VfsNode, error) {
node := &VfsNode{}
err := dao.DB.QueryRow(`
SELECT id, name, parent_id, type, created_at, updated_at
FROM vfs_nodes
WHERE id = ?`, id).Scan(
&node.ID, &node.Name, &node.ParentID, &node.Type, &node.CreatedAt, &node.UpdatedAt)
if err != nil {
if err == sql.ErrNoRows {
return nil, errors.New("node not found")
}
return nil, err
}
return node, nil
}
func (dao *VfsDAO) GetNodeByParentIDAndName(parentID uint64, name string) (*VfsNode, error) {
node := &VfsNode{}
err := dao.DB.QueryRow(`
SELECT id, name, parent_id, type, created_at, updated_at
FROM vfs_nodes
WHERE parent_id = ? AND name = ?`, parentID, name).Scan(
&node.ID, &node.Name, &node.ParentID, &node.Type, &node.CreatedAt, &node.UpdatedAt)
if err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
return nil, err
}
return node, nil
}
// GetParentID 根据父路径查找父节点 ID
// parentPath 应该是 ParsePathComponents 的第一个返回值
func (dao *VfsDAO) GetNodeByPath(parentPath string) (*VfsNode, error) {
// log.Printf("GetNodeByPath: %s", parentPath)
// 根目录特殊处理
if parentPath == "/" || parentPath == "" {
return &VfsNode{
ID: 0,
Name: "Root",
ParentID: 0,
}, nil
}
// 递归查找父路径ID
// 先解析父路径的父路径和节点名
grandParentPath, parentName, _, err := ParsePathComponents(parentPath)
if err != nil {
return nil, err
}
// 递归获取祖父节点ID
grandParentNode, err := dao.GetNodeByPath(grandParentPath)
if err != nil {
return nil, err
}
// 在祖父节点下查找父节点
var parentID uint64
err = dao.DB.QueryRow("SELECT id FROM vfs_nodes WHERE parent_id = ? AND name = ?",
grandParentNode.ID, parentName).Scan(&parentID)
// log.Printf("parentID: %+v, %+v, %+v", grandParentNode, parentName, parentID)
if err != nil {
if err == sql.ErrNoRows {
return nil, errors.New("parent path not found")
}
return nil, err
}
return dao.GetNodeByID(parentID)
}
func (dao *VfsDAO) GetChildren(parentID uint64) ([]VfsDirEntry, error) {
rows, err := dao.DB.Query("SELECT id, name, type FROM vfs_nodes WHERE parent_id = ?", parentID)
if err != nil {
return nil, err
}
defer rows.Close()
var dirEntries []VfsDirEntry
for rows.Next() {
var entry VfsDirEntry
if err := rows.Scan(&entry.ID, &entry.Name, &entry.Type); err != nil {
return nil, err
}
dirEntries = append(dirEntries, entry)
}
return dirEntries, nil
}
// 递归获取所有子项ID的辅助函数
func (dao *VfsDAO) getChildrenIDRecursive(parentID uint64, ids *[]uint64, services *[]uint64) error {
// 获取当前层级的子项
rows, err := dao.DB.Query("SELECT id, type FROM vfs_nodes WHERE parent_id = ?", parentID)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var id uint64
var nodeType VfsNodeType
if err := rows.Scan(&id, &nodeType); err != nil {
return err
}
// 将当前节点ID添加到列表中
*ids = append(*ids, id)
// 如果是目录,递归获取其子项
switch nodeType {
case VfsNodeTypeDirectory:
err := dao.getChildrenIDRecursive(id, ids, services)
if err != nil {
return err
}
case VfsNodeTypeService:
*services = append(*services, id)
}
}
return nil
}
// GetChildrenID 获取目录下所有子项的 ID
func (dao *VfsDAO) GetChildrenID(parentID uint64, recursive bool) (ids []uint64, services []uint64, err error) {
if recursive {
// 递归获取所有子项ID
err := dao.getChildrenIDRecursive(parentID, &ids, &services)
if err != nil {
return nil, nil, err
}
} else {
// 只获取直接子项ID
rows, err := dao.DB.Query("SELECT id FROM vfs_nodes WHERE parent_id = ?", parentID)
if err != nil {
return nil, nil, err
}
defer rows.Close()
for rows.Next() {
var id uint64
if err := rows.Scan(&id); err != nil {
return nil, nil, err
}
ids = append(ids, id)
}
}
return ids, services, nil
}
// DeleteNodeRecursively 递归删除节点及其所有子项
func (dao *VfsDAO) DeleteNodeRecursively(nodeID uint64) ([]uint64, error) {
// 获取所有需要删除的ID包括自己和所有子项
idsToDelete := []uint64{nodeID}
// 获取所有子项ID
childIDs, serviceIDs, err := dao.GetChildrenID(nodeID, true)
if err != nil {
return nil, err
}
idsToDelete = append(idsToDelete, childIDs...)
// 构建删除语句
if len(idsToDelete) == 0 {
return nil, nil
}
// 创建占位符
placeholders := make([]string, len(idsToDelete))
args := make([]any, len(idsToDelete))
for i, id := range idsToDelete {
placeholders[i] = "?"
args[i] = id
}
query := fmt.Sprintf("DELETE FROM vfs_nodes WHERE id IN (%s)", strings.Join(placeholders, ","))
_, err = dao.DB.Exec(query, args...)
return serviceIDs, err
}
// User 相关操作
func (dao *VfsDAO) GetUserByToken(token string) (*VfsUser, error) {
user := &VfsUser{}
err := dao.DB.QueryRow("SELECT name, token FROM vfs_users WHERE token = ?", token).
Scan(&user.Name, &user.Token)
if err != nil {
if err == sql.ErrNoRows {
return nil, errors.New("user not found")
}
return nil, err
}
return user, nil
}
func (dao *VfsDAO) GetUserByName(username string) (*VfsUser, error) {
user := &VfsUser{}
err := dao.DB.QueryRow("SELECT name, token FROM vfs_users WHERE name = ?", username).
Scan(&user.Name, &user.Token)
if err != nil {
if err == sql.ErrNoRows {
return nil, errors.New("user not found")
}
return nil, err
}
return user, nil
}
func (dao *VfsDAO) CreateUser(username, token string) error {
_, err := dao.DB.Exec("INSERT INTO vfs_users (name, token) VALUES (?, ?)", username, token)
return err
}
func (dao *VfsDAO) DeleteUser(username string) error {
_, err := dao.DB.Exec("DELETE FROM vfs_users WHERE name = ?", username)
return err
}