Go'da Generic Method nasıl oluşturulur?

BeecoV

Megapat
Katılım
18 Mayıs 2015
Mesajlar
207
Çözümler
2
Merhabalar,

Golang'de, GORM metodlarını Database.go'da hazırladım ve generic olmasını istiyorum. Bunu yapmamın nedeni tekrarlanan kodlardan kaçınmak. Sık kullanılan işlemleri aşağıdaki gibi hazırladım:

Kod:
package database

import (
    "context"
    "fmt"
    "go-microservice/internal/constants"
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
    "gorm.io/gorm/schema"
    "time"
)

type DbOperations[T any] interface {
    Ready() bool
    GetAll(ctx context.Context) ([]T, error)
    GetByParam(ctx context.Context, param any) (any, error)
    Create(ctx context.Context, data any) error
    Update(ctx context.Context, data any) error
    Delete(ctx context.Context, model any, param any) error
}

type DbConnection[T any] struct {
    DB *gorm.DB
}

func NewDatabaseConnection[T any]() DbConnection[T] {
    dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s",
        constants.Host,
        constants.User,
        constants.Password,
        constants.Dbname,
        constants.Port,
        constants.SSLMode)

    db, _ := gorm.Open(postgres.Open(dsn), &gorm.Config{
        NamingStrategy: schema.NamingStrategy{
            TablePrefix: "wisdom.",
        },
        NowFunc: func() time.Time {
            return time.Now().UTC()
        },
        QueryFields: true})

    return DbConnection[T]{DB: db}
}

func (db *DbConnection[T]) Ready() bool {
    var ready string
    tx := db.DB.Raw("SELECT 1 as ready").Scan(&ready)
    if tx.Error != nil {
        return false
    }
    if ready == "1" {
        return true
    }
    return false
}

func (db *DbConnection[T]) GetAll(ctx context.Context) ([]T, error) {
    list := make([]T, 0)
    result := db.DB.WithContext(ctx).Find(&list)
    return list, result.Error
}

func (db *DbConnection[T]) GetByParam(ctx context.Context, param any) (any, error) {
    var model any
    result := db.DB.WithContext(ctx).Where(param).Find(&model)
    return model, result.Error
}

func (db *DbConnection[T]) Create(ctx context.Context, data any) error {
    result := db.DB.WithContext(ctx).Create(data)
    return result.Error
}

func (db *DbConnection[T]) Update(ctx context.Context, data any) error {
    result := db.DB.WithContext(ctx).Model(data)
    return result.Error
}

func (db *DbConnection[T]) Delete(ctx context.Context, model any, param any) error {
    result := db.DB.WithContext(ctx).Delete(model, param)
    return result.Error
}

Bu metodları kullanmak istediğimde, mesela db_products.go'da metodu çekip kullanmak istiyorum, IDE tarafında hata alıyorum. db_products.go kodları aşağıdaki gibi:
Kod:
package database

import (
    "context"
    "go-microservice/internal/models"
)

type ProductOperations interface {
    GetAllProducts(ctx context.Context) ([]models.Products, error)
}

func (db *DbConnection[T]) GetAllProducts(ctx context.Context) ([]models.Products, error) {
    var re []models.Products
    re, _ = db.GetAll(ctx)
    return re, nil
}

Aldığım hata Cannot assign []T to re (type []models.Products) in multiple assignment şeklinde. Bu hatayı nasıl çözebilirim? Yeni bir Slice oluşturup for ile içerisine append etmeyi de denedim fakat olmadı. Zaten öyle bir yöntem de istemiyorum. Belirttiğim bu yapıyı nasıl kurabilirim? Teşekkürler.
 
Bu siteyi kullanmak için çerezler gereklidir. Siteyi kullanmaya devam etmek için çerezleri kabul etmelisiniz. Daha Fazlasını Öğren.…