Files
zzy 35e79e54f1 refactor(vfs): 重构VFS模块,拆分数据访问逻辑与路径解析逻辑
将原先的 `vfs.go` 文件中的功能进行拆分,创建了独立的 DAO 层文件 `vfs_dao.go`
和路径处理文件 `vfs_path.go`,以提升代码结构清晰度和可维护性。

- 将数据库操作相关方法迁移至 `VfsDAO` 结构体中
- 新增 `vfs_dao.go` 文件用于管理底层数据访问对象
- 新增 `vfs_path.go` 文件专门处理路径解析逻辑
- 移除了原 `vfs.go` 中的数据库初始化、用户及节点操作等冗余代码
2025-09-29 00:42:45 +08:00

337 lines
8.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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
}