Skip to content

GORM Provider

Overview

The GORM provider (github.com/lemmego/gpagorm) is the production-ready SQL provider. It wraps GORM to provide the full GPA Repository[T] interface with migration support.

Setup

import (
    "github.com/lemmego/gpa"
    "github.com/lemmego/gpagorm"
)

config := gpa.Config{
    Driver:   "postgres",
    Host:     "localhost",
    Port:     5432,
    Username: "user",
    Password: "password",
    Database: "mydb",
}

provider, err := gpagorm.NewProvider(config)

Supported Drivers

  • PostgreSQL
  • MySQL
  • SQLite
  • SQL Server / MSSQL

Connection Pooling

GORM connection pooling is configured through the Config:

config := gpa.Config{
    Driver:        "mysql",
    MaxOpenConns:  25,
    MaxIdleConns:  10,
    ConnMaxLifetime: 5 * time.Minute,
    Options: map[string]interface{}{
        "gorm": map[string]interface{}{
            "log_level": "info",
            "singular_table": true,
        },
    },
}

Creating Repositories

// From the registry (auto-resolves the "default" GORM provider)
userRepo := gpagorm.GetRepository[User]()

// From a specific provider instance
userRepo := gpagorm.GetRepository[User](provider)

// From a named registry instance
userRepo := gpagorm.GetRepository[User]("primary")

Repository Type

The GORM repository implements gpa.MigratableRepository[T], which includes:

  • Full Repository[T] CRUD
  • SQLRepository[T] (raw SQL, DDL, eager loading)
  • MigratableRepository[T] (auto-migration, migration status, table info)
// Pattern with typed wrapper
type UserRepository struct {
    gpa.MigratableRepository[User]
}

func NewUserRepository() *UserRepository {
    repo := gpagorm.GetRepository[User]()
    return &UserRepository{repo}
}

Hooks

The GORM provider supports all GPA entity hooks:

type User struct {
    ID        uint
    Name      string
    Email     string
    CreatedAt time.Time
    UpdatedAt time.Time
}

func (u *User) Validate(ctx context.Context) error {
    if u.Email == "" {
        return gpa.NewError(gpa.ErrorTypeValidation, "email required")
    }
    return nil
}

func (u *User) BeforeCreate(ctx context.Context) error {
    u.Email = strings.ToLower(u.Email)
    u.CreatedAt = time.Now()
    u.UpdatedAt = time.Now()
    return nil
}

func (u *User) AfterFind(ctx context.Context) error {
    // Post-load processing
    return nil
}

Hook execution order: ValidateBeforeCreate → DB Insert → AfterCreate

Features

FeatureSupport
Transactions + SavepointsYes
Raw SQLYes
Eager LoadingYes (Preload, FindWithRelations)
Auto MigrationYes (AutoMigrate, MigrateTable)
Index ManagementYes (CreateIndex, DropIndex)
Batch OperationsYes (CreateBatch with size 100)
SQL Injection ProtectionYes (regex-based field validation)
Error MappingYes (GORM errors → GPA typed errors)