From 894281dc30a208db077878c2830da7e4358a5daf Mon Sep 17 00:00:00 2001 From: GC <30398469+gc@users.noreply.github.com> Date: Tue, 27 Feb 2024 02:02:07 +1100 Subject: [PATCH] BigInt fixes (#5726) --- .github/workflows/integration_tests.yml | 2 +- .github/workflows/unit_tests.yml | 2 +- src/lib/addXP.ts | 6 +-- src/lib/analytics.ts | 8 ++-- src/lib/roboChimp.ts | 2 +- src/lib/rolesTask.ts | 12 +++--- src/lib/settings/prisma.ts | 2 +- src/lib/slayer/slayerUtil.ts | 2 +- src/mahoji/commands/admin.ts | 16 +++---- src/mahoji/commands/ge.ts | 2 +- src/mahoji/commands/leaderboard.ts | 2 +- src/mahoji/commands/tools.ts | 2 +- .../lib/abstracted_commands/infernoCommand.ts | 2 +- .../lib/abstracted_commands/statCommand.ts | 42 +++++++++---------- 14 files changed, 52 insertions(+), 50 deletions(-) diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index 79e9bfaf6d..5671a71eac 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -11,7 +11,7 @@ jobs: test: name: Node v${{ matrix.node_version }} - ${{ matrix.os }} runs-on: ${{ matrix.os }} - timeout-minutes: 5 + timeout-minutes: 10 strategy: matrix: node_version: [18.12.0, 20] diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 675ebb2847..168e1a2245 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -11,7 +11,7 @@ jobs: test: name: Node v${{ matrix.node_version }} - ${{ matrix.os }} runs-on: ${{ matrix.os }} - timeout-minutes: 5 + timeout-minutes: 10 strategy: matrix: node_version: [18.12.0, 20] diff --git a/src/lib/addXP.ts b/src/lib/addXP.ts index d9be2b3028..774257260d 100644 --- a/src/lib/addXP.ts +++ b/src/lib/addXP.ts @@ -12,7 +12,7 @@ import { sendToChannelID } from './util/webhook'; const skillsVals = Object.values(Skills); const maxFilter = skillsVals.map(s => `"skills.${s.id}" >= ${LEVEL_99_XP}`).join(' AND '); -const makeQuery = (ironman: boolean) => `SELECT count(id) +const makeQuery = (ironman: boolean) => `SELECT count(id)::int FROM users WHERE ${maxFilter} ${ironman ? 'AND "minion.ironman" = true' : ''};`; @@ -111,7 +111,7 @@ export async function addXP(user: MUser, params: AddXpParams): Promise { { count: string; }[] - >(`SELECT COUNT(*) FROM users WHERE "skills.${params.skillName}" >= ${LEVEL_99_XP};`); + >(`SELECT COUNT(*)::int FROM users WHERE "skills.${params.skillName}" >= ${LEVEL_99_XP};`); let str = `${skill.emoji} **${user.badgedUsername}'s** minion, ${ user.minionName @@ -125,7 +125,7 @@ export async function addXP(user: MUser, params: AddXpParams): Promise { count: string; }[] >( - `SELECT COUNT(*) FROM users WHERE "minion.ironman" = true AND "skills.${params.skillName}" >= ${LEVEL_99_XP};` + `SELECT COUNT(*)::int FROM users WHERE "minion.ironman" = true AND "skills.${params.skillName}" >= ${LEVEL_99_XP};` ); str += ` They are the ${formatOrdinal(parseInt(ironmenWith.count) + 1)} Ironman to get 99.`; } diff --git a/src/lib/analytics.ts b/src/lib/analytics.ts index f2689b8908..1d60da2474 100644 --- a/src/lib/analytics.ts +++ b/src/lib/analytics.ts @@ -39,10 +39,10 @@ export async function analyticsTick() { const [numberOfMinions, totalSacrificed, numberOfIronmen, totalGP] = ( await Promise.all( [ - 'SELECT COUNT(*) FROM users WHERE "minion.hasBought" = true;', - 'SELECT SUM ("sacrificedValue") AS count FROM users;', - 'SELECT COUNT(*) FROM users WHERE "minion.ironman" = true;', - 'SELECT SUM ("GP") AS count FROM users;' + 'SELECT COUNT(*)::int FROM users WHERE "minion.hasBought" = true;', + 'SELECT SUM("sacrificedValue")::int AS count FROM users;', + 'SELECT COUNT(*)::int FROM users WHERE "minion.ironman" = true;', + 'SELECT SUM("GP") AS count FROM users;' ].map(query => prisma.$queryRawUnsafe(query)) ) ).map((result: any) => parseInt(result[0].count)) as number[]; diff --git a/src/lib/roboChimp.ts b/src/lib/roboChimp.ts index 8373f16b7f..7b32294dcc 100644 --- a/src/lib/roboChimp.ts +++ b/src/lib/roboChimp.ts @@ -83,7 +83,7 @@ export async function roboChimpUserFetch(userID: string) { export async function calculateOwnCLRanking(userID: string) { const clPercentRank = ( - await roboChimpClient.$queryRaw<{ count: number }[]>`SELECT COUNT(*) + await roboChimpClient.$queryRaw<{ count: number }[]>`SELECT COUNT(*)::int FROM public.user WHERE osb_cl_percent >= (SELECT osb_cl_percent FROM public.user WHERE id = ${BigInt(userID)});` )[0].count; diff --git a/src/lib/rolesTask.ts b/src/lib/rolesTask.ts index 51656b8806..7008b9756a 100644 --- a/src/lib/rolesTask.ts +++ b/src/lib/rolesTask.ts @@ -44,7 +44,7 @@ LIMIT 1;`; const mostSlayerTasksDoneQuery = `SELECT user_id::text as id, 'Most Tasks' as desc FROM slayer_tasks GROUP BY user_id -ORDER BY count(user_id) DESC +ORDER BY count(user_id)::int DESC LIMIT 1;`; async function addRoles({ @@ -287,12 +287,12 @@ SELECT id, (cardinality(u.cl_keys) - u.inverse_length) as qty addToUserMap(userMap, mostValueIronman[0].id, 'Rank 1 Ironman Sacrificed Value'); const mostUniques = await q(`SELECT u.id, u.sacbanklength FROM ( - SELECT (SELECT COUNT(*) FROM JSONB_OBJECT_KEYS("sacrificed_bank")) sacbanklength, user_id::text as id FROM user_stats + SELECT (SELECT COUNT(*)::int FROM JSONB_OBJECT_KEYS("sacrificed_bank")) sacbanklength, user_id::text as id FROM user_stats ) u ORDER BY u.sacbanklength DESC LIMIT 1;`); const mostUniquesIron = await q(`SELECT u.id, u.sacbanklength FROM ( - SELECT (SELECT COUNT(*) FROM JSONB_OBJECT_KEYS("sacrificed_bank")) sacbanklength, user_id::text as id FROM user_stats + SELECT (SELECT COUNT(*)::int FROM JSONB_OBJECT_KEYS("sacrificed_bank")) sacbanklength, user_id::text as id FROM user_stats INNER JOIN users ON "user_stats"."user_id"::text = "users"."id" WHERE "users"."minion.ironman" = true ) u @@ -388,7 +388,7 @@ LIMIT 2;`, FROM activity WHERE type = 'Farming' GROUP BY user_id -ORDER BY count(user_id) DESC +ORDER BY count(user_id)::int DESC LIMIT 2;`, `SELECT user_id::text as id, 'Top 2 Tithe Farm' as desc FROM user_stats @@ -445,7 +445,9 @@ LIMIT 2;` '982989775399174184', '346304390858145792' ]; - const res = await prisma.$queryRaw<{ user_id: string; qty: number }[]>`SELECT user_id, COUNT(user_id) AS qty + const res = await prisma.$queryRaw< + { user_id: string; qty: number }[] + >`SELECT user_id, COUNT(user_id)::int AS qty FROM giveaway WHERE channel_id IN (${Prisma.join(GIVEAWAY_CHANNELS)}) AND user_id NOT IN ('157797566833098752') diff --git a/src/lib/settings/prisma.ts b/src/lib/settings/prisma.ts index b36b777d15..e8c6096614 100644 --- a/src/lib/settings/prisma.ts +++ b/src/lib/settings/prisma.ts @@ -59,7 +59,7 @@ export function convertStoredActivityToFlatActivity(activity: Activity): Activit * ⚠️ Uses queryRawUnsafe */ export async function countUsersWithItemInCl(itemID: number, ironmenOnly: boolean) { - const query = `SELECT COUNT(id) + const query = `SELECT COUNT(id)::int FROM users WHERE ("collectionLogBank"->>'${itemID}') IS NOT NULL AND ("collectionLogBank"->>'${itemID}')::int >= 1 diff --git a/src/lib/slayer/slayerUtil.ts b/src/lib/slayer/slayerUtil.ts index b2b4248edc..d18c50a9d9 100644 --- a/src/lib/slayer/slayerUtil.ts +++ b/src/lib/slayer/slayerUtil.ts @@ -453,7 +453,7 @@ export function filterLootReplace(myBank: Bank, myLoot: Bank) { export async function getSlayerTaskStats(userID: string) { const result: { monster_id: number; total_quantity: number; qty: number }[] = - await prisma.$queryRaw`SELECT monster_id, SUM(quantity) AS total_quantity, COUNT(monster_id) AS qty + await prisma.$queryRaw`SELECT monster_id, SUM(quantity)::int AS total_quantity, COUNT(monster_id)::int AS qty FROM slayer_tasks WHERE user_id = ${userID} AND quantity_remaining = 0 diff --git a/src/mahoji/commands/admin.ts b/src/mahoji/commands/admin.ts index 3b279fa17f..097731b97c 100644 --- a/src/mahoji/commands/admin.ts +++ b/src/mahoji/commands/admin.ts @@ -131,7 +131,7 @@ async function unsafeEval({ userID, code }: { userID: string; code: string }) { async function allEquippedPets() { const pets = await prisma.$queryRawUnsafe< { pet: number; qty: number }[] - >(`SELECT "minion.equippedPet" AS pet, COUNT("minion.equippedPet") AS qty + >(`SELECT "minion.equippedPet" AS pet, COUNT("minion.equippedPet")::int AS qty FROM users WHERE "minion.equippedPet" IS NOT NULL GROUP BY "minion.equippedPet" @@ -289,7 +289,7 @@ AND ("gear.melee" IS NOT NULL OR >(`SELECT (blowpipe->>'scales')::int AS scales, (blowpipe->>'dartID')::int AS dart, (blowpipe->>'dartQuantity')::int AS qty FROM users WHERE blowpipe iS NOT NULL and (blowpipe->>'dartQuantity')::int != 0;`), - prisma.$queryRawUnsafe<{ sum: number }[]>('SELECT SUM("GP") FROM users;'), + prisma.$queryRawUnsafe<{ sum: number }[]>('SELECT SUM("GP")::int FROM users;'), prisma.$queryRawUnsafe<{ banks: ItemBank }[]>(`SELECT json_object_agg(itemID, itemQTY)::jsonb as banks from ( @@ -329,7 +329,7 @@ WHERE blowpipe iS NOT NULL and (blowpipe->>'dartQuantity')::int != 0;`), name: 'Most Active', run: async () => { const res = await prisma.$queryRawUnsafe<{ num: number; username: string }[]>(` -SELECT sum(duration) as num, "new_user"."username", user_id +SELECT sum(duration)::int as num, "new_user"."username", user_id FROM activity INNER JOIN "new_users" "new_user" on "new_user"."id" = "activity"."user_id"::text WHERE start_date > now() - interval '2 days' @@ -409,11 +409,11 @@ The next buy limit reset is at: ${buyLimitInterval.nextResetStr}, it resets ever run: async () => { const result = await prisma.$queryRawUnsafe<{ item_id: string; total_gp_spent: number }[]>(`SELECT key AS item_id, - sum((cost_gp / total_items) * value::integer) AS total_gp_spent + sum((cost_gp / total_items) * value::integer)::int AS total_gp_spent FROM buy_command_transaction, json_each_text(loot_bank), - (SELECT id, sum(value::integer) as total_items FROM buy_command_transaction, json_each_text(loot_bank) GROUP BY id) subquery + (SELECT id, sum(value::integer)::int as total_items FROM buy_command_transaction, json_each_text(loot_bank) GROUP BY id) subquery WHERE buy_command_transaction.id = subquery.id GROUP BY @@ -441,7 +441,7 @@ LIMIT run: async () => { const result = await prisma.$queryRawUnsafe< { item_id: number; gp: number }[] - >(`select item_id, sum(gp_received) as gp + >(`select item_id, sum(gp_received)::int as gp from bot_item_sell group by item_id order by gp desc @@ -450,7 +450,7 @@ limit 80; const totalGPGivenOut = await prisma.$queryRawUnsafe< { total_gp_given_out: number }[] - >(`select sum(gp_received) as total_gp_given_out + >(`select sum(gp_received)::int as total_gp_given_out from bot_item_sell;`); return { @@ -479,7 +479,7 @@ from bot_item_sell;`); name: 'Max G.E Slot users', run: async () => { const res = await prisma.$queryRawUnsafe<{ user_id: string; slots_used: number }[]>(` -SELECT user_id, COUNT(*) AS slots_used +SELECT user_id, COUNT(*)::int AS slots_used FROM ge_listing WHERE cancelled_at IS NULL AND fulfilled_at IS NULL GROUP BY user_id diff --git a/src/mahoji/commands/ge.ts b/src/mahoji/commands/ge.ts index d4ec891f94..fc6e6f7726 100644 --- a/src/mahoji/commands/ge.ts +++ b/src/mahoji/commands/ge.ts @@ -396,7 +396,7 @@ The next buy limit reset is at: ${GrandExchange.getInterval().nextResetStr}, it >(`SELECT DATE_TRUNC('week', sellTransactions.created_at) AS week, AVG(sellTransactions.price_per_item_before_tax) AS average_price_per_item_before_tax, - SUM(sellTransactions.quantity_bought) AS total_quantity_bought + SUM(sellTransactions.quantity_bought)::int AS total_quantity_bought FROM ge_listing INNER JOIN diff --git a/src/mahoji/commands/leaderboard.ts b/src/mahoji/commands/leaderboard.ts index cafadd7934..f6d3cc2ac3 100644 --- a/src/mahoji/commands/leaderboard.ts +++ b/src/mahoji/commands/leaderboard.ts @@ -186,7 +186,7 @@ async function sacrificeLb( const mostUniques: { id: string; sacbanklength: number }[] = await prisma.$queryRawUnsafe( `SELECT u.user_id::text AS id, u.sacbanklength FROM ( - SELECT (SELECT COUNT(*) FROM JSONB_OBJECT_KEYS(sacrificed_bank)) sacbanklength, user_id FROM user_stats + SELECT (SELECT COUNT(*)::int FROM JSONB_OBJECT_KEYS(sacrificed_bank)) sacbanklength, user_id FROM user_stats ${ironmanOnly ? 'INNER JOIN users ON users.id::bigint = user_stats.user_id WHERE "minion.ironman" = true' : ''} ) u ORDER BY u.sacbanklength DESC LIMIT 10; diff --git a/src/mahoji/commands/tools.ts b/src/mahoji/commands/tools.ts index a054d3d8cc..65aaf20731 100644 --- a/src/mahoji/commands/tools.ts +++ b/src/mahoji/commands/tools.ts @@ -103,7 +103,7 @@ GROUP BY type ORDER BY qty DESC LIMIT 15;`), prisma.$queryRawUnsafe(` -SELECT sum(duration) +SELECT sum(duration)::int FROM activity WHERE user_id = ${id} ${whereInMassClause(id)};`) diff --git a/src/mahoji/lib/abstracted_commands/infernoCommand.ts b/src/mahoji/lib/abstracted_commands/infernoCommand.ts index de277b5a63..bef958eb09 100644 --- a/src/mahoji/lib/abstracted_commands/infernoCommand.ts +++ b/src/mahoji/lib/abstracted_commands/infernoCommand.ts @@ -118,7 +118,7 @@ function baseDuration(_attempts: number) { async function timesMadeToZuk(userID: string) { const timesMadeToZuk = Number( ( - await prisma.$queryRawUnsafe(`SELECT COUNT(*) + await prisma.$queryRawUnsafe(`SELECT COUNT(*)::int FROM activity WHERE type = 'Inferno' AND user_id = ${userID} diff --git a/src/mahoji/lib/abstracted_commands/statCommand.ts b/src/mahoji/lib/abstracted_commands/statCommand.ts index 2cb942e481..bb339a7ee4 100644 --- a/src/mahoji/lib/abstracted_commands/statCommand.ts +++ b/src/mahoji/lib/abstracted_commands/statCommand.ts @@ -118,7 +118,7 @@ WHERE export async function personalConstructionStats(user: MUser) { const result: { id: number; qty: number }[] = - await prisma.$queryRawUnsafe(`SELECT (data->>'objectID')::int AS id, SUM((data->>'quantity')::int) AS qty + await prisma.$queryRawUnsafe(`SELECT (data->>'objectID')::int AS id, SUM((data->>'quantity')::int)::int AS qty FROM activity WHERE type = 'Construction' AND user_id = '${user.id}'::bigint @@ -136,7 +136,7 @@ GROUP BY data->>'objectID';`); export async function personalFiremakingStats(user: MUser) { const result: { id: number; qty: number }[] = - await prisma.$queryRawUnsafe(`SELECT (data->>'burnableID')::int AS id, SUM((data->>'quantity')::int) AS qty + await prisma.$queryRawUnsafe(`SELECT (data->>'burnableID')::int AS id, SUM((data->>'quantity')::int)::int AS qty FROM activity WHERE type = 'Firemaking' AND user_id = '${user.id}'::bigint @@ -154,7 +154,7 @@ GROUP BY data->>'burnableID';`); export async function personalWoodcuttingStats(user: MUser) { const result: { id: number; qty: number }[] = - await prisma.$queryRawUnsafe(`SELECT (data->>'logID')::int AS id, SUM((data->>'quantity')::int) AS qty + await prisma.$queryRawUnsafe(`SELECT (data->>'logID')::int AS id, SUM((data->>'quantity')::int)::int AS qty FROM activity WHERE type = 'Woodcutting' AND user_id = '${user.id}'::bigint @@ -172,7 +172,7 @@ GROUP BY data->>'logID';`); export async function personalMiningStats(user: MUser) { const result: { id: number; qty: number }[] = - await prisma.$queryRawUnsafe(`SELECT (data->>'oreID')::int AS id, SUM((data->>'quantity')::int) AS qty + await prisma.$queryRawUnsafe(`SELECT (data->>'oreID')::int AS id, SUM((data->>'quantity')::int)::int AS qty FROM activity WHERE type = 'Mining' AND user_id = '${user.id}'::bigint @@ -190,7 +190,7 @@ GROUP BY data->>'oreID';`); export async function personalHerbloreStats(user: MUser, stats: UserStats) { const result: { id: number; qty: number }[] = - await prisma.$queryRawUnsafe(`SELECT (data->>'mixableID')::int AS id, SUM((data->>'quantity')::int) AS qty + await prisma.$queryRawUnsafe(`SELECT (data->>'mixableID')::int AS id, SUM((data->>'quantity')::int)::int AS qty FROM activity WHERE type = 'Herblore' AND user_id = '${user.id}'::bigint @@ -208,7 +208,7 @@ GROUP BY data->>'mixableID';`); } export async function personalAlchingStats(user: MUser, includeAgilityAlching = true) { const result: { id: number; qty: number }[] = - await prisma.$queryRawUnsafe(`SELECT (data->>'itemID')::int AS id, SUM((data->>'quantity')::int) AS qty + await prisma.$queryRawUnsafe(`SELECT (data->>'itemID')::int AS id, SUM((data->>'quantity')::int)::int AS qty FROM activity WHERE type = 'Alching' AND user_id = '${user.id}'::bigint @@ -216,7 +216,7 @@ AND data->>'itemID' IS NOT NULL AND completed = true GROUP BY data->>'itemID';`); const agilityAlchRes: { id: number; qty: number }[] = - await prisma.$queryRawUnsafe(`SELECT (((data->>'alch')::json)->>'itemID')::int AS id, SUM((((data->>'alch')::json)->>'quantity')::int) AS qty + await prisma.$queryRawUnsafe(`SELECT (((data->>'alch')::json)->>'itemID')::int AS id, SUM((((data->>'alch')::json)->>'quantity')::int)::int AS qty FROM activity WHERE type = 'Agility' AND user_id = '${user.id}'::bigint @@ -234,7 +234,7 @@ GROUP BY ((data->>'alch')::json)->>'itemID';`); } export async function personalSmithingStats(user: MUser) { const result: { id: number; qty: number }[] = - await prisma.$queryRawUnsafe(`SELECT (data->>'smithedBarID')::int AS id, SUM((data->>'quantity')::int) AS qty + await prisma.$queryRawUnsafe(`SELECT (data->>'smithedBarID')::int AS id, SUM((data->>'quantity')::int)::int AS qty FROM activity WHERE type = 'Smithing' AND user_id = '${user.id}'::bigint @@ -251,7 +251,7 @@ GROUP BY data->>'smithedBarID';`); } export async function personalSmeltingStats(user: MUser) { const result: { id: number; qty: number }[] = - await prisma.$queryRawUnsafe(`SELECT (data->>'barID')::int AS id, SUM((data->>'quantity')::int) AS qty + await prisma.$queryRawUnsafe(`SELECT (data->>'barID')::int AS id, SUM((data->>'quantity')::int)::int AS qty FROM activity WHERE type = 'Smelting' AND user_id = '${user.id}'::bigint @@ -268,7 +268,7 @@ GROUP BY data->>'barID';`); } export async function personalSpellCastStats(user: MUser) { const result: { id: number; qty: number }[] = - await prisma.$queryRawUnsafe(`SELECT (data->>'spellID')::int AS id, SUM((data->>'quantity')::int) AS qty + await prisma.$queryRawUnsafe(`SELECT (data->>'spellID')::int AS id, SUM((data->>'quantity')::int)::int AS qty FROM activity WHERE type = 'Casting' AND user_id = '${user.id}'::bigint @@ -279,7 +279,7 @@ GROUP BY data->>'spellID';`); } export async function personalCollectingStats(user: MUser) { const result: { id: number; qty: number }[] = - await prisma.$queryRawUnsafe(`SELECT (data->>'collectableID')::int AS id, SUM((data->>'quantity')::int) AS qty + await prisma.$queryRawUnsafe(`SELECT (data->>'collectableID')::int AS id, SUM((data->>'quantity')::int)::int AS qty FROM activity WHERE type = 'Collecting' AND user_id = '${user.id}'::bigint @@ -323,7 +323,7 @@ export const dataPoints: readonly DataPiece[] = [ perkTierNeeded: PerkTier.Four, run: async (user: MUser) => { const result: { type: activity_type_enum; qty: number }[] = - await prisma.$queryRawUnsafe(`SELECT type, count(type) AS qty + await prisma.$queryRawUnsafe(`SELECT type, count(type)::int AS qty FROM activity WHERE completed = true AND user_id = ${BigInt(user.id)} @@ -418,7 +418,7 @@ GROUP BY data->>'monsterID';`); perkTierNeeded: PerkTier.Four, run: async () => { const result: { mins: number; count: number }[] = - await prisma.$queryRaw`SELECT mins, COUNT(mins) FROM (SELECT ((data->>'deathTime')::int / 1000 / 60) as mins + await prisma.$queryRaw`SELECT mins, COUNT(mins)::int FROM (SELECT ((data->>'deathTime')::int / 1000 / 60) as mins FROM activity WHERE type = 'Inferno' AND completed = true @@ -438,7 +438,7 @@ GROUP BY mins;`; perkTierNeeded: PerkTier.Four, run: async (user: MUser) => { const result: { mins: number; count: number }[] = - await prisma.$queryRawUnsafe(`SELECT mins, COUNT(mins) FROM (SELECT ((data->>'deathTime')::int / 1000 / 60) as mins + await prisma.$queryRawUnsafe(`SELECT mins, COUNT(mins)::int FROM (SELECT ((data->>'deathTime')::int / 1000 / 60) as mins FROM activity WHERE type = 'Inferno' AND user_id = ${BigInt(user.id)} @@ -561,7 +561,7 @@ WHERE "skills.${skillName}" = 200000000::int;`) as Promise<{ qty: number; skill_ perkTierNeeded: PerkTier.Four, run: async (user: MUser) => { const result: { plant: string; qty: number }[] = - await prisma.$queryRawUnsafe(`SELECT data->>'plantsName' as plant, COUNT(data->>'plantsName') AS qty + await prisma.$queryRawUnsafe(`SELECT data->>'plantsName' as plant, COUNT(data->>'plantsName')::int AS qty FROM activity WHERE type = 'Farming' AND data->>'plantsName' IS NOT NULL @@ -581,7 +581,7 @@ GROUP BY data->>'plantsName'`); perkTierNeeded: PerkTier.Four, run: async () => { const result: { plant: string; qty: number }[] = - await prisma.$queryRaw`SELECT data->>'plantsName' as plant, COUNT(data->>'plantsName') AS qty + await prisma.$queryRaw`SELECT data->>'plantsName' as plant, COUNT(data->>'plantsName')::int AS qty FROM activity WHERE type = 'Farming' AND data->>'plantsName' IS NOT NULL @@ -783,7 +783,7 @@ ${result perkTierNeeded: PerkTier.Four, run: async () => { const result = await prisma.$queryRawUnsafe( - 'SELECT COUNT(*) FROM users WHERE "minion.hasBought" = true;' + 'SELECT COUNT(*)::int FROM users WHERE "minion.hasBought" = true;' ); return `There are ${result[0].count.toLocaleString()} minions!`; } @@ -793,7 +793,7 @@ ${result perkTierNeeded: PerkTier.Four, run: async () => { const result = await prisma.$queryRawUnsafe( - 'SELECT COUNT(*) FROM users WHERE "minion.ironman" = true;' + 'SELECT COUNT(*)::int FROM users WHERE "minion.ironman" = true;' ); return `There are ${parseInt(result[0].count).toLocaleString()} ironman minions!`; } @@ -803,7 +803,7 @@ ${result perkTierNeeded: PerkTier.Four, run: async () => { const result: { icon: string | null; qty: number }[] = await prisma.$queryRawUnsafe( - 'SELECT "minion.icon" as icon, COUNT(*) as qty FROM users WHERE "minion.icon" is not null group by "minion.icon" order by qty asc;' + 'SELECT "minion.icon" as icon, COUNT(*)::int as qty FROM users WHERE "minion.icon" is not null group by "minion.icon" order by qty asc;' ); return `**Current minion tiers and their number of users:**\n${Object.values(result) .map(row => `${row.icon ?? '<:minion:763743627092164658>'} : ${row.qty}`) @@ -814,7 +814,7 @@ ${result name: 'Global Bank Backgrounds', perkTierNeeded: PerkTier.Four, run: async () => { - const result = await prisma.$queryRawUnsafe(`SELECT "bankBackground", COUNT(*) + const result = await prisma.$queryRawUnsafe(`SELECT "bankBackground", COUNT(*)::int FROM users WHERE "bankBackground" <> 1 GROUP BY "bankBackground";`); @@ -959,7 +959,7 @@ GROUP BY "bankBackground";`); run: async (user: MUser) => { const result = await prisma.$queryRawUnsafe( `SELECT skill, - SUM(xp) AS total_xp + SUM(xp)::int AS total_xp FROM xp_gains WHERE source = 'TearsOfGuthix' AND user_id = ${BigInt(user.id)}