Skip to content

Commit 86ce9a1

Browse files
committed
docs: GORM 백엔드 반영과 changepack
1 parent dd2db4c commit 86ce9a1

7 files changed

Lines changed: 88 additions & 24 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"changes": {"crates/vespertide-cli/Cargo.toml": "Minor", "crates/vespertide-config/Cargo.toml": "Minor", "crates/vespertide-core/Cargo.toml": "Minor", "crates/vespertide-exporter/Cargo.toml": "Minor", "crates/vespertide-loader/Cargo.toml": "Minor", "crates/vespertide-lsp/Cargo.toml": "Minor", "crates/vespertide-macro/Cargo.toml": "Minor", "crates/vespertide-naming/Cargo.toml": "Minor", "crates/vespertide-planner/Cargo.toml": "Minor", "crates/vespertide-query/Cargo.toml": "Minor", "crates/vespertide/Cargo.toml": "Minor"}, "note": "GORM(Go) 익스포터를 7번째 ORM 백엔드로 추가. `Orm`이 exhaustive pub enum이라 `Orm::Gorm` 추가가 0.x 기준 breaking이고, vespertide-cli에 `export --orm gorm` 경로가 함께 들어간다(스키마 전체를 `models.go` 한 파일로 쓴다). vespertide-core의 `SimpleColumnType`·`ReferenceAction`에서 `#[non_exhaustive]`를 제거해 downstream이 exhaustive match를 쓸 수 있게 한다(기존 `_` arm은 `unreachable_patterns` 경고가 된다). published 크레이트를 전부 같은 Minor로 올리는 이유는 #185·#186과 동일하다: [workspace.dependencies]의 `=` 핀으로 물려 있어 일부만 올리면 핀과 크레이트 버전이 어긋나 resolve가 깨진다.", "date": "2026-09-15T07:40:25.0000000Z"}

‎AGENTS.md‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ vespertide/
1818
│ ├── vespertide-planner/ # Schema diffing, baseline reconstruction, validation
1919
│ ├── vespertide-query/ # SQL generation (Postgres/MySQL/SQLite)
2020
│ ├── vespertide-cli/ # CLI commands: init, diff, sql, revision, export
21-
│ ├── vespertide-exporter/ # ORM codegen: SeaORM, SQLAlchemy, SQLModel, JPA, Prisma, Drizzle
21+
│ ├── vespertide-exporter/ # ORM codegen: SeaORM, SQLAlchemy, SQLModel, JPA, Prisma, Drizzle, GORM
2222
│ ├── vespertide-loader/ # Filesystem loading of models/migrations
2323
│ ├── vespertide-config/ # vespertide.json configuration
2424
│ ├── vespertide-lsp/ # Language server: 13 LSP capabilities + HS-7~11 caching
@@ -48,7 +48,7 @@ vespertide/
4848
| Schema diffing | `vespertide-planner/src/diff/` | topological sort for FK deps |
4949
| SQL generation | `vespertide-query/src/sql/` | One file per action type |
5050
| CLI commands | `vespertide-cli/src/commands/` | `cmd_*` functions |
51-
| ORM export | `vespertide-exporter/src/{seaorm,sqlalchemy,sqlmodel,jpa,prisma,drizzle}/` | Backend-specific generators |
51+
| ORM export | `vespertide-exporter/src/{seaorm,sqlalchemy,sqlmodel,jpa,prisma,drizzle,gorm}/` | Backend-specific generators |
5252
| Compile-time macro | `vespertide-macro/src/lib.rs` | `vespertide_migration!` proc macro |
5353
| **LSP RingCache (HS-7~11)** | `vespertide-lsp/src/cache.rs` | Generic ring-buffer LRU shared across symbols/diagnostics/drift/semantic-token caches |
5454
| **LSP drift cache** | `vespertide-lsp/src/drift/cache.rs` | HS-10 drift cache implementation |
@@ -170,7 +170,7 @@ See `docs/clippy-allow-audit.md` for the full audit history.
170170
| `QueryError::Other(...)` in new code | Emits deprecation warning. Use `SchemaError` / `InvalidColumnType` / `BackendError` / `UnsupportedAction` |
171171
| Exhaustive struct literal for `MigrationOptions` / `VespertideConfig` | `#[non_exhaustive]` — use `..Default::default()` |
172172
| Comparing newtype with `String::eq(&name.to_string(), "user")` | `TableName: PartialEq<&str>` — use `name == "user"` directly |
173-
| Per-ORM exporter snapshot test (single ORM) | Use the 6-ORM `orm_cases!` macro; snapshots must cross-compare all ORMs |
173+
| Per-ORM exporter snapshot test (single ORM) | Use the 7-ORM `orm_cases!` macro; snapshots must cross-compare all ORMs |
174174

175175
## COMMANDS
176176

