Skip to content

yyle88/gormrepo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

65 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

GitHub Workflow Status (branch) GoDoc Coverage Status Supported Go Versions GitHub Release Go Report Card

πŸš€ GORM Ecosystem - Enterprise-Grade Type-Safe Database Operations

gormrepo is the centerpiece of a complete GORM ecosystem, delivering type-safe, enterprise-grade, and quite efficient database operations to Go developers.

🌟 Combining the best of Java MyBatis Plus + Python SQLAlchemy, designed with Go's next-generation ORM toolchain


Ecosystem

GORM Type-Safe Ecosystem


CHINESE README

δΈ­ζ–‡θ―΄ζ˜Ž


πŸ”„ Tech Comparison

Ecosystem Java MyBatis Plus Python SQLAlchemy Go GORM Ecosystem
Type-Safe Columns Example::getName Example.name cls.Name.Eq()
Code Generation βœ… Plugin support βœ… Reflection βœ… AST precision
Repo Pattern βœ… BaseMapper βœ… Session API βœ… GormRepo
Native Language 🟑 Limited 🟑 Limited βœ… Complete support

πŸš€ Quick Start

Installation

go get github.com/yyle88/gormrepo

Complete Usage Flow

1. Define The Model (Supporting Native Fields)

type Account struct {
    ID       uint   `gorm:"primaryKey"`
    Accountname string `gorm:"uniqueIndex" cnm:"accountname"` 
    Nickname string `gorm:"index" cnm:"nickname"`
    Age      int    `cnm:"age"`
}

2. Auto-Generate Column Structs (gormcngen)

// Auto-generated
func (*Account) Columns() *AccountColumns {
    return &AccountColumns{
        ID:       "id",
        Accountname: "accountname",
        Nickname: "nickname",
        Age:      "age",
    }
}

type AccountColumns struct {
    ID       gormcnm.ColumnName[uint]
    Accountname gormcnm.ColumnName[string]
    Nickname gormcnm.ColumnName[string]
    Age      gormcnm.ColumnName[int]
}

3. Create Repo

repo := gormrepo.NewRepo(&Account{}, (&Account{}).Columns())

4. How to Select

// Classic GORM
err := db.Where("name = ?", "alice").First(&account).Error

// gormrepo - First
account, err := repo.With(ctx, db).First(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.Accountname.Eq("alice"))
})

// gormrepo - FirstE (returns ErrorOrNotExist)
account, erb := repo.With(ctx, db).FirstE(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.Accountname.Eq("alice"))
})

// gormrepo - Find
accounts, err := repo.With(ctx, db).Find(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.Age.Gte(18))
})

// gormrepo - FindPage
accounts, err := repo.With(ctx, db).FindPage(
    func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
        return db.Where(cls.Age.Gte(18))
    },
    func(cls *AccountColumns) gormcnm.OrderByBottle {
        return cls.ID.OrderByBottle("DESC")
    },
    &gormrepo.Pagination{Limit: 10, Offset: 0},
)

// gormrepo - FindPageAndCount
accounts, count, err := repo.With(ctx, db).FindPageAndCount(
    func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
        return db.Where(cls.Age.Between(18, 65))
    },
    func(cls *AccountColumns) gormcnm.OrderByBottle {
        return cls.ID.OrderByBottle("DESC")
    },
    &gormrepo.Pagination{Limit: 10, Offset: 0},
)

// gormrepo - Count
count, err := repo.With(ctx, db).Count(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.Age.Gte(18))
})

// gormrepo - Exist
exist, err := repo.With(ctx, db).Exist(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.Accountname.Eq("alice"))
})

// gormrepo - Where conditions: Eq, Ne, Gt, Lt, Gte, Lte
accounts, err := repo.With(ctx, db).Find(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.Age.Gt(18)).    // age > 18
              Where(cls.Age.Lt(60)).    // age < 60
              Where(cls.Age.Ne(30))     // age != 30
})

// gormrepo - Like / NotLike
accounts, err := repo.With(ctx, db).Find(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.Nickname.Like("%test%")).
              Where(cls.Accountname.NotLike("%admin%"))
})

// gormrepo - In / NotIn
accounts, err := repo.With(ctx, db).Find(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.ID.In([]uint{1, 2, 3})).
              Where(cls.Age.NotIn([]int{18, 19, 20}))
})

