# database 结构化 MySQL 配置、独立 TLS/mTLS、驱动日志和生成项目接入见 [官方 MySQL 适配器](mysql/README.md)。已有 Open/OpenConnector 接口继续支持。 `database` 包提供基于标准库 `database/sql` 的连接池生命周期,不绑定 ORM 或驱动: - `Config` / `ConfigFromEnv`:连接池参数和 `GO_OMNI_DB_*` 环境变量。 - `Open` / `OpenConnector`:通过 DSN 或标准 Connector 创建连接池、设置连接上限并在返回前执行 `PingContext`。 - `Health`:用于就绪检查,等待连接和 Ping 均受 `PingTimeout` 限制。 - `InTx`:统一事务提交和回滚;工作函数返回错误或 panic 时回滚。 - `Close`:由嵌入的 `*sql.DB` 提供,应用退出时显式调用。 框架不导入 MySQL、PostgreSQL 等具体驱动。应用负责注册驱动: ```go import ( "context" _ "github.com/go-sql-driver/mysql" "git.yuntuo.hk/k2safe/go-omni/database" ) cfg, err := database.ConfigFromEnv("GO_OMNI_DB_") if err != nil { return err } db, err := database.Open(context.Background(), cfg) if err != nil { return err } defer db.Close() ``` 连接池相关环境变量: ```text GO_OMNI_DB_DRIVER=mysql GO_OMNI_DB_DSN=user:password@tcp(127.0.0.1:3306)/app?parseTime=true GO_OMNI_DB_MAX_OPEN_CONNS=10 GO_OMNI_DB_MAX_IDLE_CONNS=5 GO_OMNI_DB_CONN_MAX_LIFETIME=30m GO_OMNI_DB_CONN_MAX_IDLE_TIME=5m GO_OMNI_DB_PING_TIMEOUT=5s ``` 使用 `ConfigFromEnv` / `Open` 时 `DSN` 必填,环境变量入口的驱动默认是 `mysql`。数据库建库、迁移、表结构和具体 Repository 属于业务项目或可选模块,不会被核心包自动执行。 `MaxIdleConns=0` 会禁用空闲连接。初始化 Ping 失败会关闭已创建的连接池。 `go-omni new --database mysql` 会生成项目自己的 MySQL Repository、ServiceContext、 数据库就绪探针和 `schema.sql`。核心包不需要知道业务表结构。 真实数据库验收(需要本地 Docker): ```sh python3 scripts/verifyDatabase.py --version v0.2.0 ``` 脚本仅操作本次创建的独立容器与数据库,验证 HTTP CRUD、服务重启持久化、事务提交与 错误/panic/取消回滚、连接池关闭、缺少表结构时启动失败,以及停库后的 readiness 503 和恢复后的 200。 结束时清理容器、匿名数据卷和临时项目。常规 `go test ./...` 不依赖 Docker。 ## 项目配置叠加 `database.ApplyEnv(cfg, prefix)` 在已有文件/默认配置上覆盖非空环境变量,保留未覆盖的池参数。 `Config` 的 JSON/YAML 字段使用 lowerCamelCase,`DSN` 使用 `json:"-"`,连接密钥从环境变量加载。 API 脚手架 `--database mysql` 使用此流程,并要求正的 `maxOpenConns`,提供数据库 readiness 与幂等清理。 具体表结构、迁移和 Repository 留在业务项目,参考 `examples/userService`。 ## Connector 接入(v0.9.1-preview) 项目已有 `database/sql/driver.Connector` 时使用 `OpenConnector`。这是标准驱动接口,核心包不增加具体驱动依赖。项目可以在同一进程创建多个使用不同证书、日志、拨号策略的连接池。 下面是 MySQL 的完整组装函数;连接地址、凭据、TLS 和驱动 Logger 都从调用方传入,不在框架中约定: ```go package connection import ( "context" "crypto/tls" "github.com/go-sql-driver/mysql" "git.yuntuo.hk/k2safe/go-omni/database" ) func Open(ctx context.Context, address, user, password, name string, tlsConfig *tls.Config, logger mysql.Logger, pool database.PoolConfig) (*database.DB, error) { cfg := mysql.NewConfig() cfg.Net, cfg.Addr = "tcp", address cfg.User, cfg.Passwd, cfg.DBName = user, password, name cfg.TLS = tlsConfig // 项目设置 RootCAs、ServerName、MinVersion 等 if logger != nil { cfg.Logger = logger // 项目现有的 Print(...any) 日志适配器 } connector, err := mysql.NewConnector(cfg) if err != nil { return nil, err } return database.OpenConnector(ctx, connector, pool) } ``` 调用时以 `database.DefaultPoolConfig()` 为起点,按项目需要调整。已有 `database.Config` 可调用 `.PoolConfig()` 提取池设置;`ConfigFromEnv` / `ApplyEnv` 仍是 DSN 入口,不用为 Connector 填假 DSN。`PoolConfig` 支持通过 `config.DecodeFile` 加载项目的 JSON/YAML 嵌套配置,环境覆盖由项目按自己的驱动配置组织。 | PoolConfig 字段 | 默认值 / 含义 | | --- | --- | | `MaxOpenConns` | `10`;`0` 表示不限制 | | `MaxIdleConns` | `5`;`0` 禁止保留空闲连接 | | `ConnMaxLifetime` | `30m`;`0` 不因连接年龄回收 | | `ConnMaxIdleTime` | `5m`;`0` 不因空闲时长回收 | | `PingTimeout` | `5s`;必须为正,约束启动 Ping 和 Health 等待 | 返回的 `*database.DB` 嵌入 `*sql.DB`,可使用 `QueryContext`、`ExecContext`、`Stats`,以及框架的 `Health`、`InTx`。需要标准数据库指针的 ORM/迁移器可取 `db.DB`;不要重复建立池。项目负责驱动支持的 context 取消与读写超时设置,框架不能强制中断不遵守 context 的自定义驱动。 **生命周期:** nil/带类型的 nil Connector、非法池参数、启动前已取消的 context 会在创建池前返回,Connector 仍归调用方。进入 `sql.OpenDB` 后由池持有;启动 Ping 失败自动关闭,成功后由调用方负责 `db.Close`,通常注册 `app.OnShutdown(db.Close)`。若 Connector 实现 `io.Closer`,遵循标准 `database/sql` 规则随池关闭;有资源的 Connector 不应跨多个池共享。资源初始化过程中、注册退出回调之前若业务校验失败,项目也须关闭池。 `db.PoolConfig()` 返回池配置快照。Connector 入口的 `db.Config()` 中 `Driver` / `DSN` 为空,不能用它重建 Connector。TLS、Logger、驱动版本检查、字符集、时区以及迁移规则保持由项目负责;不写入框架配置快照。 验收脚本使用独立本地 MySQL 8.4 容器(1 CPU / 768 MiB),自动生成测试 CA/证书与随机凭据,检查 TLS 信任/主机名、两池配置隔离、驱动日志、事务和 HTTP 超时,结束后清理本次资源: ```sh python3 scripts/verifyConnector.py --local --report performance/connectorLocal.json # 发布后通过全新 module cache 验证远程依赖,无本地 replace: python3 scripts/verifyConnector.py --version v0.9.1-preview --report performance/connectorRemote.json ```