gpagorm

package module
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2025 License: MIT Imports: 14 Imported by: 2

README

GPAGorm - GORM Adapter for Go Persistence API

A type-safe GORM adapter implementation for the Go Persistence API (GPA), providing compile-time type safety and unified database operations across multiple SQL databases.

Features

  • Type-Safe Operations: Leverages Go generics for compile-time type safety
  • Multi-Database Support: PostgreSQL, MySQL, SQLite, and SQL Server
  • Unified API: Consistent interface across different database drivers
  • Transaction Support: Safe transaction handling with automatic rollback
  • Migration Support: Schema migration and table management
  • Raw SQL Support: Direct SQL execution when needed
  • Relationship Support: Preload relationships with type safety
  • Connection Pooling: Configurable connection pool settings

Supported Databases

  • PostgreSQL (postgres, postgresql)
  • MySQL (mysql)
  • SQLite (sqlite, sqlite3)
  • SQL Server (sqlserver, mssql)

Installation

go get github.com/lemmego/gpagorm

Quick Start

package main

import (
    "context"
    "log"

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

type User struct {
    ID    uint   `gorm:"primaryKey"`
    Name  string `gorm:"size:100"`
    Email string `gorm:"uniqueIndex"`
}

func main() {
    // Configure database connection
    config := gpa.Config{
        Driver:   "postgres",
        Host:     "localhost",
        Port:     5432,
        Database: "myapp",
        Username: "user",
        Password: "password",
    }

    // Create provider
    provider, err := gpagorm.NewProvider(config)
    if err != nil {
        log.Fatal(err)
    }
    defer provider.Close()

    // Get type-safe repository
    userRepo := gpagorm.GetRepository[User](provider)

    // Create user
    user := &User{Name: "John Doe", Email: "john@example.com"}
    err = userRepo.Create(context.Background(), user)
    if err != nil {
        log.Fatal(err)
    }

    // Find user by ID
    foundUser, err := userRepo.FindByID(context.Background(), user.ID)
    if err != nil {
        log.Fatal(err)
    }

    log.Printf("Found user: %+v", foundUser)
}

Configuration

Basic Configuration
config := gpa.Config{
    Driver:   "postgres",
    Host:     "localhost",
    Port:     5432,
    Database: "myapp",
    Username: "user",
    Password: "password",
}
Advanced Configuration
config := gpa.Config{
    Driver:          "postgres",
    Host:            "localhost",
    Port:            5432,
    Database:        "myapp",
    Username:        "user",
    Password:        "password",
    MaxOpenConns:    25,
    MaxIdleConns:    5,
    ConnMaxLifetime: time.Hour,
    ConnMaxIdleTime: time.Minute * 30,
    SSL: gpa.SSLConfig{
        Enabled:  true,
        Mode:     "require",
        CertFile: "/path/to/cert.pem",
        KeyFile:  "/path/to/key.pem",
        CAFile:   "/path/to/ca.pem",
    },
    Options: map[string]interface{}{
        "gorm": map[string]interface{}{
            "log_level":      "info",
            "singular_table": false,
        },
    },
}

API Reference

Repository Operations
// Create operations
err := repo.Create(ctx, entity)
err := repo.CreateBatch(ctx, entities)

// Read operations
entity, err := repo.FindByID(ctx, id)
entities, err := repo.FindAll(ctx, opts...)
entities, err := repo.Query(ctx, opts...)
entity, err := repo.QueryOne(ctx, opts...)

// Update operations
err := repo.Update(ctx, entity)
err := repo.UpdatePartial(ctx, id, updates)

// Delete operations
err := repo.Delete(ctx, id)
err := repo.DeleteByCondition(ctx, condition)

// Aggregation
count, err := repo.Count(ctx, opts...)
exists, err := repo.Exists(ctx, opts...)
Query Options
// Filtering
entities, err := repo.Query(ctx,
    gpa.Where("name", gpa.OpEqual, "John"),
    gpa.Where("age", gpa.OpGreaterThan, 18),
)

// Ordering
entities, err := repo.Query(ctx,
    gpa.OrderBy("name", gpa.ASC),
    gpa.OrderBy("created_at", gpa.DESC),
)

// Pagination
entities, err := repo.Query(ctx,
    gpa.Limit(10),
    gpa.Offset(20),
)

// Field selection
entities, err := repo.Query(ctx,
    gpa.Select("id", "name", "email"),
)

// Preloading relationships
entities, err := repo.FindWithRelations(ctx, []string{"Profile", "Orders"})
Transactions
err := repo.Transaction(ctx, func(txRepo gpa.Transaction[User]) error {
    // All operations within this function are part of the transaction
    user := &User{Name: "Jane", Email: "jane@example.com"}
    if err := txRepo.Create(ctx, user); err != nil {
        return err // Transaction will be rolled back
    }

    // More operations...
    return nil // Transaction will be committed
})
Raw SQL
// Raw query
users, err := repo.RawQuery(ctx, "SELECT * FROM users WHERE age > ?", []interface{}{18})

// Raw execution
result, err := repo.RawExec(ctx, "UPDATE users SET status = ? WHERE active = ?", []interface{}{"verified", true})
Schema Management
// Create table
err := repo.CreateTable(ctx)

// Migrate table
err := repo.MigrateTable(ctx)

// Drop table
err := repo.DropTable(ctx)

// Create index
err := repo.CreateIndex(ctx, []string{"email"}, true) // unique index

// Get table info
info, err := repo.GetTableInfo(ctx)

Error Handling

GPAGorm converts GORM errors to GPA errors for consistent error handling:

user, err := repo.FindByID(ctx, 999)
if err != nil {
    if gpaErr, ok := err.(gpa.GPAError); ok {
        switch gpaErr.Type {
        case gpa.ErrorTypeNotFound:
            log.Println("User not found")
        case gpa.ErrorTypeDuplicate:
            log.Println("Duplicate key violation")
        case gpa.ErrorTypeDatabase:
            log.Println("Database error:", gpaErr.Cause)
        }
    }
}

Testing

Run the test suite:

go test -v

License

This project is licensed under the MIT License - see the LICENSE.md file for details.

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Dependencies

  • GORM - The fantastic ORM library for Golang
  • Go Persistence API - Unified persistence layer for Go
  • Database drivers for PostgreSQL, MySQL, SQLite, and SQL Server

Documentation

Overview

Package gpagorm provides a GORM adapter for the Go Persistence API (GPA)

Package gpagorm provides a GORM adapter for the Go Persistence API (GPA)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetRepository

func GetRepository[T any](instanceName ...string) gpa.Repository[T]

GetRepository returns a type-safe repository for any entity type T If no instanceName provided, uses default instance Usage:

userRepo := gpagorm.GetRepository[User]()           // default
userRepo := gpagorm.GetRepository[User]("primary")  // named

func SupportedDrivers

func SupportedDrivers() []string

SupportedDrivers returns the list of supported database drivers

Types

type Provider

type Provider struct {
	// contains filtered or unexported fields
}

Provider implements gpa.Provider and gpa.SQLProvider using GORM

func NewProvider

func NewProvider(config gpa.Config) (*Provider, error)

NewProvider creates a new GORM provider instance

func (*Provider) BeginTx added in v0.1.1

func (p *Provider) BeginTx(ctx context.Context, opts *gpa.TxOptions) (interface{}, error)

BeginTx starts a transaction with specific isolation level

func (*Provider) Close

func (p *Provider) Close() error

Close closes the database connection

func (*Provider) Configure

func (p *Provider) Configure(config gpa.Config) error

Configure applies configuration to the provider

func (*Provider) DB added in v0.1.1

func (p *Provider) DB() interface{}

DB returns the underlying database/sql.DB instance

func (*Provider) Health

func (p *Provider) Health() error

Health checks the database connection health

func (*Provider) Migrate added in v0.1.1

func (p *Provider) Migrate(models ...interface{}) error

Migrate runs database migrations

func (*Provider) ProviderInfo

func (p *Provider) ProviderInfo() gpa.ProviderInfo

ProviderInfo returns information about this provider

func (*Provider) RawExec added in v0.1.1

func (p *Provider) RawExec(ctx context.Context, query string, args ...interface{}) (gpa.Result, error)

RawExec executes raw SQL without returning results

func (*Provider) RawQuery added in v0.1.1

func (p *Provider) RawQuery(ctx context.Context, query string, args ...interface{}) (interface{}, error)

RawQuery executes raw SQL and returns results

func (*Provider) SupportedFeatures

func (p *Provider) SupportedFeatures() []gpa.Feature

SupportedFeatures returns the list of supported features

type Repository

type Repository[T any] struct {
	// contains filtered or unexported fields
}

Repository implements type-safe GORM operations using Go generics. Provides compile-time type safety for all CRUD and SQL operations.

func NewRepository

func NewRepository[T any](db *gorm.DB, provider *Provider) *Repository[T]

NewRepository creates a new generic GORM repository for type T. Example: userRepo := NewRepository[User](db, provider)

func (*Repository[T]) Close

func (r *Repository[T]) Close() error

Close closes the repository (no-op for GORM).

func (*Repository[T]) Count

func (r *Repository[T]) Count(ctx context.Context, opts ...gpa.QueryOption) (int64, error)

Count returns the number of entities matching query options.

func (*Repository[T]) Create

func (r *Repository[T]) Create(ctx context.Context, entity *T) error

Create inserts a new entity with compile-time type safety.

func (*Repository[T]) CreateBatch

func (r *Repository[T]) CreateBatch(ctx context.Context, entities []*T) error

CreateBatch inserts multiple entities with compile-time type safety.

func (*Repository[T]) CreateIndex

func (r *Repository[T]) CreateIndex(ctx context.Context, fields []string, unique bool) error

CreateIndex creates an index on the specified fields.

func (*Repository[T]) CreateTable

func (r *Repository[T]) CreateTable(ctx context.Context) error

CreateTable creates a new table for entity type T.

func (*Repository[T]) Delete

func (r *Repository[T]) Delete(ctx context.Context, id interface{}) error

Delete removes an entity by ID with compile-time type safety.

func (*Repository[T]) DeleteByCondition

func (r *Repository[T]) DeleteByCondition(ctx context.Context, condition gpa.Condition) error

DeleteByCondition removes entities matching a condition.

func (*Repository[T]) DropIndex

func (r *Repository[T]) DropIndex(ctx context.Context, indexName string) error

DropIndex removes an index.

func (*Repository[T]) DropTable

func (r *Repository[T]) DropTable(ctx context.Context) error

DropTable drops the table for entity type T.

func (*Repository[T]) ExecSQL

func (r *Repository[T]) ExecSQL(ctx context.Context, sql string, args ...interface{}) (gpa.Result, error)

ExecSQL executes a raw SQL statement.

func (*Repository[T]) Exists

func (r *Repository[T]) Exists(ctx context.Context, opts ...gpa.QueryOption) (bool, error)

Exists checks if any entity matches the query options.

func (*Repository[T]) FindAll

func (r *Repository[T]) FindAll(ctx context.Context, opts ...gpa.QueryOption) ([]*T, error)

FindAll retrieves all entities with compile-time type safety.

func (*Repository[T]) FindByID

func (r *Repository[T]) FindByID(ctx context.Context, id interface{}) (*T, error)

FindByID retrieves a single entity by ID with compile-time type safety.

func (*Repository[T]) FindByIDWithRelations

func (r *Repository[T]) FindByIDWithRelations(ctx context.Context, id interface{}, relations []string) (*T, error)

FindByIDWithRelations retrieves an entity by ID with preloaded relationships.

func (*Repository[T]) FindBySQL

func (r *Repository[T]) FindBySQL(ctx context.Context, sql string, args []interface{}) ([]*T, error)

FindBySQL executes a raw SQL SELECT query with compile-time type safety.

func (*Repository[T]) FindWithRelations

func (r *Repository[T]) FindWithRelations(ctx context.Context, relations []string, opts ...gpa.QueryOption) ([]*T, error)

FindWithRelations retrieves entities with preloaded relationships.

func (*Repository[T]) GetEntityInfo

func (r *Repository[T]) GetEntityInfo() (*gpa.EntityInfo, error)

GetEntityInfo returns metadata about entity type T.

func (*Repository[T]) GetMigrationStatus

func (r *Repository[T]) GetMigrationStatus(ctx context.Context) (gpa.MigrationStatus, error)

GetMigrationStatus returns the current migration status for entity type T.

func (*Repository[T]) GetTableInfo

func (r *Repository[T]) GetTableInfo(ctx context.Context) (gpa.TableInfo, error)

GetTableInfo returns detailed information about the current table structure.

func (*Repository[T]) MigrateTable

func (r *Repository[T]) MigrateTable(ctx context.Context) error

MigrateTable migrates the table schema for entity type T.

func (*Repository[T]) Query

func (r *Repository[T]) Query(ctx context.Context, opts ...gpa.QueryOption) ([]*T, error)

Query retrieves entities based on query options with compile-time type safety.

func (*Repository[T]) QueryOne

func (r *Repository[T]) QueryOne(ctx context.Context, opts ...gpa.QueryOption) (*T, error)

QueryOne retrieves a single entity based on query options.

func (*Repository[T]) RawExec

func (r *Repository[T]) RawExec(ctx context.Context, query string, args []interface{}) (gpa.Result, error)

RawExec executes a raw SQL statement.

func (*Repository[T]) RawQuery

func (r *Repository[T]) RawQuery(ctx context.Context, query string, args []interface{}) ([]*T, error)

RawQuery executes a raw SQL query with compile-time type safety.

func (*Repository[T]) Transaction

func (r *Repository[T]) Transaction(ctx context.Context, fn gpa.TransactionFunc[T]) error

Transaction executes a function within a transaction with type safety.

func (*Repository[T]) Update

func (r *Repository[T]) Update(ctx context.Context, entity *T) error

Update modifies an existing entity with compile-time type safety.

func (*Repository[T]) UpdatePartial

func (r *Repository[T]) UpdatePartial(ctx context.Context, id interface{}, updates map[string]interface{}) error

UpdatePartial modifies specific fields of an entity.

type SQLResult

type SQLResult struct {
	// contains filtered or unexported fields
}

SQLResult implements gpa.Result interface

func (*SQLResult) LastInsertId

func (r *SQLResult) LastInsertId() (int64, error)

LastInsertId returns the last insert ID

func (*SQLResult) RowsAffected

func (r *SQLResult) RowsAffected() (int64, error)

RowsAffected returns the number of rows affected

type Transaction

type Transaction[T any] struct {
	*Repository[T]
}

TransactionG implements gpa.TransactionG using GORM with type safety.

func (*Transaction[T]) Commit

func (t *Transaction[T]) Commit() error

Commit commits the transaction (handled automatically by GORM).

func (*Transaction[T]) Rollback

func (t *Transaction[T]) Rollback() error

Rollback rolls back the transaction (handled automatically by GORM).

func (*Transaction[T]) RollbackToSavepoint

func (t *Transaction[T]) RollbackToSavepoint(name string) error

RollbackToSavepoint rolls back to a previously created savepoint.

func (*Transaction[T]) SetSavepoint

func (t *Transaction[T]) SetSavepoint(name string) error

SetSavepoint creates a savepoint within the transaction.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL