Files
relspecgo/pkg/readers/gorm
Hein ed7130bba8 refactor(pkg): canonicalize base types and adjust length handling
* Update base types to keep explicit modifier forms
* Modify length handling for vector types in tests
2026-04-26 17:35:15 +02:00
..
2025-12-28 10:34:20 +02:00

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

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

// 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

# 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

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