Files
yuan-lab-llm--clawmanager/backend/internal/repository/instance_repository.go
T
2026-04-05 01:02:53 +08:00

175 lines
5.4 KiB
Go

package repository
import (
"fmt"
"strings"
"clawreef/internal/models"
"github.com/upper/db/v4"
)
// InstanceRepository defines the interface for instance data operations
type InstanceRepository interface {
Create(instance *models.Instance) error
GetByID(id int) (*models.Instance, error)
GetByAccessToken(accessToken string) (*models.Instance, error)
GetByAgentBootstrapToken(bootstrapToken string) (*models.Instance, error)
GetAll(offset, limit int) ([]models.Instance, error)
CountAll() (int, error)
GetByUserID(userID int, offset, limit int) ([]models.Instance, error)
CountByUserID(userID int) (int, error)
ExistsByUserIDAndName(userID int, name string) (bool, error)
GetAllRunning() ([]models.Instance, error)
Update(instance *models.Instance) error
Delete(id int) error
}
// instanceRepository implements InstanceRepository
type instanceRepository struct {
sess db.Session
}
// NewInstanceRepository creates a new instance repository
func NewInstanceRepository(sess db.Session) InstanceRepository {
return &instanceRepository{sess: sess}
}
// Create creates a new instance
func (r *instanceRepository) Create(instance *models.Instance) error {
res, err := r.sess.Collection("instances").Insert(instance)
if err != nil {
return fmt.Errorf("failed to create instance: %w", err)
}
// Get the generated ID
if id, ok := res.ID().(int64); ok {
instance.ID = int(id)
}
return nil
}
// GetByID gets an instance by ID
func (r *instanceRepository) GetByID(id int) (*models.Instance, error) {
var instance models.Instance
err := r.sess.Collection("instances").Find(db.Cond{"id": id}).One(&instance)
if err != nil {
if err == db.ErrNoMoreRows {
return nil, nil
}
return nil, fmt.Errorf("failed to get instance: %w", err)
}
return &instance, nil
}
// GetByAccessToken gets an instance by its lifecycle gateway token.
func (r *instanceRepository) GetByAccessToken(accessToken string) (*models.Instance, error) {
var instance models.Instance
err := r.sess.Collection("instances").Find(db.Cond{"access_token": accessToken}).One(&instance)
if err != nil {
if err == db.ErrNoMoreRows {
return nil, nil
}
return nil, fmt.Errorf("failed to get instance by access token: %w", err)
}
return &instance, nil
}
func (r *instanceRepository) GetByAgentBootstrapToken(bootstrapToken string) (*models.Instance, error) {
var instance models.Instance
err := r.sess.Collection("instances").Find(db.Cond{"agent_bootstrap_token": bootstrapToken}).One(&instance)
if err != nil {
if err == db.ErrNoMoreRows {
return nil, nil
}
return nil, fmt.Errorf("failed to get instance by agent bootstrap token: %w", err)
}
return &instance, nil
}
func (r *instanceRepository) GetAll(offset, limit int) ([]models.Instance, error) {
var instances []models.Instance
err := r.sess.Collection("instances").Find().Offset(offset).Limit(limit).All(&instances)
if err != nil {
return nil, fmt.Errorf("failed to get all instances: %w", err)
}
return instances, nil
}
func (r *instanceRepository) CountAll() (int, error) {
count, err := r.sess.Collection("instances").Find().Count()
if err != nil {
return 0, fmt.Errorf("failed to count all instances: %w", err)
}
return int(count), nil
}
// GetByUserID gets instances by user ID with pagination
func (r *instanceRepository) GetByUserID(userID int, offset, limit int) ([]models.Instance, error) {
var instances []models.Instance
err := r.sess.Collection("instances").Find(db.Cond{"user_id": userID}).Offset(offset).Limit(limit).All(&instances)
if err != nil {
return nil, fmt.Errorf("failed to get instances: %w", err)
}
return instances, nil
}
// CountByUserID counts instances by user ID
func (r *instanceRepository) CountByUserID(userID int) (int, error) {
count, err := r.sess.Collection("instances").Find(db.Cond{"user_id": userID}).Count()
if err != nil {
return 0, fmt.Errorf("failed to count instances: %w", err)
}
return int(count), nil
}
// ExistsByUserIDAndName checks whether the user already has an instance with the same display name.
func (r *instanceRepository) ExistsByUserIDAndName(userID int, name string) (bool, error) {
instances, err := r.GetByUserID(userID, 0, 1000)
if err != nil {
return false, err
}
normalized := strings.TrimSpace(strings.ToLower(name))
for _, instance := range instances {
if strings.TrimSpace(strings.ToLower(instance.Name)) == normalized {
return true, nil
}
}
return false, nil
}
// GetAllRunning gets all instances that are not in stopped or error state (for sync)
func (r *instanceRepository) GetAllRunning() ([]models.Instance, error) {
var instances []models.Instance
err := r.sess.Collection("instances").Find(
db.Or(
db.Cond{"status": "running"},
db.Cond{"status": "creating"},
db.Cond{"status": "stopped"},
db.Cond{"status": "error"},
),
).All(&instances)
if err != nil {
return nil, fmt.Errorf("failed to get running instances: %w", err)
}
return instances, nil
}
// Update updates an instance
func (r *instanceRepository) Update(instance *models.Instance) error {
err := r.sess.Collection("instances").Find(db.Cond{"id": instance.ID}).Update(instance)
if err != nil {
return fmt.Errorf("failed to update instance: %w", err)
}
return nil
}
// Delete deletes an instance
func (r *instanceRepository) Delete(id int) error {
err := r.sess.Collection("instances").Find(db.Cond{"id": id}).Delete()
if err != nil {
return fmt.Errorf("failed to delete instance: %w", err)
}
return nil
}