diff --git a/backend/internal/database/db.go b/backend/internal/database/db.go index f05530a..e7f9251 100644 --- a/backend/internal/database/db.go +++ b/backend/internal/database/db.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "time" + "ttime/internal/types" "github.com/jmoiron/sqlx" _ "github.com/mattn/go-sqlite3" @@ -25,6 +26,9 @@ type Database interface { ChangeUserRole(username string, projectname string, role string) error GetAllUsersProject(projectname string) ([]UserProjectMember, error) GetAllUsersApplication() ([]string, error) + GetProjectsForUser(username string) ([]types.Project, error) + GetAllProjects() ([]types.Project, error) + GetUserRole(username string, projectname string) (string, error) } // This struct is a wrapper type that holds the database connection @@ -52,6 +56,21 @@ const addTimeReport = `WITH UserLookup AS (SELECT id FROM users WHERE username = const addUserToProject = "INSERT INTO user_roles (user_id, project_id, p_role) VALUES (?, ?, ?)" // WIP const changeUserRole = "UPDATE user_roles SET p_role = ? WHERE user_id = ? AND project_id = ?" +const getProjectsForUser = ` +SELECT + projects.id, + projects.name, + projects.description, + projects.owner_user_id +FROM + projects +JOIN + user_roles ON projects.id = user_roles.project_id +JOIN + users ON user_roles.user_id = users.id +WHERE + users.username = ?;` + // DbConnect connects to the database func DbConnect(dbpath string) Database { // Open the database @@ -69,6 +88,18 @@ func DbConnect(dbpath string) Database { return &Db{db} } +func (d *Db) GetProjectsForUser(username string) ([]types.Project, error) { + var projects []types.Project + err := d.Select(&projects, getProjectsForUser, username) + return projects, err +} + +func (d *Db) GetAllProjects() ([]types.Project, error) { + var projects []types.Project + err := d.Select(&projects, "SELECT * FROM projects") + return projects, err +} + func (d *Db) AddTimeReport(projectName string, userName string, start time.Time, end time.Time) error { // WIP _, err := d.Exec(addTimeReport, userName, projectName, start, end) return err @@ -108,6 +139,12 @@ func (d *Db) ChangeUserRole(username string, projectname string, role string) er return err3 } +func (d *Db) GetUserRole(username string, projectname string) (string, error) { + var role string + err := d.Get(&role, "SELECT p_role FROM user_roles WHERE user_id = (SELECT id FROM users WHERE username = ?) AND project_id = (SELECT id FROM projects WHERE name = ?)", username, projectname) + return role, err +} + // AddUser adds a user to the database func (d *Db) AddUser(username string, password string) error { _, err := d.Exec(userInsert, username, password) diff --git a/backend/internal/database/db_test.go b/backend/internal/database/db_test.go index e5aceb2..7650739 100644 --- a/backend/internal/database/db_test.go +++ b/backend/internal/database/db_test.go @@ -169,10 +169,27 @@ func TestChangeUserRole(t *testing.T) { t.Error("AddUserToProject failed:", err) } + role, err := db.GetUserRole("testuser", "testproject") + if err != nil { + t.Error("GetUserRole failed:", err) + } + if role != "user" { + t.Error("GetUserRole failed: expected user, got", role) + } + err = db.ChangeUserRole("testuser", "testproject", "admin") if err != nil { t.Error("ChangeUserRole failed:", err) } + + role, err = db.GetUserRole("testuser", "testproject") + if err != nil { + t.Error("GetUserRole failed:", err) + } + if role != "admin" { + t.Error("GetUserRole failed: expected admin, got", role) + } + } func TestGetAllUsersProject(t *testing.T) { @@ -286,3 +303,43 @@ func TestGetAllUsersApplication(t *testing.T) { t.Error("testuser2 not found") } } + +func TestGetProjectsForUser(t *testing.T) { + db, err := setupState() + if err != nil { + t.Error("setupState failed:", err) + } + + err = db.AddUser("testuser", "password") + if err != nil { + t.Error("AddUser failed:", err) + } + + err = db.AddProject("testproject", "description", "testuser") + if err != nil { + t.Error("AddProject failed:", err) + } + + err = db.AddUserToProject("testuser", "testproject", "user") + if err != nil { + t.Error("AddUserToProject failed:", err) + } + + projects1, err := db.GetAllProjects() + if err != nil { + t.Error("GetAllProjects failed:", err) + } + + if len(projects1) != 1 { + t.Error("GetAllProjects failed: expected 1, got", len(projects1)) + } + + projects, err := db.GetProjectsForUser("testuser") + if err != nil { + t.Error("GetProjectsForUser failed:", err) + } + + if len(projects) != 1 { + t.Error("GetProjectsForUser failed: expected 1, got", len(projects)) + } +} diff --git a/backend/internal/types/project.go b/backend/internal/types/project.go index cabf6c6..8fcfaf5 100644 --- a/backend/internal/types/project.go +++ b/backend/internal/types/project.go @@ -1,16 +1,11 @@ package types -import ( - "time" -) - // Project is a struct that holds the information about a project type Project struct { - ID int `json:"id" db:"id"` - Name string `json:"name" db:"name"` - Description string `json:"description" db:"description"` - Owner string `json:"owner" db:"owner"` - Created time.Time `json:"created" db:"created"` + ID int `json:"id" db:"id"` + Name string `json:"name" db:"name"` + Description string `json:"description" db:"description"` + Owner string `json:"owner" db:"owner_user_id"` } // As it arrives from the client