Skip to content

Commit 2460eb6

Browse files
authored
fix: user duplication and handling case-insensitive username indexing and deduplication (#184)
1 parent a755942 commit 2460eb6

1 file changed

Lines changed: 28 additions & 9 deletions

File tree

lib/db-store.ts

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ export class DatabaseStore {
114114
ON github_users(stale_after)
115115
WHERE country IS NOT NULL;
116116
117+
CREATE UNIQUE INDEX IF NOT EXISTS idx_github_users_username_lower
118+
ON github_users(LOWER(username));
119+
117120
CREATE TABLE IF NOT EXISTS leaderboard_calculation (
118121
country_slug VARCHAR(100) PRIMARY KEY,
119122
country_title TEXT NOT NULL DEFAULT '',
@@ -193,7 +196,8 @@ export class DatabaseStore {
193196
$8, $9, $10, $11,
194197
NOW(), NOW() + ($12 || ' days')::INTERVAL, NOW()
195198
)
196-
ON CONFLICT (username) DO UPDATE SET
199+
ON CONFLICT (LOWER(username)) DO UPDATE SET
200+
username = EXCLUDED.username,
197201
name = EXCLUDED.name,
198202
avatar_url = EXCLUDED.avatar_url,
199203
location = EXCLUDED.location,
@@ -251,8 +255,13 @@ export class DatabaseStore {
251255
): Promise<GitHubUserRow[]> {
252256
const client = getPool();
253257
const result = await client.query(
254-
`SELECT * FROM github_users
255-
WHERE country = $1
258+
`SELECT *
259+
FROM (
260+
SELECT DISTINCT ON (LOWER(username)) *
261+
FROM github_users
262+
WHERE country = $1
263+
ORDER BY LOWER(username), final_score DESC, updated_at DESC
264+
) deduped_users
256265
ORDER BY final_score DESC
257266
LIMIT $2`,
258267
[country, limit],
@@ -263,7 +272,7 @@ export class DatabaseStore {
263272
async getLeaderboardCount(country: string): Promise<number> {
264273
const client = getPool();
265274
const result = await client.query(
266-
"SELECT COUNT(*) FROM github_users WHERE country = $1",
275+
"SELECT COUNT(DISTINCT LOWER(username)) FROM github_users WHERE country = $1",
267276
[country],
268277
);
269278
return Number(result.rows[0].count);
@@ -279,8 +288,13 @@ export class DatabaseStore {
279288
): Promise<GitHubUserRow[]> {
280289
const client = getPool();
281290
const result = await client.query(
282-
`SELECT * FROM github_users
283-
WHERE country = $1 AND stale_after < NOW()
291+
`SELECT *
292+
FROM (
293+
SELECT DISTINCT ON (LOWER(username)) *
294+
FROM github_users
295+
WHERE country = $1 AND stale_after < NOW()
296+
ORDER BY LOWER(username), final_score DESC, updated_at DESC
297+
) deduped_users
284298
ORDER BY final_score DESC
285299
LIMIT $2`,
286300
[country, limit],
@@ -298,8 +312,13 @@ export class DatabaseStore {
298312
): Promise<GitHubUserRow[]> {
299313
const client = getPool();
300314
const result = await client.query(
301-
`SELECT * FROM github_users
302-
WHERE country = $1
315+
`SELECT *
316+
FROM (
317+
SELECT DISTINCT ON (LOWER(username)) *
318+
FROM github_users
319+
WHERE country = $1
320+
ORDER BY LOWER(username), final_score DESC, updated_at DESC
321+
) deduped_users
303322
ORDER BY final_score DESC
304323
LIMIT $2`,
305324
[country, limit],
@@ -329,4 +348,4 @@ export function getDatabaseStore(): DatabaseStore {
329348
defaultStore = new DatabaseStore();
330349
}
331350
return defaultStore;
332-
}
351+
}

0 commit comments

Comments
 (0)