package postgres import ( "database/sql" "gardomatic.kleiax.de/internal/storage" ) // TaskPriorityModel implements storage.TaskPriorityModelInterface for the // application-wide priority catalogue. type TaskPriorityModel struct{ DB *sql.DB } func scanTaskPriority(s scanner) (storage.TaskPriority, error) { var priority storage.TaskPriority err := s.Scan(&priority.ID, &priority.Name, &priority.Value, &priority.SortOrder, &priority.Active, &priority.CreatedAt, &priority.UpdatedAt, &priority.Version) return priority, err } // Insert creates a priority catalogue entry. func (m TaskPriorityModel) Insert(priority storage.TaskPriority) (storage.TaskPriority, error) { ctx, cancel := contextWithTimeout() defer cancel() err := m.DB.QueryRowContext(ctx, `INSERT INTO task_priorities (name, value, sort_order, active) VALUES ($1,$2,$3,$4) RETURNING id, created_at, updated_at, version`, priority.Name, priority.Value, priority.SortOrder, priority.Active).Scan(&priority.ID, &priority.CreatedAt, &priority.UpdatedAt, &priority.Version) if err != nil { return storage.TaskPriority{}, recordError(err) } return priority, nil } // Get returns a priority catalogue entry by ID. func (m TaskPriorityModel) Get(id int) (storage.TaskPriority, error) { ctx, cancel := contextWithTimeout() defer cancel() priority, err := scanTaskPriority(m.DB.QueryRowContext(ctx, `SELECT id,name,value,sort_order,active,created_at,updated_at,version FROM task_priorities WHERE id=$1`, id)) if err != nil { return storage.TaskPriority{}, recordError(err) } return priority, nil } // GetAll lists all priority catalogue entries in display order. func (m TaskPriorityModel) GetAll() ([]storage.TaskPriority, error) { ctx, cancel := contextWithTimeout() defer cancel() rows, err := m.DB.QueryContext(ctx, `SELECT id,name,value,sort_order,active,created_at,updated_at,version FROM task_priorities ORDER BY sort_order, value, id`) if err != nil { return nil, err } defer rows.Close() result := []storage.TaskPriority{} for rows.Next() { value, err := scanTaskPriority(rows) if err != nil { return nil, err } result = append(result, value) } return result, rows.Err() } // Update changes a priority catalogue entry using optimistic locking. func (m TaskPriorityModel) Update(priority storage.TaskPriority) (storage.TaskPriority, error) { ctx, cancel := contextWithTimeout() defer cancel() err := m.DB.QueryRowContext(ctx, `UPDATE task_priorities SET name=$1,value=$2,sort_order=$3,active=$4,updated_at=CURRENT_TIMESTAMP,version=version+1 WHERE id=$5 AND version=$6 RETURNING updated_at,version`, priority.Name, priority.Value, priority.SortOrder, priority.Active, priority.ID, priority.Version).Scan(&priority.UpdatedAt, &priority.Version) if err == sql.ErrNoRows { return storage.TaskPriority{}, storage.ErrEditConflict } if err != nil { return storage.TaskPriority{}, recordError(err) } return priority, nil }