From c2cdbc589b9db1e3f00766fbcd532667544e038f Mon Sep 17 00:00:00 2001 From: Chaitanya Date: Sun, 21 Jul 2024 13:06:19 +0530 Subject: [PATCH] fix: separate leaderboard query on users query (#891) * fix: count leaderboard entry as valid user * fix: delegate field alias handling to helper * fix: delete unused field * fix: fix invalid id assignment * fix: remove unused params * fix: `users` query should return user if exists in only leaderboard or users table * Revert "fix: `users` query should return user if exists in only leaderboard or users table" This reverts commit 6371ce8e97faf585bd842296982cea427262fea5. * fix: only return if user exist * fix: only return results if user exist * fix: seperate leaderboard query on users query * Update src/graphql/helpers.ts * fix user query * fix: optimize query * Revert "fix: optimize query" This reverts commit 6e854b3cd6ce7f2da29e53606143730509d66b27. * Update src/graphql/operations/users.ts * Query leaderboard only to users who don't have a created * remove logs * Use left join and COALESCE * Update src/graphql/operations/users.ts * chore: lint fix --------- Co-authored-by: Wan Qi Chen <495709+wa0x6e@users.noreply.github.com> --- src/graphql/operations/user.ts | 23 +++++++----------- src/graphql/operations/users.ts | 41 +++++++++++++++++++++++++++++---- src/graphql/schema.gql | 14 +---------- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/src/graphql/operations/user.ts b/src/graphql/operations/user.ts index e3419837..6e9852d4 100644 --- a/src/graphql/operations/user.ts +++ b/src/graphql/operations/user.ts @@ -1,21 +1,14 @@ -import { capture } from '@snapshot-labs/snapshot-sentry'; -import db from '../../helpers/mysql'; -import log from '../../helpers/log'; -import { formatUser, formatAddresses, PublicError } from '../helpers'; +import { formatAddresses, PublicError } from '../helpers'; +import users from './users'; export default async function (parent, args) { const addresses = formatAddresses([args.id]); if (!addresses.length) throw new PublicError('Invalid address'); + const usersObject = await users(parent, { + first: 1, + skip: 0, + where: { id: addresses[0] } + }); - const query = `SELECT u.* FROM users u WHERE id = ? LIMIT 1`; - - try { - const users = await db.queryAsync(query, addresses[0]); - if (users.length === 1) return formatUser(users[0]); - return null; - } catch (e: any) { - log.error(`[graphql] user, ${JSON.stringify(e)}`); - capture(e, { args }); - return Promise.reject(new Error('request failed')); - } + return usersObject[0] || null; } diff --git a/src/graphql/operations/users.ts b/src/graphql/operations/users.ts index 12cc466e..e7d5d2aa 100644 --- a/src/graphql/operations/users.ts +++ b/src/graphql/operations/users.ts @@ -16,6 +16,8 @@ export default async function (parent, args) { const whereQuery = buildWhereQuery(fields, 'u', where); const queryStr = whereQuery.query; const params: any[] = whereQuery.params; + const ids = (where.id_in || [where.id]).filter(Boolean); + if (Object.keys(where).length > 1) ids.length = 0; let orderBy = args.orderBy || 'created'; let orderDirection = args.orderDirection || 'desc'; @@ -27,11 +29,11 @@ export default async function (parent, args) { const query = ` SELECT u.*, - SUM(l.vote_count) as votesCount, - SUM(l.proposal_count) as proposalsCount, + COALESCE(SUM(l.vote_count), 0) as votesCount, + COALESCE(SUM(l.proposal_count), 0) as proposalsCount, MAX(l.last_vote) as lastVote FROM users u - INNER JOIN leaderboard l ON l.user = u.id + LEFT JOIN leaderboard l ON l.user = u.id WHERE 1=1 ${queryStr} GROUP BY u.id ORDER BY ${orderBy} ${orderDirection} LIMIT ?, ? @@ -39,7 +41,38 @@ export default async function (parent, args) { params.push(skip, first); try { const users = await db.queryAsync(query, params); - return users.map(user => formatUser(user)); + ids.forEach(element => { + if (!users.find((u: any) => u.id === element)) { + users.push({ id: element }); + } + }); + if (!users.length) return []; + + const usersWithOutCreated = users + .filter((u: any) => !u.created) + .map((u: any) => u.id); + if (usersWithOutCreated.length) { + const counts = await db.queryAsync( + ` + SELECT + user, + COALESCE(SUM(vote_count), 0) as votesCount, + COALESCE(SUM(proposal_count) ,0) as proposalsCount, + MAX(last_vote) as lastVote + FROM leaderboard + WHERE user IN (?) + GROUP BY user + `, + [usersWithOutCreated] + ); + counts.forEach((count: any) => { + const user = users.find((u: any) => u.id === count.user); + user.votesCount = count.votesCount; + user.proposalsCount = count.proposalsCount; + user.lastVote = count.lastVote; + }); + } + return users.map(formatUser); } catch (e: any) { log.error(`[graphql] users, ${JSON.stringify(e)}`); capture(e, { args }); diff --git a/src/graphql/schema.gql b/src/graphql/schema.gql index 626957e5..d992b76a 100644 --- a/src/graphql/schema.gql +++ b/src/graphql/schema.gql @@ -325,18 +325,6 @@ input UsersWhere { created_gte: Int created_lt: Int created_lte: Int - vote_count: Int - vote_count_in: [Int] - vote_count_gt: Int - vote_count_gte: Int - vote_count_lt: Int - vote_count_lte: Int - proposal_count: Int - proposal_count_in: [Int] - proposal_count_gt: Int - proposal_count_gte: Int - proposal_count_lt: Int - proposal_count_lte: Int } input StatementsWhere { @@ -575,7 +563,7 @@ type User { twitter: String lens: String farcaster: String - created: Int! + created: Int votesCount: Int proposalsCount: Int lastVote: Int