// gormrepo - Between / NotBetween
accounts, err := repo.With(ctx, db).Find(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.Age.Between(20, 40)).
              Where(cls.ID.NotBetween(100, 200))
})

// gormrepo - IsNull / IsNotNull
accounts, err := repo.With(ctx, db).Find(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.Nickname.IsNotNull())
})

// gormrepo - Or conditions
accounts, err := repo.With(ctx, db).Find(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.Age.Gte(18)).
              Or(cls.Nickname.Eq("vip"))
})

// gormrepo - Order / Select
accounts, err := repo.With(ctx, db).Find(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.Age.Gte(18)).
              Order(cls.Age.Name() + " DESC").
              Select(cls.ID.Name(), cls.Accountname.Name())
})

Select Operations

Method Parameters Returns Description
First where func(db *gorm.DB, cls CLS) *gorm.DB *MOD, error Find first matching record
FirstE where func(db *gorm.DB, cls CLS) *gorm.DB *MOD, *ErrorOrNotExist Find first or not-exist indication
Find where func(db *gorm.DB, cls CLS) *gorm.DB []*MOD, error Find each matching records
FindPage where, ordering, pagination []*MOD, error Paginated search
FindPageAndCount where, ordering, pagination []*MOD, int64, error Paginated search with record count
Count where func(db *gorm.DB, cls CLS) *gorm.DB int64, error Count matching records
Exist where func(db *gorm.DB, cls CLS) *gorm.DB bool, error Check if records exist

5. How to Create

// Classic GORM
err := db.Create(&Account{Accountname: "bob", Nickname: "Bob", Age: 25}).Error

// gormrepo
err := repo.With(ctx, db).Create(&Account{Accountname: "bob", Nickname: "Bob", Age: 25})

Create Operations

Method Parameters Returns Description
Create one *MOD error Create new record
Save one *MOD error Insert/update record

6. How to Update

// Classic GORM
err := db.Model(&Account{}).Where("id = ?", 1).Updates(map[string]interface{}{"age": 26}).Error

// gormrepo - Updates
err := repo.With(ctx, db).Updates(
    func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
        return db.Where(cls.ID.Eq(1))
    },
    func(cls *AccountColumns) map[string]interface{} {
        return cls.Kw(cls.Age.Kv(26)).
                  Kw(cls.Nickname.Kv("NewNick")).
                  AsMap()
    },
)

// gormrepo - UpdatesM (using ColumnValueMap)
err := repo.With(ctx, db).UpdatesM(
    func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
        return db.Where(cls.ID.Eq(1))
    },
    func(cls *AccountColumns) *gormcnm.ColumnValueMap {
        return cls.Kw(cls.Age.Kv(26)).
                  Kw(cls.Nickname.Kv("NewNick"))
    },
)

// gormrepo - UpdatesO (by primary key)
account := &Account{ID: 1}
err := repo.With(ctx, db).UpdatesO(account, func(cls *AccountColumns) *gormcnm.ColumnValueMap {
    return cls.Kw(cls.Age.Kv(26))
})

// gormrepo - UpdatesC (combined conditions)
account := &Account{ID: 1}
err := repo.With(ctx, db).UpdatesC(account,
    func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
        return db.Where(cls.Age.Lt(30))
    },
    func(cls *AccountColumns) *gormcnm.ColumnValueMap {
        return cls.Kw(cls.Age.Kv(26))
    },
)

Update Operations

Method Parameters Returns Description
Update where, valueFunc error Update single field
Updates where, mapValues error Update multiple fields
UpdatesM where, newValues error Update with ColumnValueMap (M=Map)
UpdatesO object, newValues error Update via primary key (O=Object)
UpdatesC object, where, newValues error Update with combined conditions (C=Combined)

7. How to Delete

// Classic GORM
err := db.Where("id = ?", 1).Delete(&Account{}).Error

// gormrepo - Delete (by instance)
account := &Account{ID: 1}
err := repo.With(ctx, db).Delete(account)

// gormrepo - DeleteW (by where conditions)
err := repo.With(ctx, db).DeleteW(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.ID.Eq(1))
})

// gormrepo - DeleteM (instance + conditions)
account := &Account{ID: 1}
err := repo.With(ctx, db).DeleteM(account, func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.Age.Lt(30))
})

Delete Operations

