From 840da6a4d30561c822bac703620ed812c5fc1f19 Mon Sep 17 00:00:00 2001 From: Christopher Thai Date: Sun, 4 Aug 2024 17:06:36 -0700 Subject: [PATCH] Removed insert on duplicate update on animals to prevent db locks --- src/commands/commandList/zoo/animalUtil.js | 27 +++++++++++++------ src/commands/commandList/zoo/autohunt.js | 2 +- src/commands/commandList/zoo/catch.js | 2 +- src/utils/cacheUtil.js | 30 ++++++++++++++++++++++ 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/commands/commandList/zoo/animalUtil.js b/src/commands/commandList/zoo/animalUtil.js index 4296551d..68507c94 100644 --- a/src/commands/commandList/zoo/animalUtil.js +++ b/src/commands/commandList/zoo/animalUtil.js @@ -9,6 +9,7 @@ const mysql = require('../../../botHandlers/mysqlHandler.js'); const global = require('../../../utils/global.js'); const animals = require('../../../utils/animalInfoUtil.js'); const eventUtil = require('../../../utils/eventUtil.js'); +const cacheUtil = require('../../../utils/cacheUtil.js'); let enableDistortedTier = true; setTimeout(() => { @@ -151,7 +152,7 @@ function getEventRarity(animal, event) { return rate; } -exports.getMultipleAnimals = function (count, user, opt) { +exports.getMultipleAnimals = async function (count, user, opt) { const total = {}; let xp = 0; for (let i = 0; i < count; i++) { @@ -175,7 +176,7 @@ exports.getMultipleAnimals = function (count, user, opt) { } const ordered = sortAnimals(total); - const { sql, typeCount } = createSql(ordered, user); + const { sql, typeCount } = await createSql(ordered, user); return { animals: total, @@ -252,12 +253,16 @@ function sortAnimals(animals) { return animalList; } -function createSql(orderedAnimal, user) { +async function createSql(orderedAnimal, user) { let animalSql = []; let animalCountSql = {}; + let animalCase = '( CASE\n'; + let animals = []; orderedAnimal.forEach((animal) => { animalSql.push(`(${user.id}, '${animal.value}', ${animal.count}, ${animal.count})`); + animals.push(`'${animal.value}'`); + animalCase += `WHEN name = '${animal.value}' THEN ${animal.count}\n` if (!animalCountSql[animal.rank]) animalCountSql[animal.rank] = { rank: animal.rank, @@ -266,12 +271,11 @@ function createSql(orderedAnimal, user) { animalCountSql[animal.rank].count += animal.count; }); animalCountSql = Object.values(animalCountSql); + animalCase += 'ELSE 0 END)' - let sql = `INSERT INTO animal (id, name, count, totalcount) - VALUES ${animalSql.join(',')} - ON DUPLICATE KEY UPDATE - count = count + VALUES(count), - totalcount = totalcount + VALUES(totalcount);`; + let sql = `UPDATE animal SET + count = count + ${animalCase}, totalcount = totalcount + ${animalCase} + WHERE id = ${user.id} AND name in (${animals.join(',')});` sql += `INSERT INTO animal_count (id, ${animalCountSql .map((animalCount) => animalCount.rank) .join(',')}) @@ -283,8 +287,15 @@ function createSql(orderedAnimal, user) { }) .join(',')}; `; + await checkDbInsert(user.id, orderedAnimal); return { sql, typeCount: animalCountSql, }; } + +async function checkDbInsert(id, animals) { + for (let i in animals) { + await cacheUtil.insertAnimal(id, animals[i].value); + } +} diff --git a/src/commands/commandList/zoo/autohunt.js b/src/commands/commandList/zoo/autohunt.js index 07d7f173..59e9e68b 100644 --- a/src/commands/commandList/zoo/autohunt.js +++ b/src/commands/commandList/zoo/autohunt.js @@ -88,7 +88,7 @@ async function claim(p, msg, con, query, bot) { //Get all animal let radar = autohuntutil.getLvl(query.radar, 0, 'radar'); - let { animals, animalSql } = animalUtil.getMultipleAnimals(query.huntcount, p.msg.author, { + let { animals, animalSql } = await animalUtil.getMultipleAnimals(query.huntcount, p.msg.author, { patreon: patreon, huntbot: radar.stat, }); diff --git a/src/commands/commandList/zoo/catch.js b/src/commands/commandList/zoo/catch.js index 43f19b2c..ef4d25cb 100644 --- a/src/commands/commandList/zoo/catch.js +++ b/src/commands/commandList/zoo/catch.js @@ -173,7 +173,7 @@ async function getAnimals(p, result, gems, uid) { if (gems['Patreon']) count += 1; } - let { ordered, animalSql, typeCount, xp } = animalUtil.getMultipleAnimals( + let { ordered, animalSql, typeCount, xp } = await animalUtil.getMultipleAnimals( count, p.msg.author, opt diff --git a/src/utils/cacheUtil.js b/src/utils/cacheUtil.js index bc87d9b4..fdd5de9c 100644 --- a/src/utils/cacheUtil.js +++ b/src/utils/cacheUtil.js @@ -9,6 +9,7 @@ const mysql = require('./../botHandlers/mysqlHandler.js'); class CacheUtil { constructor() { this.getUid = this.getUid.bind(this); + this.getAnimalNames = this.getAnimalNames.bind(this); this.get = this.get.bind(this); this.set = this.set.bind(this); this.cache = {}; @@ -102,6 +103,35 @@ class CacheUtil { return quest.qname === questName && (showLocked || quest.locked === 0); }); } + + async getAnimalNames(id) { + id = BigInt(id); + let result = this.get('animalNames', id); + if (result) { + return result; + } + + const sql = `SELECT name FROM animal WHERE id = ${id};`; + result = await mysql.query(sql); + const animals = {}; + result.forEach((row) => { + animals[row.name] = true; + }); + this.set('animalNames', id, animals); + return animals; + } + + async insertAnimal(id, animalName) { + const animals = await this.getAnimalNames(id); + if (animals[animalName]) { + return; + } + + const sql = `INSERT INTO animal (id, name, count, totalcount) VALUES (${id}, '${animalName}', 0, 0);`; + await mysql.query(sql); + + animals[animalName] = true; + } } module.exports = new CacheUtil();