1
0
Files
nex/openspec/specs/mysql-driver/spec.md

4.5 KiB
Raw Blame History

MySQL Driver

Purpose

支持 MySQL 作为可选数据库后端,通过配置选择 sqlite 或 mysql 驱动,提供 MySQL 连接管理、初始化和方言迁移文件。

Requirements

Requirement: MySQL 数据库驱动支持

系统 SHALL 支持通过配置项 database.driver 选择 sqlitemysql 数据库驱动,默认值为 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 不是 sqlitemysql
  • THEN SHALL 配置验证失败,拒绝启动

Requirement: MySQL 连接配置

系统 SHALL 在 DatabaseConfig 中支持 MySQL 连接参数。

Scenario: MySQL 连接参数字段

  • WHEN database.drivermysql
  • THEN SHALL 读取 hostMySQL 主机地址,必填)
  • THEN SHALL 读取 portMySQL 端口,默认 3306
  • THEN SHALL 读取 userMySQL 用户名,必填)
  • THEN SHALL 读取 passwordMySQL 密码,选填)
  • THEN SHALL 读取 dbname(数据库名,必填)

Scenario: SQLite 模式忽略 MySQL 参数

  • WHEN database.driversqlite
  • THEN SHALL 忽略 MySQL 相关配置字段host/port/user/password/dbname
  • THEN SHALL 仅使用 path 字段作为数据库文件路径

Scenario: MySQL 模式忽略 SQLite 参数

  • WHEN database.drivermysql
  • THEN SHALL 忽略 path 字段

Requirement: 数据库初始化公共包

系统 SHALL 提供 internal/database 公共包,封装数据库初始化、迁移执行和连接关闭逻辑,供 cmd/servercmd/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 KEYname VARCHAR(255) NOT NULLapi_key VARCHAR(255) NOT NULLbase_url VARCHAR(255) NOT NULLprotocol VARCHAR(50) DEFAULT 'openai'enabled BOOLEAN DEFAULT TRUEcreated_at DATETIME(3)updated_at DATETIME(3)

Scenario: models 表

  • WHEN 执行 MySQL 初始迁移
  • THEN SHALL 创建 models 表,字段:id VARCHAR(36) PRIMARY KEYprovider_id VARCHAR(36) NOT NULLmodel_name VARCHAR(255) NOT NULLenabled BOOLEAN DEFAULT TRUEcreated_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_ididx_models_model_name 索引

Scenario: usage_stats 表

  • WHEN 执行 MySQL 初始迁移
  • THEN SHALL 创建 usage_stats 表,字段:id INT UNSIGNED AUTO_INCREMENT PRIMARY KEYprovider_id VARCHAR(36) NOT NULLmodel_name VARCHAR(255) NOT NULLrequest_count INT DEFAULT 0date 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