package repository import ( "context" "errors" "time" "github.com/cloudprint/cloudprint-backend/internal/model" "gorm.io/gorm" ) type PrinterRepository struct { db *gorm.DB } func NewPrinterRepository(db *gorm.DB) *PrinterRepository { return &PrinterRepository{db: db} } func (r *PrinterRepository) Create(ctx context.Context, printer *model.Printer) error { return r.db.WithContext(ctx).Create(printer).Error } func (r *PrinterRepository) GetByID(ctx context.Context, id int32) (*model.Printer, error) { var printer model.Printer err := r.db.WithContext(ctx).First(&printer, id).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, nil } return nil, err } return &printer, nil } func (r *PrinterRepository) GetByName(ctx context.Context, name string) (*model.Printer, error) { var printer model.Printer err := r.db.WithContext(ctx).Where("name = ?", name).First(&printer).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, nil } return nil, err } return &printer, nil } func (r *PrinterRepository) GetByAPIKey(ctx context.Context, apiKey string) (*model.Printer, error) { var printer model.Printer err := r.db.WithContext(ctx).Where("api_key = ?", apiKey).First(&printer).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, nil } return nil, err } return &printer, nil } func (r *PrinterRepository) GetAllActive(ctx context.Context) ([]*model.Printer, error) { var printers []*model.Printer err := r.db.WithContext(ctx).Where("is_active = ?", true).Find(&printers).Error return printers, err } func (r *PrinterRepository) UpdateStatus(ctx context.Context, id int32, status int8) error { return r.db.WithContext(ctx).Model(&model.Printer{}).Where("id = ?", id).Update("status", status).Error } func (r *PrinterRepository) UpdateHeartbeat(ctx context.Context, id int32) error { now := time.Now() return r.db.WithContext(ctx).Model(&model.Printer{}).Where("id = ?", id).Update("last_heartbeat", &now).Error } func (r *PrinterRepository) CountActive(ctx context.Context) (int64, error) { var count int64 err := r.db.WithContext(ctx).Model(&model.Printer{}).Where("is_active = ? AND status != ?", true, model.PrinterStatusOffline).Count(&count).Error return count, err } type PrintJobRepository struct { db *gorm.DB } func NewPrintJobRepository(db *gorm.DB) *PrintJobRepository { return &PrintJobRepository{db: db} } func (r *PrintJobRepository) Create(ctx context.Context, job *model.PrintJob) error { return r.db.WithContext(ctx).Create(job).Error } func (r *PrintJobRepository) GetByID(ctx context.Context, id int32) (*model.PrintJob, error) { var job model.PrintJob err := r.db.WithContext(ctx).First(&job, id).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, nil } return nil, err } return &job, nil } func (r *PrintJobRepository) GetByJobNo(ctx context.Context, jobNo string) (*model.PrintJob, error) { var job model.PrintJob err := r.db.WithContext(ctx).Where("job_no = ?", jobNo).First(&job).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, nil } return nil, err } return &job, nil } func (r *PrintJobRepository) GetPendingJobs(ctx context.Context, printerID int32) ([]*model.PrintJob, error) { var jobs []*model.PrintJob err := r.db.WithContext(ctx). Where("printer_id = ? AND status = ?", printerID, model.PrintJobStatusPending). Preload("OrderItem"). Preload("OrderItem.File"). Find(&jobs).Error return jobs, err } func (r *PrintJobRepository) UpdateStatus(ctx context.Context, jobNo string, status string, progress int, errorMsg string) error { updates := map[string]interface{}{ "status": status, "progress": progress, "error_msg": errorMsg, } if status == model.PrintJobStatusPrinting { now := time.Now() updates["started_at"] = &now } else if status == model.PrintJobStatusCompleted || status == model.PrintJobStatusFailed { now := time.Now() updates["completed_at"] = &now } return r.db.WithContext(ctx).Model(&model.PrintJob{}). Where("job_no = ?", jobNo).Updates(updates).Error } func (r *PrintJobRepository) GetQueueCount(ctx context.Context, printerID int32) (int64, error) { var count int64 err := r.db.WithContext(ctx).Model(&model.PrintJob{}). Where("printer_id = ? AND status IN ?", printerID, []string{model.PrintJobStatusPending, model.PrintJobStatusPrinting}). Count(&count).Error return count, err }