Skip to content

Instantly share code, notes, and snippets.

@suciuvlad
Created October 27, 2022 09:02
Show Gist options
  • Save suciuvlad/f55e4ecba273f7481204b3108ba955a5 to your computer and use it in GitHub Desktop.
Save suciuvlad/f55e4ecba273f7481204b3108ba955a5 to your computer and use it in GitHub Desktop.
Go Generics Repository
// BonusRepository implements bonus.Repository
// backed by a psql database.
type BonusRepository[M GormModel[E], E any] struct {
GormRepository[M, E]
}
type bonusRepository struct {
db *gorm.DB
}
// NewBonusRepository returns a new BonusRepository instance.
func NewBonusRepository[M GormModel[E], E any](db *gorm.DB) *BonusRepository[M, E] {
return &BonusRepository[M, E]{
GormRepository[M, E](GormRepository[BonusGorm, bonus.Bonus]{
Db: db,
}),
}
}
// BonusGorm represents a Bonus DTO in the psql database.
type BonusGorm struct {
Title string `json:"title"`
Type string `json:"type"`
Metadata datatypes.JSON `json:"metadata"`
}
func (b BonusGorm) ToEntity() bonus.Bonus {
//TODO implement me
panic("implement me")
}
func (b BonusGorm) FromEntity(entity bonus.Bonus) interface{} {
//TODO implement me
panic("implement me")
}
func (r BonusRepository[M, E]) MyCustomMethod() {
}
package psql
import (
"context"
"gorm.io/gorm"
)
type GormModel[E any] interface {
ToEntity() E
FromEntity(entity E) interface{}
}
func NewRepository[M GormModel[E], E any](db *gorm.DB) *GormRepository[M, E] {
return &GormRepository[M, E]{
Db: db,
}
}
type GormRepository[M GormModel[E], E any] struct {
Db *gorm.DB
}
func (r *GormRepository[M, E]) Create(
ctx context.Context,
entity *E,
) error {
var m M
model := m.FromEntity(*entity).(M)
err := r.Db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
if err := tx.Create(model).Error; err != nil {
return err
}
return nil
})
if err != nil {
return err
}
*entity = model.ToEntity()
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment