diff --git a/.gitignore b/.gitignore index adf8f72..04d91ae 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ # Go workspace file go.work +gin-bin +TODO diff --git a/main.go b/main.go index ac06593..020b1da 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "database/sql" + "errors" "fmt" "log" "net/http" @@ -15,11 +16,55 @@ import ( var db *sql.DB +// Emoji counts for each post are retrieved in this format type EmojiCount struct { Emoji string TotalCount int } +// Emojis' order should be like this +var emojis = [6]string{"👍", "👎", "😀", "😑", "🤢", "👀"} + +// Get the emoji counts foe a given post id +func countEmojis(postId string) ([]EmojiCount, error) { + emojiList := []EmojiCount{} + // This will hold the total counts for each emoji + // for a given post + var emojiCounter = map[string]int{ + "👍": 0, + "👎": 0, + "😀": 0, + "😑": 0, + "🤢": 0, + "👀": 0, + } + + // Get the emoji counts for each emoji + rows, err := db.Query("SELECT emoji, COUNT(*) FROM emoji_clicks WHERE post_id = ? GROUP BY emoji;", postId) + if err != nil { + return emojiList, errors.New("couldn't get emoji counts") + } + defer rows.Close() + + // Read the rows and update the counter + for rows.Next() { + var ec EmojiCount + if err := rows.Scan(&ec.Emoji, &ec.TotalCount); err != nil { + return emojiList, errors.New("DB results couldn't read") + } + emojiCounter[ec.Emoji] = ec.TotalCount + } + + // Emojis are returned as an ordered list + // as maps are randomly iterated + for _, emoji := range emojis { + var count = EmojiCount{emoji, emojiCounter[emoji]} + emojiList = append(emojiList, count) + } + + return emojiList, nil +} + func main() { cfg := mysql.Config{ User: os.Getenv("DBUSER"), @@ -35,6 +80,7 @@ func main() { log.Fatal(err) } + // Check db connection pingErr := db.Ping() if pingErr != nil { log.Fatal(pingErr) @@ -44,85 +90,59 @@ func main() { r := gin.Default() r.LoadHTMLGlob("templates/*") + // CORS configuration corsConfig := cors.DefaultConfig() corsConfig.AllowOrigins = []string{"*"} corsConfig.AllowHeaders = []string{"hx-current-url", "hx-request"} r.Use(cors.New(corsConfig)) + // Get the emoji form, you must provide postId query parameter r.GET("/forms/emoji", func(c *gin.Context) { - var emojiCounts = map[string]int{ - "👍": 0, - "👎": 0, - "😀": 0, - "😑": 0, - "🤢": 0, - "👀": 0, - } postId := c.Query("postId") - rows, err := db.Query("SELECT emoji, COUNT(*) FROM emoji_clicks WHERE post_id = ? GROUP BY emoji;", postId) + // get emoji counts for each emoji + emojiCounter, err := countEmojis(postId) if err != nil { - c.HTML(http.StatusOK, "emoji_form.tmpl", gin.H{"error": err.Error(), "postId": postId}) + c.HTML(http.StatusOK, "emoji_form.tmpl", gin.H{"error": "error getting the emoji counts", "postId": postId}) return } - defer rows.Close() - - for rows.Next() { - var ec EmojiCount - if err := rows.Scan(&ec.Emoji, &ec.TotalCount); err != nil { - c.HTML(http.StatusOK, "emoji_form.tmpl", gin.H{"error": "error getting emoji rows", "postId": postId}) - return - } - emojiCounts[ec.Emoji] = ec.TotalCount - } + // Return the html template c.HTML(http.StatusOK, "emoji_form.tmpl", gin.H{ "postId": c.Query("postId"), - "results": emojiCounts, + "results": emojiCounter, }) }) + // Update the emoji counter, this handler will + // add a new entry to the database with anonymized ip + // then sums the results to get the emoji counter r.POST("/forms/emoji/post", func(c *gin.Context) { postId := c.PostForm("postId") emoji := c.PostForm("emojiInput") - var emojiCounts = map[string]int{ - "👍": 0, - "👎": 0, - "😀": 0, - "😑": 0, - "🤢": 0, - "👀": 0, - } - + // Check if parameters are missing if postId == "" || emoji == "" { c.HTML(http.StatusOK, "emoji_form.tmpl", gin.H{"error": "missing parameters", "postId": postId}) return } + // Add the new emoji entry to the database _, err := db.Exec("INSERT INTO emoji_clicks (post_id, emoji) VALUES (?, ?)", postId, emoji) if err != nil { c.HTML(http.StatusOK, "emoji_form.tmpl", gin.H{"error": "error writing to database", "postId": postId}) return } - rows, err := db.Query("SELECT emoji, COUNT(*) FROM emoji_clicks WHERE post_id = ? GROUP BY emoji;", postId) + // get emoji counts for each emoji + emojiCounter, err := countEmojis(postId) if err != nil { - c.HTML(http.StatusOK, "emoji_form.tmpl", gin.H{"error": err.Error(), "postId": postId}) + c.HTML(http.StatusOK, "emoji_form.tmpl", gin.H{"error": "error getting the emoji counts", "postId": postId}) return } - defer rows.Close() - for rows.Next() { - var ec EmojiCount - if err := rows.Scan(&ec.Emoji, &ec.TotalCount); err != nil { - c.HTML(http.StatusOK, "emoji_form.tmpl", gin.H{"error": "error getting emoji rows", "postId": postId}) - return - } - emojiCounts[ec.Emoji] = ec.TotalCount - } - - c.HTML(http.StatusOK, "emoji_form.tmpl", gin.H{"postId": postId, "results": emojiCounts}) + // Return the html with the updated emoji counter + c.HTML(http.StatusOK, "emoji_form.tmpl", gin.H{"postId": postId, "results": emojiCounter}) }) r.Run(":3001") diff --git a/templates/emoji_form.tmpl b/templates/emoji_form.tmpl index c31efe0..b469e50 100644 --- a/templates/emoji_form.tmpl +++ b/templates/emoji_form.tmpl @@ -1,12 +1,9 @@
- - - - - - +{{ range .results }} + +{{ end }}

{{.error}}