feat: group members always initialized

This commit is contained in:
Teajey 2024-11-21 14:47:00 +09:00
parent 271163a889
commit 98a39f8e4f
Signed by: Teajey
GPG Key ID: 970E790FE834A713
6 changed files with 45 additions and 80 deletions

View File

@ -10,11 +10,11 @@ type Group struct {
Id string Id string
Name string Name string
Reference string Reference string
Users []User Members []User
} }
func (g *Group) MemberIndex(userId string) int { func (g *Group) MemberIndex(userId string) int {
for i, u := range g.Users { for i, u := range g.Members {
if u.Id == userId { if u.Id == userId {
return i return i
} }
@ -30,53 +30,15 @@ func queryForGroup(query string, args ...any) (*Group, error) {
} else if err != nil { } else if err != nil {
return nil, err return nil, err
} }
members, err := queryForGroupMembers(group.Id)
if err != nil {
return nil, err
}
group.Members = members
return &group, nil return &group, nil
} }
func GetGroupByReference(reference string) (*Group, error) { func queryForGroups(query string, args ...any) ([]Group, error) {
query := "SELECT [group].id, [group].name, [group].reference FROM [group] WHERE [group].reference = ?"
return queryForGroup(query, reference)
}
func GetGroupByReferenceWithMembers(reference string) (*Group, error) {
group, err := GetGroupByReference(reference)
if err != nil {
return group, err
}
members, err := group.GetMembers()
if err != nil {
return group, fmt.Errorf("Failed to get members: %w\n", err)
}
group.Users = members
return group, err
}
func (g *Group) GetMembers() ([]User, error) {
stmt := "SELECT user.id, user.name, user.reference, user.is_admin FROM user JOIN group_member ON group_member.user_id = user.id JOIN [group] ON [group].id = group_member.group_id WHERE [group].id = ?"
rows, err := database.Query(stmt, g.Id)
users := []User{}
if err != nil {
return users, err
}
defer rows.Close()
for rows.Next() {
var user User
err := rows.Scan(&user.Id, &user.Name, &user.Reference, &user.IsAdmin)
if err != nil {
return users, err
}
users = append(users, user)
}
err = rows.Err()
if err != nil {
return users, err
}
g.Users = users
return users, nil
}
func GetAllGroups() ([]Group, error) {
query := "SELECT id, name, reference FROM [group];"
groups := []Group{} groups := []Group{}
rows, err := database.Query(query) rows, err := database.Query(query)
if err != nil { if err != nil {
@ -89,11 +51,11 @@ func GetAllGroups() ([]Group, error) {
if err != nil { if err != nil {
return groups, err return groups, err
} }
users, err := group.GetMembers() members, err := queryForGroupMembers(group.Id)
if err != nil { if err != nil {
return groups, fmt.Errorf("Failed to get a member: %w", err) return groups, err
} }
group.Users = users group.Members = members
groups = append(groups, group) groups = append(groups, group)
} }
err = rows.Err() err = rows.Err()
@ -103,6 +65,25 @@ func GetAllGroups() ([]Group, error) {
return groups, nil return groups, nil
} }
func queryForGroupMembers(groupId string) ([]User, error) {
query := "SELECT user.id, user.name, user.reference, user.is_admin FROM 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 := queryForUsers(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 queryForGroup(query, reference)
}
func GetAllGroups() ([]Group, error) {
query := "SELECT id, name, reference FROM [group];"
return queryForGroups(query)
}
func CreateGroup(name string, reference string) (*Group, error) { func CreateGroup(name string, reference string) (*Group, error) {
stmt := "INSERT INTO [group] (name, reference) VALUES (?, ?)" stmt := "INSERT INTO [group] (name, reference) VALUES (?, ?)"
result, err := database.Exec(stmt, name, reference) result, err := database.Exec(stmt, name, reference)

View File

@ -421,11 +421,6 @@ func (u *User) GetGroups() ([]Group, error) {
return groups, nil return groups, nil
} }
func (u *User) GetPeers(groupId string) ([]User, error) {
stmt := "SELECT user.id, user.name, user.reference FROM user JOIN group_member ON group_member.user_id = user.id JOIN [group] ON [group].id = group_member.group_id WHERE [group].id = ? AND user.id != ?"
return queryForUsers(stmt, groupId, u.Id)
}
func (u *User) GetGroupByReference(reference string) (*Group, error) { func (u *User) GetGroupByReference(reference string) (*Group, error) {
stmt := "SELECT [group].id, [group].name, [group].reference FROM [group] JOIN group_member ON [group].id == group_member.group_id WHERE [group].reference = ? AND group_member.user_id = ?" stmt := "SELECT [group].id, [group].name, [group].reference FROM [group] JOIN group_member ON [group].id == group_member.group_id WHERE [group].reference = ? AND group_member.user_id = ?"
return queryForGroup(stmt, reference, u.Id) return queryForGroup(stmt, reference, u.Id)

View File

@ -11,8 +11,7 @@ import (
) )
type GroupProps struct { type GroupProps struct {
Name string Group *db.Group
Members []db.User
CurrentUsername string CurrentUsername string
} }
@ -27,14 +26,10 @@ func (ctx *Context) GroupPage(user *db.User, w http.ResponseWriter, r *http.Requ
error.Page(w, "Group not found. (It might be because you're not a member)", http.StatusNotFound, nil) error.Page(w, "Group not found. (It might be because you're not a member)", http.StatusNotFound, nil)
return return
} }
peers, err := user.GetPeers(group.Id) index := group.MemberIndex(user.Id)
if err != nil { group.Members = slices.Delete(group.Members, index, index+1)
error.Page(w, "An error occurred while fetching this group :(", http.StatusInternalServerError, err)
return
}
p := GroupProps{ p := GroupProps{
Name: group.Name, Group: group,
Members: peers,
CurrentUsername: user.Name, CurrentUsername: user.Name,
} }
templates.Execute(w, "group_page.gotmpl", p) templates.Execute(w, "group_page.gotmpl", p)
@ -47,14 +42,8 @@ func (ctx *Context) PublicGroupPage(w http.ResponseWriter, r *http.Request) {
error.Page(w, "An error occurred while fetching this group :(", http.StatusInternalServerError, err) error.Page(w, "An error occurred while fetching this group :(", http.StatusInternalServerError, err)
return return
} }
members, err := group.GetMembers()
if err != nil {
error.Page(w, "An error occurred while fetching this group :(", http.StatusInternalServerError, err)
return
}
p := GroupProps{ p := GroupProps{
Name: group.Name, Group: group,
Members: members,
} }
templates.Execute(w, "public_group_page.gotmpl", p) templates.Execute(w, "public_group_page.gotmpl", p)
} }
@ -84,7 +73,7 @@ func (ctx *Context) GroupPost(currentUser *db.User, w http.ResponseWriter, r *ht
} }
group = createdGroup group = createdGroup
} else { } else {
existingGroup, err := db.GetGroupByReferenceWithMembers(reference) existingGroup, err := db.GetGroupByReference(reference)
if err != nil { if err != nil {
writeGeneralErrorJson(w, http.StatusBadRequest, "Failed to get group: "+err.Error()) writeGeneralErrorJson(w, http.StatusBadRequest, "Failed to get group: "+err.Error())
return return
@ -106,7 +95,7 @@ func (ctx *Context) GroupPost(currentUser *db.User, w http.ResponseWriter, r *ht
writeGeneralErrorJson(w, http.StatusBadRequest, "On group %q failed to remove user with id %s: %s", reference, userId, err) writeGeneralErrorJson(w, http.StatusBadRequest, "On group %q failed to remove user with id %s: %s", reference, userId, err)
return return
} }
group.Users = slices.Delete(group.Users, index, index) group.Members = slices.Delete(group.Members, index, index+1)
} }
} }
@ -125,7 +114,7 @@ func (ctx *Context) GroupPost(currentUser *db.User, w http.ResponseWriter, r *ht
writeGeneralErrorJson(w, http.StatusBadRequest, "Groups exists, but failed to add user with id %s: %s", userId, err) writeGeneralErrorJson(w, http.StatusBadRequest, "Groups exists, but failed to add user with id %s: %s", userId, err)
return return
} }
group.Users = append(group.Users, *currentUser) group.Members = append(group.Members, *currentUser)
} }
_ = json.NewEncoder(w).Encode(group) _ = json.NewEncoder(w).Encode(group)
@ -152,7 +141,7 @@ func (ctx *Context) Group(user *db.User, w http.ResponseWriter, r *http.Request)
return return
} }
groupReference := r.PathValue("groupReference") groupReference := r.PathValue("groupReference")
group, err := db.GetGroupByReferenceWithMembers(groupReference) group, err := db.GetGroupByReference(groupReference)
if err != nil { if err != nil {
writeGeneralErrorJson(w, http.StatusBadRequest, "Couldn't get group: %s", err) writeGeneralErrorJson(w, http.StatusBadRequest, "Couldn't get group: %s", err)
return return

View File

@ -14,7 +14,7 @@ func (ctx *Context) UsersJson(user *db.User, w http.ResponseWriter, r *http.Requ
users, err := db.GetAllUsers() users, err := db.GetAllUsers()
if err != nil { if err != nil {
writeGeneralErrorJson(w, http.StatusBadRequest, "Failed to get users: "+err.Error()) writeGeneralErrorJson(w, http.StatusInternalServerError, "Failed to get users: "+err.Error())
return return
} }

View File

@ -30,8 +30,8 @@
<div class="container py-5"> <div class="container py-5">
<section class="card"> <section class="card">
<div class="card-body"> <div class="card-body">
<h2><em>{{.Name}}</em> group members</h2> <h2><em>{{.Group.Name}}</em> group members</h2>
{{with .Members}} {{with .Group.Members}}
<ul class="list-group"> <ul class="list-group">
{{range .}} {{range .}}
<li class="list-group-item"> <li class="list-group-item">

View File

@ -17,9 +17,9 @@
<div class="container py-5"> <div class="container py-5">
<section class="card"> <section class="card">
<div class="card-body"> <div class="card-body">
<h2><em>{{.Name}}</em> group members</h2> <h2><em>{{.Group.Name}}</em> group members</h2>
<p>{{template "login_prompt"}} to see your groups</p> <p>{{template "login_prompt"}} to see your groups</p>
{{with .Members}} {{with .Group.Members}}
<ul class="list-group"> <ul class="list-group">
{{range .}} {{range .}}
<li class="list-group-item"> <li class="list-group-item">