package analize import ( "fmt" "net/http" "path/filepath" "strconv" "strings" "github.com/che4web/go4rest" "github.com/gin-gonic/gin" "gorm.io/gorm" ) type AnalizeController struct { *go4rest.ViewSet[Analize] db *gorm.DB } func NewAnalizeController(db *gorm.DB) *AnalizeController { return &AnalizeController{ ViewSet: go4rest.NewViewSet[Analize](db), db: db, } } type AnalizeSeriesPoint struct { CaseID uint `json:"case_id"` CaseName string `json:"case_name"` X float64 `json:"x"` Omega float64 `json:"omega"` PsiMax float64 `json:"psi_max"` } type AnalizeSeriesResponse struct { Parameter string `json:"parameter"` Label string `json:"label"` Points []AnalizeSeriesPoint `json:"points"` } var analizeParameterColumns = map[string]struct { Column string Label string }{ "Rel": {Column: "rel", Label: "Rel"}, "RelC": {Column: "rel_c", Label: "RelC"}, "Le": {Column: "le", Label: "Le"}, "Pr": {Column: "pr", Label: "Pr"}, "Pe": {Column: "pe", Label: "Pe"}, "Ma": {Column: "ma", Label: "Ma"}, "Time": {Column: "time", Label: "Time"}, } func (c *AnalizeController) Series(ctx *gin.Context) { param := ctx.DefaultQuery("parameter", "Rel") selected, ok := analizeParameterColumns[param] if !ok { ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid parameter"}) return } filterParam := ctx.Query("filter_parameter") filterSelected, filterOK := analizeParameterColumns[filterParam] filterMin := ctx.Query("filter_min") filterMax := ctx.Query("filter_max") type row struct { CaseID uint `gorm:"column:case_id"` CaseName string `gorm:"column:case_name"` X float64 `gorm:"column:x"` Omega float64 `gorm:"column:omega"` PsiMax float64 `gorm:"column:psi_max"` } query := fmt.Sprintf(` SELECT a.case_id, a.case_name, p.%s AS x, a.omega, a.psi_max FROM analizes a JOIN control_cases c ON c.id = a.case_id JOIN params p ON p.id = c.params_id `, selected.Column) where := make([]string, 0, 2) args := make([]any, 0, 2) if filterParam != "" { if !filterOK { ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid filter parameter"}) return } if filterMin != "" { where = append(where, fmt.Sprintf("p.%s >= ?", filterSelected.Column)) args = append(args, filterMin) } if filterMax != "" { where = append(where, fmt.Sprintf("p.%s <= ?", filterSelected.Column)) args = append(args, filterMax) } } if len(where) > 0 { query += " WHERE " + strings.Join(where, " AND ") } query += fmt.Sprintf(" ORDER BY p.%s, a.id", selected.Column) var rows []row if err := c.db.Raw(query, args...).Scan(&rows).Error; err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } points := make([]AnalizeSeriesPoint, 0, len(rows)) for _, r := range rows { points = append(points, AnalizeSeriesPoint{ CaseID: r.CaseID, CaseName: r.CaseName, X: r.X, Omega: r.Omega, PsiMax: r.PsiMax, }) } ctx.JSON(http.StatusOK, AnalizeSeriesResponse{ Parameter: param, Label: selected.Label, Points: points, }) } func (c *AnalizeController) Recalculate(ctx *gin.Context) { id, err := strconv.ParseUint(ctx.Param("id"), 10, 32) if err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid ID"}) return } var item Analize if err := c.db.First(&item, id).Error; err != nil { ctx.JSON(http.StatusNotFound, gin.H{"error": "record not found"}) return } csvPath := filepath.Join(".", fmt.Sprintf("%d", item.CaseID), "foo.csv") updated, err := AnalyzeCSV(c.db, item.CaseID, item.CaseName, csvPath) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } ctx.JSON(http.StatusOK, updated) }