ggdgsdbsdbbb / discussion.v
131 lines · 115 sloc · 3.1 KB · d230c5a6e59810a96cb2862c844cc11574f7eb07
Raw
1// Copyright (c) 2019-2026 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by a GPL license that can be found in the LICENSE file.
3module main
4
5import time
6import veb
7
8struct Discussion {
9 id int @[primary; sql: serial]
10mut:
11 repo_id int
12 author_id int
13 title string
14 body string
15 category string // general, qa, announcement, idea
16 is_locked bool
17 is_answered bool
18 answer_id int
19 comments_count int
20 created_at int
21}
22
23struct DiscussionComment {
24 id int @[primary; sql: serial]
25mut:
26 discussion_id int
27 author_id int
28 text string
29 created_at int
30}
31
32fn (d &Discussion) relative_time() string {
33 return time.unix(d.created_at).relative()
34}
35
36fn (d &Discussion) formatted_title() veb.RawHtml {
37 return html_escape_text(d.title)
38}
39
40fn (d &Discussion) category_label() string {
41 return match d.category {
42 'qa' { 'Q&A' }
43 'announcement' { 'Announcement' }
44 'idea' { 'Idea' }
45 else { 'General' }
46 }
47}
48
49fn (c &DiscussionComment) relative() string {
50 return time.unix(c.created_at).relative()
51}
52
53fn (mut app App) add_discussion(repo_id int, author_id int, title string, body string, category string) !int {
54 d := Discussion{
55 repo_id: repo_id
56 author_id: author_id
57 title: title
58 body: body
59 category: category
60 created_at: int(time.now().unix())
61 }
62 sql app.db {
63 insert d into Discussion
64 }!
65 return db_last_insert_id(app.db)
66}
67
68fn (mut app App) find_discussion(id int) ?Discussion {
69 rows := sql app.db {
70 select from Discussion where id == id limit 1
71 } or { []Discussion{} }
72 if rows.len == 0 {
73 return none
74 }
75 return rows.first()
76}
77
78fn (mut app App) list_repo_discussions(repo_id int) []Discussion {
79 return sql app.db {
80 select from Discussion where repo_id == repo_id order by created_at desc
81 } or { []Discussion{} }
82}
83
84fn (mut app App) add_discussion_comment(discussion_id int, author_id int, text string) ! {
85 c := DiscussionComment{
86 discussion_id: discussion_id
87 author_id: author_id
88 text: text
89 created_at: int(time.now().unix())
90 }
91 sql app.db {
92 insert c into DiscussionComment
93 }!
94 sql app.db {
95 update Discussion set comments_count = comments_count + 1 where id == discussion_id
96 }!
97}
98
99fn (mut app App) get_discussion_comments(discussion_id int) []DiscussionComment {
100 return sql app.db {
101 select from DiscussionComment where discussion_id == discussion_id order by created_at
102 } or { []DiscussionComment{} }
103}
104
105fn (mut app App) set_discussion_lock(discussion_id int, locked bool) ! {
106 sql app.db {
107 update Discussion set is_locked = locked where id == discussion_id
108 }!
109}
110
111fn (mut app App) mark_discussion_answer(discussion_id int, comment_id int) ! {
112 sql app.db {
113 update Discussion set is_answered = true, answer_id = comment_id where id == discussion_id
114 }!
115}
116
117fn (mut app App) delete_discussion(id int) ! {
118 sql app.db {
119 delete from DiscussionComment where discussion_id == id
120 }!
121 sql app.db {
122 delete from Discussion where id == id
123 }!
124}
125
126fn (mut app App) delete_repo_discussions(repo_id int) ! {
127 ds := app.list_repo_discussions(repo_id)
128 for d in ds {
129 app.delete_discussion(d.id) or {}
130 }
131}
132