177 lines
4.8 KiB
Markdown
177 lines
4.8 KiB
Markdown
# GORM Writer
|
|
|
|
Generates Go source files with GORM model definitions from database schema information.
|
|
|
|
## Overview
|
|
|
|
The GORM Writer converts RelSpec's internal database model representation into Go source code with GORM struct definitions, complete with proper tags, relationships, and methods.
|
|
|
|
## Features
|
|
|
|
- Generates GORM-compatible Go structs
|
|
- Creates proper `gorm` struct tags
|
|
- Generates `TableName()` methods
|
|
- Adds relationship fields (belongs-to, has-many)
|
|
- Supports both single-file and multi-file output
|
|
- Auto-generates helper methods (optional)
|
|
- Maps SQL types to Go types
|
|
- Handles nullable fields with custom sql_types
|
|
|
|
## Usage
|
|
|
|
### Basic Example
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
|
"git.warky.dev/wdevs/relspecgo/pkg/writers"
|
|
"git.warky.dev/wdevs/relspecgo/pkg/writers/gorm"
|
|
)
|
|
|
|
func main() {
|
|
// Assume db is a *models.Database from a reader
|
|
options := &writers.WriterOptions{
|
|
OutputPath: "models.go",
|
|
PackageName: "models",
|
|
}
|
|
|
|
writer := gorm.NewWriter(options)
|
|
err := writer.WriteDatabase(db)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
```
|
|
|
|
### CLI Examples
|
|
|
|
```bash
|
|
# Generate GORM models from PostgreSQL database (single file)
|
|
relspec --input pgsql \
|
|
--conn "postgres://localhost/mydb" \
|
|
--output gorm \
|
|
--out-file models.go \
|
|
--package models
|
|
|
|
# Generate GORM models with multi-file output (one file per table)
|
|
relspec --input json \
|
|
--in-file schema.json \
|
|
--output gorm \
|
|
--out-file models/ \
|
|
--package models
|
|
|
|
# Convert DBML to GORM models
|
|
relspec --input dbml --in-file schema.dbml --output gorm --out-file models.go
|
|
```
|
|
|
|
## Output Modes
|
|
|
|
### Single File Mode
|
|
|
|
Generates all models in one file:
|
|
|
|
```bash
|
|
relspec --input pgsql --conn "..." --output gorm --out-file models.go
|
|
```
|
|
|
|
### Multi-File Mode
|
|
|
|
Generates one file per table (auto-detected when output is a directory):
|
|
|
|
```bash
|
|
relspec --input pgsql --conn "..." --output gorm --out-file models/
|
|
```
|
|
|
|
Files are named: `sql_{schema}_{table}.go`
|
|
|
|
## Generated Code Example
|
|
|
|
```go
|
|
package models
|
|
|
|
import (
|
|
"time"
|
|
sql_types "git.warky.dev/wdevs/sql_types"
|
|
)
|
|
|
|
type ModelUser struct {
|
|
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement" json:"id"`
|
|
Username string `gorm:"column:username;type:varchar(50);not null;uniqueIndex" json:"username"`
|
|
Email string `gorm:"column:email;type:varchar(100);not null" json:"email"`
|
|
CreatedAt time.Time `gorm:"column:created_at;type:timestamp;not null;default:now()" json:"created_at"`
|
|
|
|
// Relationships
|
|
Pos []*ModelPost `gorm:"foreignKey:UserID;references:ID;constraint:OnDelete:CASCADE" json:"pos,omitempty"`
|
|
}
|
|
|
|
func (ModelUser) TableName() string {
|
|
return "public.users"
|
|
}
|
|
|
|
type ModelPost struct {
|
|
ID int64 `gorm:"column:id;type:bigint;primaryKey" json:"id"`
|
|
UserID int64 `gorm:"column:user_id;type:bigint;not null" json:"user_id"`
|
|
Title string `gorm:"column:title;type:varchar(200);not null" json:"title"`
|
|
Content sql_types.SqlString `gorm:"column:content;type:text" json:"content,omitempty"`
|
|
|
|
// Belongs to
|
|
Use *ModelUser `gorm:"foreignKey:UserID;references:ID" json:"use,omitempty"`
|
|
}
|
|
|
|
func (ModelPost) TableName() string {
|
|
return "public.posts"
|
|
}
|
|
```
|
|
|
|
## Writer Options
|
|
|
|
### Metadata Options
|
|
|
|
Configure the writer behavior using metadata in `WriterOptions`:
|
|
|
|
```go
|
|
options := &writers.WriterOptions{
|
|
OutputPath: "models.go",
|
|
PackageName: "models",
|
|
Metadata: map[string]interface{}{
|
|
"multi_file": true, // Enable multi-file mode
|
|
"populate_refs": true, // Populate RefDatabase/RefSchema
|
|
"generate_get_id_str": true, // Generate GetIDStr() methods
|
|
},
|
|
}
|
|
```
|
|
|
|
## Type Mapping
|
|
|
|
| SQL Type | Go Type | Notes |
|
|
|----------|---------|-------|
|
|
| bigint, int8 | int64 | - |
|
|
| integer, int, int4 | int | - |
|
|
| smallint, int2 | int16 | - |
|
|
| varchar, text | string | Not nullable |
|
|
| varchar, text (nullable) | sql_types.SqlString | Nullable |
|
|
| boolean, bool | bool | - |
|
|
| timestamp, timestamptz | time.Time | - |
|
|
| numeric, decimal | float64 | - |
|
|
| uuid | string | - |
|
|
| json, jsonb | string | - |
|
|
|
|
## Relationship Generation
|
|
|
|
The writer automatically generates relationship fields:
|
|
|
|
- **Belongs-to**: Generated for tables with foreign keys
|
|
- **Has-many**: Generated for tables referenced by foreign keys
|
|
- Relationship field names use 3-letter prefixes
|
|
- Includes proper `gorm` tags with `foreignKey` and `references`
|
|
|
|
## Notes
|
|
|
|
- Model names are prefixed with "Model" (e.g., `ModelUser`)
|
|
- Nullable columns use `sql_types.SqlString`, `sql_types.SqlInt64`, etc.
|
|
- Generated code is auto-formatted with `go fmt`
|
|
- JSON tags are automatically added
|
|
- Supports schema-qualified table names in `TableName()` method
|