@@ -235,7 +235,7 @@ Files near the ceiling (next split candidates — line counts as of the
235235
| `query/src/sql/delete_column/mod.rs` | 1138 | prod+inline-tests (≤1200) | DROP COLUMN with SQLite rebuild |
236236
| `query/src/sql/add_constraint/mod.rs` | 1138 | prod+inline-tests (≤1200) | ADD CONSTRAINT |
237237
| `core/src/schema/table/tests/mod.rs` | 1137 | test-file (≤1200) | Table normalization tests |
238-
| `exporter/src/tests/fixtures/mod.rs` | 1146 | test-file (≤1200) | Shared 6-ORM fixture schemas |
238+
| `exporter/src/tests/fixtures/mod.rs` | 1168 | test-file (≤1200) | Shared 7-ORM fixture schemas |
239239
| `planner/src/validate/check_strengthening.rs` | 1121 | prod+inline-tests (≤1200) | CHECK strengthening analysis |
240240
| `query/src/sql/helpers.rs` | 1109 | prod+inline-tests (≤1200) | Identifier quoting / type-cast helpers |
241241
| `lsp/src/code_actions.rs` | 1107 | prod+inline-tests (≤1200) | LSP code actions (incl. CHECK BETWEEN-swap) |
@@ -369,7 +369,7 @@ alongside what the dialect emits *in place of* the missing construct.
369369
**How many cases:**
370370

371371
Where the axis has a documented matrix — `vespertide-query`'s
372-
`{PG, MySQL, SQLite}` triple and the exporter's six-ORM `orm_cases!` — fan out
372+
`{PG, MySQL, SQLite}` triple and the exporter's seven-ORM `orm_cases!` — fan out
373373
**always**, even when every case renders the same bytes: identity across the
374374
matrix is itself the assertion (`uniform_sql_is_emitted_byte_for_byte`), and a
375375
lone single-backend snapshot is a fault (`vespertide-query/AGENTS.md`).
@@ -397,14 +397,14 @@ fn create_table_snapshot(#[case] backend: DatabaseBackend) {
397397
```
398398

399399
This is the same pattern used by `vespertide-query` (3 backends, 564 snapshots)
400-
and `vespertide-exporter` (6 ORMs via `Orm` enum, 414 cross-ORM snapshots). When
400+
and `vespertide-exporter` (7 ORMs via `Orm` enum, 525 cross-ORM snapshots). When
401401
adding a new backend / ORM / format, the change is **one `#[case::name(Value)]`
402402
line**.
403403

404404
### Exporter snapshots MUST cover ALL ORMs (no per-ORM snapshots)
405-
Every `vespertide-exporter` snapshot test MUST be written through the shared `orm_cases!` rstest macro in `crates/vespertide-exporter/src/tests/mod.rs`, which renders each fixture for **all six ORMs** (`Orm::SeaOrm`, `Orm::SqlAlchemy`, `Orm::SqlModel`, `Orm::Jpa`, `Orm::Prisma`, `Orm::Drizzle`). A new export scenario = ONE fixture + ONE `orm_cases!(...)` line, producing exactly six snapshots (one per ORM) in the single shared `crates/vespertide-exporter/src/tests/snapshots/` directory.
405+
Every `vespertide-exporter` snapshot test MUST be written through the shared `orm_cases!` rstest macro in `crates/vespertide-exporter/src/tests/mod.rs`, which renders each fixture for **all seven ORMs** (`Orm::SeaOrm`, `Orm::SqlAlchemy`, `Orm::SqlModel`, `Orm::Jpa`, `Orm::Prisma`, `Orm::Drizzle`, `Orm::Gorm`). A new export scenario = ONE fixture + ONE `orm_cases!(...)` line, producing exactly seven snapshots (one per ORM) in the single shared `crates/vespertide-exporter/src/tests/snapshots/` directory.
406406

407-
FORBIDDEN: per-ORM `#[test]` snapshot functions inside `src/seaorm/`, `src/sqlalchemy/`, `src/sqlmodel/`, `src/jpa/`, `src/prisma/`, `src/drizzle/`, or any `snapshots/` directory other than `src/tests/snapshots/`. A scenario snapshotted for only one ORM is a defect — ORM output must always be cross-compared across all six. When adding a new ORM the change is a single `#[case::<orm>(Orm::<Variant>)]` line in the macro, never a new per-ORM test.
407+
FORBIDDEN: per-ORM `#[test]` snapshot functions inside `src/seaorm/`, `src/sqlalchemy/`, `src/sqlmodel/`, `src/jpa/`, `src/prisma/`, `src/drizzle/`, `src/gorm/`, or any `snapshots/` directory other than `src/tests/snapshots/`. A scenario snapshotted for only one ORM is a defect — ORM output must always be cross-compared across all seven. When adding a new ORM the change is a single `#[case::<orm>(Orm::<Variant>)]` line in the macro, never a new per-ORM test.
408408

409409
Exception: an entry point that exists in only one backend (Prisma's single-file `render_schema`, which deduplicates enums globally; Drizzle's dialect-aware `render_schema`, whose axis is the SQL dialect rather than the ORM) is not a cross-ORM scenario, so its snapshot tests live as inline tests of that module — with the snapshot files still written to the shared `src/tests/snapshots/` via `with_settings!(snapshot_path => ...)`.
410410

‎README.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Declarative database schema management. Define your schemas in JSON, and Vespert
1616
- **Enum Types**: Native string enums and integer enums (no migration needed for new values)
1717
- **Zero-Runtime Migrations**: Compile-time macro generates database-specific SQL
1818
- **JSON Schema Validation**: Ships with JSON Schemas for IDE autocompletion and validation
19-
- **ORM Export**: Export schemas to SeaORM, SQLAlchemy, SQLModel, JPA, Prisma, Drizzle
19+
- **ORM Export**: Export schemas to SeaORM, SQLAlchemy, SQLModel, JPA, Prisma, Drizzle, GORM
2020
- **Language Server**: First-class editor support via the bundled `vespertide-lsp` — see [LSP Features](#lsp-features) below
2121

2222
## What's new in 0.2.0
@@ -245,6 +245,7 @@ vespertide export --orm sqlmodel # Python - SQLModel (FastAPI)
245245
vespertide export --orm jpa # Java - JPA/Hibernate entities
246246
vespertide export --orm prisma # Prisma - schema.prisma models
247247
vespertide export --orm drizzle # TypeScript - Drizzle ORM (pg/mysql/sqlite files)
248+
vespertide export --orm gorm # Go - GORM models (models.go)
248249
```
249250

250251
## Runtime Migrations (Macro)

‎bridge/node/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Declarative database schema management: define tables in JSON or YAML, diff
44
them against the migration history, and generate SQL for PostgreSQL, MySQL
5-
and SQLite plus ORM code (SeaORM, SQLAlchemy, SQLModel, JPA, Prisma, Drizzle).
5+
and SQLite plus ORM code (SeaORM, SQLAlchemy, SQLModel, JPA, Prisma, Drizzle, GORM).
66

77
This package is the `vespertide` command-line tool as a native Node addon,
88
so no Rust toolchain is needed.

‎crates/vespertide-cli/AGENTS.md‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ src/
2121
│ # choices_and_apply/), tests/
2222
├── status.rs # Show config and sync status
2323
├── log.rs # List applied migrations with SQL
24-
├── export/ # Export to ORM code (SeaORM/SQLAlchemy/SQLModel/JPA/Prisma/Drizzle) —
25-
│ # mod.rs + tests/ (mod.rs, prisma.rs, drizzle.rs)
24+
├── export/ # Export to ORM code (SeaORM/SQLAlchemy/SQLModel/JPA/Prisma/Drizzle/GORM) —
25+
│ # mod.rs + tests/ (mod.rs, prisma.rs, drizzle.rs, gorm.rs,
26+
│ # models_file.rs)
2627
└── erd/ # ERD diagram export — mod.rs, mermaid.rs, dot.rs, svg/ (style, model,
2728
# layout, edges, render, util), tests/
2829
```
@@ -38,7 +39,7 @@ src/
3839
| `revision -m` | `cmd_revision(msg, fill_with)` | Interactive prompts via `dialoguer::Input` |
3940
| `status` | `cmd_status()` | Display config paths and migration count |
4041
| `log` | `cmd_log(backend)` | Iterate applied migrations, print SQL |
41-
| `export --orm` | `cmd_export(orm, dir)` | `render_entity_with_schema()` + mod.rs wiring |
42+
| `export --orm` | `cmd_export(orm, dir)` | per-table `render_entity_with_schema()` + mod.rs wiring; Prisma/Drizzle/GORM render the whole schema into fixed file names |
4243
| `erd -f svg\|mermaid\|dot` | `cmd_erd_with_filters(format, output, include, exclude, depth)` | FK-graph filtered ERD rendering |
4344

4445
## WHERE TO LOOK
@@ -55,7 +56,7 @@ src/
5556
## NOTES
5657

5758
- **revision/**: Most complex command — handles interactive `--fill-with` prompts for NOT NULL columns without defaults; long ago split from a single 3064-line file into `revision/{mod,parse,emit,write,timezones}.rs` + `prompts/` + `tests/`
58-
- **export/**: Generates the `mod.rs` chain for SeaORM exports; Python/Java ORMs skip it. Prisma and Drizzle take separate single-file paths rather than one file per model — Prisma writes one `models.prisma`, Drizzle one file per dialect (`models.pg.ts` / `models.mysql.ts` / `models.sqlite.ts`)
59+
- **export/**: Generates the `mod.rs` chain for SeaORM exports; Python/Java ORMs skip it. Prisma, Drizzle and GORM take separate single-file paths rather than one file per model — Prisma writes one `models.prisma`, Drizzle one file per dialect (`models.pg.ts` / `models.mysql.ts` / `models.sqlite.ts`), GORM `models.go`. The last one skips the extension sweep like Drizzle, and refuse to overwrite a `models.*` that does not open with the `Code generated by vespertide. DO NOT EDIT.` line
5960
- All commands use `load_config()`, `load_models()`, `load_migrations()` from `vespertide_loader`
6061
- YAML and JSON are both fully supported for models and migrations; `new <name> -f yaml` creates YAML templates.
6162
- Prefer typed `MigrationAction` enums; `RawSql` exists as a documented emergency escape hatch, but is not recommended for normal use.

0 commit comments

Comments
 (0)