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:
336
internal/vfs/models/vfs_dao.go
Normal file
336
internal/vfs/models/vfs_dao.go
Normal 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
|
||||
}
|
Reference in New Issue
Block a user