Planner/core/plans.go

127 lines
3.3 KiB
Go
Raw Normal View History

2025-02-12 19:29:00 +01:00
package core
2024-11-09 19:35:44 +01:00
import (
2025-02-11 21:16:39 +01:00
"crypto/rand"
2025-04-16 23:24:23 +02:00
"database/sql"
2025-02-11 21:16:39 +01:00
"encoding/base64"
2024-11-09 19:35:44 +01:00
"errors"
2025-04-16 23:24:23 +02:00
"fmt"
2024-11-09 19:35:44 +01:00
)
2025-04-16 23:24:23 +02:00
func PlanCreate(db *sql.DB, user *User, name string) (*Plan, error) {
2025-02-12 20:12:30 +01:00
join_code := make([]byte, 32)
_, err := rand.Read(join_code)
if err != nil {
return nil, err
}
var plan Plan = Plan{
2025-04-16 23:24:23 +02:00
Name: name,
Owner: user.Username,
2025-02-12 20:12:30 +01:00
JoinCode: base64.URLEncoding.EncodeToString(join_code),
}
2025-04-16 23:24:23 +02:00
row := db.QueryRow(
"INSERT INTO plans(name, owner, description, join_jode) VALUES (?, ?, '', ?) RETURNING id",
plan.Name,
plan.Owner,
plan.JoinCode,
)
if err := row.Scan(&plan.Id); err != nil {
return nil, err
2025-02-12 20:12:30 +01:00
}
return &plan, nil
}
2025-04-16 23:24:23 +02:00
func PlanGet(db *sql.DB, id uint) (*Plan, error) {
plan := Plan{}
row := db.QueryRow("SELECT name,owner,description,join_code FROM plans WHERE id=?", id)
if err := row.Scan(&plan.Name, &plan.Owner, &plan.Description, &plan.JoinCode); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, ErrNotFound
}
return nil, fmt.Errorf("Unexpected database error: %w", err)
2024-11-09 19:35:44 +01:00
}
return &plan, nil
}
2025-04-16 23:24:23 +02:00
func (p *Plan) GetAllUsers(db *sql.DB) ([]Member, error) {
members := []Member{}
rows, err := db.Query("SELECT id,plan_id,name,user_id FROM members WHERE plan_id=?", p.Id)
if err != nil {
return members, err
}
defer rows.Close()
for rows.Next() {
var m Member
rows.Scan(&m.Id, &m.PlanId, &m.Name, &m.UserId)
members = append(members, m)
}
2025-01-14 20:14:07 +01:00
return members, err
2024-11-09 19:35:44 +01:00
}
2025-04-16 23:24:23 +02:00
func (p *Plan) IsMember(db *sql.DB, u *User) (bool, error) {
var member_count int
row := db.QueryRow("SELECT count(1) FROM members WHERE plan_id=? AND user_id=?", p.Id, u.Username)
if err := row.Scan(&member_count); err != nil {
return false, nil
2024-11-09 19:35:44 +01:00
}
2025-01-14 20:14:07 +01:00
return member_count == 1, nil
2024-11-09 19:35:44 +01:00
}
2025-02-11 21:16:39 +01:00
2025-04-16 23:24:23 +02:00
func (p *Plan) GetMember(db *sql.DB, u *User) (*Member, error) {
2025-02-11 21:16:39 +01:00
var m Member
2025-04-16 23:24:23 +02:00
row := db.QueryRow("SELECT id,plan_id,name,user_id FROM members WHERE plan_id=? AND user_id=?", p.Id, u.Username)
if err := row.Scan(&m.Id, &m.PlanId, &m.Name, &m.UserId); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, ErrNotMember
}
return nil, fmt.Errorf("Unable to check if user %s is member in plan %d: %w", u.Username, p.Id, err)
2025-02-11 21:16:39 +01:00
}
return &m, nil
}
2025-04-16 23:24:23 +02:00
func (p *Plan) HasNonUser(db *sql.DB, name string) (bool, error) {
var member_count int
row := db.QueryRow("SELECT count(1) FROM members WHERE plan_id=? AND name=?", p.Id, name)
if err := row.Scan(&member_count); err != nil {
return false, nil
2025-02-11 21:16:39 +01:00
}
return member_count == 1, nil
}
2025-04-16 23:24:23 +02:00
func (p *Plan) AddMember(db *sql.DB, new_member *Member) error {
2025-02-11 21:16:39 +01:00
if new_member == nil {
return errors.New("Member is nil")
}
2025-04-16 23:24:23 +02:00
new_member.PlanId = p.Id
2025-04-09 18:37:02 +02:00
if new_member.Name != "" {
2025-04-16 23:24:23 +02:00
found, err := p.HasNonUser(db, new_member.Name)
2025-02-11 21:16:39 +01:00
if err != nil {
return nil
}
if found {
return errors.New("Non user name taken")
}
2025-04-16 23:24:23 +02:00
_, err = db.Exec("INSERT INTO members(plan_id, name) VALUES (?,?)", new_member.PlanId, new_member.Name)
return err
} else if *new_member.UserId != "" {
user, err := UserGet(db, *new_member.UserId)
2025-02-11 21:16:39 +01:00
if err != nil {
return err
}
2025-04-16 23:24:23 +02:00
found, err := p.IsMember(db, &user)
2025-02-11 21:16:39 +01:00
if err != nil {
return nil
}
if found {
return errors.New("User already is member")
}
2025-04-16 23:24:23 +02:00
_, err = db.Exec("INSERT INTO members(plan_id, user_id) VALUES (?,?)", new_member.PlanId, new_member.UserId)
return err
2025-02-11 21:16:39 +01:00
} else {
2025-04-09 18:37:02 +02:00
return errors.New("Member object requires one of Name or UserID to be filled")
2025-02-11 21:16:39 +01:00
}
}