Skip to content

Commit 04ba632

Browse files
committed
Use stored procedures for faster queries on getting edit users and search functions
1 parent 2bb63c9 commit 04ba632

3 files changed

Lines changed: 54 additions & 47 deletions

File tree

backend/postgres/circles_repo.go

Lines changed: 12 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -269,59 +269,27 @@ func EditRoleInCircle(circleID string, targetUserID string, role string) error {
269269
}
270270
}
271271

272-
func GetRoleInCircle(userID string, circleID string) (string, error) {
273-
var role string
274-
err := pool.QueryRow(
275-
context.Background(),
276-
`
277-
SELECT role
278-
FROM users_circles
279-
WHERE user_id = $1 AND circle_id = $2;
280-
`,
281-
userID,
282-
circleID,
283-
).Scan(&role)
284-
if err != nil {
285-
fmt.Fprintf(os.Stderr, "Unable to query PSQL: %v\n", err)
286-
return "", err
287-
}
288-
return role, nil
289-
}
290-
291272
func GetExistingUsersInCircle(userID string, circleID string) ([]models.UserRole, error) {
292-
requestingRole, err := GetRoleInCircle(userID, circleID)
293-
if err != nil {
294-
fmt.Fprintf(os.Stderr, "Unable to get role in circle: %v\n", err)
295-
return nil, err
296-
}
297-
if requestingRole != "admin" {
298-
fmt.Fprintf(os.Stderr, "User is not admin of circle\n")
299-
return nil, fmt.Errorf("permission error")
300-
}
301-
302-
var users []models.UserRole
303273
rows, err := pool.Query(
304274
context.Background(),
305-
`
306-
SELECT u.id, u.username, uc.role
307-
FROM users u
308-
INNER JOIN users_circles uc ON u.id = uc.user_id
309-
WHERE u.id != $1 AND uc.circle_id = $2
310-
ORDER BY u.username ASC;
311-
`,
275+
"SELECT * FROM get_users_in_circle($1, $2);",
312276
userID,
313277
circleID,
314278
)
315279
if err != nil {
316-
fmt.Fprintf(os.Stderr, "Unable to query PSQL: %v\n", err)
280+
if err.Error() == "permission error" {
281+
fmt.Fprintf(os.Stderr, "User is not admin of circle\n")
282+
return nil, fmt.Errorf("permission error")
283+
}
284+
fmt.Fprintf(os.Stderr, "Unable to query get_existing_users_in_circle: %v\n", err)
317285
return nil, err
318286
}
319287
defer rows.Close()
320288

289+
var users []models.UserRole
321290
for rows.Next() {
322291
var user models.UserRole
323-
err = rows.Scan(&user.UserID, &user.Username, &user.Role)
324-
if err != nil {
292+
if err := rows.Scan(&user.UserID, &user.Username, &user.Role); err != nil {
325293
fmt.Fprintf(os.Stderr, "Unable to scan row: %v\n", err)
326294
return nil, err
327295
}
@@ -380,17 +348,12 @@ func SearchCircle(circleID string, content string) ([]models.SearchMessage, erro
380348

381349
rows, err := conn.Query(
382350
ctx,
383-
`
384-
SELECT m.content, m.created_at, u.username
385-
FROM messages m
386-
INNER JOIN users u ON m.author_id = u.id
387-
WHERE m.circle_id = $1 AND m.content ILIKE '%' || $2 || '%';
388-
`,
351+
"SELECT * FROM search_circle_messages($1, $2)",
389352
circleID,
390353
content,
391354
)
392355
if err != nil {
393-
fmt.Fprintf(os.Stderr, "Unable to query PSQL: %v\n", err)
356+
fmt.Fprintf(os.Stderr, "Unable to query search_circle_messages: %v\n", err)
394357
return nil, err
395358
}
396359
defer rows.Close()
@@ -407,8 +370,10 @@ func SearchCircle(circleID string, content string) ([]models.SearchMessage, erro
407370
message.CreatedAt = time.Format("2006-01-02 15:04:05 EST")
408371
messages = append(messages, message)
409372
}
373+
410374
sort.Slice(messages, func(i, j int) bool {
411375
return messages[i].CreatedAt > messages[j].CreatedAt
412376
})
377+
413378
return messages, nil
414379
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
DROP FUNCTION IF EXISTS search_circle_messages(INT, TEXT);
2+
DROP FUNCTION IF EXISTS get_users_in_circle(INT, INT);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
CREATE OR REPLACE FUNCTION search_circle_messages(circle_id_input INT, content_input TEXT)
2+
RETURNS TABLE (
3+
content TEXT,
4+
created_at TIMESTAMP,
5+
author_username VARCHAR(100)
6+
) AS $$
7+
BEGIN
8+
RETURN QUERY
9+
SELECT m.content, m.created_at, u.username
10+
FROM messages m
11+
INNER JOIN users u ON m.author_id = u.id
12+
WHERE m.circle_id = circle_id_input AND m.content ILIKE '%' || content_input || '%';
13+
END;
14+
$$ LANGUAGE plpgsql;
15+
16+
CREATE OR REPLACE FUNCTION get_users_in_circle(request_user_id INT, circle_id_input INT)
17+
RETURNS TABLE (
18+
user_id INT,
19+
username VARCHAR(100),
20+
role VARCHAR(50)
21+
) AS $$
22+
BEGIN
23+
IF NOT EXISTS (
24+
SELECT *
25+
FROM users_circles
26+
WHERE user_id = request_user_id
27+
AND circle_id = circle_id_input
28+
AND role = 'admin'
29+
) THEN
30+
RAISE EXCEPTION 'permission denied';
31+
END IF;
32+
33+
RETURN QUERY
34+
SELECT u.id, u.username, uc.role
35+
FROM users u
36+
INNER JOIN users_circles uc ON u.id = uc.user_id
37+
WHERE u.id != p_requester_id AND uc.circle_id = p_circle_id
38+
ORDER BY u.username ASC;
39+
END;
40+
$$ LANGUAGE plpgsql;

0 commit comments

Comments
 (0)