Method Parameters Returns Description
Delete one *MOD error Delete record via instance
DeleteW where func(db *gorm.DB, cls CLS) *gorm.DB error Delete via conditions
DeleteM one *MOD, where func(db *gorm.DB, cls CLS) *gorm.DB error Delete item with conditions

8. Custom Operations

When above methods do not fit, use Invoke:

// Invoke - batch update
err := repo.With(ctx, db).Invoke(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.Age.Gte(18)).Update(cls.Nickname.Name(), "adult")
})

// Invoke - increment field
err := repo.With(ctx, db).Invoke(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.ID.Eq(1)).
        Update(cls.Age.Name(), gorm.Expr(cls.Age.Name()+" + ?", 1))
})

// Invoke - select specific columns
var names []string
err := repo.With(ctx, db).Invoke(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.Age.Gte(18)).Pluck(cls.Accountname.Name(), &names)
})

// Invoke - complex conditions
err := repo.With(ctx, db).Invoke(func(db *gorm.DB, cls *AccountColumns) *gorm.DB {
    return db.Where(cls.Age.Between(18, 60)).
        Where(cls.Nickname.IsNotNull()).
        Updates(map[string]interface{}{
            cls.Nickname.Name(): "active",
        })
})

Invoke Operations

Method Parameters Returns Description
Invoke clsRun func(db *gorm.DB, cls CLS) *gorm.DB error Execute custom operation

πŸ“ Complete Examples

Check examples DIR with complete integration examples.


Related Projects

Explore the complete GORM ecosystem with these integrated packages:

Core Ecosystem

  • gormcnm - GORM foundation providing type-safe column queries operations
  • gormcngen - Code generation engine using AST, enables type-safe GORM operations
  • gormrepo - Repo pattern implementation with GORM best practices (this project)
  • gormmom - Native language GORM tag generation engine with smart column naming
  • gormzhcn - Complete Chinese programming interface with GORM

Each package targets different aspects of GORM development, from localization to type-safe operations and code generation.


πŸ“„ License

MIT License - see LICENSE.


πŸ’¬ Contact & Feedback

Contributions are welcome! Report bugs, suggest features, and contribute code:

  • πŸ› Mistake reports? Open an issue on GitHub with reproduction steps
  • πŸ’‘ Fresh ideas? Create an issue to discuss
  • πŸ“– Documentation confusing? Report it so we can improve
  • πŸš€ Need new features? Share the use cases to help us understand requirements
  • ⚑ Performance issue? Help us optimize through reporting slow operations
  • πŸ”§ Configuration problem? Ask questions about complex setups
  • πŸ“’ Follow project progress? Watch the repo to get new releases and features
  • 🌟 Success stories? Share how this package improved the workflow
  • πŸ’¬ Feedback? We welcome suggestions and comments

πŸ”§ Development

New code contributions, follow this process:

  1. Fork: Fork the repo on GitHub (using the webpage UI).
  2. Clone: Clone the forked project (git clone https://github.com/yourname/repo-name.git).
  3. Navigate: Navigate to the cloned project (cd repo-name)
  4. Branch: Create a feature branch (git checkout -b feature/xxx).
  5. Code: Implement the changes with comprehensive tests
  6. Testing: (Golang project) Ensure tests pass (go test ./...) and follow Go code style conventions
  7. Documentation: Update documentation to support client-facing changes
  8. Stage: Stage changes (git add .)
  9. Commit: Commit changes (git commit -m "Add feature xxx") ensuring backward compatible code
  10. Push: Push to the branch (git push origin feature/xxx).
  11. PR: Open a merge request on GitHub (on the GitHub webpage) with detailed description.

Please ensure tests pass and include relevant documentation updates.


🌟 Support

Welcome to contribute to this project via submitting merge requests and reporting issues.

Project Support:

  • ⭐ Give GitHub stars if this project helps you
  • 🀝 Share with teammates and (golang) programming friends
  • πŸ“ Write tech blogs about development tools and workflows - we provide content writing support
  • 🌟 Join the ecosystem - committed to supporting open source and the (golang) development scene

Have Fun Coding with this package! πŸŽ‰πŸŽ‰πŸŽ‰


πŸ“ˆ GitHub Stars

Stargazers

About

gormrepo - Provides simple CRUD operations, simplifying GORM usage

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •