package model import ( "database/sql" "fmt" "log" "os" "path/filepath" "time" _ "modernc.org/sqlite" ) // Database 数据库管理器 type Database struct { db *sql.DB } // NewDatabase 创建新的数据库连接 func NewDatabase() (*Database, error) { dbPath := getDatabasePath() log.Printf("[db] init: path=%s", dbPath) // 确保目录存在 dir := filepath.Dir(dbPath) if err := os.MkdirAll(dir, 0755); err != nil { log.Printf("[db] mkdir failed: dir=%s err=%v", dir, err) return nil, fmt.Errorf("创建数据库目录失败: %w", err) } // 连接数据库 db, err := sql.Open("sqlite", dbPath) if err != nil { log.Printf("[db] open failed: path=%s err=%v", dbPath, err) return nil, fmt.Errorf("连接数据库失败: %w", err) } // 测试连接 if err := db.Ping(); err != nil { log.Printf("[db] ping failed: err=%v", err) return nil, fmt.Errorf("数据库连接测试失败: %w", err) } database := &Database{db: db} // 初始化表结构 if err := database.initTables(); err != nil { log.Printf("[db] init tables failed: err=%v", err) return nil, fmt.Errorf("初始化数据库表失败: %w", err) } log.Printf("[db] init ok") return database, nil } // Close 关闭数据库连接 func (d *Database) Close() error { return d.db.Close() } // getDatabasePath 获取数据库文件路径 func getDatabasePath() string { homeDir, err := os.UserHomeDir() if err != nil { return "equipment_analyzer.db" } return filepath.Join(homeDir, ".equipment-analyzer", "equipment_analyzer.db") } // initTables 初始化数据库表结构 func (d *Database) initTables() error { // 解析数据表 - 存储抓包解析后的装备和角色数据 parsedDataTable := ` CREATE TABLE IF NOT EXISTS parsed_data ( id INTEGER PRIMARY KEY AUTOINCREMENT, session_name TEXT NOT NULL, items_json TEXT NOT NULL, heroes_json TEXT NOT NULL, created_at INTEGER NOT NULL );` // 应用设置表 settingsTable := ` CREATE TABLE IF NOT EXISTS app_settings ( key TEXT PRIMARY KEY, value TEXT NOT NULL, updated_at INTEGER NOT NULL );` tables := []string{ parsedDataTable, settingsTable, } for _, table := range tables { if _, err := d.db.Exec(table); err != nil { return fmt.Errorf("创建表失败: %w", err) } } return nil } // SaveParsedData 保存解析后的数据 func (d *Database) SaveParsedData(sessionName string, itemsJSON, heroesJSON string) error { stmt := ` INSERT INTO parsed_data (session_name, items_json, heroes_json, created_at) VALUES (?, ?, ?, ?)` _, err := d.db.Exec(stmt, sessionName, itemsJSON, heroesJSON, time.Now().Unix()) return err } // GetLatestParsedData 获取最新的解析数据 func (d *Database) GetLatestParsedData() (string, string, error) { stmt := ` SELECT items_json, heroes_json FROM parsed_data ORDER BY created_at DESC LIMIT 1` var itemsJSON, heroesJSON string err := d.db.QueryRow(stmt).Scan(&itemsJSON, &heroesJSON) if err != nil { if err == sql.ErrNoRows { return "", "", nil } return "", "", err } return itemsJSON, heroesJSON, nil } // GetParsedSessions 获取所有解析会话 func (d *Database) GetParsedSessions() ([]ParsedSession, error) { stmt := ` SELECT id, session_name, created_at FROM parsed_data ORDER BY created_at DESC` rows, err := d.db.Query(stmt) if err != nil { return nil, err } defer rows.Close() sessions := make([]ParsedSession, 0) for rows.Next() { var s ParsedSession if err := rows.Scan(&s.ID, &s.SessionName, &s.CreatedAt); err != nil { return nil, err } sessions = append(sessions, s) } return sessions, nil } // GetParsedDataByID 获取指定会话的数据 func (d *Database) GetParsedDataByID(id int64) (string, string, error) { stmt := ` SELECT items_json, heroes_json FROM parsed_data WHERE id = ? LIMIT 1` var itemsJSON, heroesJSON string err := d.db.QueryRow(stmt, id).Scan(&itemsJSON, &heroesJSON) if err != nil { if err == sql.ErrNoRows { return "", "", nil } return "", "", err } return itemsJSON, heroesJSON, nil } // UpdateParsedSessionName 更新解析会话名称 func (d *Database) UpdateParsedSessionName(id int64, name string) error { stmt := ` UPDATE parsed_data SET session_name = ? WHERE id = ?` _, err := d.db.Exec(stmt, name, id) return err } // DeleteParsedSession 删除解析会话 func (d *Database) DeleteParsedSession(id int64) error { stmt := ` DELETE FROM parsed_data WHERE id = ?` _, err := d.db.Exec(stmt, id) return err } // SaveSetting 保存应用设置 func (d *Database) SaveSetting(key, value string) error { stmt := "INSERT OR REPLACE INTO app_settings (key, value, updated_at) VALUES (?, ?, ?)" _, err := d.db.Exec(stmt, key, value, time.Now().Unix()) return err } // GetSetting 获取应用设置 func (d *Database) GetSetting(key string) (string, error) { stmt := "SELECT value FROM app_settings WHERE key = ?" var value string err := d.db.QueryRow(stmt, key).Scan(&value) if err != nil { return "", err } return value, nil } // GetAllSettings 获取所有设置 func (d *Database) GetAllSettings() (map[string]string, error) { stmt := "SELECT key, value FROM app_settings" rows, err := d.db.Query(stmt) if err != nil { return nil, err } defer rows.Close() settings := make(map[string]string) for rows.Next() { var key, value string if err := rows.Scan(&key, &value); err != nil { return nil, err } settings[key] = value } return settings, nil }