142 lines
3.7 KiB
Markdown
142 lines
3.7 KiB
Markdown
# GORM Reader
|
|
|
|
Reads Go source files containing GORM model definitions and extracts database schema information.
|
|
|
|
## Overview
|
|
|
|
The GORM Reader parses Go source code files that define GORM models (structs with `gorm` struct tags) and converts them into RelSpec's internal database model representation. It supports reading from individual files or entire directories.
|
|
|
|
## Features
|
|
|
|
- Parses GORM struct tags to extract column definitions
|
|
- Extracts table names from `TableName()` methods
|
|
- Identifies primary keys, foreign keys, and indexes
|
|
- Supports relationship detection (has-many, belongs-to)
|
|
- Handles both single files and directories
|
|
|
|
## Usage
|
|
|
|
### Basic Example
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"git.warky.dev/wdevs/relspecgo/pkg/readers"
|
|
"git.warky.dev/wdevs/relspecgo/pkg/readers/gorm"
|
|
)
|
|
|
|
func main() {
|
|
// Read from a single file
|
|
options := &readers.ReaderOptions{
|
|
FilePath: "/path/to/models.go",
|
|
}
|
|
|
|
reader := gorm.NewReader(options)
|
|
db, err := reader.ReadDatabase()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Printf("Found %d schemas\n", len(db.Schemas))
|
|
}
|
|
```
|
|
|
|
### Reading from Directory
|
|
|
|
```go
|
|
// Read all .go files from a directory
|
|
options := &readers.ReaderOptions{
|
|
FilePath: "/path/to/models/",
|
|
}
|
|
|
|
reader := gorm.NewReader(options)
|
|
db, err := reader.ReadDatabase()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
```
|
|
|
|
### CLI Example
|
|
|
|
```bash
|
|
# Read GORM models and convert to JSON
|
|
relspec --input gorm --in-file models/ --output json --out-file schema.json
|
|
|
|
# Convert GORM models to Bun
|
|
relspec --input gorm --in-file models.go --output bun --out-file bun_models.go
|
|
```
|
|
|
|
## Supported GORM Tags
|
|
|
|
The reader recognizes the following GORM struct tags:
|
|
|
|
- `column` - Column name
|
|
- `type` - SQL data type (e.g., `varchar(255)`, `bigint`)
|
|
- `primaryKey` or `primary_key` - Mark as primary key
|
|
- `not null` - NOT NULL constraint
|
|
- `autoIncrement` - Auto-increment column
|
|
- `default` - Default value
|
|
- `size` - Column size/length
|
|
- `index` - Create index
|
|
- `uniqueIndex` - Create unique index
|
|
- `unique` - Unique constraint
|
|
- `foreignKey` - Foreign key column
|
|
- `references` - Referenced column
|
|
- `constraint` - Constraint behavior (OnDelete, OnUpdate)
|
|
|
|
## Example GORM Model
|
|
|
|
```go
|
|
package models
|
|
|
|
import (
|
|
"time"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type ModelUser struct {
|
|
gorm.Model
|
|
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement"`
|
|
Username string `gorm:"column:username;type:varchar(50);not null;uniqueIndex"`
|
|
Email string `gorm:"column:email;type:varchar(100);not null"`
|
|
CreatedAt time.Time `gorm:"column:created_at;type:timestamp;not null;default:now()"`
|
|
|
|
// Relationships
|
|
Posts []*ModelPost `gorm:"foreignKey:UserID;references:ID;constraint:OnDelete:CASCADE"`
|
|
}
|
|
|
|
func (ModelUser) TableName() string {
|
|
return "public.users"
|
|
}
|
|
|
|
type ModelPost struct {
|
|
ID int64 `gorm:"column:id;type:bigint;primaryKey"`
|
|
UserID int64 `gorm:"column:user_id;type:bigint;not null"`
|
|
Title string `gorm:"column:title;type:varchar(200);not null"`
|
|
Content string `gorm:"column:content;type:text"`
|
|
|
|
// Belongs-to relationship
|
|
User *ModelUser `gorm:"foreignKey:UserID;references:ID"`
|
|
}
|
|
|
|
func (ModelPost) TableName() string {
|
|
return "public.posts"
|
|
}
|
|
```
|
|
|
|
## Notes
|
|
|
|
- Test files (ending in `_test.go`) are automatically excluded
|
|
- The `gorm.Model` embedded struct is automatically recognized and skipped
|
|
- Table names are derived from struct names if `TableName()` method is not present
|
|
- Schema defaults to `public` if not specified in `TableName()`
|
|
- Relationships are inferred from GORM relationship tags
|
|
|
|
## Limitations
|
|
|
|
- Complex relationship types (many-to-many with join tables) may need manual verification
|
|
- Custom GORM types may not be fully supported
|
|
- Some advanced GORM features may not be captured
|