package repository import ( "context" "database/sql" "fmt" "git.godopu.com/lab/landing_page/backend/internal/models" ) type StandardizationRepository struct { db *sql.DB } func NewStandardizationRepository(db *sql.DB) *StandardizationRepository { return &StandardizationRepository{db: db} } func (r *StandardizationRepository) GetStandardsBodiesWithProjects(ctx context.Context) ([]models.StandardsBodyWithProjects, error) { bodyQuery := ` SELECT id, org, full_name, scope, period, role, display_order FROM standards_bodies ORDER BY display_order ASC, id ASC ` bodyRows, err := r.db.QueryContext(ctx, bodyQuery) if err != nil { return nil, fmt.Errorf("query standards bodies: %w", err) } defer bodyRows.Close() bodies := make([]models.StandardsBodyWithProjects, 0) bodyMap := make(map[int]int) for bodyRows.Next() { var b models.StandardsBodyWithProjects if err := bodyRows.Scan(&b.ID, &b.Org, &b.FullName, &b.Scope, &b.Period, &b.Role, &b.DisplayOrder); err != nil { return nil, fmt.Errorf("scan standards body: %w", err) } b.Projects = []models.StandardProjectGroup{} bodyMap[b.ID] = len(bodies) bodies = append(bodies, b) } if err := bodyRows.Err(); err != nil { return nil, err } docQuery := ` SELECT id, body_id, wg, project_name, title, doc_ref, status, published_at FROM standard_documents ORDER BY body_id ASC, id ASC ` docRows, err := r.db.QueryContext(ctx, docQuery) if err != nil { return nil, fmt.Errorf("query standard documents: %w", err) } defer docRows.Close() type projectKey struct { bodyID int wg string projectName string } projectMap := make(map[projectKey]int) for docRows.Next() { var d models.StandardDocument if err := docRows.Scan(&d.ID, &d.BodyID, &d.WG, &d.ProjectName, &d.Title, &d.DocRef, &d.Status, &d.PublishedAt); err != nil { return nil, fmt.Errorf("scan standard document: %w", err) } bIdx, bodyExists := bodyMap[d.BodyID] if !bodyExists { continue } key := projectKey{bodyID: d.BodyID, wg: d.WG, projectName: d.ProjectName} pIdx, projExists := projectMap[key] if !projExists { pIdx = len(bodies[bIdx].Projects) bodies[bIdx].Projects = append(bodies[bIdx].Projects, models.StandardProjectGroup{ WG: d.WG, Name: d.ProjectName, Documents: []models.StandardDocument{}, }) projectMap[key] = pIdx } bodies[bIdx].Projects[pIdx].Documents = append(bodies[bIdx].Projects[pIdx].Documents, d) } return bodies, docRows.Err() } func (r *StandardizationRepository) CreateStandardsBody(ctx context.Context, b models.StandardsBody) (int, error) { res, err := r.db.ExecContext(ctx, ` INSERT INTO standards_bodies (org, full_name, scope, period, role, display_order) VALUES (?, ?, ?, ?, ?, ?) `, b.Org, b.FullName, b.Scope, b.Period, b.Role, b.DisplayOrder) if err != nil { return 0, fmt.Errorf("insert standards body: %w", err) } id, err := res.LastInsertId() return int(id), err } func (r *StandardizationRepository) UpdateStandardsBody(ctx context.Context, id int, b models.StandardsBody) error { res, err := r.db.ExecContext(ctx, ` UPDATE standards_bodies SET org = ?, full_name = ?, scope = ?, period = ?, role = ?, display_order = ? WHERE id = ? `, b.Org, b.FullName, b.Scope, b.Period, b.Role, b.DisplayOrder, id) if err != nil { return fmt.Errorf("update standards body: %w", err) } rows, err := res.RowsAffected() if err == nil && rows == 0 { return sql.ErrNoRows } return err } func (r *StandardizationRepository) DeleteStandardsBody(ctx context.Context, id int) error { res, err := r.db.ExecContext(ctx, `DELETE FROM standards_bodies WHERE id = ?`, id) if err != nil { return fmt.Errorf("delete standards body: %w", err) } rows, err := res.RowsAffected() if err == nil && rows == 0 { return sql.ErrNoRows } return err } func (r *StandardizationRepository) CreateStandardDocument(ctx context.Context, d models.StandardDocument) (int, error) { res, err := r.db.ExecContext(ctx, ` INSERT INTO standard_documents (body_id, wg, project_name, title, doc_ref, status, published_at) VALUES (?, ?, ?, ?, ?, ?, ?) `, d.BodyID, d.WG, d.ProjectName, d.Title, d.DocRef, d.Status, d.PublishedAt) if err != nil { return 0, fmt.Errorf("insert standard document: %w", err) } id, err := res.LastInsertId() return int(id), err } func (r *StandardizationRepository) UpdateStandardDocument(ctx context.Context, id int, d models.StandardDocument) error { res, err := r.db.ExecContext(ctx, ` UPDATE standard_documents SET wg = ?, project_name = ?, title = ?, doc_ref = ?, status = ?, published_at = ? WHERE id = ? `, d.WG, d.ProjectName, d.Title, d.DocRef, d.Status, d.PublishedAt, id) if err != nil { return fmt.Errorf("update standard document: %w", err) } rows, err := res.RowsAffected() if err == nil && rows == 0 { return sql.ErrNoRows } return err } func (r *StandardizationRepository) DeleteStandardDocument(ctx context.Context, id int) error { res, err := r.db.ExecContext(ctx, `DELETE FROM standard_documents WHERE id = ?`, id) if err != nil { return fmt.Errorf("delete standard document: %w", err) } rows, err := res.RowsAffected() if err == nil && rows == 0 { return sql.ErrNoRows } return err }