/* storage.go - 数据存储 实现了任务数据的持久化存储 */ package todo import ( "encoding/json" "fmt" "io/ioutil" "os" "path/filepath" ) // Storage 存储接口 type Storage interface { Load() ([]Task, error) Save(tasks []Task) error } // JSONStorage JSON文件存储实现 type JSONStorage struct { filePath string } // NewJSONStorage 创建新的JSON存储 func NewJSONStorage(filePath string) (*JSONStorage, error) { if filePath == "" { return nil, fmt.Errorf("文件路径不能为空") } // 确保目录存在 dir := filepath.Dir(filePath) if err := os.MkdirAll(dir, 0755); err != nil { return nil, fmt.Errorf("创建目录失败: %v", err) } return &JSONStorage{ filePath: filePath, }, nil } // Load 从JSON文件加载任务 func (s *JSONStorage) Load() ([]Task, error) { // 检查文件是否存在 if _, err := os.Stat(s.filePath); os.IsNotExist(err) { // 文件不存在,返回空任务列表 return []Task{}, nil } // 读取文件内容 data, err := ioutil.ReadFile(s.filePath) if err != nil { return nil, fmt.Errorf("读取文件失败: %v", err) } // 如果文件为空,返回空任务列表 if len(data) == 0 { return []Task{}, nil } // 解析JSON数据 var tasks []Task if err := json.Unmarshal(data, &tasks); err != nil { return nil, fmt.Errorf("解析JSON数据失败: %v", err) } return tasks, nil } // Save 保存任务到JSON文件 func (s *JSONStorage) Save(tasks []Task) error { // 序列化任务数据 data, err := json.MarshalIndent(tasks, "", " ") if err != nil { return fmt.Errorf("序列化任务数据失败: %v", err) } // 写入文件 if err := ioutil.WriteFile(s.filePath, data, 0644); err != nil { return fmt.Errorf("写入文件失败: %v", err) } return nil } // GetFilePath 获取文件路径 func (s *JSONStorage) GetFilePath() string { return s.filePath } // FileExists 检查文件是否存在 func (s *JSONStorage) FileExists() bool { _, err := os.Stat(s.filePath) return !os.IsNotExist(err) } // GetFileSize 获取文件大小 func (s *JSONStorage) GetFileSize() (int64, error) { info, err := os.Stat(s.filePath) if err != nil { return 0, err } return info.Size(), nil } // Backup 备份数据文件 func (s *JSONStorage) Backup(backupPath string) error { if !s.FileExists() { return fmt.Errorf("源文件不存在") } // 读取源文件 data, err := ioutil.ReadFile(s.filePath) if err != nil { return fmt.Errorf("读取源文件失败: %v", err) } // 确保备份目录存在 dir := filepath.Dir(backupPath) if err := os.MkdirAll(dir, 0755); err != nil { return fmt.Errorf("创建备份目录失败: %v", err) } // 写入备份文件 if err := ioutil.WriteFile(backupPath, data, 0644); err != nil { return fmt.Errorf("写入备份文件失败: %v", err) } return nil } // Restore 从备份恢复数据 func (s *JSONStorage) Restore(backupPath string) error { // 检查备份文件是否存在 if _, err := os.Stat(backupPath); os.IsNotExist(err) { return fmt.Errorf("备份文件不存在") } // 读取备份文件 data, err := ioutil.ReadFile(backupPath) if err != nil { return fmt.Errorf("读取备份文件失败: %v", err) } // 验证备份数据 var tasks []Task if err := json.Unmarshal(data, &tasks); err != nil { return fmt.Errorf("备份数据格式无效: %v", err) } // 写入主文件 if err := ioutil.WriteFile(s.filePath, data, 0644); err != nil { return fmt.Errorf("恢复数据失败: %v", err) } return nil } // Clear 清空数据文件 func (s *JSONStorage) Clear() error { return s.Save([]Task{}) } // MemoryStorage 内存存储实现(用于测试) type MemoryStorage struct { tasks []Task } // NewMemoryStorage 创建新的内存存储 func NewMemoryStorage() *MemoryStorage { return &MemoryStorage{ tasks: make([]Task, 0), } } // Load 从内存加载任务 func (s *MemoryStorage) Load() ([]Task, error) { // 返回任务副本 tasks := make([]Task, len(s.tasks)) copy(tasks, s.tasks) return tasks, nil } // Save 保存任务到内存 func (s *MemoryStorage) Save(tasks []Task) error { // 保存任务副本 s.tasks = make([]Task, len(tasks)) copy(s.tasks, tasks) return nil } // Clear 清空内存中的任务 func (s *MemoryStorage) Clear() { s.tasks = make([]Task, 0) } // GetTasks 获取内存中的任务(用于测试) func (s *MemoryStorage) GetTasks() []Task { tasks := make([]Task, len(s.tasks)) copy(tasks, s.tasks) return tasks } // CSVStorage CSV文件存储实现(扩展功能) type CSVStorage struct { filePath string } // NewCSVStorage 创建新的CSV存储 func NewCSVStorage(filePath string) (*CSVStorage, error) { if filePath == "" { return nil, fmt.Errorf("文件路径不能为空") } // 确保目录存在 dir := filepath.Dir(filePath) if err := os.MkdirAll(dir, 0755); err != nil { return nil, fmt.Errorf("创建目录失败: %v", err) } return &CSVStorage{ filePath: filePath, }, nil } // Load 从CSV文件加载任务(简化实现) func (s *CSVStorage) Load() ([]Task, error) { // 这里可以实现CSV解析逻辑 // 为了简化,暂时返回空列表 return []Task{}, nil } // Save 保存任务到CSV文件(简化实现) func (s *CSVStorage) Save(tasks []Task) error { // 这里可以实现CSV写入逻辑 // 为了简化,暂时不做任何操作 return nil } // StorageManager 存储管理器 type StorageManager struct { storages map[string]Storage current string } // NewStorageManager 创建新的存储管理器 func NewStorageManager() *StorageManager { return &StorageManager{ storages: make(map[string]Storage), } } // AddStorage 添加存储实现 func (sm *StorageManager) AddStorage(name string, storage Storage) { sm.storages[name] = storage } // SetCurrent 设置当前使用的存储 func (sm *StorageManager) SetCurrent(name string) error { if _, exists := sm.storages[name]; !exists { return fmt.Errorf("存储 '%s' 不存在", name) } sm.current = name return nil } // GetCurrent 获取当前存储 func (sm *StorageManager) GetCurrent() (Storage, error) { if sm.current == "" { return nil, fmt.Errorf("未设置当前存储") } storage, exists := sm.storages[sm.current] if !exists { return nil, fmt.Errorf("当前存储 '%s' 不存在", sm.current) } return storage, nil } // ListStorages 列出所有可用的存储 func (sm *StorageManager) ListStorages() []string { var names []string for name := range sm.storages { names = append(names, name) } return names } // Load 使用当前存储加载数据 func (sm *StorageManager) Load() ([]Task, error) { storage, err := sm.GetCurrent() if err != nil { return nil, err } return storage.Load() } // Save 使用当前存储保存数据 func (sm *StorageManager) Save(tasks []Task) error { storage, err := sm.GetCurrent() if err != nil { return err } return storage.Save(tasks) }