Skip to content
This repository was archived by the owner on May 7, 2024. It is now read-only.

Commit 2618f12

Browse files
committed
Merge remote-tracking branch 'origin/master' into prod
2 parents 46d1cef + 5e6889a commit 2618f12

3 files changed

Lines changed: 133 additions & 94 deletions

File tree

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "navigo-learn-api",
3-
"version": "2.0.2",
3+
"version": "2.0.3",
44
"description": "Navigo Learn API",
55
"repository": "https://github.com/NavigoLearn/API.git",
66
"author": "Navigo",

src/util/Database/ExploreDB.ts

Lines changed: 130 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import Database, { DatabaseConfig } from '@src/util/Database/DatabaseDriver';
1+
import Database, {DatabaseConfig} from '@src/util/Database/DatabaseDriver';
22
import EnvVars from '@src/constants/EnvVars';
33
import {
44
SearchParameters,
55
} from '@src/middleware/validators/validateSearchParameters';
6-
import { ResRoadmap } from '@src/types/response/ResRoadmap';
6+
import {ResRoadmap} from '@src/types/response/ResRoadmap';
7+
import {RoadmapTopic} from '@src/types/models/Roadmap';
78

89
// database credentials
910
const { DBCred } = EnvVars;
@@ -18,120 +19,158 @@ class ExploreDB extends Database {
1819
super(config);
1920
}
2021

