1package database23import (4 "context"5 "strings"67 "github.com/charmbracelet/soft-serve/pkg/access"8 "github.com/charmbracelet/soft-serve/pkg/db"9 "github.com/charmbracelet/soft-serve/pkg/db/models"10 "github.com/charmbracelet/soft-serve/pkg/store"11 "github.com/charmbracelet/soft-serve/pkg/utils"12)1314type collabStore struct{}1516var _ store.CollaboratorStore = (*collabStore)(nil)1718// AddCollabByUsernameAndRepo implements store.CollaboratorStore.19func (*collabStore) AddCollabByUsernameAndRepo(ctx context.Context, tx db.Handler, username string, repo string, level access.AccessLevel) error {20 username = strings.ToLower(username)21 if err := utils.ValidateUsername(username); err != nil {22 return err23 }2425 repo = utils.SanitizeRepo(repo)2627 query := tx.Rebind(`INSERT INTO collabs (access_level, user_id, repo_id, updated_at)28 VALUES (29 ?,30 (31 SELECT id FROM users WHERE username = ?32 ),33 (34 SELECT id FROM repos WHERE name = ?35 ),36 CURRENT_TIMESTAMP37 );`)38 _, err := tx.ExecContext(ctx, query, level, username, repo)39 return err40}4142// GetCollabByUsernameAndRepo implements store.CollaboratorStore.43func (*collabStore) GetCollabByUsernameAndRepo(ctx context.Context, tx db.Handler, username string, repo string) (models.Collab, error) {44 var m models.Collab4546 username = strings.ToLower(username)47 if err := utils.ValidateUsername(username); err != nil {48 return models.Collab{}, err49 }5051 repo = utils.SanitizeRepo(repo)5253 err := tx.GetContext(ctx, &m, tx.Rebind(`54 SELECT55 collabs.*56 FROM57 collabs58 INNER JOIN users ON users.id = collabs.user_id59 INNER JOIN repos ON repos.id = collabs.repo_id60 WHERE61 users.username = ? AND repos.name = ?62 `), username, repo)6364 return m, err65}6667// ListCollabsByRepo implements store.CollaboratorStore.68func (*collabStore) ListCollabsByRepo(ctx context.Context, tx db.Handler, repo string) ([]models.Collab, error) {69 var m []models.Collab7071 repo = utils.SanitizeRepo(repo)72 query := tx.Rebind(`73 SELECT74 collabs.*75 FROM76 collabs77 INNER JOIN repos ON repos.id = collabs.repo_id78 WHERE79 repos.name = ?80 `)8182 err := tx.SelectContext(ctx, &m, query, repo)83 return m, err84}8586// ListCollabsByRepoAsUsers implements store.CollaboratorStore.87func (*collabStore) ListCollabsByRepoAsUsers(ctx context.Context, tx db.Handler, repo string) ([]models.User, error) {88 var m []models.User8990 repo = utils.SanitizeRepo(repo)91 query := tx.Rebind(`92 SELECT93 users.*94 FROM95 users96 INNER JOIN collabs ON collabs.user_id = users.id97 INNER JOIN repos ON repos.id = collabs.repo_id98 WHERE99 repos.name = ?100 `)101102 err := tx.SelectContext(ctx, &m, query, repo)103 return m, err104}105106// RemoveCollabByUsernameAndRepo implements store.CollaboratorStore.107func (*collabStore) RemoveCollabByUsernameAndRepo(ctx context.Context, tx db.Handler, username string, repo string) error {108 username = strings.ToLower(username)109 if err := utils.ValidateUsername(username); err != nil {110 return err111 }112113 repo = utils.SanitizeRepo(repo)114 query := tx.Rebind(`115 DELETE FROM116 collabs117 WHERE118 user_id = (119 SELECT id FROM users WHERE username = ?120 ) AND repo_id = (121 SELECT id FROM repos WHERE name = ?122 )123 `)124 _, err := tx.ExecContext(ctx, query, username, repo)125 return err126}