# Model/cache 教程

## 目标

从 MySQL/goctl 或显式 PostgreSQL SQL schema 生成 Rust entity、repository trait、SQLx repository、cache key helper 和可选 cache-aside repository。

## 输入文件

MySQL/goctl 示例 schema：`examples/model-cache/schema.sql`。PostgreSQL 示例 schema：`tests/fixtures/postgres/model/user.sql`。

## 生成 skeleton

```bash
cargo run -p rs-zero-cli -- model gen \
  -s examples/model-cache/schema.sql \
  -d target/generated \
  --with-sqlx \
  --with-redis-cache
```

生成结果包含：

- `src/entity.rs`：Rust entity struct。
- `src/repository.rs`：repository trait、可选 SQLx repository 和可选 cached repository。
- `src/cache.rs`：主键/唯一索引 cache key helper 和可选 Redis/L1/L2 cache alias。
- `Cargo.toml`、`README.md`。

## PostgreSQL schema

```bash
cargo run -p rs-zero-cli -- model gen \
  -s tests/fixtures/postgres/model/user.sql \
  -d target/generated \
  --dialect postgres \
  --with-sqlx
```

显式 MySQL backend：

```bash
cargo run -p rs-zero-cli -- model gen \
  -s examples/model-cache/schema.sql \
  -d target/generated \
  --with-sqlx \
  --sqlx-backend mysql
```

PostgreSQL 命令会生成 `rs_zero::db::PostgresDatabasePool` repository；MySQL backend 命令会生成 `rs_zero::db::MySqlDatabasePool` repository。

## 支持的 SQL 子集

默认 parser 面向常见 MySQL `CREATE TABLE` 子集，覆盖：

- 字段名、SQL 类型、nullable、primary key、unique。
- `DEFAULT`、`COMMENT`、`AUTO_INCREMENT`、`ON UPDATE`。
- table charset、collation、comment。
- primary key、unique key、normal index、复合索引。

MySQL backend 支持 unsigned integer、decimal、timestamp/datetime/date、json 和 blob/binary 等常见类型映射。PostgreSQL 显式方言覆盖双引号标识符、schema-qualified table、identity、`CREATE INDEX`、`COMMENT ON` 和常见 PostgreSQL 类型。

完整边界见 [Model/cache 手册](../manual/model-cache.md)。

## Cache key 命名

cache helper 使用稳定命名，例如：

- `user_by_id_key`
- `user_by_email_mobile_key`

普通非唯一索引不会生成单对象 cache key；它们在 repository 中以 `find_all_by_*` 形式保留为 DB 查询。复合唯一索引会按列顺序生成 key segment。

## Cache-aside repository

同时启用 `--with-sqlx --with-redis-cache` 时，生成的 `Cached{Entity}Repository<S>` 会使用 `CacheAside<S>`：

- `find_by_id` 和唯一索引 `find_by_*` 先查缓存，miss 后读取 SQLx repository 并写回缓存。
- `save` 和 `delete_by_*` 会删除相关主键/唯一索引 key。
- L1 可使用 `LruCacheStore`，L2 可使用 `RedisCacheStore` 或 `RedisShardedCacheStore`，也可通过 `TwoLevelCacheStore` 组合。

## 验证

```bash
cargo test -p rs-zero-cli --test model_codegen_integration
cargo test -p rs-zero-cli --test goctl_model_compat
cargo test -p rs-zero-cli --test model_mysql_cli
cargo test -p rs-zero-cli --test model_postgres_codegen
cargo test -p rs-zero-cli --test model_postgres_cli
```

## 常见问题

- `schema does not contain a CREATE TABLE statement`：输入 SQL 中没有可解析的 `CREATE TABLE`。
- 生成文件已存在：默认拒绝覆盖；确认需要覆盖时使用 `--force`。
- 复杂 MySQL 或 PostgreSQL 语法无法解析：先缩小到当前支持的 `CREATE TABLE` 子集，或在文档中标注为未支持。
