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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
open Piaf
type pool = ((module Rapper_helper.CONNECTION), Caqti_error.t) Caqti_eio.Pool.t
(* This is the main handler function for the GET /posts endpoint. *)
(* It takes a database connection pool and a Piaf request as input. *)
let get_posts (db_pool : pool) (_request : Request.t) =
(* Use a connection from the pool. Caqti_eio.Pool.use handles acquiring and releasing the connection. *)
Caqti_eio.Pool.use
(fun conn ->
(* Call the get_poasts function from the Query module to fetch posts from the database. *)
let posts_or_error = Query.get_poasts () conn in
(* Pattern match on the result of the database query. *)
match posts_or_error with
(* If the query is successful, the result is a list of posts. *)
| Ok posts ->
(* Map the list of post tuples to a Yojson list. *)
let json =
`List
((* For each post tuple, create a JSON object. *)
List.map
(fun (post : Query.post_summary) -> `Assoc [ "title", `String post.title ])
posts)
in
(* Return a 200 OK response with the JSON body. *)
Ok (Response.of_string ~body:(Yojson.Safe.to_string json) `OK)
(* If the query fails, log the error and return a 500 Internal Server Error response. *)
| Error err ->
Logs.err (fun m -> m "Database error: %a" Caqti_error.pp err);
Ok (Response.create `Internal_server_error))
db_pool
;;
(* Handler for GET /posts/:id - gets a single post by ID *)
let get_post post_id (db_pool : pool) (_request : Request.t) =
Caqti_eio.Pool.use
(fun conn ->
let post_or_error = Query.get_poast post_id conn in
match post_or_error with
| Ok (Some post) ->
let json =
`Assoc
[ "id", `Int post.id
; "title", `String post.title
; "content", `String post.content
; "date", `String post.date
; "tags", `String post.tags
; "url", `String post.url
]
in
Ok (Response.of_string ~body:(Yojson.Safe.to_string json) `OK)
| Ok None -> Ok (Response.create `Not_found)
| Error err ->
Logs.err (fun m -> m "Database error: %a" Caqti_error.pp err);
Ok (Response.create `Internal_server_error))
db_pool
;;
(* Handler for GET /comments/:id - gets a single comment by ID *)
let get_comment comment_id (db_pool : pool) (_request : Request.t) =
Caqti_eio.Pool.use
(fun conn ->
let comment_or_error = Query.Query.comment ~id:comment_id conn in
match comment_or_error with
| Ok (Some comment) ->
let json =
`Assoc
[ "id", `Int comment.id
; "content", `String comment.content
; "date", `String comment.date
; "tags", `String comment.tags
; "url", `String comment.url
]
in
Ok (Response.of_string ~body:(Yojson.Safe.to_string json) `OK)
| Ok None -> Ok (Response.create `Not_found)
| Error err ->
Logs.err (fun m -> m "Database error: %a" Caqti_error.pp err);
Ok (Response.create `Internal_server_error))
db_pool
;;
(* Handler for GET /users/:username/comments - gets comments by a user *)
let get_user_comments username (db_pool : pool) (_request : Request.t) =
Caqti_eio.Pool.use
(fun conn ->
let comments_or_error = Query.Query.user_comments ~username conn in
match comments_or_error with
| Ok comments ->
let json =
`List
(List.map
(fun (comment : Query.comment) ->
`Assoc
[ "id", `Int comment.id
; "content", `String comment.content
; "date", `String comment.date
; "tags", `String comment.tags
; "url", `String comment.url
])
comments)
in
Ok (Response.of_string ~body:(Yojson.Safe.to_string json) `OK)
| Error err ->
Logs.err (fun m -> m "Database error: %a" Caqti_error.pp err);
Ok (Response.create `Internal_server_error))
db_pool
;;
(* Handler for GET /posts/:id/comments - gets comments for a post *)
let get_post_comments post_id (db_pool : pool) (_request : Request.t) =
Caqti_eio.Pool.use
(fun conn ->
let comments_or_error = Query.Query.post_comments ~post_id conn in
match comments_or_error with
| Ok comments ->
let json =
`List
(List.map
(fun (comment : Query.comment) ->
`Assoc
[ "id", `Int comment.id
; "content", `String comment.content
; "date", `String comment.date
; "tags", `String comment.tags
; "url", `String comment.url
])
comments)
in
Ok (Response.of_string ~body:(Yojson.Safe.to_string json) `OK)
| Error err ->
Logs.err (fun m -> m "Database error: %a" Caqti_error.pp err);
Ok (Response.create `Internal_server_error))
db_pool
;;
(* Handler for GET /comments/:id/children - gets child comments *)
let get_comment_children parent_id (db_pool : pool) (_request : Request.t) =
Caqti_eio.Pool.use
(fun conn ->
let comments_or_error = Query.Query.comment_children ~post_id:parent_id conn in
match comments_or_error with
| Ok comments ->
let json =
`List
(List.map
(fun (comment : Query.comment) ->
`Assoc
[ "id", `Int comment.id
; "content", `String comment.content
; "date", `String comment.date
; "tags", `String comment.tags
; "url", `String comment.url
])
comments)
in
Ok (Response.of_string ~body:(Yojson.Safe.to_string json) `OK)
| Error err ->
Logs.err (fun m -> m "Database error: %a" Caqti_error.pp err);
Ok (Response.create `Internal_server_error))
db_pool
;;
|