a mini social media app for small communities
1module database
2
3import db.pg
4import entity { SavedPost, Post }
5import util
6
7// get_saved_posts_for gets all SavedPost objects for a given user.
8pub fn (app &DatabaseAccess) get_saved_posts_for(user_id int) []SavedPost {
9 saved_posts := sql app.db {
10 select from SavedPost where user_id == user_id && saved == true
11 } or { [] }
12 return saved_posts
13}
14
15// get_saved_posts_as_post_for gets all saved posts for a given user converted
16// to Post objects.
17pub fn (app &DatabaseAccess) get_saved_posts_as_post_for(user_id int) []Post {
18 saved_posts := app.db.exec_param('SELECT id, post_id FROM "SavedPost" WHERE user_id = $1 AND saved = TRUE', user_id.str()) or { [] }
19 posts := saved_posts.map(fn [app] (it pg.Row) Post {
20 return app.get_post_by_id(util.or_throw(it.vals[1]).int()) or {
21 // if the post does not exist, we will remove it now
22 id := util.or_throw(it.vals[0]).int()
23 sql app.db {
24 delete from SavedPost where id == id
25 } or {
26 eprintln('get_saved_posts_as_post_for: failed to remove non-existent post from saved post: ${it}')
27 }
28 app.get_unknown_post()
29 }
30 }).filter(it.id != 0)
31 return posts
32}
33
34// get_saved_posts_as_post_for gets all posts saved for later for a given user
35// converted to Post objects.
36pub fn (app &DatabaseAccess) get_saved_for_later_posts_as_post_for(user_id int) []Post {
37 saved_posts := sql app.db {
38 select from SavedPost where user_id == user_id && later == true
39 } or { [] }
40 posts := saved_posts.map(fn [app] (it SavedPost) Post {
41 return app.get_post_by_id(it.post_id) or {
42 // if the post does not exist, we will remove it now
43 sql app.db {
44 delete from SavedPost where id == it.id
45 } or {
46 eprintln('get_saved_for_later_posts_as_post_for: failed to remove non-existent post from saved post: ${it}')
47 }
48 app.get_unknown_post()
49 }
50 }).filter(it.id != 0)
51 return posts
52}
53
54// get_user_post_save_status returns the SavedPost object representing the user
55// and post id. returns none if the post is not saved anywhere.
56pub fn (app &DatabaseAccess) get_user_post_save_status(user_id int, post_id int) ?SavedPost {
57 saved_posts := sql app.db {
58 select from SavedPost where user_id == user_id && post_id == post_id
59 } or { [] }
60 if saved_posts.len == 1 {
61 return saved_posts[0]
62 } else if saved_posts.len == 0 {
63 return none
64 } else {
65 eprintln('get_user_post_save_status: user `${user_id}` had multiple SavedPost entries for post `${post_id}')
66 return none
67 }
68}
69
70pub fn (app &DatabaseAccess) is_post_saved_by(user_id int, post_id int) bool {
71 saved_post := app.get_user_post_save_status(user_id, post_id) or {
72 return false
73 }
74 return saved_post.saved
75}
76
77pub fn (app &DatabaseAccess) is_post_saved_for_later_by(user_id int, post_id int) bool {
78 saved_post := app.get_user_post_save_status(user_id, post_id) or {
79 return false
80 }
81 return saved_post.later
82}
83
84// toggle_save_post (un)saves the given post for the user. returns true if this
85// succeeds and false otherwise.
86pub fn (app &DatabaseAccess) toggle_save_post(user_id int, post_id int) bool {
87 if s := app.get_user_post_save_status(user_id, post_id) {
88 if s.saved {
89 sql app.db {
90 update SavedPost set saved = false where id == s.id
91 } or {
92 eprintln('toggle_save_post: failed to unsave post (user_id: ${user_id}, post_id: ${post_id})')
93 return false
94 }
95 return true
96 } else {
97 sql app.db {
98 update SavedPost set saved = true where id == s.id
99 } or {
100 eprintln('toggle_save_post: failed to save post (user_id: ${user_id}, post_id: ${post_id})')
101 return false
102 }
103 return true
104 }
105 } else {
106 post := SavedPost{
107 user_id: user_id
108 post_id: post_id
109 saved: true
110 later: false
111 }
112 sql app.db {
113 insert post into SavedPost
114 } or {
115 eprintln('toggle_save_post: failed to create saved post: ${post}')
116 return false
117 }
118 return true
119 }
120}
121
122// toggle_save_for_later_post (un)saves the given post for later for the user.
123// returns true if this succeeds and false otherwise.
124pub fn (app &DatabaseAccess) toggle_save_for_later_post(user_id int, post_id int) bool {
125 if s := app.get_user_post_save_status(user_id, post_id) {
126 if s.later {
127 sql app.db {
128 update SavedPost set later = false where id == s.id
129 } or {
130 eprintln('toggle_save_post: failed to unsave post for later (user_id: ${user_id}, post_id: ${post_id})')
131 return false
132 }
133 return true
134 } else {
135 sql app.db {
136 update SavedPost set later = true where id == s.id
137 } or {
138 eprintln('toggle_save_post: failed to save post for later (user_id: ${user_id}, post_id: ${post_id})')
139 return false
140 }
141 return true
142 }
143 } else {
144 post := SavedPost{
145 user_id: user_id
146 post_id: post_id
147 saved: false
148 later: true
149 }
150 sql app.db {
151 insert post into SavedPost
152 } or {
153 eprintln('toggle_save_post: failed to create saved post for later: ${post}')
154 return false
155 }
156 return true
157 }
158}