From 6eb5a67add9891eda11802b9a1a37746c7943b5e Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Sat, 8 Nov 2025 21:06:03 +0100 Subject: [PATCH] Profiler/Optimization * move searchable flags to their own db cols to speed up lookups * don't cast profile name to LOWER in SQL when displaying tooltips. --- endpoints/achievement/achievement.php | 2 +- endpoints/arena-team/arena-team.php | 6 +++--- endpoints/faction/faction.php | 2 +- endpoints/guild/guild.php | 6 +++--- endpoints/profile/delete.php | 4 +--- endpoints/profile/link.php | 4 ++-- endpoints/profile/load.php | 8 ++++---- endpoints/profile/profile.php | 12 ++++++------ endpoints/profile/profile_power.php | 2 +- endpoints/profile/save.php | 7 ++++--- endpoints/quest/quest.php | 2 +- endpoints/spell/spell.php | 2 +- endpoints/title/title.php | 2 +- endpoints/user/user.php | 2 +- includes/components/profiler.class.php | 12 ++++++------ includes/dbtypes/arenateam.class.php | 2 +- includes/dbtypes/guild.class.php | 10 ++++------ includes/dbtypes/profile.class.php | 15 +++++++-------- includes/defines.php | 6 +++--- includes/user.class.php | 2 +- setup/sql/01-db_structure.sql | 14 ++++++++++++-- setup/sql/updates/1762629696_01.sql | 18 ++++++++++++++++++ setup/sql/updates/1762629696_02.sql | 10 ++++++++++ 23 files changed, 92 insertions(+), 58 deletions(-) create mode 100644 setup/sql/updates/1762629696_01.sql create mode 100644 setup/sql/updates/1762629696_02.sql diff --git a/endpoints/achievement/achievement.php b/endpoints/achievement/achievement.php index 1068fe42..07e5532e 100644 --- a/endpoints/achievement/achievement.php +++ b/endpoints/achievement/achievement.php @@ -121,7 +121,7 @@ class AchievementBaseResponse extends TemplateResponse implements ICache if (Cfg::get('PROFILER_ENABLE') && !($this->subject->getField('flags') & ACHIEVEMENT_FLAG_COUNTER)) { $x = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_completion_achievements WHERE `achievementId` = ?d', $this->typeId); - $y = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_profiles WHERE `realm` IS NOT NULL AND `realmGUID` IS NOT NULL AND `cuFlags` & ?d = 0', PROFILER_CU_NEEDS_RESYNC); + $y = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_profiles WHERE `custom` = 0 AND `stub` = 0'); $infobox[] = Lang::profiler('attainedBy', [round(($x ?: 0) * 100 / ($y ?: 1))]); // completion row added by InfoboxMarkup diff --git a/endpoints/arena-team/arena-team.php b/endpoints/arena-team/arena-team.php index 2d50aa08..7e30a1c2 100644 --- a/endpoints/arena-team/arena-team.php +++ b/endpoints/arena-team/arena-team.php @@ -46,11 +46,11 @@ class ArenateamBaseResponse extends TemplateResponse // 3 possibilities // 1) already synced to aowow - if ($subject = DB::Aowow()->selectRow('SELECT `id`, `realmGUID`, `cuFlags` FROM ?_profiler_arena_team WHERE `realm` = ?d AND `nameUrl` = ?', $this->realmId, Profiler::urlize($this->subjectName))) + if ($subject = DB::Aowow()->selectRow('SELECT `id`, `realmGUID`, `stub` FROM ?_profiler_arena_team WHERE `realm` = ?d AND `nameUrl` = ?', $this->realmId, Profiler::urlize($this->subjectName))) { $this->typeId = $subject['id']; - if ($subject['cuFlags'] & PROFILER_CU_NEEDS_RESYNC) + if ($subject['stub']) $this->handleIncompleteData(Type::ARENA_TEAM, $subject['realmGUID']); return; @@ -62,7 +62,7 @@ class ArenateamBaseResponse extends TemplateResponse { $subject = $subject[0]; $subject['realm'] = $this->realmId; - $subject['cuFlags'] = PROFILER_CU_NEEDS_RESYNC; + $subject['stub'] = 1; $subject['nameUrl'] = Profiler::urlize($subject['name']); // create entry from realm with basic info diff --git a/endpoints/faction/faction.php b/endpoints/faction/faction.php index 2ca7ca92..a5bd4867 100644 --- a/endpoints/faction/faction.php +++ b/endpoints/faction/faction.php @@ -103,7 +103,7 @@ class FactionBaseResponse extends TemplateResponse implements ICache if (Cfg::get('PROFILER_ENABLE') && !($this->subject->getField('cuFlags') & CUSTOM_EXCLUDE_FOR_LISTVIEW)) { $x = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_completion_reputation WHERE `standing` >= ?d AND `factionId` = ?d', 42000, $this->typeId); - $y = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_profiles WHERE `realm` IS NOT NULL AND `realmGUID` IS NOT NULL AND `cuFlags` & ?d = 0', PROFILER_CU_NEEDS_RESYNC); + $y = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_profiles WHERE `custom` = 0 AND `stub` = 0'); $infobox[] = Lang::profiler('attainedBy', [round(($x ?: 0) * 100 / ($y ?: 1))]); // completion row added by InfoboxMarkup diff --git a/endpoints/guild/guild.php b/endpoints/guild/guild.php index fa247e40..2cd0f3f6 100644 --- a/endpoints/guild/guild.php +++ b/endpoints/guild/guild.php @@ -46,11 +46,11 @@ class GuildBaseResponse extends TemplateResponse // 3 possibilities // 1) already synced to aowow - if ($subject = DB::Aowow()->selectRow('SELECT `id`, `realmGUID`, `cuFlags` FROM ?_profiler_guild WHERE `realm` = ?d AND `nameUrl` = ?', $this->realmId, Profiler::urlize($this->subjectName))) + if ($subject = DB::Aowow()->selectRow('SELECT `id`, `realmGUID`, `stub` FROM ?_profiler_guild WHERE `realm` = ?d AND `nameUrl` = ?', $this->realmId, Profiler::urlize($this->subjectName))) { $this->typeId = $subject['id']; - if ($subject['cuFlags'] & PROFILER_CU_NEEDS_RESYNC) + if ($subject['stub']) $this->handleIncompleteData(Type::GUILD, $subject['realmGUID']); return; @@ -62,7 +62,7 @@ class GuildBaseResponse extends TemplateResponse { $subject = $subject[0]; $subject['realm'] = $this->realmId; - $subject['cuFlags'] = PROFILER_CU_NEEDS_RESYNC; + $subject['stub'] = 1; $subject['nameUrl'] = Profiler::urlize($subject['name']); // create entry from realm with basic info diff --git a/endpoints/profile/delete.php b/endpoints/profile/delete.php index 0bf905cd..15a8e961 100644 --- a/endpoints/profile/delete.php +++ b/endpoints/profile/delete.php @@ -37,10 +37,8 @@ class ProfileDeleteResponse extends TextResponse // only flag as deleted; only custom profiles DB::Aowow()->query( - 'UPDATE ?_profiler_profiles SET `cuFlags` = `cuFlags` | ?d WHERE `id` IN (?a) AND `cuFlags` & ?d {AND `user` = ?d}', - PROFILER_CU_DELETED, + 'UPDATE ?_profiler_profiles SET `deleted` = 1 WHERE `id` IN (?a) AND `custom` = 1 {AND `user` = ?d}', $this->_get['id'], - PROFILER_CU_PROFILE, User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU) ? DBSIMPLE_SKIP : User::$id ); } diff --git a/endpoints/profile/link.php b/endpoints/profile/link.php index bcd32ab0..63a7434f 100644 --- a/endpoints/profile/link.php +++ b/endpoints/profile/link.php @@ -38,8 +38,8 @@ class ProfileLinkResponse extends TextResponse // only link characters, not custom profiles $newId = DB::Aowow()->query( 'REPLACE INTO ?_account_profiles (`accountId`, `profileId`, `extraFlags`) - SELECT ?d, p.`id`, 0 FROM ?_profiler_profiles p WHERE p.`id` = ?d AND (`cuFlags` & ?d) = 0', - User::$id, $this->_get['id'], PROFILER_CU_PROFILE + SELECT ?d, p.`id`, 0 FROM ?_profiler_profiles p WHERE p.`id` = ?d AND `custom` = 0', + User::$id, $this->_get['id'] ); if (!is_int($newId)) diff --git a/endpoints/profile/load.php b/endpoints/profile/load.php index 8be7a2da..32370ee1 100644 --- a/endpoints/profile/load.php +++ b/endpoints/profile/load.php @@ -47,7 +47,7 @@ class ProfileLoadResponse extends TextResponse return; } - if (($pBase['cuFlags'] & PROFILER_CU_DELETED) && !User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU)) + if ($pBase['deleted'] && !User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU)) return; @@ -56,7 +56,7 @@ class ProfileLoadResponse extends TextResponse if ($rId == $pBase['realm']) break; - if (!$rData) // realm doesn't exist or access is restricted + if ($pBase['realm'] && !$rData) // realm doesn't exist or access is restricted return; $profile = array( @@ -103,7 +103,7 @@ class ProfileLoadResponse extends TextResponse 'activity' => [], // recent raid activity [achievementId => 1] (is a subset of statistics) ); - if ($pBase['cuFlags'] & PROFILER_CU_PROFILE) + if ($pBase['custom']) { // this parameter is _really_ strange .. probably still not doing this right $profile['source'] = $pBase['realm'] ? $pBase['sourceId'] : 0; @@ -135,7 +135,7 @@ class ProfileLoadResponse extends TextResponse $profile['pets'] = $pets; // source for custom profiles; profileId => [name, ownerId, iconString(optional)] - if ($customs = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `name`, `user`, `icon` FROM ?_profiler_profiles WHERE `sourceId` = ?d AND `sourceId` <> `id` {AND (`cuFlags` & ?d) = 0}', $pBase['id'], User::isInGroup(U_GROUP_STAFF) ? DBSIMPLE_SKIP : PROFILER_CU_DELETED)) + if ($customs = DB::Aowow()->select('SELECT `id` AS ARRAY_KEY, `name`, `user`, `icon` FROM ?_profiler_profiles WHERE `sourceId` = ?d AND `sourceId` <> `id` {AND `deleted` = ?d}', $pBase['id'], User::isInGroup(U_GROUP_STAFF) ? DBSIMPLE_SKIP : 0)) { foreach ($customs as $id => $cu) { diff --git a/endpoints/profile/profile.php b/endpoints/profile/profile.php index 39484228..e3db2365 100644 --- a/endpoints/profile/profile.php +++ b/endpoints/profile/profile.php @@ -67,11 +67,11 @@ class ProfileBaseResponse extends TemplateResponse // 3 possibilities // 1) already synced to aowow - if ($subject = DB::Aowow()->selectRow('SELECT `id`, `realmGUID`, `cuFlags` FROM ?_profiler_profiles WHERE `realm` = ?d AND `realmGUID` IS NOT NULL AND `name` = ? AND `renameItr` = ?d', $this->realmId, Util::ucFirst($this->subjectName), $rnItr)) + if ($subject = DB::Aowow()->selectRow('SELECT `id`, `realmGUID`, `stub` FROM ?_profiler_profiles WHERE `realm` = ?d AND `custom` = 0 AND `name` = ? AND `renameItr` = ?d', $this->realmId, Util::ucFirst($this->subjectName), $rnItr)) { $this->typeId = $subject['id']; - if ($subject['cuFlags'] & PROFILER_CU_NEEDS_RESYNC) + if ($subject['stub']) $this->handleIncompleteData(Type::PROFILE, $subject['realmGUID']); return; @@ -93,18 +93,18 @@ class ProfileBaseResponse extends TemplateResponse if ($subject = array_filter($subjects, fn($x) => Util::lower($x['name']) == Util::lower($this->subjectName))) { $subject = $subject[0]; - $subject['realm'] = $this->realmId; - $subject['cuFlags'] = PROFILER_CU_NEEDS_RESYNC; + $subject['realm'] = $this->realmId; + $subject['stub'] = 1; if ($subject['at_login'] & 0x1) - $subject['renameItr'] = DB::Aowow()->selectCell('SELECT MAX(`renameItr`) FROM ?_profiler_profiles WHERE `realm` = ?d AND `realmGUID` IS NOT NULL AND `name` = ?', $this->realmId, $subject['name']); + $subject['renameItr'] = DB::Aowow()->selectCell('SELECT MAX(`renameItr`) FROM ?_profiler_profiles WHERE `realm` = ?d AND `custom` = 0 AND `name` = ?', $this->realmId, $subject['name']); if ($subject['guildGUID']) { // create empty guild if necessary to satisfy foreign keys $subject['guild'] = DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_guild WHERE `realm` = ?d AND `realmGUID` = ?d', $this->realmId, $subject['guildGUID']); if (!$subject['guild']) - $subject['guild'] = DB::Aowow()->query('INSERT INTO ?_profiler_guild (`realm`, `realmGUID`, `cuFlags`, `name`, `nameUrl`) VALUES (?d, ?d, ?d, ?, ?)', $this->realmId, $subject['guildGUID'], PROFILER_CU_NEEDS_RESYNC, $subject['guildName'], Profiler::urlize($subject['guildName'])); + $subject['guild'] = DB::Aowow()->query('INSERT INTO ?_profiler_guild (`realm`, `realmGUID`, `stub`, `name`, `nameUrl`) VALUES (?d, ?d, 1, ?, ?)', $this->realmId, $subject['guildGUID'], $subject['guildName'], Profiler::urlize($subject['guildName'])); } unset($subject['guildGUID'], $subject['guildName'], $subject['at_login']); diff --git a/endpoints/profile/profile_power.php b/endpoints/profile/profile_power.php index ea15084a..a1a23844 100644 --- a/endpoints/profile/profile_power.php +++ b/endpoints/profile/profile_power.php @@ -38,7 +38,7 @@ class ProfilePowerResponse extends TextResponse implements ICache if (preg_match('/([^\-]+)-(\d+)/i', $this->subjectName, $m)) [, $this->subjectName, $renameItr] = $m; - if ($x = DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_profiles WHERE `realm` = ?d AND `realmGUID` IS NOT NULL AND LOWER(`name`) = ? AND `renameItr` = ?d', $this->realmId, $this->subjectName, $renameItr ?? 0)) + if ($x = DB::Aowow()->selectCell('SELECT `id` FROM ?_profiler_profiles WHERE `realm` = ?d AND `custom` = 0 AND `name` = ? AND `renameItr` = ?d', $this->realmId, Util::ucWords($this->subjectName), $renameItr ?? 0)) $this->typeId = $x; } diff --git a/endpoints/profile/save.php b/endpoints/profile/save.php index 0dd3eabc..51caca81 100644 --- a/endpoints/profile/save.php +++ b/endpoints/profile/save.php @@ -72,7 +72,8 @@ class ProfileSaveResponse extends TextResponse 'glyphs2' => $this->_post['glyphs2'], 'gearscore' => $this->_post['gearscore'], 'icon' => $this->_post['icon'], - 'cuFlags' => PROFILER_CU_PROFILE | ($this->_post['public'] ? PROFILER_CU_PUBLISHED : 0) + 'custom' => 1, + 'cuFlags' => $this->_post['public'] ? PROFILER_CU_PUBLISHED : 0 ); // remnant of a conflict between wotlk generic icons and cata+ auto-generated, char-based icons (see profile=avatar) @@ -88,7 +89,7 @@ class ProfileSaveResponse extends TextResponse if ($_ = $this->_post['copy']) // gets set to source profileId when "save as" is clicked. Whats the difference to 'source' though? { // get character origin info if possible - if ($r = DB::Aowow()->selectCell('SELECT `realm` FROM ?_profiler_profiles WHERE `id` = ?d AND `realm` IS NOT NULL', $_)) + if ($r = DB::Aowow()->selectCell('SELECT `realm` FROM ?_profiler_profiles WHERE `id` = ?d AND `custom` = 0', $_)) $cuProfile['realm'] = $r; $cuProfile['sourceId'] = $_; @@ -105,7 +106,7 @@ class ProfileSaveResponse extends TextResponse } else // new { - $nProfiles = DB::Aowow()->selectCell('SELECT COUNT(*) FROM ?_profiler_profiles WHERE `user` = ?d AND (`cuFlags` & ?d) = 0 AND `realmGUID` IS NULL', User::$id, PROFILER_CU_DELETED); + $nProfiles = DB::Aowow()->selectCell('SELECT COUNT(*) FROM ?_profiler_profiles WHERE `user` = ?d AND `deleted` = 0 AND `custom` = 1', User::$id); if ($nProfiles < 10 || User::isPremium()) if ($newId = DB::Aowow()->query('INSERT INTO ?_profiler_profiles (?#) VALUES (?a)', array_keys($cuProfile), array_values($cuProfile))) $charId = $newId; diff --git a/endpoints/quest/quest.php b/endpoints/quest/quest.php index 6830704d..10c56534 100644 --- a/endpoints/quest/quest.php +++ b/endpoints/quest/quest.php @@ -279,7 +279,7 @@ class QuestBaseResponse extends TemplateResponse implements ICache if (Cfg::get('PROFILER_ENABLE') && $hasCompletion) { $x = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_completion_quests WHERE `questId` = ?d', $this->typeId); - $y = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_profiles WHERE `realm` IS NOT NULL AND `realmGUID` IS NOT NULL AND `cuFlags` & ?d = 0', PROFILER_CU_NEEDS_RESYNC); + $y = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_profiles WHERE `custom` = 0 AND `stub` = 0'); $infobox[] = Lang::profiler('attainedBy', [round(($x ?: 0) * 100 / ($y ?: 1))]); // completion row added by InfoboxMarkup diff --git a/endpoints/spell/spell.php b/endpoints/spell/spell.php index 5508beff..f473a698 100644 --- a/endpoints/spell/spell.php +++ b/endpoints/spell/spell.php @@ -2449,7 +2449,7 @@ class SpellBaseResponse extends TemplateResponse implements ICache if (Cfg::get('PROFILER_ENABLE') && $hasCompletion) { $x = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_completion_spells WHERE `spellId` = ?d', $this->typeId); - $y = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_profiles WHERE `realm` IS NOT NULL AND `realmGUID` IS NOT NULL AND `cuFlags` & ?d = 0', PROFILER_CU_NEEDS_RESYNC); + $y = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_profiles WHERE `custom` = 0 AND `stub` = 0'); $infobox[] = Lang::profiler('attainedBy', [round(($x ?: 0) * 100 / ($y ?: 1))]); // completion row added by InfoboxMarkup diff --git a/endpoints/title/title.php b/endpoints/title/title.php index 1c935196..726c9dfe 100644 --- a/endpoints/title/title.php +++ b/endpoints/title/title.php @@ -91,7 +91,7 @@ class TitleBaseResponse extends TemplateResponse implements ICache if (Cfg::get('PROFILER_ENABLE')) { $x = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_completion_titles WHERE `titleId` = ?d', $this->typeId); - $y = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_profiles WHERE `realm` IS NOT NULL AND `realmGUID` IS NOT NULL AND `cuFlags` & ?d = 0', PROFILER_CU_NEEDS_RESYNC); + $y = DB::Aowow()->selectCell('SELECT COUNT(1) FROM ?_profiler_profiles WHERE `custom` = 0 AND `stub` = 0'); $infobox[] = Lang::profiler('attainedBy', [round(($x ?: 0) * 100 / ($y ?: 1))]); // completion row added by InfoboxMarkup diff --git a/endpoints/user/user.php b/endpoints/user/user.php index 72b87671..93b8c2af 100644 --- a/endpoints/user/user.php +++ b/endpoints/user/user.php @@ -235,7 +235,7 @@ class UserBaseResponse extends TemplateResponse { $conditions = array( ['OR', ['cuFlags', PROFILER_CU_PUBLISHED, '&'], ['ap.extraFlags', PROFILER_CU_PUBLISHED, '&']], - [['cuFlags', PROFILER_CU_DELETED, '&'], 0], + ['deleted', 0], ['OR', ['user', $this->user['id']], ['ap.accountId', $this->user['id']]] ); diff --git a/includes/components/profiler.class.php b/includes/components/profiler.class.php index bfaa1128..d7b1a621 100644 --- a/includes/components/profiler.class.php +++ b/includes/components/profiler.class.php @@ -503,7 +503,7 @@ class Profiler // char is flagged for rename if ($char['at_login'] & 0x1) { - $ri = DB::Aowow()->selectCell('SELECT MAX(`renameItr`) FROM ?_profiler_profiles WHERE `realm` = ?d AND `realmGUID` IS NOT NULL AND `name` = ?', $realmId, $char['name']); + $ri = DB::Aowow()->selectCell('SELECT MAX(`renameItr`) FROM ?_profiler_profiles WHERE `realm` = ?d AND `custom` = 0 AND `name` = ?', $realmId, $char['name']); $data['renameItr'] = $ri ? ++$ri : 1; } @@ -827,7 +827,7 @@ class Profiler 'realmGUID' => $guild['id'], 'name' => $guild['name'], 'nameUrl' => self::urlize($guild['name']), - 'cuFlags' => PROFILER_CU_NEEDS_RESYNC + 'stub' => 1 ); $guildId = DB::Aowow()->query('INSERT IGNORE INTO ?_profiler_guild (?#) VALUES (?a)', array_keys($gData), array_values($gData)); @@ -853,7 +853,7 @@ class Profiler 'name' => $t['name'], 'nameUrl' => self::urlize($t['name']), 'type' => $t['type'], - 'cuFlags' => PROFILER_CU_NEEDS_RESYNC + 'stub' => 1 ); $teamId = DB::Aowow()->query('INSERT IGNORE INTO ?_profiler_arena_team (?#) VALUES (?a)', array_keys($team), array_values($team)); @@ -889,7 +889,7 @@ class Profiler /*********************/ if (DB::Aowow()->query('UPDATE ?_profiler_profiles SET ?a WHERE `realm` = ?d AND `realmGUID` = ?d', $data, $realmId, $charGuid) !== null) - DB::Aowow()->query('UPDATE ?_profiler_profiles SET `cuFlags` = `cuFlags` & ?d WHERE `id` = ?d', ~PROFILER_CU_NEEDS_RESYNC, $profileId); + DB::Aowow()->query('UPDATE ?_profiler_profiles SET `stub` = 0 WHERE `id` = ?d', $profileId); return true; } @@ -956,7 +956,7 @@ class Profiler /* mark guild as done */ /*********************/ - DB::Aowow()->query('UPDATE ?_profiler_guild SET `cuFlags` = `cuFlags` & ?d WHERE `id` = ?d', ~PROFILER_CU_NEEDS_RESYNC, $guildId); + DB::Aowow()->query('UPDATE ?_profiler_guild SET `stub` = 0 WHERE `id` = ?d', $guildId); return true; } @@ -1056,7 +1056,7 @@ class Profiler /* mark team as done */ /*********************/ - DB::Aowow()->query('UPDATE ?_profiler_arena_team SET `cuFlags` = `cuFlags` & ?d WHERE `id` = ?d', ~PROFILER_CU_NEEDS_RESYNC, $teamId); + DB::Aowow()->query('UPDATE ?_profiler_arena_team SET `stub` = 0 WHERE `id` = ?d', $teamId); return true; } diff --git a/includes/dbtypes/arenateam.class.php b/includes/dbtypes/arenateam.class.php index 8bb26a37..a5947644 100644 --- a/includes/dbtypes/arenateam.class.php +++ b/includes/dbtypes/arenateam.class.php @@ -235,7 +235,7 @@ class RemoteArenaTeamList extends ArenaTeamList 'nameUrl' => Profiler::urlize($this->getField('name')), 'type' => $this->getField('type'), 'rating' => $this->getField('rating'), - 'cuFlags' => PROFILER_CU_NEEDS_RESYNC + 'stub' => 1 ); } diff --git a/includes/dbtypes/guild.class.php b/includes/dbtypes/guild.class.php index 93f1c9d1..b58e288c 100644 --- a/includes/dbtypes/guild.class.php +++ b/includes/dbtypes/guild.class.php @@ -48,18 +48,16 @@ class GuildList extends DBTypeList if (!$guilds) return; - $stats = DB::Aowow()->select('SELECT `guild` AS ARRAY_KEY, `id` AS ARRAY_KEY2, `level`, `gearscore`, `achievementpoints`, IF(`cuFlags` & ?d, 0, 1) AS "synced" FROM ?_profiler_profiles WHERE `guild` IN (?a) ORDER BY `gearscore` DESC', PROFILER_CU_NEEDS_RESYNC, $guilds); + $stats = DB::Aowow()->select('SELECT `guild` AS ARRAY_KEY, `id` AS ARRAY_KEY2, `level`, `gearscore`, `achievementpoints` FROM ?_profiler_profiles WHERE `guild` IN (?a) AND `stub` = 0 ORDER BY `gearscore` DESC', $guilds); foreach ($this->iterate() as &$_curTpl) { $id = $_curTpl['id']; if (empty($stats[$id])) continue; - $guildStats = array_filter($stats[$id], function ($x) { return $x['synced']; } ); - if (!$guildStats) - continue; + $guildStats = $stats[$id]; - $nMaxLevel = count(array_filter($stats[$id], function ($x) { return $x['level'] >= MAX_LEVEL; } )); + $nMaxLevel = count(array_filter($stats[$id], fn($x) => $x['level'] >= MAX_LEVEL)); $levelMod = 1.0; if ($nMaxLevel < 25) @@ -227,7 +225,7 @@ class RemoteGuildList extends GuildList 'realmGUID' => $this->getField('guildid'), 'name' => $this->getField('name'), 'nameUrl' => Profiler::urlize($this->getField('name')), - 'cuFlags' => PROFILER_CU_NEEDS_RESYNC + 'stub' => 1 ); } diff --git a/includes/dbtypes/profile.class.php b/includes/dbtypes/profile.class.php index fe109400..98819401 100644 --- a/includes/dbtypes/profile.class.php +++ b/includes/dbtypes/profile.class.php @@ -83,7 +83,7 @@ class ProfileList extends DBTypeList if ($this->getField('cuFlags') & PROFILER_CU_PINNED) $data[$this->id]['pinned'] = 1; - if ($this->getField('cuFlags') & PROFILER_CU_DELETED) + if ($this->getField('deleted')) $data[$this->id]['deleted'] = 1; } @@ -168,7 +168,7 @@ class ProfileList extends DBTypeList public function isCustom() : bool { - return $this->getField('cuFlags') & PROFILER_CU_PROFILE; + return $this->getField('custom'); } public function isVisibleToUser() : bool @@ -176,7 +176,7 @@ class ProfileList extends DBTypeList if (!$this->isCustom() || User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU)) return true; - if ($this->getField('cuFlags') & PROFILER_CU_DELETED) + if ($this->getField('deleted')) return false; if (User::$id == $this->getField('user')) @@ -515,7 +515,7 @@ class RemoteProfileList extends ProfileList if ($curTpl['at_login'] & 0x1) { if (!isset($this->rnItr[$curTpl['name']])) - $this->rnItr[$curTpl['name']] = DB::Aowow()->selectCell('SELECT MAX(`renameItr`) FROM ?_profiler_profiles WHERE `realm` = ?d AND `realmGUID` IS NOT NULL AND `name` = ?', $r, $curTpl['name']) ?: 0; + $this->rnItr[$curTpl['name']] = DB::Aowow()->selectCell('SELECT MAX(`renameItr`) FROM ?_profiler_profiles WHERE `realm` = ?d AND `custom` = 0 AND `name` = ?', $r, $curTpl['name']) ?: 0; // already saved as "pending rename" if ($rnItr = DB::Aowow()->selectCell('SELECT `renameItr` FROM ?_profiler_profiles WHERE `realm` = ?d AND `realmGUID` = ?d', $r, $g)) @@ -606,7 +606,7 @@ class RemoteProfileList extends ProfileList 'gender' => $this->getField('gender'), 'guild' => $guildGUID ?: null, 'guildrank' => $guildGUID ? $this->getField('guildrank') : null, - 'cuFlags' => PROFILER_CU_NEEDS_RESYNC + 'stub' => 1 ); if ($guildGUID && empty($guildData[$realmId.'-'.$guildGUID])) @@ -615,7 +615,7 @@ class RemoteProfileList extends ProfileList 'realmGUID' => $guildGUID, 'name' => $this->getField('guildname'), 'nameUrl' => Profiler::urlize($this->getField('guildname')), - 'cuFlags' => PROFILER_CU_NEEDS_RESYNC + 'stub' => 1 ); } @@ -643,8 +643,7 @@ class RemoteProfileList extends ProfileList // merge back local ids $localIds = DB::Aowow()->select( - 'SELECT CONCAT(`realm`, ":", `realmGUID`) AS ARRAY_KEY, `id`, `gearscore` FROM ?_profiler_profiles WHERE (`cuFlags` & ?d) = 0 AND `realm` IN (?a) AND `realmGUID` IN (?a)', - PROFILER_CU_PROFILE, + 'SELECT CONCAT(`realm`, ":", `realmGUID`) AS ARRAY_KEY, `id`, `gearscore` FROM ?_profiler_profiles WHERE `custom` = 0 AND `realm` IN (?a) AND `realmGUID` IN (?a)', array_column($baseData, 'realm'), array_column($baseData, 'realmGUID') ); diff --git a/includes/defines.php b/includes/defines.php index b6eda11c..d2c944d8 100644 --- a/includes/defines.php +++ b/includes/defines.php @@ -374,9 +374,9 @@ define('QUEST_CU_PART_OF_SERIES', 0x0200); define('PROFILER_CU_PUBLISHED', 0x01); define('PROFILER_CU_PINNED', 0x02); -define('PROFILER_CU_DELETED', 0x04); -define('PROFILER_CU_PROFILE', 0x08); -define('PROFILER_CU_NEEDS_RESYNC', 0x10); +// define('PROFILER_CU_DELETED', 0x04); // migrated to separate db cols +// define('PROFILER_CU_PROFILE', 0x08); +// define('PROFILER_CU_NEEDS_RESYNC', 0x10); define('GUIDE_CU_NO_QUICKFACTS', 0x100); // merge with CC_FLAG_* define('GUIDE_CU_NO_RATING', 0x200); diff --git a/includes/user.class.php b/includes/user.class.php index 7233b016..c16c0c7e 100644 --- a/includes/user.class.php +++ b/includes/user.class.php @@ -785,7 +785,7 @@ class User // the old approach ['OR', ['user', self::$id], ['ap.accountId', self::$id]] caused keys to not get used $conditions = $ap ? [['OR', ['user', self::$id], ['id', $ap]]] : ['user', self::$id]; if (!self::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU)) - $conditions[] = [['cuFlags', PROFILER_CU_DELETED, '&'], 0]; + $conditions[] = ['deleted', 0]; self::$profiles = (new LocalProfileList($conditions)); } diff --git a/setup/sql/01-db_structure.sql b/setup/sql/01-db_structure.sql index 3434c71c..04d45dc6 100644 --- a/setup/sql/01-db_structure.sql +++ b/setup/sql/01-db_structure.sql @@ -1663,6 +1663,7 @@ CREATE TABLE `aowow_profiler_arena_team` ( `nameUrl` varchar(24) NOT NULL, `type` tinyint(3) unsigned NOT NULL DEFAULT 0, `cuFlags` int(10) unsigned NOT NULL DEFAULT 0 COMMENT 'see defines.php for flags', + `stub` tinyint(1) DEFAULT 0 COMMENT 'arena team stub needs resync', `rating` smallint(5) unsigned NOT NULL DEFAULT 0, `seasonGames` smallint(5) unsigned NOT NULL DEFAULT 0, `seasonWins` smallint(5) unsigned NOT NULL DEFAULT 0, @@ -1676,7 +1677,8 @@ CREATE TABLE `aowow_profiler_arena_team` ( `borderColor` int(10) unsigned NOT NULL DEFAULT 0, PRIMARY KEY (`id`), UNIQUE KEY `realm_realmGUID` (`realm`,`realmGUID`), - KEY `name` (`name`) + KEY `name` (`name`), + KEY `idx_stub` (`stub`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -1849,6 +1851,7 @@ CREATE TABLE `aowow_profiler_guild` ( `realm` int(10) unsigned NOT NULL, `realmGUID` int(10) unsigned NOT NULL, `cuFlags` int(10) unsigned NOT NULL DEFAULT 0 COMMENT 'see defines.php for flags', + `stub` tinyint(1) DEFAULT 0 COMMENT 'guild stub needs resync', `name` varchar(26) NOT NULL, `nameUrl` varchar(26) NOT NULL, `emblemStyle` tinyint(3) unsigned NOT NULL DEFAULT 0, @@ -1860,7 +1863,8 @@ CREATE TABLE `aowow_profiler_guild` ( `createDate` int(10) unsigned NOT NULL DEFAULT 0, PRIMARY KEY (`id`), UNIQUE KEY `realm_realmGUID` (`realm`,`realmGUID`), - KEY `name` (`name`) + KEY `name` (`name`), + KEY `idx_stub` (`stub`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; @@ -1940,6 +1944,9 @@ CREATE TABLE `aowow_profiler_profiles` ( `realm` tinyint(3) unsigned DEFAULT NULL, `realmGUID` int(10) unsigned DEFAULT NULL, `cuFlags` int(10) unsigned NOT NULL DEFAULT 0 COMMENT 'see defines.php for flags', + `custom` tinyint(1) DEFAULT 0 COMMENT 'custom profile', + `stub` tinyint(1) DEFAULT 0 COMMENT 'profile stub needs resync', + `deleted` tinyint(1) DEFAULT 0 COMMENT 'only on custom profiles', `sourceId` int(10) unsigned DEFAULT NULL, `sourceName` varchar(50) DEFAULT NULL, `copy` int(10) unsigned DEFAULT NULL, @@ -1978,6 +1985,9 @@ CREATE TABLE `aowow_profiler_profiles` ( KEY `user` (`user`), KEY `guild` (`guild`), KEY `name` (`name`), + KEY `idx_custom` (`custom`), + KEY `idx_stub` (`stub`), + KEY `idx_deleted` (`deleted`), CONSTRAINT `FK_aowow_profiler_profiles_aowow_profiler_guild` FOREIGN KEY (`guild`) REFERENCES `aowow_profiler_guild` (`id`) ON DELETE SET NULL ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; diff --git a/setup/sql/updates/1762629696_01.sql b/setup/sql/updates/1762629696_01.sql new file mode 100644 index 00000000..40beca4d --- /dev/null +++ b/setup/sql/updates/1762629696_01.sql @@ -0,0 +1,18 @@ +ALTER TABLE aowow_profiler_profiles + ADD COLUMN `custom` tinyint(1) DEFAULT 0 COMMENT 'custom profile' AFTER `cuFlags`, + ADD COLUMN `stub` tinyint(1) DEFAULT 0 COMMENT 'character stub needs resync' AFTER `custom`, + ADD COLUMN `deleted` tinyint(1) DEFAULT 0 COMMENT 'only on custom profiles' AFTER `stub`, + ADD KEY `idx_custom` (`custom`), + ADD KEY `idx_stub` (`stub`), + ADD KEY `idx_deleted` (`deleted`) +; + +ALTER TABLE aowow_profiler_arena_team + ADD COLUMN `stub` tinyint(1) DEFAULT 0 COMMENT 'arena team stub needs resync' AFTER `cuFlags`, + ADD KEY `idx_stub` (`stub`) +; + +ALTER TABLE aowow_profiler_guild + ADD COLUMN `stub` tinyint(1) DEFAULT 0 COMMENT 'guild stub needs resync' AFTER `cuFlags`, + ADD KEY `idx_stub` (`stub`) +; diff --git a/setup/sql/updates/1762629696_02.sql b/setup/sql/updates/1762629696_02.sql new file mode 100644 index 00000000..c9f18965 --- /dev/null +++ b/setup/sql/updates/1762629696_02.sql @@ -0,0 +1,10 @@ +UPDATE aowow_profiler_profiles SET `deleted` = 1 WHERE `cuFlags` & 4; +UPDATE aowow_profiler_profiles SET `custom` = 1 WHERE `cuFlags` & 8; +UPDATE aowow_profiler_profiles SET `stub` = 1 WHERE `cuFlags` & 16; +UPDATE aowow_profiler_profiles SET `cuFlags` = `cuFlags` & ~(4 | 8 | 16); + +UPDATE aowow_profiler_arena_team SET `stub` = 1 WHERE `cuFlags` & 16; +UPDATE aowow_profiler_arena_team SET `cuFlags` = `cuFlags` & ~16; + +UPDATE aowow_profiler_guild SET `stub` = 1 WHERE `cuFlags` & 16; +UPDATE aowow_profiler_guild SET `cuFlags` = `cuFlags` & ~16;