+26
src/database/like.v
+26
src/database/like.v
···
2
2
3
3
import entity { Like, LikeCache }
4
4
5
+
// add_like adds a like to the database, returns true if this succeeds and false
6
+
// otherwise.
7
+
pub fn (app &DatabaseAccess) add_like(like &Like) bool {
8
+
sql app.db {
9
+
insert like into Like
10
+
// yeet the old cached like value
11
+
delete from LikeCache where post_id == like.post_id
12
+
} or {
13
+
return false
14
+
}
15
+
return true
16
+
}
17
+
5
18
// get_net_likes_for_post returns the net likes of the given post.
6
19
pub fn (app &DatabaseAccess) get_net_likes_for_post(post_id int) int {
7
20
// check cache
···
43
56
44
57
return likes
45
58
}
59
+
60
+
// unlike_post removes a (dis)like from the given post, returns true if this
61
+
// succeeds and false otherwise.
62
+
pub fn (app &DatabaseAccess) unlike_post(post_id int, user_id int) bool {
63
+
sql app.db {
64
+
delete from Like where user_id == user_id && post_id == post_id
65
+
// yeet the old cached like value
66
+
delete from LikeCache where post_id == post_id
67
+
} or {
68
+
return false
69
+
}
70
+
return true
71
+
}
+34
src/database/notification.v
+34
src/database/notification.v
···
2
2
3
3
import entity { Notification }
4
4
5
+
// get_notification_by_id gets a notification by its given id, returns none if
6
+
// the notification does not exist.
7
+
pub fn (app &DatabaseAccess) get_notification_by_id(id int) ?Notification {
8
+
notifications := sql app.db {
9
+
select from Notification where id == id
10
+
} or { [] }
11
+
if notifications.len != 1 {
12
+
return none
13
+
}
14
+
return notifications[0]
15
+
}
16
+
17
+
// delete_notification deletes the given notification, returns true if this
18
+
// succeeded and false otherwise.
19
+
pub fn (app &DatabaseAccess) delete_notification(id int) bool {
20
+
sql app.db {
21
+
delete from Notification where id == id
22
+
} or {
23
+
return false
24
+
}
25
+
return true
26
+
}
27
+
28
+
// delete_notifications_for_user deletes all notifications for the given user,
29
+
// returns true if this succeeded and false otherwise.
30
+
pub fn (app &DatabaseAccess) delete_notifications_for_user(user_id int) bool {
31
+
sql app.db {
32
+
delete from Notification where user_id == user_id
33
+
} or {
34
+
return false
35
+
}
36
+
return true
37
+
}
38
+
5
39
// get_notifications_for gets a list of notifications for the given user.
6
40
pub fn (app &DatabaseAccess) get_notifications_for(user_id int) []Notification {
7
41
notifications := sql app.db {
+46
src/database/post.v
+46
src/database/post.v
···
3
3
import time
4
4
import entity { Post, Like, LikeCache }
5
5
6
+
// add_post adds a new post to the database, returns true if this succeeded and
7
+
// false otherwise.
8
+
pub fn (app &DatabaseAccess) add_post(post &Post) bool {
9
+
sql app.db {
10
+
insert post into Post
11
+
} or {
12
+
return false
13
+
}
14
+
return true
15
+
}
16
+
6
17
// get_post_by_id gets a post by its id, returns none if it does not exist.
7
18
pub fn (app &DatabaseAccess) get_post_by_id(id int) ?Post {
8
19
posts := sql app.db {
···
84
95
} or { [] }
85
96
return posts
86
97
}
98
+
99
+
// pin_post pins the given post, returns true if this succeeds and false
100
+
// otherwise.
101
+
pub fn (app &DatabaseAccess) pin_post(post_id int) bool {
102
+
sql app.db {
103
+
update Post set pinned = true where id == post_id
104
+
} or {
105
+
return false
106
+
}
107
+
return true
108
+
}
109
+
110
+
// update_post updates the given post's title and body with the given title and
111
+
// body, returns true if this succeeds and false otherwise.
112
+
pub fn (app &DatabaseAccess) update_post(post_id int, new_title string, new_body string) bool {
113
+
sql app.db {
114
+
update Post set body = new_body, title = new_title where id == post_id
115
+
} or {
116
+
return false
117
+
}
118
+
return true
119
+
}
120
+
121
+
// delete_post deletes the given post and all likes associated with it, returns
122
+
// true if this succeeds and false otherwise.
123
+
pub fn (app &DatabaseAccess) delete_post(id int) bool {
124
+
sql app.db {
125
+
delete from Post where id == id
126
+
delete from Like where post_id == id
127
+
delete from LikeCache where post_id == id
128
+
} or {
129
+
return false
130
+
}
131
+
return true
132
+
}
+11
src/database/site.v
+11
src/database/site.v
···
18
18
}
19
19
return configs[0]
20
20
}
21
+
22
+
// set_motd sets the site's current message of the day, returns true if this
23
+
// succeeds and false otherwise.
24
+
pub fn (app &DatabaseAccess) set_motd(motd string) bool {
25
+
sql app.db {
26
+
update Site set motd = motd where id == 1
27
+
} or {
28
+
return false
29
+
}
30
+
return true
31
+
}
+35
-1
src/database/user.v
+35
-1
src/database/user.v
···
1
1
module database
2
2
3
-
import entity { User, Notification, Like, Post }
3
+
import entity { User, Notification, Like, LikeCache, Post }
4
4
5
5
// new_user creates a new user and returns their struct after creation.
6
6
pub fn (app &DatabaseAccess) new_user(user User) ?User {
···
172
172
}
173
173
return likes.len == 1
174
174
}
175
+
176
+
// delete_user deletes the given user and their data, returns true if this
177
+
// succeeded and false otherwise.
178
+
pub fn (app &DatabaseAccess) delete_user(user_id int) bool {
179
+
sql app.db {
180
+
delete from User where id == user_id
181
+
delete from Like where user_id == user_id
182
+
delete from Notification where user_id == user_id
183
+
} or {
184
+
return false
185
+
}
186
+
187
+
// delete posts and their likes
188
+
posts_from_this_user := sql app.db {
189
+
select from Post where author_id == id
190
+
} or { [] }
191
+
192
+
for post in posts_from_this_user {
193
+
sql app.db {
194
+
delete from Like where post_id == post.id
195
+
delete from LikeCache where post_id == post.id
196
+
} or {
197
+
eprintln('failed to delete like cache for post during user deletion: ${post.id}')
198
+
}
199
+
}
200
+
201
+
sql app.db {
202
+
delete from Post where author_id == id
203
+
} or {
204
+
eprintln('failed to delete posts by deleting user: ${user_id}')
205
+
}
206
+
207
+
return true
208
+
}
+30
-78
src/webapp/api.v
+30
-78
src/webapp/api.v
···
329
329
330
330
@['/api/user/notification/clear']
331
331
fn (mut app App) api_user_notification_clear(mut ctx Context, id int) veb.Result {
332
-
if !ctx.is_logged_in() {
332
+
user := app.whoami(mut ctx) or {
333
333
ctx.error('you are not logged in!')
334
334
return ctx.redirect('/login')
335
335
}
336
-
sql app.db {
337
-
delete from Notification where id == id
338
-
} or {
339
-
ctx.error('failed to delete notification')
340
-
return ctx.redirect('/inbox')
336
+
337
+
if notification := app.get_notification_by_id(id) {
338
+
if notification.user_id != user.id {
339
+
ctx.error('no such notification for user')
340
+
return ctx.redirect('/inbox')
341
+
} else {
342
+
if !app.delete_notification(id) {
343
+
ctx.error('failed to delete notification')
344
+
return ctx.redirect('/inbox')
345
+
}
346
+
}
347
+
} else {
348
+
ctx.error('no such notification for user')
341
349
}
350
+
342
351
return ctx.redirect('/inbox')
343
352
}
344
353
···
348
357
ctx.error('you are not logged in!')
349
358
return ctx.redirect('/login')
350
359
}
351
-
sql app.db {
352
-
delete from Notification where user_id == user.id
353
-
} or {
360
+
if !app.delete_notifications_for_user(user.id) {
354
361
ctx.error('failed to delete notifications')
355
362
return ctx.redirect('/inbox')
356
363
}
···
368
375
369
376
if user.admin || user.id == id {
370
377
// yeet
371
-
sql app.db {
372
-
delete from User where id == id
373
-
delete from Like where user_id == id
374
-
delete from Notification where user_id == id
375
-
} or {
378
+
if !app.delete_user(user.id) {
376
379
ctx.error('failed to delete user: ${id}')
377
380
return ctx.redirect('/')
378
-
}
379
-
380
-
// delete posts and their likes
381
-
posts_from_this_user := sql app.db {
382
-
select from Post where author_id == id
383
-
} or { [] }
384
-
385
-
for post in posts_from_this_user {
386
-
sql app.db {
387
-
delete from Like where post_id == post.id
388
-
delete from LikeCache where post_id == post.id
389
-
} or {
390
-
eprintln('failed to delete like cache for post during user deletion: ${post.id}')
391
-
}
392
-
}
393
-
394
-
sql app.db {
395
-
delete from Post where author_id == id
396
-
} or {
397
-
eprintln('failed to delete posts by deleting user: ${user.id}')
398
381
}
399
382
400
383
app.auth.delete_tokens_for_user(id) or {
···
459
442
post.replying_to = replying_to
460
443
}
461
444
462
-
sql app.db {
463
-
insert post into Post
464
-
} or {
445
+
if !app.add_post(post) {
465
446
ctx.error('failed to post!')
466
447
println('failed to post: ${post} from user ${user.id}')
467
448
return ctx.redirect('/post/new')
···
490
471
}
491
472
492
473
if user.admin || user.id == post.author_id {
493
-
sql app.db {
494
-
delete from Post where id == id
495
-
delete from Like where post_id == id
496
-
} or {
474
+
if !app.delete_post(post.id) {
497
475
ctx.error('failed to delete post')
498
476
eprintln('failed to delete post: ${id}')
499
477
return ctx.redirect('/')
···
514
492
post := app.get_post_by_id(id) or { return ctx.server_error('post does not exist') }
515
493
516
494
if app.does_user_like_post(user.id, post.id) {
517
-
sql app.db {
518
-
delete from Like where user_id == user.id && post_id == post.id
519
-
// yeet the old cached like value
520
-
delete from LikeCache where post_id == post.id
521
-
} or {
495
+
if !app.unlike_post(post.id, user.id) {
522
496
eprintln('user ${user.id} failed to unlike post ${id}')
523
497
return ctx.server_error('failed to unlike post')
524
498
}
···
526
500
} else {
527
501
// remove the old dislike, if it exists
528
502
if app.does_user_dislike_post(user.id, post.id) {
529
-
sql app.db {
530
-
delete from Like where user_id == user.id && post_id == post.id
531
-
} or {
503
+
if !app.unlike_post(post.id, user.id) {
532
504
eprintln('user ${user.id} failed to remove dislike on post ${id} when liking it')
533
505
}
534
506
}
···
538
510
post_id: post.id
539
511
is_like: true
540
512
}
541
-
sql app.db {
542
-
insert like into Like
543
-
// yeet the old cached like value
544
-
delete from LikeCache where post_id == post.id
545
-
} or {
513
+
if !app.add_like(like) {
546
514
eprintln('user ${user.id} failed to like post ${id}')
547
515
return ctx.server_error('failed to like post')
548
516
}
···
557
525
post := app.get_post_by_id(id) or { return ctx.server_error('post does not exist') }
558
526
559
527
if app.does_user_dislike_post(user.id, post.id) {
560
-
sql app.db {
561
-
delete from Like where user_id == user.id && post_id == post.id
562
-
// yeet the old cached like value
563
-
delete from LikeCache where post_id == post.id
564
-
} or {
565
-
eprintln('user ${user.id} failed to unlike post ${id}')
566
-
return ctx.server_error('failed to unlike post')
528
+
if !app.unlike_post(post.id, user.id) {
529
+
eprintln('user ${user.id} failed to undislike post ${id}')
530
+
return ctx.server_error('failed to undislike post')
567
531
}
568
532
return ctx.ok('undisliked post')
569
533
} else {
570
534
// remove the old like, if it exists
571
535
if app.does_user_like_post(user.id, post.id) {
572
-
sql app.db {
573
-
delete from Like where user_id == user.id && post_id == post.id
574
-
} or {
536
+
if !app.unlike_post(post.id, user.id) {
575
537
eprintln('user ${user.id} failed to remove like on post ${id} when disliking it')
576
538
}
577
539
}
···
581
543
post_id: post.id
582
544
is_like: false
583
545
}
584
-
sql app.db {
585
-
insert like into Like
586
-
// yeet the old cached like value
587
-
delete from LikeCache where post_id == post.id
588
-
} or {
546
+
if !app.add_like(like) {
589
547
eprintln('user ${user.id} failed to dislike post ${id}')
590
548
return ctx.server_error('failed to dislike post')
591
549
}
···
614
572
return ctx.redirect('/')
615
573
}
616
574
617
-
sql app.db {
618
-
update Post set body = body, title = title where id == id
619
-
} or {
575
+
if !app.update_post(id, title, body) {
620
576
eprintln('failed to update post')
621
577
ctx.error('failed to update post')
622
578
return ctx.redirect('/')
···
633
589
}
634
590
635
591
if user.admin {
636
-
sql app.db {
637
-
update Post set pinned = true where id == id
638
-
} or {
592
+
if !app.pin_post(id) {
639
593
eprintln('failed to pin post: ${id}')
640
594
ctx.error('failed to pin post')
641
595
return ctx.redirect('/post/${id}')
···
658
612
}
659
613
660
614
if user.admin {
661
-
sql app.db {
662
-
update Site set motd = motd where id == 1
663
-
} or {
615
+
if !app.set_motd(motd) {
664
616
ctx.error('failed to set motd')
665
617
eprintln('failed to set motd: ${motd}')
666
618
return ctx.redirect('/')