add filtering and base repository
This commit is contained in:
@@ -2,35 +2,16 @@ package repository
|
||||
|
||||
import (
|
||||
"acc-server-manager/local/model"
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ApiRepository struct {
|
||||
db *gorm.DB
|
||||
*BaseRepository[model.ApiModel, model.ApiFilter]
|
||||
}
|
||||
|
||||
func NewApiRepository(db *gorm.DB) *ApiRepository {
|
||||
return &ApiRepository{
|
||||
db: db,
|
||||
BaseRepository: NewBaseRepository[model.ApiModel, model.ApiFilter](db, model.ApiModel{}),
|
||||
}
|
||||
}
|
||||
|
||||
// GetFirst
|
||||
// Gets first row from API table.
|
||||
//
|
||||
// Args:
|
||||
// context.Context: Application context
|
||||
// Returns:
|
||||
// model.ApiModel: Api object from database.
|
||||
func (as ApiRepository) GetFirst(ctx context.Context) *model.ApiModel {
|
||||
db := as.db.WithContext(ctx)
|
||||
apiModel := new(model.ApiModel)
|
||||
result := db.First(&apiModel)
|
||||
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||
return nil
|
||||
}
|
||||
return apiModel
|
||||
}
|
||||
|
||||
121
local/repository/base.go
Normal file
121
local/repository/base.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// BaseRepository provides generic CRUD operations for any model
|
||||
type BaseRepository[T any, F any] struct {
|
||||
db *gorm.DB
|
||||
modelType T
|
||||
}
|
||||
|
||||
// NewBaseRepository creates a new base repository for the given model type
|
||||
func NewBaseRepository[T any, F any](db *gorm.DB, model T) *BaseRepository[T, F] {
|
||||
return &BaseRepository[T, F]{
|
||||
db: db,
|
||||
modelType: model,
|
||||
}
|
||||
}
|
||||
|
||||
// GetAll retrieves all records based on the filter
|
||||
func (r *BaseRepository[T, F]) GetAll(ctx context.Context, filter *F) (*[]T, error) {
|
||||
result := new([]T)
|
||||
query := r.db.WithContext(ctx).Model(&r.modelType)
|
||||
|
||||
// Apply filter conditions if filter implements Filterable
|
||||
if filterable, ok := any(filter).(Filterable); ok {
|
||||
query = filterable.ApplyFilter(query)
|
||||
}
|
||||
|
||||
// Apply pagination if filter implements Pageable
|
||||
if pageable, ok := any(filter).(Pageable); ok {
|
||||
offset, limit := pageable.Pagination()
|
||||
query = query.Offset(offset).Limit(limit)
|
||||
}
|
||||
|
||||
// Apply sorting if filter implements Sortable
|
||||
if sortable, ok := any(filter).(Sortable); ok {
|
||||
field, desc := sortable.GetSorting()
|
||||
if desc {
|
||||
query = query.Order(field + " DESC")
|
||||
} else {
|
||||
query = query.Order(field)
|
||||
}
|
||||
}
|
||||
|
||||
if err := query.Find(result).Error; err != nil {
|
||||
return nil, fmt.Errorf("error getting records: %w", err)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetByID retrieves a single record by ID
|
||||
func (r *BaseRepository[T, F]) GetByID(ctx context.Context, id interface{}) (*T, error) {
|
||||
result := new(T)
|
||||
if err := r.db.WithContext(ctx).First(result, id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("error getting record by ID: %w", err)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Insert creates a new record
|
||||
func (r *BaseRepository[T, F]) Insert(ctx context.Context, model *T) error {
|
||||
if err := r.db.WithContext(ctx).Create(model).Error; err != nil {
|
||||
return fmt.Errorf("error creating record: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update modifies an existing record
|
||||
func (r *BaseRepository[T, F]) Update(ctx context.Context, model *T) error {
|
||||
if err := r.db.WithContext(ctx).Save(model).Error; err != nil {
|
||||
return fmt.Errorf("error updating record: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete removes a record by ID
|
||||
func (r *BaseRepository[T, F]) Delete(ctx context.Context, id interface{}) error {
|
||||
if err := r.db.WithContext(ctx).Delete(new(T), id).Error; err != nil {
|
||||
return fmt.Errorf("error deleting record: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Count returns the total number of records matching the filter
|
||||
func (r *BaseRepository[T, F]) Count(ctx context.Context, filter *F) (int64, error) {
|
||||
var count int64
|
||||
query := r.db.WithContext(ctx).Model(&r.modelType)
|
||||
|
||||
if filterable, ok := any(filter).(Filterable); ok {
|
||||
query = filterable.ApplyFilter(query)
|
||||
}
|
||||
|
||||
if err := query.Count(&count).Error; err != nil {
|
||||
return 0, fmt.Errorf("error counting records: %w", err)
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// Interfaces for filter capabilities
|
||||
|
||||
type Filterable interface {
|
||||
ApplyFilter(*gorm.DB) *gorm.DB
|
||||
}
|
||||
|
||||
type Pageable interface {
|
||||
Pagination() (offset, limit int)
|
||||
}
|
||||
|
||||
type Sortable interface {
|
||||
GetSorting() (field string, desc bool)
|
||||
}
|
||||
@@ -3,64 +3,27 @@ package repository
|
||||
import (
|
||||
"acc-server-manager/local/model"
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ConfigRepository struct {
|
||||
db *gorm.DB
|
||||
*BaseRepository[model.Config, model.ConfigFilter]
|
||||
}
|
||||
|
||||
func NewConfigRepository(db *gorm.DB) *ConfigRepository {
|
||||
return &ConfigRepository{
|
||||
db: db,
|
||||
BaseRepository: NewBaseRepository[model.Config, model.ConfigFilter](db, model.Config{}),
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateConfig
|
||||
// Updates first row from Config table.
|
||||
//
|
||||
// Args:
|
||||
// context.Context: Application context
|
||||
// Returns:
|
||||
// model.ConfigModel: Config object from database.
|
||||
func (as ConfigRepository) UpdateFirst(ctx context.Context) *model.Config {
|
||||
db := as.db.WithContext(ctx)
|
||||
ConfigModel := new(model.Config)
|
||||
db.First(&ConfigModel)
|
||||
return ConfigModel
|
||||
}
|
||||
|
||||
// UpdateAll
|
||||
// Updates All rows from Config table.
|
||||
//
|
||||
// Args:
|
||||
// context.Context: Application context
|
||||
// Returns:
|
||||
// model.ConfigModel: Config object from database.
|
||||
func (as ConfigRepository) UpdateAll(ctx context.Context) *[]model.Config {
|
||||
db := as.db.WithContext(ctx)
|
||||
ConfigModel := new([]model.Config)
|
||||
db.Find(&ConfigModel)
|
||||
return ConfigModel
|
||||
}
|
||||
|
||||
// UpdateConfig
|
||||
// Updates Config row from Config table.
|
||||
//
|
||||
// Args:
|
||||
// context.Context: Application context
|
||||
// Returns:
|
||||
// model.ConfigModel: Config object from database.
|
||||
func (as ConfigRepository) UpdateConfig(ctx context.Context, body *model.Config) *model.Config {
|
||||
db := as.db.WithContext(ctx)
|
||||
|
||||
existingConfig := new(model.Config)
|
||||
result := db.Where("server_id=?", body.ServerID).Where("config_file=?", body.ConfigFile).First(existingConfig)
|
||||
if !errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||
body.ID = existingConfig.ID
|
||||
// UpdateConfig updates or creates a Config record
|
||||
func (r *ConfigRepository) UpdateConfig(ctx context.Context, config *model.Config) *model.Config {
|
||||
if err := r.Update(ctx, config); err != nil {
|
||||
// If update fails, try to insert
|
||||
if err := r.Insert(ctx, config); err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
db.Save(body)
|
||||
return body
|
||||
}
|
||||
return config
|
||||
}
|
||||
@@ -9,28 +9,15 @@ import (
|
||||
)
|
||||
|
||||
type ServerRepository struct {
|
||||
db *gorm.DB
|
||||
*BaseRepository[model.Server, model.ServerFilter]
|
||||
}
|
||||
|
||||
func NewServerRepository(db *gorm.DB) *ServerRepository {
|
||||
return &ServerRepository{
|
||||
db: db,
|
||||
BaseRepository: NewBaseRepository[model.Server, model.ServerFilter](db, model.Server{}),
|
||||
}
|
||||
}
|
||||
|
||||
// GetFirst
|
||||
// Gets first row from Server table.
|
||||
//
|
||||
// Args:
|
||||
// context.Context: Application context
|
||||
// Returns:
|
||||
// model.ServerModel: Server object from database.
|
||||
func (as ServerRepository) GetFirst(ctx context.Context, serverId int) *model.Server {
|
||||
db := as.db.WithContext(ctx)
|
||||
ServerModel := new(model.Server)
|
||||
db.Where("id=?", serverId).First(&ServerModel)
|
||||
return ServerModel
|
||||
}
|
||||
|
||||
// GetFirstByServiceName
|
||||
// Gets first row from Server table.
|
||||
@@ -39,45 +26,13 @@ func (as ServerRepository) GetFirst(ctx context.Context, serverId int) *model.Se
|
||||
// context.Context: Application context
|
||||
// Returns:
|
||||
// model.ServerModel: Server object from database.
|
||||
func (as ServerRepository) GetFirstByServiceName(ctx context.Context, serviceName string) *model.Server {
|
||||
db := as.db.WithContext(ctx)
|
||||
ServerModel := new(model.Server)
|
||||
result := db.Where("service_name=?", serviceName).First(&ServerModel)
|
||||
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||
return nil
|
||||
func (r *ServerRepository) GetFirstByServiceName(ctx context.Context, serviceName string) (*model.Server, error) {
|
||||
result := new(model.Server)
|
||||
if err := r.db.WithContext(ctx).Where("service_name = ?", serviceName).First(result).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return ServerModel
|
||||
}
|
||||
|
||||
// GetAll
|
||||
// Gets All rows from Server table.
|
||||
//
|
||||
// Args:
|
||||
// context.Context: Application context
|
||||
// Returns:
|
||||
// model.ServerModel: Server object from database.
|
||||
func (as ServerRepository) GetAll(ctx context.Context) *[]model.Server {
|
||||
db := as.db.WithContext(ctx)
|
||||
ServerModel := new([]model.Server)
|
||||
db.Find(&ServerModel)
|
||||
return ServerModel
|
||||
}
|
||||
|
||||
// UpdateServer
|
||||
// Updates Server row from Server table.
|
||||
//
|
||||
// Args:
|
||||
// context.Context: Application context
|
||||
// Returns:
|
||||
// model.Server: Server object from database.
|
||||
func (as ServerRepository) UpdateServer(ctx context.Context, body *model.Server) *model.Server {
|
||||
db := as.db.WithContext(ctx)
|
||||
|
||||
existingServer := new(model.Server)
|
||||
result := db.Where("id=?", body.ID).First(existingServer)
|
||||
if !errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||
body.ID = existingServer.ID
|
||||
}
|
||||
db.Save(body)
|
||||
return body
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
@@ -8,38 +8,21 @@ import (
|
||||
)
|
||||
|
||||
type StateHistoryRepository struct {
|
||||
db *gorm.DB
|
||||
*BaseRepository[model.StateHistory, model.StateHistoryFilter]
|
||||
}
|
||||
|
||||
func NewStateHistoryRepository(db *gorm.DB) *StateHistoryRepository {
|
||||
return &StateHistoryRepository{
|
||||
db: db,
|
||||
BaseRepository: NewBaseRepository[model.StateHistory, model.StateHistoryFilter](db, model.StateHistory{}),
|
||||
}
|
||||
}
|
||||
|
||||
// GetAll
|
||||
// Gets All rows from Server table.
|
||||
//
|
||||
// Args:
|
||||
// context.Context: Application context
|
||||
// Returns:
|
||||
// model.ServerModel: Server object from database.
|
||||
func (as StateHistoryRepository) GetAll(ctx context.Context, id int) *[]model.StateHistory {
|
||||
db := as.db.WithContext(ctx)
|
||||
ServerModel := new([]model.StateHistory)
|
||||
db.Find(&ServerModel).Where("ID = ?", id)
|
||||
return ServerModel
|
||||
// GetAll retrieves all state history records with the given filter
|
||||
func (r *StateHistoryRepository) GetAll(ctx context.Context, filter *model.StateHistoryFilter) (*[]model.StateHistory, error) {
|
||||
return r.BaseRepository.GetAll(ctx, filter)
|
||||
}
|
||||
|
||||
// UpdateServer
|
||||
// Updates Server row from Server table.
|
||||
//
|
||||
// Args:
|
||||
// context.Context: Application context
|
||||
// Returns:
|
||||
// model.Server: Server object from database.
|
||||
func (as StateHistoryRepository) Insert(ctx context.Context, body *model.StateHistory) *model.StateHistory {
|
||||
db := as.db.WithContext(ctx)
|
||||
db.Save(body)
|
||||
return body
|
||||
// Insert creates a new state history record
|
||||
func (r *StateHistoryRepository) Insert(ctx context.Context, model *model.StateHistory) error {
|
||||
return r.BaseRepository.Insert(ctx, model)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user