# 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