22+
private static getIsLikedQuery(userid?: bigint): string {
23+
return !!userid
24+
? `SELECT COALESCE((SELECT value
25+
FROM roadmapLikes
26+
WHERE roadmapId = r.id
27+
AND userId = ?
28+
LIMIT 1), 0)`
29+
: '0';
30+
}
31+
32+
private static getTopicQuery(topic: string | string[]): string {
33+
if (Array.isArray(topic)) {
34+
return topic.map(() => '?').join(', ');
35+
}
36+
return '?';
37+
}
38+
39+
private static getOrderByQuery(order: {
40+
by: string;
41+
direction: string;
42+
}): string {
43+
let query = '';
44+
if (order.by === 't.likeCount') {
45+
query = `CASE
46+
WHEN t.likeCount < 0 THEN 3
47+
WHEN t.likeCount = 0 THEN 2
48+
ELSE 1
49+
END ${order.direction}, `;
50+
}
51+
52+
return `${query}${order.by} ${order.direction}`;
53+
}
54+
55+
private static buildQueryParams(
56+
userid: bigint | undefined,
57+
search: string,
58+
topic: RoadmapTopic | RoadmapTopic[],
59+
page: number,
60+
limit: number,
61+
isCountQuery = false,
62+
): unknown[] {
63+
const params = [];
64+
65+
if (!isCountQuery) {
66+
params.push(userid);
67+
}
68+
69+
params.push(`%${search}%`, `%${search}%`);
70+
params.push(Array.isArray(topic) ? topic.map((t) => t.toString()) : topic);
71+
72+
if (!isCountQuery) {
73+
params.push((page - 1) * limit, limit);
74+
}
75+
76+
return params;
77+
}
78+
2179
public async getRoadmaps(
2280
{ search, page, limit, topic, order }: SearchParameters,
2381
userid?: bigint,
2482
): Promise<ResRoadmapExplore> {
2583
if (typeof search != 'string' || !page || !limit || !topic || !order)
2684
return { result: [], totalRoadmaps: 0n };
85+
86+
const isLikeQuery = ExploreDB.getIsLikedQuery(userid);
87+
const topicQuery = ExploreDB.getTopicQuery(topic);
88+
const orderQuery = ExploreDB.getOrderByQuery(order);
89+
2790
const query = `
28-
SELECT *
29-
FROM (SELECT r.id as id,
30-
r.name AS name,
31-
r.description AS description,
32-
r.topic AS topic,
33-
r.isFeatured AS isFeatured,
34-
r.isPublic AS isPublic,
35-
r.isDraft AS isDraft,
36-
r.createdAt AS createdAt,
37-
r.updatedAt AS updatedAt,
38-
u.id AS userId,
39-
u.avatar AS userAvatar,
40-
u.name AS userName,
41-
(SELECT SUM(rl.value)
42-
FROM roadmapLikes rl
43-
WHERE roadmapId = r.id) AS likeCount,
44-
(SELECT COUNT(*)
45-
FROM roadmapViews
46-
WHERE roadmapId = r.id) AS viewCount,
47-
${
48-
!!userid
49-
? `(SELECT value FROM roadmapLikes
50-
WHERE roadmapId = r.id
51-
AND userId = ?
52-
)
53-
`
54-
: '0'
55-
} AS isLiked
56-
FROM roadmaps r
57-
INNER JOIN users u ON r.userId = u.id
58-
WHERE (r.name LIKE ? OR r.description LIKE ?)
59-
AND r.topic IN (${
60-
Array.isArray(topic) ? topic.map(() => '?').join(', ') : '?'
61-
})
62-
AND r.isPublic = 1
63-
AND r.isDraft = 0) as t
64-
ORDER BY t.isFeatured DESC, ${
65-
order.by === 't.likeCount'
66-
? `CASE
67-
WHEN t.likeCount < 0 THEN 3
68-
WHEN t.likeCount = 0 THEN 2
69-
ELSE 1
70-
END,`
71-
: ''
72-
} ${order.by} ${order.direction}
73-
LIMIT ?, ?
74-
;
91+
SELECT *
92+
FROM (SELECT r.id as id,
93+
r.name AS name,
94+
r.description AS description,
95+
r.topic AS topic,
96+
r.isFeatured AS isFeatured,
97+
r.isPublic AS isPublic,
98+
r.isDraft AS isDraft,
99+
r.createdAt AS createdAt,
100+
r.updatedAt AS updatedAt,
101+
u.id AS userId,
102+
u.avatar AS userAvatar,
103+
u.name AS userName,
104+
(SELECT COALESCE(
105+
(SELECT SUM(rl.value)
106+
FROM roadmapLikes rl
107+
WHERE roadmapId = r.id), 0)) AS likeCount,
108+
(SELECT COUNT(*)
109+
FROM roadmapViews
110+
WHERE roadmapId = r.id) AS viewCount,
111+
( ${isLikeQuery} ) AS isLiked
112+
FROM roadmaps r
113+
INNER JOIN users u ON r.userId = u.id
114+
WHERE ( r.name LIKE ?
115+
OR r.description LIKE ? )
116+
AND r.topic IN ( ${topicQuery} )
117+
AND r.isPublic = 1
118+
AND r.isDraft = 0) as t
119+
ORDER BY ${orderQuery}
120+
LIMIT ?, ?;
75121
`;
76-
const query2 = `
77-
SELECT count(*) AS result,
78-
${
79-
!!userid
80-
? `(SELECT value FROM roadmapLikes
81-
WHERE roadmapId = r.id
82-
AND userId = ?
83-
)`
84-
: '0'
85-
} AS isLiked
86-
FROM roadmaps r
87-
INNER JOIN users u ON r.userId = u.id
88-
WHERE (r.name LIKE ? OR r.description LIKE ?)
89-
AND r.topic IN (${
90-
Array.isArray(topic) ? topic.map(() => '?').join(', ') : '?'
91-
})
92-
AND r.isPublic = 1
93-
AND r.isDraft = 0;
122+
const countQuery = `
123+
SELECT count(*) AS result
124+
FROM roadmaps r
125+
INNER JOIN users u ON r.userId = u.id
126+
WHERE ( r.name LIKE ? OR r.description LIKE ? )
127+
AND r.topic IN ( ${topicQuery} )
128+
AND r.isPublic = 1
129+
AND r.isDraft = 0;
94130
`;
95-
const params = [];
96131

97-
if (!!userid) {
98-
params.push(userid);
99-
}
100-
params.push(`%${search}%`);
101-
params.push(`%${search}%`);
102-
if (Array.isArray(topic)) topic.forEach((t) => params.push(t.toString()));
103-
else params.push(topic);
104-
params.push((page - 1) * limit);
105-
params.push(limit);
132+
const params = ExploreDB.buildQueryParams(
133+
userid,
134+
search,
135+
topic,
136+
page,
137+
limit,
138+
);
139+
140+
const countParams = ExploreDB.buildQueryParams(
141+
userid,
142+
search,
143+
topic,
144+
page,
145+
limit,
146+
true,
147+
);
106148

107149
const result = await this.getQuery(query, params);
108-
const result2 = await this.countQuery(query2, params.slice(0, -2));
150+
const count = await this.countQuery(countQuery, countParams);
109151

110152
if (result === null) return { result: [], totalRoadmaps: 0n };
111153
return {
112154
result: result as unknown as ResRoadmap[],
113-
totalRoadmaps: result2,
155+
totalRoadmaps: count,
114156
};
115157
}
116158

117159
public async getRandomRoadmapId(): Promise<bigint | null> {
118160
const query = `
119-
SELECT id
120-
FROM roadmaps
121-
WHERE isPublic = 1
122-
AND isDraft = 0
123-
ORDER BY RAND()
124-
LIMIT 1
161+
SELECT id
162+
FROM roadmaps
163+
WHERE isPublic = 1
164+
AND isDraft = 0
165+
ORDER BY RAND()
166+
LIMIT 1
125167
`;
126168

127169
const result = await this.getQuery(query);
128170

129-
if (result === null)
130-
return null;
131-
if(result.length === 0)
132-
return null;
133-
if(result[0].id === null)
134-
return null;
171+
if (result === null) return null;
172+
if (result.length === 0) return null;
173+
if (result[0].id === null) return null;
135174

136175
return result[0].id as bigint;
137176
}

0 commit comments

Comments
 (0)