This repository has been archived by the owner on Oct 3, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 74
/
reader.go
115 lines (97 loc) · 2.71 KB
/
reader.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package db
import (
"github.com/bakape/meguca/common"
r "github.com/dancannon/gorethink"
)
// Preconstructed REQL queries that don't have to be rebuilt
var (
// Retrieves all threads for the /all/ metaboard
getAllBoard = r.
Table("threads").
EqJoin("id", r.Table("posts")).
Zip().
Without(omitForBoards).
Merge(mergeLastUpdated).
OrderBy(r.Desc("replyTime"))
// Gets the most recently updated post timestamp from thread
getLastUpdated = r.
Table("posts").
GetAllByIndex("op", r.Row.Field("id")).
Field("lastUpdated").
Max().
Default(0)
mergeLastUpdated = map[string]r.Term{
"lastUpdated": getLastUpdated,
}
// Fields to omit in board queries. Decreases payload of DB replies.
omitForBoards = []string{
"body", "password", "commands", "links", "backlinks", "ip", "editing",
"op",
}
// Fields to omit for post queries
omitForPosts = []string{"password", "ip", "lastUpdated"}
omitForThreadPosts = append(omitForPosts, []string{"op", "board"}...)
)
// GetThread retrieves public thread data from the database
func GetThread(id uint64, lastN int) (common.Thread, error) {
q := r.
Table("threads").
GetAll(id). // Can not join after Get(). Meh.
EqJoin("id", r.Table("posts")).
Zip()
getPosts := r.
Table("posts").
GetAllByIndex("op", id).
OrderBy("id").
CoerceTo("array")
// Only fetch last N number of replies
if lastN != 0 {
getPosts = getPosts.Slice(-lastN)
}
q = q.Merge(map[string]r.Term{
"posts": getPosts.Without(omitForThreadPosts),
"lastUpdated": getLastUpdated,
}).
Without("ip", "op", "password")
var thread common.Thread
if err := One(q, &thread); err != nil {
return thread, err
}
// Remove OP from posts slice to prevent possible duplication. Post might
// be deleted before the thread due to a deletion race.
if len(thread.Posts) != 0 && thread.Posts[0].ID == id {
thread.Posts = thread.Posts[1:]
}
return thread, nil
}
// GetPost reads a single post from the database
func GetPost(id uint64) (post common.StandalonePost, err error) {
q := FindPost(id).Without(omitForPosts).Default(nil)
err = One(q, &post)
return
}
// GetBoard retrieves all OPs of a single board
func GetBoard(board string) (data common.Board, err error) {
q := r.
Table("threads").
GetAllByIndex("board", board).
EqJoin("id", r.Table("posts")).
Zip().
Without(omitForBoards).
Merge(mergeLastUpdated).
OrderBy(r.Desc("replyTime"))
err = All(q, &data)
// So that JSON always produces and array
if data == nil {
data = common.Board{}
}
return
}
// GetAllBoard retrieves all threads for the "/all/" meta-board
func GetAllBoard() (data common.Board, err error) {
err = All(getAllBoard, &data)
if data == nil {
data = common.Board{}
}
return
}