package data import ( "errors" "time" "database/sql" "party.at/party/internal/validator" ) type Option struct { ID int64 `json:"id"` IssueID int64 `json:"issue_id"` Label string `json:"label"` Created time.Time `json:"created"` Version int `json:"version"` } func ValidateOption(v *validator.Validator, option *Option) { v.Check(option.Label != "", "options", "option labels must not be empty") } type OptionModel struct { DB *sql.DB } func (m OptionModel) Insert(option *Option) error { query := ` INSERT INTO options (issue_id, label) VALUES ($1, $2) RETURNING id, created, version` args := []interface{}{ option.IssueID, option.Label, } return m.DB.QueryRow(query, args...).Scan( &option.ID, &option.Created, &option.Version, ) } func (m OptionModel) GetAllForIssue(issueID int64) ([]*Option, error) { query := ` SELECT id, issue_id, label, created, version FROM options WHERE issue_id = $1 ORDER BY id` rows, err := m.DB.Query(query, issueID) if err != nil { return nil, err } defer rows.Close() var options []*Option for rows.Next() { var option Option err := rows.Scan(&option.ID, &option.IssueID, &option.Label, &option.Created, &option.Version) if err != nil { return nil, err } options = append(options, &option) } return options, rows.Err() } func (m OptionModel) Get(id int64) (*Option, error) { if id < 1 { return nil, ErrRecordNotFound } query := ` SELECT id, issue_id, label, created, version FROM options WHERE id = $1` var option Option err := m.DB.QueryRow(query, id).Scan( &option.ID, &option.IssueID, &option.Label, &option.Created, &option.Version, ) if err != nil { switch { case errors.Is(err, sql.ErrNoRows): return nil, ErrRecordNotFound default: return nil, err } } return &option, nil }