package mysql import ( "context" "errors" "strings" "gorm.io/gorm" filemanager "wucher/internal/domain/file_manager" "wucher/internal/domain/helicopter" helicopterfile "wucher/internal/domain/helicopter_file" ) type HelicopterFileRepository struct { db *gorm.DB } func NewHelicopterFileRepository(db *gorm.DB) *HelicopterFileRepository { return &HelicopterFileRepository{db: db} } func (r *HelicopterFileRepository) Create(ctx context.Context, row *helicopterfile.HelicopterFile) error { return r.db.WithContext(ctx).Create(row).Error } func (r *HelicopterFileRepository) Update(ctx context.Context, row *helicopterfile.HelicopterFile) error { return r.db.WithContext(ctx).Save(row).Error } func (r *HelicopterFileRepository) Delete(ctx context.Context, id []byte) error { if err := ensureNoReferenceBeforeDelete(ctx, r.db, "helicopter_files", id); err != nil { return err } return mapDeleteConstraintError(r.db.WithContext(ctx).Delete(&helicopterfile.HelicopterFile{}, "id = ?", id).Error) } func (r *HelicopterFileRepository) GetByID(ctx context.Context, id []byte) (*helicopterfile.HelicopterFile, error) { var row helicopterfile.HelicopterFile err := r.db.WithContext(ctx). Preload("Helicopter"). Preload("FileAttachment"). Preload("FileAttachment.File"). Preload("SourceFile"). Where("id = ?", id). First(&row).Error if errors.Is(err, gorm.ErrRecordNotFound) { return nil, nil } return &row, err } func (r *HelicopterFileRepository) List(ctx context.Context, filter string, sort string, limit, offset int) ([]helicopterfile.HelicopterFile, int64, error) { rows := make([]helicopterfile.HelicopterFile, 0) var total int64 base := r.db.WithContext(ctx).Model(&helicopterfile.HelicopterFile{}) if strings.TrimSpace(filter) != "" { like := "%" + strings.ToLower(strings.TrimSpace(filter)) + "%" base = base.Where( "LOWER(section) LIKE ? OR LOWER(HEX(id)) LIKE ? OR LOWER(HEX(helicopter_id)) LIKE ? OR LOWER(HEX(file_attachment_id)) LIKE ? OR LOWER(HEX(source_file_id)) LIKE ? OR CAST(is_mandatory AS CHAR) LIKE ?", like, like, like, like, like, like, ) } query := base if sort != "" { query = query.Order(sort) } if err := base.Count(&total).Error; err != nil { return nil, 0, err } if limit > 0 { query = query.Limit(limit).Offset(offset) } if err := query. Preload("Helicopter"). Preload("FileAttachment"). Preload("FileAttachment.File"). Preload("SourceFile"). Find(&rows).Error; err != nil { return nil, 0, err } return rows, total, nil } func (r *HelicopterFileRepository) ListPendingAttachments(ctx context.Context, limit int) ([]helicopterfile.HelicopterFile, error) { rows := make([]helicopterfile.HelicopterFile, 0) query := r.db.WithContext(ctx). Preload("Helicopter"). Preload("SourceFile"). Where("source_file_id IS NOT NULL AND file_attachment_id IS NULL"). Order("created_at ASC") if limit > 0 { query = query.Limit(limit) } if err := query.Find(&rows).Error; err != nil { return nil, err } return rows, nil } func (r *HelicopterFileRepository) ListPendingAttachmentsBySourceFileID(ctx context.Context, sourceFileID []byte, limit int) ([]helicopterfile.HelicopterFile, error) { rows := make([]helicopterfile.HelicopterFile, 0) if len(sourceFileID) != 16 { return rows, nil } query := r.db.WithContext(ctx). Preload("Helicopter"). Preload("SourceFile"). Where("source_file_id = ? AND file_attachment_id IS NULL", sourceFileID). Order("created_at ASC") if limit > 0 { query = query.Limit(limit) } if err := query.Find(&rows).Error; err != nil { return nil, err } return rows, nil } func (r *HelicopterFileRepository) ListByHelicopter(ctx context.Context, helicopterID []byte) ([]helicopterfile.HelicopterFile, error) { rows := make([]helicopterfile.HelicopterFile, 0) if len(helicopterID) != 16 { return rows, nil } err := r.db.WithContext(ctx). Preload("Helicopter"). Preload("FileAttachment"). Preload("FileAttachment.File"). Preload("SourceFile"). Where("helicopter_id = ?", helicopterID). Order("section ASC, position ASC, created_at ASC"). Find(&rows).Error return rows, err } func (r *HelicopterFileRepository) ListByHelicopterAndSection(ctx context.Context, helicopterID []byte, section string) ([]helicopterfile.HelicopterFile, error) { rows := make([]helicopterfile.HelicopterFile, 0) if len(helicopterID) != 16 || strings.TrimSpace(section) == "" { return rows, nil } err := r.db.WithContext(ctx). Preload("Helicopter"). Preload("FileAttachment"). Preload("FileAttachment.File"). Preload("SourceFile"). Where("helicopter_id = ? AND section = ?", helicopterID, strings.TrimSpace(section)). Order("position ASC, created_at ASC"). Find(&rows).Error return rows, err } func (r *HelicopterFileRepository) HelicopterExists(ctx context.Context, helicopterID []byte) (bool, error) { if len(helicopterID) != 16 { return false, nil } var total int64 err := r.db.WithContext(ctx). Model(&helicopter.Helicopter{}). Where("id = ?", helicopterID). Count(&total).Error return total > 0, err } func (r *HelicopterFileRepository) AttachmentExists(ctx context.Context, attachmentID []byte) (bool, error) { if len(attachmentID) != 16 { return false, nil } var total int64 err := r.db.WithContext(ctx). Model(&filemanager.Attachment{}). Where("id = ?", attachmentID). Count(&total).Error return total > 0, err }