61 lines
2.3 KiB
Go
61 lines
2.3 KiB
Go
package postgres
|
|
|
|
import (
|
|
"database/sql"
|
|
|
|
"gardomatic.kleiax.de/internal/storage"
|
|
)
|
|
|
|
// TaskTemplateOptOutModel stores per-plant task-generation suppression while
|
|
// enforcing the garden boundary.
|
|
type TaskTemplateOptOutModel struct{ DB *sql.DB }
|
|
|
|
// IsOptedOut reports whether task generation is suppressed for a plant-template pair.
|
|
func (m TaskTemplateOptOutModel) IsOptedOut(gardenID, plantID, templateID int) (bool, error) {
|
|
ctx, cancel := contextWithTimeout()
|
|
defer cancel()
|
|
var value bool
|
|
err := m.DB.QueryRowContext(ctx, `SELECT EXISTS(SELECT 1 FROM task_template_opt_outs o JOIN plants p ON p.id=o.plant_id JOIN species_task_templates st ON st.id=o.template_id WHERE p.garden_id=$1 AND p.id=$2 AND st.id=$3 AND st.species_id=p.species_id)`, gardenID, plantID, templateID).Scan(&value)
|
|
return value, err
|
|
}
|
|
|
|
// GetAllForPlant lists suppressed template IDs for a plant.
|
|
func (m TaskTemplateOptOutModel) GetAllForPlant(gardenID, plantID int) ([]int, error) {
|
|
ctx, cancel := contextWithTimeout()
|
|
defer cancel()
|
|
rows, err := m.DB.QueryContext(ctx, `SELECT o.template_id FROM task_template_opt_outs o JOIN plants p ON p.id=o.plant_id WHERE p.garden_id=$1 AND p.id=$2 ORDER BY o.template_id`, gardenID, plantID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
result := []int{}
|
|
for rows.Next() {
|
|
var id int
|
|
if err = rows.Scan(&id); err != nil {
|
|
return nil, err
|
|
}
|
|
result = append(result, id)
|
|
}
|
|
return result, rows.Err()
|
|
}
|
|
|
|
// Set creates or removes suppression for a plant-template pair.
|
|
func (m TaskTemplateOptOutModel) Set(gardenID, plantID, templateID int, optedOut bool) error {
|
|
ctx, cancel := contextWithTimeout()
|
|
defer cancel()
|
|
var valid bool
|
|
err := m.DB.QueryRowContext(ctx, `SELECT EXISTS(SELECT 1 FROM plants p JOIN species_task_templates st ON st.species_id=p.species_id WHERE p.garden_id=$1 AND p.id=$2 AND st.id=$3)`, gardenID, plantID, templateID).Scan(&valid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !valid {
|
|
return storage.ErrRecordNotFound
|
|
}
|
|
if optedOut {
|
|
_, err = m.DB.ExecContext(ctx, `INSERT INTO task_template_opt_outs(plant_id,template_id) VALUES($1,$2) ON CONFLICT DO NOTHING`, plantID, templateID)
|
|
} else {
|
|
_, err = m.DB.ExecContext(ctx, `DELETE FROM task_template_opt_outs WHERE plant_id=$1 AND template_id=$2`, plantID, templateID)
|
|
}
|
|
return err
|
|
}
|