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