a mini social media app for small communities
1module database
2
3import entity { Like, LikeCache }
4import util
5
6// add_like adds a like to the database, returns true if this succeeds and false
7// otherwise.
8pub fn (app &DatabaseAccess) add_like(like &Like) bool {
9 sql app.db {
10 insert like into Like
11 // yeet the old cached like value
12 delete from LikeCache where post_id == like.post_id
13 } or {
14 return false
15 }
16 return true
17}
18
19// get_net_likes_for_post returns the net likes of the given post.
20pub fn (app &DatabaseAccess) get_net_likes_for_post(post_id int) int {
21 // check cache
22 cache := app.db.exec_param('SELECT likes FROM "LikeCache" WHERE post_id = $1 LIMIT 1', post_id.str()) or { [] }
23
24 mut likes := 0
25
26 if cache.len != 1 {
27 println('calculating net likes for post: ${post_id}')
28 // calculate
29 db_likes := app.db.exec_param('SELECT is_like FROM "Like" WHERE post_id = $1', post_id.str()) or { [] }
30 for like in db_likes {
31 if util.or_throw(like.vals[0]).bool() {
32 likes++
33 } else {
34 likes--
35 }
36 }
37
38 // cache
39 cached := LikeCache{
40 post_id: post_id
41 likes: likes
42 }
43 sql app.db {
44 insert cached into LikeCache
45 } or {
46 eprintln('failed to cache like: ${cached}')
47 return likes
48 }
49 } else {
50 likes = util.or_throw(cache.first().vals[0]).int()
51 }
52
53 return likes
54}
55
56// unlike_post removes a (dis)like from the given post, returns true if this
57// succeeds and false otherwise.
58pub fn (app &DatabaseAccess) unlike_post(post_id int, user_id int) bool {
59 sql app.db {
60 delete from Like where user_id == user_id && post_id == post_id
61 // yeet the old cached like value
62 delete from LikeCache where post_id == post_id
63 } or {
64 return false
65 }
66 return true
67}