4.5 KiB
4.5 KiB
MySQL Driver
Purpose
支持 MySQL 作为可选数据库后端,通过配置选择 sqlite 或 mysql 驱动,提供 MySQL 连接管理、初始化和方言迁移文件。
Requirements
Requirement: MySQL 数据库驱动支持
系统 SHALL 支持通过配置项 database.driver 选择 sqlite 或 mysql 数据库驱动,默认值为 sqlite。
Scenario: 默认使用 SQLite 驱动
- WHEN 配置中未指定
database.driver - THEN SHALL 使用
sqlite作为数据库驱动 - THEN SHALL 行为与现有逻辑完全一致
Scenario: 配置 MySQL 驱动
- WHEN 配置
database.driver设置为mysql - THEN SHALL 使用 MySQL 驱动连接远程数据库
- THEN SHALL 使用
gorm.io/driver/mysql打开连接 - THEN SHALL 构建 DSN 格式为
{user}:{password}@tcp({host}:{port})/{dbname}?charset=utf8mb4&parseTime=true&loc=Local
Scenario: driver 值不合法
- WHEN 配置
database.driver不是sqlite或mysql - THEN SHALL 配置验证失败,拒绝启动
Requirement: MySQL 连接配置
系统 SHALL 在 DatabaseConfig 中支持 MySQL 连接参数。
Scenario: MySQL 连接参数字段
- WHEN
database.driver为mysql - THEN SHALL 读取
host(MySQL 主机地址,必填) - THEN SHALL 读取
port(MySQL 端口,默认 3306) - THEN SHALL 读取
user(MySQL 用户名,必填) - THEN SHALL 读取
password(MySQL 密码,选填) - THEN SHALL 读取
dbname(数据库名,必填)
Scenario: SQLite 模式忽略 MySQL 参数
- WHEN
database.driver为sqlite - THEN SHALL 忽略 MySQL 相关配置字段(host/port/user/password/dbname)
- THEN SHALL 仅使用
path字段作为数据库文件路径
Scenario: MySQL 模式忽略 SQLite 参数
- WHEN
database.driver为mysql - THEN SHALL 忽略
path字段
Requirement: 数据库初始化公共包
系统 SHALL 提供 internal/database 公共包,封装数据库初始化、迁移执行和连接关闭逻辑,供 cmd/server 和 cmd/desktop 共同调用。
Scenario: 公共包 Init 函数
- WHEN 调用
database.Init(cfg, logger) - THEN SHALL 根据
cfg.Driver选择对应的 GORM 驱动打开连接 - THEN SHALL 执行对应方言的 goose 迁移
- THEN SHALL 配置连接池参数
- THEN SHALL 在
driver=sqlite时执行PRAGMA journal_mode=WAL - THEN SHALL 在
driver=mysql时跳过 SQLite 专有 PRAGMA - THEN SHALL 返回
*gorm.DB实例
Scenario: 公共包 Close 函数
- WHEN 调用
database.Close(db) - THEN SHALL 获取底层
sql.DB并关闭连接
Scenario: 迁移目录选择
- WHEN 执行迁移
- THEN SHALL 在
driver=sqlite时使用migrations/sqlite/目录,goose dialect 为sqlite3 - THEN SHALL 在
driver=mysql时使用migrations/mysql/目录,goose dialect 为mysql
Requirement: MySQL 方言迁移文件
系统 SHALL 提供 MySQL 方言的初始迁移文件 migrations/mysql/20260421000001_initial_schema.sql。
Scenario: providers 表
- WHEN 执行 MySQL 初始迁移
- THEN SHALL 创建
providers表,字段:id VARCHAR(36) PRIMARY KEY、name VARCHAR(255) NOT NULL、api_key VARCHAR(255) NOT NULL、base_url VARCHAR(255) NOT NULL、protocol VARCHAR(50) DEFAULT 'openai'、enabled BOOLEAN DEFAULT TRUE、created_at DATETIME(3)、updated_at DATETIME(3)
Scenario: models 表
- WHEN 执行 MySQL 初始迁移
- THEN SHALL 创建
models表,字段:id VARCHAR(36) PRIMARY KEY、provider_id VARCHAR(36) NOT NULL、model_name VARCHAR(255) NOT NULL、enabled BOOLEAN DEFAULT TRUE、created_at DATETIME(3) - THEN SHALL 创建
UNIQUE(provider_id, model_name)约束 - THEN SHALL 创建
FOREIGN KEY (provider_id) REFERENCES providers(id) ON DELETE CASCADE约束 - THEN SHALL 创建
idx_models_provider_id和idx_models_model_name索引
Scenario: usage_stats 表
- WHEN 执行 MySQL 初始迁移
- THEN SHALL 创建
usage_stats表,字段:id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY、provider_id VARCHAR(36) NOT NULL、model_name VARCHAR(255) NOT NULL、request_count INT DEFAULT 0、date DATE NOT NULL - THEN SHALL 创建
UNIQUE(provider_id, model_name, date)约束 - THEN SHALL 创建
idx_usage_stats_provider_model_date复合索引
Scenario: Down 迁移
- WHEN 执行 MySQL down 迁移
- THEN SHALL 按正确顺序删除索引和表(usage_stats → models → providers)