package main import ( "database/sql" "github.com/gin-gonic/gin" _ "github.com/mattn/go-sqlite3" "net/http" ) // define global db var db, _ = sql.Open("sqlite3", "./database/data.db") // types representing json queries type loginInput struct { Name string `json:"name"` Password string `json:"password"` } type loginOutput struct { UID int `json:"uid"` Name string `json:"name"` Password string `json:"password"` Role string `json:"role"` } type task struct { TID int `json:"tid"` Name string `json:"name"` Points int `json:"points"` } type taskArray struct { Tasks []task `json:"tasks"` } type historyData struct { UID int `json:"uid"` TID int `json:"tid"` Time string `json:"time"` PointsGained int `json:"pointsGained"` } type historyArray struct { History []historyData `json:"history"` } // log the user into their account func login(c *gin.Context) { // get the username and password from the request var userData loginInput if err := c.BindJSON(&userData); err != nil { c.IndentedJSON(http.StatusBadRequest, userData) return } // check for user using given credentials stmt, err := db.Prepare("SELECT * FROM users WHERE name=?") checkErr(err) defer stmt.Close() var user loginOutput err = stmt.QueryRow(userData.Name).Scan(&user.UID, &user.Name, &user.Password, &user.Role) if err != nil { // search failed user not real c.IndentedJSON(http.StatusNotFound, userData) panic(err) return } if user.Password != userData.Password { // user not real c.IndentedJSON(http.StatusNotFound, userData) panic(err) return } else { // user is in c.IndentedJSON(http.StatusOK, user) } } func getTasks(c *gin.Context) { // return a list of all the tasks var tasks []task // get array of all tasks rows, err := db.Query("SELECT * FROM activities") checkErr(err) for rows.Next() { var tempTask task err = rows.Scan(&tempTask.TID, &tempTask.Name, &tempTask.Points) if err != nil { c.IndentedJSON(http.StatusNotFound, tasks) return } tasks = append(tasks, tempTask) } rows.Close() var jsonTasks taskArray jsonTasks.Tasks = tasks c.IndentedJSON(http.StatusOK, jsonTasks) } func completeTask(c *gin.Context) { // get the task data from the request var completedTask historyData if err := c.BindJSON(&completedTask); err != nil { c.IndentedJSON(http.StatusBadRequest, completedTask) return } // insert data to history table stmt, err := db.Prepare("INSERT INTO history (uid, taskid, time, pointsGained) VALUES (?, ?, ?, ?)") if err != nil { c.IndentedJSON(http.StatusNotModified, completedTask) return } _, err = stmt.Exec(completedTask.UID, completedTask.TID, completedTask.Time, completedTask.PointsGained) if err != nil { c.IndentedJSON(http.StatusNotModified, completedTask) return } c.IndentedJSON(http.StatusOK, completedTask) } func getHistory(c *gin.Context) { // get the log of past points gained var history []historyData // get array of all historyData rows, err := db.Query("SELECT * FROM history") checkErr(err) for rows.Next() { var tempHistoryData historyData err = rows.Scan(&tempHistoryData.UID, &tempHistoryData.TID, &tempHistoryData.Time, &tempHistoryData.PointsGained) if err != nil { c.IndentedJSON(http.StatusNotFound, history) return } history = append(history, tempHistoryData) } rows.Close() var jsonHistory historyArray jsonHistory.History = history c.IndentedJSON(http.StatusOK, jsonHistory) } func addTask(c *gin.Context) { // get the data of the new task var newTask task if err := c.BindJSON(&newTask); err != nil { c.IndentedJSON(http.StatusBadRequest, newTask) return } // insert new task into the task table stmt, err := db.Prepare("INSERT INTO activities (name, points) VALUES (?,?)") if err != nil { c.IndentedJSON(http.StatusNotModified, newTask) return } _, err = stmt.Exec(newTask.Name, newTask.Points) if err != nil { c.IndentedJSON(http.StatusNotModified, newTask) return } c.IndentedJSON(http.StatusOK, newTask) } func main() { //release mode //gin.SetMode(gin.ReleaseMode) router := gin.Default() // api routes router.POST("/login", login) router.POST("/completeTask", completeTask) router.POST("/addTask", addTask) router.GET("/getTasks", getTasks) router.GET("/getHistory", getHistory) // page routes router.LoadHTMLGlob("frontend/*") router.GET("/", func(c *gin.Context) { c.HTML(http.StatusOK, "index.html", gin.H{}) }) router.Static("/frontend", "./frontend") router.Run("localhost:8080") } func checkErr(err error) { if err != nil { panic(err) } }