ResolveSpec/pkg/resolvespec/gorm_adapter.go

282 lines
6.7 KiB
Go

package resolvespec
import (
"context"
"gorm.io/gorm"
)
// GormAdapter adapts GORM to work with our Database interface
type GormAdapter struct {
db *gorm.DB
}
// NewGormAdapter creates a new GORM adapter
func NewGormAdapter(db *gorm.DB) *GormAdapter {
return &GormAdapter{db: db}
}
func (g *GormAdapter) NewSelect() SelectQuery {
return &GormSelectQuery{db: g.db}
}
func (g *GormAdapter) NewInsert() InsertQuery {
return &GormInsertQuery{db: g.db}
}
func (g *GormAdapter) NewUpdate() UpdateQuery {
return &GormUpdateQuery{db: g.db}
}
func (g *GormAdapter) NewDelete() DeleteQuery {
return &GormDeleteQuery{db: g.db}
}
func (g *GormAdapter) Exec(ctx context.Context, query string, args ...interface{}) (Result, error) {
result := g.db.WithContext(ctx).Exec(query, args...)
return &GormResult{result: result}, result.Error
}
func (g *GormAdapter) Query(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
return g.db.WithContext(ctx).Raw(query, args...).Find(dest).Error
}
func (g *GormAdapter) BeginTx(ctx context.Context) (Database, error) {
tx := g.db.WithContext(ctx).Begin()
if tx.Error != nil {
return nil, tx.Error
}
return &GormAdapter{db: tx}, nil
}
func (g *GormAdapter) CommitTx(ctx context.Context) error {
return g.db.WithContext(ctx).Commit().Error
}
func (g *GormAdapter) RollbackTx(ctx context.Context) error {
return g.db.WithContext(ctx).Rollback().Error
}
func (g *GormAdapter) RunInTransaction(ctx context.Context, fn func(Database) error) error {
return g.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
adapter := &GormAdapter{db: tx}
return fn(adapter)
})
}
// GormSelectQuery implements SelectQuery for GORM
type GormSelectQuery struct {
db *gorm.DB
}
func (g *GormSelectQuery) Model(model interface{}) SelectQuery {
g.db = g.db.Model(model)
return g
}
func (g *GormSelectQuery) Table(table string) SelectQuery {
g.db = g.db.Table(table)
return g
}
func (g *GormSelectQuery) Column(columns ...string) SelectQuery {
g.db = g.db.Select(columns)
return g
}
func (g *GormSelectQuery) Where(query string, args ...interface{}) SelectQuery {
g.db = g.db.Where(query, args...)
return g
}
func (g *GormSelectQuery) WhereOr(query string, args ...interface{}) SelectQuery {
g.db = g.db.Or(query, args...)
return g
}
func (g *GormSelectQuery) Join(query string, args ...interface{}) SelectQuery {
g.db = g.db.Joins(query, args...)
return g
}
func (g *GormSelectQuery) LeftJoin(query string, args ...interface{}) SelectQuery {
g.db = g.db.Joins("LEFT JOIN "+query, args...)
return g
}
func (g *GormSelectQuery) Order(order string) SelectQuery {
g.db = g.db.Order(order)
return g
}
func (g *GormSelectQuery) Limit(n int) SelectQuery {
g.db = g.db.Limit(n)
return g
}
func (g *GormSelectQuery) Offset(n int) SelectQuery {
g.db = g.db.Offset(n)
return g
}
func (g *GormSelectQuery) Group(group string) SelectQuery {
g.db = g.db.Group(group)
return g
}
func (g *GormSelectQuery) Having(having string, args ...interface{}) SelectQuery {
g.db = g.db.Having(having, args...)
return g
}
func (g *GormSelectQuery) Scan(ctx context.Context, dest interface{}) error {
return g.db.WithContext(ctx).Find(dest).Error
}
func (g *GormSelectQuery) Count(ctx context.Context) (int, error) {
var count int64
err := g.db.WithContext(ctx).Count(&count).Error
return int(count), err
}
func (g *GormSelectQuery) Exists(ctx context.Context) (bool, error) {
var count int64
err := g.db.WithContext(ctx).Limit(1).Count(&count).Error
return count > 0, err
}
// GormInsertQuery implements InsertQuery for GORM
type GormInsertQuery struct {
db *gorm.DB
model interface{}
values map[string]interface{}
}
func (g *GormInsertQuery) Model(model interface{}) InsertQuery {
g.model = model
g.db = g.db.Model(model)
return g
}
func (g *GormInsertQuery) Table(table string) InsertQuery {
g.db = g.db.Table(table)
return g
}
func (g *GormInsertQuery) Value(column string, value interface{}) InsertQuery {
if g.values == nil {
g.values = make(map[string]interface{})
}
g.values[column] = value
return g
}
func (g *GormInsertQuery) OnConflict(action string) InsertQuery {
// GORM handles conflicts differently, this would need specific implementation
return g
}
func (g *GormInsertQuery) Returning(columns ...string) InsertQuery {
// GORM doesn't have explicit RETURNING, but updates the model
return g
}
func (g *GormInsertQuery) Exec(ctx context.Context) (Result, error) {
var result *gorm.DB
if g.model != nil {
result = g.db.WithContext(ctx).Create(g.model)
} else if g.values != nil {
result = g.db.WithContext(ctx).Create(g.values)
} else {
result = g.db.WithContext(ctx).Create(map[string]interface{}{})
}
return &GormResult{result: result}, result.Error
}
// GormUpdateQuery implements UpdateQuery for GORM
type GormUpdateQuery struct {
db *gorm.DB
model interface{}
updates interface{}
}
func (g *GormUpdateQuery) Model(model interface{}) UpdateQuery {
g.model = model
g.db = g.db.Model(model)
return g
}
func (g *GormUpdateQuery) Table(table string) UpdateQuery {
g.db = g.db.Table(table)
return g
}
func (g *GormUpdateQuery) Set(column string, value interface{}) UpdateQuery {
if g.updates == nil {
g.updates = make(map[string]interface{})
}
if updates, ok := g.updates.(map[string]interface{}); ok {
updates[column] = value
}
return g
}
func (g *GormUpdateQuery) SetMap(values map[string]interface{}) UpdateQuery {
g.updates = values
return g
}
func (g *GormUpdateQuery) Where(query string, args ...interface{}) UpdateQuery {
g.db = g.db.Where(query, args...)
return g
}
func (g *GormUpdateQuery) Returning(columns ...string) UpdateQuery {
// GORM doesn't have explicit RETURNING
return g
}
func (g *GormUpdateQuery) Exec(ctx context.Context) (Result, error) {
result := g.db.WithContext(ctx).Updates(g.updates)
return &GormResult{result: result}, result.Error
}
// GormDeleteQuery implements DeleteQuery for GORM
type GormDeleteQuery struct {
db *gorm.DB
model interface{}
}
func (g *GormDeleteQuery) Model(model interface{}) DeleteQuery {
g.model = model
g.db = g.db.Model(model)
return g
}
func (g *GormDeleteQuery) Table(table string) DeleteQuery {
g.db = g.db.Table(table)
return g
}
func (g *GormDeleteQuery) Where(query string, args ...interface{}) DeleteQuery {
g.db = g.db.Where(query, args...)
return g
}
func (g *GormDeleteQuery) Exec(ctx context.Context) (Result, error) {
result := g.db.WithContext(ctx).Delete(g.model)
return &GormResult{result: result}, result.Error
}
// GormResult implements Result for GORM
type GormResult struct {
result *gorm.DB
}
func (g *GormResult) RowsAffected() int64 {
return g.result.RowsAffected
}
func (g *GormResult) LastInsertId() (int64, error) {
// GORM doesn't directly provide last insert ID, would need specific implementation
return 0, nil
}