| | |
| | | "fmt" |
| | | "os" |
| | | "path/filepath" |
| | | "strings" |
| | | |
| | | _ "github.com/mattn/go-sqlite3" |
| | | "github.com/aisim/kb-cli/internal/graph" |
| | |
| | | |
| | | return links, nil |
| | | } |
| | | |
| | | // NodeInfo 节点基本信息(用于 GC) |
| | | type NodeInfo struct { |
| | | ID int64 |
| | | Path string |
| | | } |
| | | |
| | | // GetAllNodes 获取所有节点(用于 GC 检查) |
| | | func (s *Store) GetAllNodes() ([]NodeInfo, error) { |
| | | rows, err := s.db.Query("SELECT id, path FROM nodes") |
| | | if err != nil { |
| | | return nil, fmt.Errorf("查询节点失败: %w", err) |
| | | } |
| | | defer rows.Close() |
| | | |
| | | var nodes []NodeInfo |
| | | for rows.Next() { |
| | | var n NodeInfo |
| | | if err := rows.Scan(&n.ID, &n.Path); err != nil { |
| | | return nil, fmt.Errorf("扫描节点失败: %w", err) |
| | | } |
| | | nodes = append(nodes, n) |
| | | } |
| | | |
| | | if err := rows.Err(); err != nil { |
| | | return nil, fmt.Errorf("遍历节点失败: %w", err) |
| | | } |
| | | |
| | | return nodes, nil |
| | | } |
| | | |
| | | // DeleteNodesByPaths 删除指定路径的节点及其关联边 |
| | | func (s *Store) DeleteNodesByPaths(paths []string) (int, error) { |
| | | if len(paths) == 0 { |
| | | return 0, nil |
| | | } |
| | | |
| | | // 构建 IN 子句 |
| | | placeholders := make([]string, len(paths)) |
| | | args := make([]interface{}, len(paths)) |
| | | for i, path := range paths { |
| | | placeholders[i] = "?" |
| | | args[i] = path |
| | | } |
| | | |
| | | tx, err := s.db.Begin() |
| | | if err != nil { |
| | | return 0, fmt.Errorf("开始事务失败: %w", err) |
| | | } |
| | | |
| | | // 先删除关联边 |
| | | query := fmt.Sprintf(` |
| | | DELETE FROM edges |
| | | WHERE from_node IN (SELECT id FROM nodes WHERE path IN (%s)) |
| | | OR to_node IN (SELECT id FROM nodes WHERE path IN (%s)) |
| | | `, strings.Join(placeholders, ","), strings.Join(placeholders, ",")) |
| | | |
| | | // 参数需要重复两次 |
| | | allArgs := append(args, args...) |
| | | _, err = tx.Exec(query, allArgs...) |
| | | if err != nil { |
| | | tx.Rollback() |
| | | return 0, fmt.Errorf("删除边失败: %w", err) |
| | | } |
| | | |
| | | // 删除节点 |
| | | query = fmt.Sprintf("DELETE FROM nodes WHERE path IN (%s)", strings.Join(placeholders, ",")) |
| | | result, err := tx.Exec(query, args...) |
| | | if err != nil { |
| | | tx.Rollback() |
| | | return 0, fmt.Errorf("删除节点失败: %w", err) |
| | | } |
| | | |
| | | if err := tx.Commit(); err != nil { |
| | | return 0, fmt.Errorf("提交事务失败: %w", err) |
| | | } |
| | | |
| | | affected, _ := result.RowsAffected() |
| | | return int(affected), nil |
| | | } |