package db import ( "fmt" "lishwist/normalize" "strconv" ) type Group struct { Id string Name string Reference string Members []User } func (g *Group) MemberIndex(userId string) int { for i, u := range g.Members { if u.Id == userId { return i } } return -1 } func queryManyGroups(query string, args ...any) ([]Group, error) { groups := []Group{} rows, err := database.Query(query, args...) if err != nil { return nil, fmt.Errorf("Query failed: %w", err) } defer rows.Close() for rows.Next() { var group Group err := rows.Scan(&group.Id, &group.Name, &group.Reference) if err != nil { return nil, fmt.Errorf("Failed to scan row: %w", err) } members, err := queryManyGroupMembers(group.Id) if err != nil { return nil, fmt.Errorf("Failed to query for group members: %w", err) } group.Members = members groups = append(groups, group) } err = rows.Err() if err != nil { return nil, fmt.Errorf("Rows error: %w", err) } return groups, nil } func queryOneGroup(query string, args ...any) (*Group, error) { groups, err := queryManyGroups(query, args...) if err != nil { return nil, err } if len(groups) < 1 { return nil, nil } return &groups[0], nil } func queryManyGroupMembers(groupId string) ([]User, error) { query := "SELECT user.id, user.name, user.display_name, user.reference, user.is_admin, user.is_live FROM v_user AS user JOIN group_member ON group_member.user_id = user.id JOIN [group] ON [group].id = group_member.group_id WHERE [group].id = ? ORDER BY group_member.user_id" members, err := queryManyUsers(query, groupId) if err != nil { return members, fmt.Errorf("Failed to get members: %w", err) } return members, nil } func GetGroupByReference(reference string) (*Group, error) { query := "SELECT [group].id, [group].name, [group].reference FROM [group] WHERE [group].reference = ?" return queryOneGroup(query, reference) } func GetAllGroups() ([]Group, error) { query := "SELECT id, name, reference FROM [group];" return queryManyGroups(query) } func CreateGroup(name string, reference string) (*Group, error) { name = normalize.Name(name) stmt := "INSERT INTO [group] (name, reference) VALUES (?, ?)" result, err := database.Exec(stmt, name, reference) if err != nil { return nil, err } id, err := result.LastInsertId() if err != nil { return nil, err } group := Group{ Id: strconv.FormatInt(id, 10), Name: name, Reference: reference, } return &group, nil } func (g *Group) AddUser(userId string) error { stmt := "INSERT INTO group_member (group_id, user_id) VALUES (?, ?)" _, err := database.Exec(stmt, g.Id, userId) if err != nil { return err } return nil } func (g *Group) RemoveUser(userId string) error { stmt := "DELETE FROM group_member WHERE group_id = ? AND user_id = ?" _, err := database.Exec(stmt, g.Id, userId) if err != nil { return err } return nil }