parent
5a19fc041d
commit
aa26a8f338
@ -40,3 +40,19 @@ func TestGetUserBadId(t *testing.T) {
|
|||||||
e := startServer(t)
|
e := startServer(t)
|
||||||
e.GET("/user/bad-id").Expect().Status(400)
|
e.GET("/user/bad-id").Expect().Status(400)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetUserGoalsWhenNoGoalsPresent(t *testing.T) {
|
||||||
|
e := startServer(t)
|
||||||
|
result := e.GET("/user/1/goals").Expect().Status(200).JSON().Array()
|
||||||
|
result.Length().IsEqual(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetUserGoalsNoUser(t *testing.T) {
|
||||||
|
e := startServer(t)
|
||||||
|
e.GET("/user/999/goals").Expect().Status(404)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetUserGoalsBadId(t *testing.T) {
|
||||||
|
e := startServer(t)
|
||||||
|
e.GET("/user/bad-id/goals").Expect().Status(400)
|
||||||
|
}
|
||||||
|
@ -57,3 +57,32 @@ func (db *Db) GetUser(id int) (*User, error) {
|
|||||||
}
|
}
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *Db) UserExists(userId int) (bool, error) {
|
||||||
|
count := 0
|
||||||
|
err := db.db.Query("select count(*) from users where id = ?").
|
||||||
|
Bind(userId).ScanSingle(&count)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return count > 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Db) GetUserGoals(userId int) ([]Goal, error) {
|
||||||
|
goals := make([]Goal, 0)
|
||||||
|
var err error
|
||||||
|
|
||||||
|
for row := range db.db.Query("select id, name, target, progress, weight from goals where user_id = ?").
|
||||||
|
Bind(userId).Range(&err) {
|
||||||
|
goal := Goal{}
|
||||||
|
err = row.Scan(&goal.ID, &goal.Name, &goal.Target, &goal.Progress, &goal.Weight)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
goals = append(goals, goal)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return goals, nil
|
||||||
|
}
|
||||||
|
@ -15,10 +15,18 @@ import (
|
|||||||
var migrations embed.FS
|
var migrations embed.FS
|
||||||
var db *Db
|
var db *Db
|
||||||
|
|
||||||
|
// ServerConfig holds configuration for the server.
|
||||||
type ServerConfig struct {
|
type ServerConfig struct {
|
||||||
|
// The datasource to the SQLite database.
|
||||||
|
// Use ":memory:" for an in-memory database.
|
||||||
Datasource string
|
Datasource string
|
||||||
Port string
|
|
||||||
Started chan bool
|
// The port to listen on.
|
||||||
|
// Use an empty string to listen on a random port.
|
||||||
|
Port string
|
||||||
|
|
||||||
|
// The channel that gets signaled when the server has started.
|
||||||
|
Started chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUsers(c *gin.Context) {
|
func getUsers(c *gin.Context) {
|
||||||
@ -54,6 +62,41 @@ func getUser(c *gin.Context) {
|
|||||||
c.IndentedJSON(http.StatusOK, user)
|
c.IndentedJSON(http.StatusOK, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getUserGoals(c *gin.Context) {
|
||||||
|
userIdStr := c.Param("userId")
|
||||||
|
userId, err := strconv.Atoi(userIdStr)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Invalid user ID: %v", err)
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
exists, err := db.UserExists(userId)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error checking user existence: %v", err)
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal Server Error"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
log.Printf("Error checking user existence: %v", err)
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
goals, err := db.GetUserGoals(userId)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error getting user goals: %v", err)
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal Server Error"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.IndentedJSON(http.StatusOK, goals)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
Initialises the database, and then starts the server.
|
||||||
|
If the context gets cancelled, the server is shutdown and the database is closed.
|
||||||
|
*/
|
||||||
func start(ctx context.Context, config *ServerConfig) {
|
func start(ctx context.Context, config *ServerConfig) {
|
||||||
db = NewDb(config.Datasource)
|
db = NewDb(config.Datasource)
|
||||||
defer db.db.MustClose()
|
defer db.db.MustClose()
|
||||||
@ -61,6 +104,7 @@ func start(ctx context.Context, config *ServerConfig) {
|
|||||||
router := gin.Default()
|
router := gin.Default()
|
||||||
router.GET("/api/users", getUsers)
|
router.GET("/api/users", getUsers)
|
||||||
router.GET("/api/user/:userId", getUser)
|
router.GET("/api/user/:userId", getUser)
|
||||||
|
router.GET("/api/user/:userId/goals", getUserGoals)
|
||||||
|
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
Addr: ":" + config.Port,
|
Addr: ":" + config.Port,
|
||||||
@ -73,7 +117,9 @@ func start(ctx context.Context, config *ServerConfig) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
log.Printf("Running server on port %s\n", config.Port)
|
log.Printf("Running server on port %s\n", config.Port)
|
||||||
config.Started <- true
|
if config.Started != nil {
|
||||||
|
config.Started <- true
|
||||||
|
}
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
log.Println("Shutting down")
|
log.Println("Shutting down")
|
||||||
if err := srv.Shutdown(context.Background()); err != nil {
|
if err := srv.Shutdown(context.Background()); err != nil {
|
||||||
|
@ -15,6 +15,7 @@ create table history
|
|||||||
create table goals
|
create table goals
|
||||||
(
|
(
|
||||||
id integer primary key,
|
id integer primary key,
|
||||||
|
user_id integer not null,
|
||||||
name text not null,
|
name text not null,
|
||||||
target integer not null,
|
target integer not null,
|
||||||
progress integer not null,
|
progress integer not null,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user